about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2025-09-05 05:00:55 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2025-09-05 05:00:55 +0000
commit7c5fdb072e3d07674ba88153a4cac4f792c20fdc (patch)
tree78897a875065b81c78004b1cd0f83e78254fb11d
parent9a1eb85394e3612213e829ed871eb281079a2364 (diff)
parentb6f8824315367f73e43efe08f6e5a88cc3f117ce (diff)
downloadrust-7c5fdb072e3d07674ba88153a4cac4f792c20fdc.tar.gz
rust-7c5fdb072e3d07674ba88153a4cac4f792c20fdc.zip
Merge ref 'b3cfb8faf84c' from rust-lang/rust
Pull recent changes from https://github.com/rust-lang/rust via Josh.

Upstream ref: b3cfb8faf84c5f3b7909479a9f9b6a3290d5f4d7
Filtered ref: 8995aa7743caf019203bc853f27af6006705ae30
Upstream diff: https://github.com/rust-lang/rust/compare/9385c64c95d971329e62917adc4349c8ccdbafe0...b3cfb8faf84c5f3b7909479a9f9b6a3290d5f4d7

This merge was created using https://github.com/rust-lang/josh-sync.
-rw-r--r--Cargo.lock4
-rw-r--r--bootstrap.example.toml3
-rw-r--r--compiler/rustc_ast/src/token.rs20
-rw-r--r--compiler/rustc_attr_parsing/messages.ftl2
-rw-r--r--compiler/rustc_codegen_cranelift/src/driver/aot.rs11
-rw-r--r--compiler/rustc_codegen_gcc/src/back/lto.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs31
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs29
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs26
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl14
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs17
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs17
-rw-r--r--compiler/rustc_codegen_ssa/src/back/lto.rs22
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs52
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs137
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs91
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/messages.ftl2
-rw-r--r--compiler/rustc_driver_impl/messages.ftl4
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs20
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs8
-rw-r--r--compiler/rustc_interface/src/interface.rs6
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs54
-rw-r--r--compiler/rustc_metadata/src/creader.rs18
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs2
-rw-r--r--compiler/rustc_middle/src/middle/region.rs39
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
-rw-r--r--compiler/rustc_middle/src/ty/rvalue_scopes.rs37
-rw-r--r--compiler/rustc_mir_transform/src/check_inline_always_target_features.rs88
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs41
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs4
-rw-r--r--compiler/rustc_parse/messages.ftl2
-rw-r--r--compiler/rustc_parse/src/lib.rs20
-rw-r--r--compiler/rustc_passes/messages.ftl1
-rw-r--r--compiler/rustc_passes/src/errors.rs18
-rw-r--r--compiler/rustc_passes/src/liveness.rs50
-rw-r--r--compiler/rustc_query_system/messages.ftl4
-rw-r--r--compiler/rustc_resolve/messages.ftl2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs172
-rw-r--r--compiler/rustc_resolve/src/errors.rs12
-rw-r--r--compiler/rustc_resolve/src/late.rs52
-rw-r--r--compiler/rustc_resolve/src/lib.rs4
-rw-r--r--compiler/rustc_session/src/options.rs71
-rw-r--r--compiler/rustc_span/src/analyze_source_file.rs109
-rw-r--r--compiler/rustc_span/src/lib.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs2
-rw-r--r--compiler/rustc_type_ir/src/interner.rs7
-rw-r--r--compiler/rustc_type_ir/src/solve/inspect.rs2
-rw-r--r--library/alloc/src/raw_vec/mod.rs27
-rw-r--r--library/core/src/array/mod.rs1
-rw-r--r--library/core/src/intrinsics/fallback.rs73
-rw-r--r--library/core/src/intrinsics/mod.rs55
-rw-r--r--library/core/src/iter/adapters/chain.rs1
-rw-r--r--library/core/src/iter/adapters/peekable.rs102
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/num/int_macros.rs2
-rw-r--r--library/core/src/num/mod.rs24
-rw-r--r--library/core/src/num/uint_macros.rs75
-rw-r--r--library/core/src/ops/range.rs1
-rw-r--r--library/core/src/ptr/mut_ptr.rs1
-rw-r--r--library/coretests/tests/iter/adapters/peekable.rs86
-rw-r--r--library/coretests/tests/lib.rs2
-rw-r--r--library/coretests/tests/num/uint_macros.rs36
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/int.rs1
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/num/uint.rs1
-rw-r--r--library/std/src/fs/tests.rs112
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/unix/fs.rs89
-rw-r--r--library/std/src/os/windows/fs.rs43
-rw-r--r--library/std/src/path.rs10
-rw-r--r--library/std/src/sys/fd/unix.rs65
-rw-r--r--library/std/src/sys/fs/unix.rs4
-rw-r--r--library/std/src/sys/fs/windows.rs4
-rw-r--r--library/std/src/sys/pal/windows/handle.rs13
-rw-r--r--library/std/tests/path.rs8
-rw-r--r--src/bootstrap/Cargo.lock138
-rw-r--r--src/bootstrap/Cargo.toml4
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs19
-rw-r--r--src/bootstrap/src/core/build_steps/clippy.rs21
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs20
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/run.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs162
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs18
-rw-r--r--src/bootstrap/src/core/builder/cargo.rs30
-rw-r--r--src/bootstrap/src/core/builder/tests.rs45
-rw-r--r--src/bootstrap/src/core/config/config.rs3
-rw-r--r--src/bootstrap/src/core/config/toml/rust.rs2
-rw-r--r--src/bootstrap/src/lib.rs23
-rw-r--r--src/bootstrap/src/utils/cc_detect/tests.rs21
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md7
-rw-r--r--src/doc/rustc/src/command-line-arguments/print-options.md2
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/windows-msvc.md5
-rwxr-xr-xsrc/etc/htmldocck.py2
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/config.rs14
-rw-r--r--src/librustdoc/html/static/js/search.js9
-rw-r--r--src/librustdoc/html/static/js/stringdex.d.ts13
-rw-r--r--src/librustdoc/html/static/js/stringdex.js783
-rw-r--r--src/librustdoc/scrape_examples.rs7
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/.cargo/config.toml7
-rw-r--r--src/tools/clippy/CHANGELOG.md6
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md14
-rw-r--r--src/tools/clippy/clippy.toml6
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs6
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml4
-rw-r--r--src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/async_yields_async.rs60
-rw-r--r--src/tools/clippy/clippy_lints/src/bool_comparison.rs179
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs80
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs67
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/float_literal.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/instant_subtraction.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_include_file.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/map_unit_fn.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs49
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/try_err.rs40
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_flatten.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_identity.rs96
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_reference.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs228
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_for_each.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/panic_unimplemented.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/semicolon_block.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/types/rc_buffer.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_unit.rs58
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap_in_result.rs206
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/vec.rs232
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/zombie_processes.rs20
-rw-r--r--src/tools/clippy/clippy_utils/README.md2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs27
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs55
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs9
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs8
-rw-r--r--src/tools/clippy/rust-toolchain.toml2
-rw-r--r--src/tools/clippy/src/driver.rs3
-rw-r--r--src/tools/clippy/tests/config-consistency.rs30
-rw-r--r--src/tools/clippy/tests/no-profile-in-cargo-toml.rs34
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_precision/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.fixed38
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.rs38
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.stderr38
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr3
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.fixed11
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.rs11
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_result_states.stderr10
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.fixed39
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.rs41
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.stderr50
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.fixed39
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.rs39
-rw-r--r--src/tools/clippy/tests/ui/async_yields_async.stderr47
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.fixed167
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.rs167
-rw-r--r--src/tools/clippy/tests/ui/bool_comparison.stderr154
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed39
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs25
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr66
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.fixed55
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.rs55
-rw-r--r--src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.stderr83
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.rs41
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.stderr71
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match2.stderr2
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.fixed38
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.rs41
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls.stderr47
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls_derive_const.fixed25
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls_derive_const.rs32
-rw-r--r--src/tools/clippy/tests/ui/derivable_impls_derive_const.stderr46
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed1
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs1
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.stderr44
-rw-r--r--src/tools/clippy/tests/ui/entry_unfixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed45
-rw-r--r--src/tools/clippy/tests/ui/eta.rs45
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr28
-rw-r--r--src/tools/clippy/tests/ui/excessive_precision.fixed45
-rw-r--r--src/tools/clippy/tests/ui/excessive_precision.rs45
-rw-r--r--src/tools/clippy/tests/ui/excessive_precision.stderr85
-rw-r--r--src/tools/clippy/tests/ui/float_equality_without_abs.rs14
-rw-r--r--src/tools/clippy/tests/ui/float_equality_without_abs.stderr18
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.fixed41
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.rs51
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.stderr25
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.rs15
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.stderr12
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.fixed4
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.rs4
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.stderr30
-rw-r--r--src/tools/clippy/tests/ui/map_identity.fixed20
-rw-r--r--src/tools/clippy/tests/ui/map_identity.rs16
-rw-r--r--src/tools/clippy/tests/ui/map_identity.stderr66
-rw-r--r--src/tools/clippy/tests/ui/missing_inline.rs7
-rw-r--r--src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.rs29
-rw-r--r--src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.stderr36
-rw-r--r--src/tools/clippy/tests/ui/mut_reference.fixed170
-rw-r--r--src/tools/clippy/tests/ui/mut_reference.rs152
-rw-r--r--src/tools/clippy/tests/ui/mut_reference.stderr76
-rw-r--r--src/tools/clippy/tests/ui/needless_bool/fixable.stderr8
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_unfixable.rs19
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr38
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop.rs32
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop.stderr26
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.rs2
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.stderr50
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed9
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs9
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr18
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.fixed6
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.rs6
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.stderr10
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.rs15
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.stderr46
-rw-r--r--src/tools/clippy/tests/ui/print_literal.fixed13
-rw-r--r--src/tools/clippy/tests/ui/print_literal.rs14
-rw-r--r--src/tools/clippy/tests/ui/print_literal.stderr38
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.fixed6
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.rs6
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.stderr8
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.fixed6
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.rs6
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.stderr8
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block.fixed5
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block.rs5
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.fixed11
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.rs11
-rw-r--r--src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.stderr16
-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/unit_cmp.rs17
-rw-r--r--src/tools/clippy/tests/ui/unit_cmp.stderr20
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_clone.stderr12
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.fixed25
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.rs25
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.stderr54
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.edition2021.fixed27
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.edition2021.stderr6
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.edition2024.fixed29
-rw-r--r--src/tools/clippy/tests/ui/unused_unit.rs29
-rw-r--r--src/tools/clippy/tests/ui/unwrap_in_result.rs70
-rw-r--r--src/tools/clippy/tests/ui/unwrap_in_result.stderr132
-rw-r--r--src/tools/clippy/tests/ui/vec.fixed9
-rw-r--r--src/tools/clippy/tests/ui/vec.rs9
-rw-r--r--src/tools/clippy/tests/ui/vec.stderr8
-rw-r--r--src/tools/clippy/triagebot.toml7
-rw-r--r--src/tools/compiletest/src/common.rs5
-rw-r--r--src/tools/compiletest/src/executor.rs88
-rw-r--r--src/tools/compiletest/src/lib.rs28
-rw-r--r--src/tools/compiletest/src/output_capture.rs52
-rw-r--r--src/tools/compiletest/src/runtest.rs96
-rw-r--r--src/tools/compiletest/src/runtest/codegen_units.rs30
-rw-r--r--src/tools/compiletest/src/runtest/compute_diff.rs7
-rw-r--r--src/tools/compiletest/src/runtest/crashes.rs8
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs20
-rw-r--r--src/tools/compiletest/src/runtest/incremental.rs2
-rw-r--r--src/tools/compiletest/src/runtest/mir_opt.rs2
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc_json.rs4
-rw-r--r--src/tools/compiletest/src/runtest/ui.rs8
-rw-r--r--src/tools/compiletest/src/util.rs2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/funnel_shl.rs7
-rw-r--r--src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr15
-rw-r--r--src/tools/miri/tests/fail/intrinsics/funnel_shr.rs7
-rw-r--r--src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr15
-rw-r--r--src/tools/miri/tests/pass/intrinsics/integer.rs8
-rw-r--r--src/tools/tidy/src/extra_checks/mod.rs20
-rw-r--r--src/tools/tidy/src/triagebot.rs7
-rw-r--r--tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/add-canonical-jump-tables-flag.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/add-cfi-normalize-integers-flag.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/add-enable-split-lto-unit-flag.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/dbg-location-on-cfi-blocks.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-checks-attr-sanitize-off.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-checks.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-trait-objects.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/external_weak_symbols.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/generalize-pointers.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/cfi/normalize-integers.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/dataflow-instrument-functions.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/memory-track-origins.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/memtag-attr-check.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/safestack-attr-check.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/sanitize-off-inlining.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/sanitize-off-kasan-asan.rs2
-rw-r--r--tests/codegen-llvm/sanitizer/sanitizer-recover.rs2
-rw-r--r--tests/run-make/multiline-args-value/cfg.stderr4
-rw-r--r--tests/run-make/multiline-args-value/check-cfg.stderr7
-rw-r--r--tests/run-make/multiline-args-value/rmake.rs34
-rw-r--r--tests/run-make/rustdoc-dep-info/rmake.rs12
-rw-r--r--tests/run-make/rustdoc-search-load-itemtype/bar.rs27
-rw-r--r--tests/run-make/rustdoc-search-load-itemtype/baz.rs3
-rw-r--r--tests/run-make/rustdoc-search-load-itemtype/foo.rs119
-rw-r--r--tests/run-make/rustdoc-search-load-itemtype/rmake.rs21
-rw-r--r--tests/run-make/sanitizer-cdylib-link/rmake.rs2
-rw-r--r--tests/run-make/sanitizer-dylib-link/rmake.rs2
-rw-r--r--tests/run-make/sanitizer-staticlib-link/rmake.rs2
-rw-r--r--tests/run-make/separate-link-fail/rmake.rs2
-rw-r--r--tests/rustdoc-gui/scrape-examples-ice-links.goml2
-rw-r--r--tests/rustdoc-gui/src/scrape_examples_ice/empty.html1
-rw-r--r--tests/rustdoc-gui/src/scrape_examples_ice/extra.html1
-rw-r--r--tests/rustdoc-gui/src/scrape_examples_ice/src/lib.rs2
-rw-r--r--tests/rustdoc/sanitizer-option.rs2
-rw-r--r--tests/ui/asm/global-asm-isnt-really-a-mir-body.rs2
-rw-r--r--tests/ui/codegen/empty-static-libs-issue-108825.rs2
-rw-r--r--tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr4
-rw-r--r--tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr4
-rw-r--r--tests/ui/const-ptr/forbidden_slices.stderr26
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr2
-rw-r--r--tests/ui/consts/const-eval/raw-bytes.32bit.stderr100
-rw-r--r--tests/ui/consts/const-eval/raw-bytes.64bit.stderr100
-rw-r--r--tests/ui/consts/const-eval/transmute-const.stderr2
-rw-r--r--tests/ui/consts/const-eval/ub-enum.stderr10
-rw-r--r--tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr12
-rw-r--r--tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr12
-rw-r--r--tests/ui/consts/const-eval/ub-int-array.stderr6
-rw-r--r--tests/ui/consts/const-eval/ub-nonnull.stderr12
-rw-r--r--tests/ui/consts/const-eval/ub-ref-ptr.stderr18
-rw-r--r--tests/ui/consts/const-eval/ub-uninhabit.stderr2
-rw-r--r--tests/ui/consts/const-eval/ub-upvars.32bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/ub-upvars.64bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/ub-wide-ptr.stderr46
-rw-r--r--tests/ui/consts/const-eval/union-ub.32bit.stderr2
-rw-r--r--tests/ui/consts/const-eval/union-ub.64bit.stderr2
-rw-r--r--tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr4
-rw-r--r--tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr10
-rw-r--r--tests/ui/consts/const_refs_to_static_fail_invalid.stderr2
-rw-r--r--tests/ui/consts/dangling-alloc-id-ice.stderr2
-rw-r--r--tests/ui/consts/dangling-zst-ice-issue-126393.stderr2
-rw-r--r--tests/ui/consts/interior-mut-const-via-union.32bit.stderr2
-rw-r--r--tests/ui/consts/interior-mut-const-via-union.64bit.stderr2
-rw-r--r--tests/ui/consts/issue-17718-const-bad-values.stderr2
-rw-r--r--tests/ui/consts/issue-63952.32bit.stderr2
-rw-r--r--tests/ui/consts/issue-63952.64bit.stderr2
-rw-r--r--tests/ui/consts/issue-79690.64bit.stderr2
-rw-r--r--tests/ui/consts/miri_unleashed/mutable_references.stderr16
-rw-r--r--tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr8
-rw-r--r--tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr8
-rw-r--r--tests/ui/consts/validate_never_arrays.stderr6
-rw-r--r--tests/ui/drop/if-let-super-let.rs112
-rw-r--r--tests/ui/feature-gates/feature-gate-target-feature-inline-always.rs9
-rw-r--r--tests/ui/feature-gates/feature-gate-target-feature-inline-always.stderr13
-rw-r--r--tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed8
-rw-r--r--tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs8
-rw-r--r--tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr25
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr2
-rw-r--r--tests/ui/linking/mixed-allocator-shim.rs16
-rw-r--r--tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr32
-rw-r--r--tests/ui/lto/issue-100772.rs2
-rw-r--r--tests/ui/or-patterns/binding-typo-2.rs122
-rw-r--r--tests/ui/or-patterns/binding-typo-2.stderr254
-rw-r--r--tests/ui/or-patterns/binding-typo.fixed32
-rw-r--r--tests/ui/or-patterns/binding-typo.rs32
-rw-r--r--tests/ui/or-patterns/binding-typo.stderr31
-rw-r--r--tests/ui/or-patterns/missing-bindings.stderr81
-rw-r--r--tests/ui/pattern/at-in-struct-patterns.rs2
-rw-r--r--tests/ui/pattern/at-in-struct-patterns.stderr2
-rw-r--r--tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr12
-rw-r--r--tests/ui/resolve/resolve-inconsistent-names.rs4
-rw-r--r--tests/ui/resolve/resolve-inconsistent-names.stderr20
-rw-r--r--tests/ui/sanitizer/address.rs2
-rw-r--r--tests/ui/sanitizer/asan_odr_windows.rs2
-rw-r--r--tests/ui/sanitizer/badfree.rs2
-rw-r--r--tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs2
-rw-r--r--tests/ui/sanitizer/cfi/async-closures.rs2
-rw-r--r--tests/ui/sanitizer/cfi/can-reveal-opaques.rs2
-rw-r--r--tests/ui/sanitizer/cfi/closures.rs2
-rw-r--r--tests/ui/sanitizer/cfi/complex-receiver.rs2
-rw-r--r--tests/ui/sanitizer/cfi/coroutine.rs1
-rw-r--r--tests/ui/sanitizer/cfi/drop-in-place.rs1
-rw-r--r--tests/ui/sanitizer/cfi/drop-no-principal.rs2
-rw-r--r--tests/ui/sanitizer/cfi/fn-ptr.rs1
-rw-r--r--tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs1
-rw-r--r--tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs2
-rw-r--r--tests/ui/sanitizer/cfi/self-ref.rs2
-rw-r--r--tests/ui/sanitizer/cfi/sized-associated-ty.rs2
-rw-r--r--tests/ui/sanitizer/cfi/supertraits.rs2
-rw-r--r--tests/ui/sanitizer/cfi/transparent-has-regions.rs2
-rw-r--r--tests/ui/sanitizer/cfi/virtual-auto.rs2
-rw-r--r--tests/ui/sanitizer/dataflow.rs2
-rw-r--r--tests/ui/sanitizer/hwaddress.rs2
-rw-r--r--tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs2
-rw-r--r--tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs2
-rw-r--r--tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs2
-rw-r--r--tests/ui/sanitizer/kcfi-mangling.rs2
-rw-r--r--tests/ui/sanitizer/leak.rs2
-rw-r--r--tests/ui/sanitizer/memory-eager.rs2
-rw-r--r--tests/ui/sanitizer/memory-passing.rs2
-rw-r--r--tests/ui/sanitizer/memory.rs2
-rw-r--r--tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs2
-rw-r--r--tests/ui/sanitizer/thread.rs2
-rw-r--r--tests/ui/sanitizer/use-after-scope.rs2
-rw-r--r--tests/ui/span/issue-39698.stderr24
-rw-r--r--tests/ui/statics/mutable_memory_validation.stderr2
-rw-r--r--tests/ui/target-feature/inline-always.aarch64.stderr60
-rw-r--r--tests/ui/target-feature/inline-always.rs54
-rw-r--r--tests/ui/target-feature/invalid-attribute.rs2
-rw-r--r--tests/ui/target-feature/invalid-attribute.stderr28
-rw-r--r--tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs7
-rw-r--r--tests/ui/target_modifiers/auxiliary/no-sanitizers.rs6
-rw-r--r--tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs10
-rw-r--r--tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs18
-rw-r--r--tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr13
-rw-r--r--tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr13
-rw-r--r--tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs19
-rw-r--r--tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr13
-rw-r--r--tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr13
-rw-r--r--tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr13
-rw-r--r--tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs23
-rw-r--r--tests/ui/type/pattern_types/validity.stderr10
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs2
-rw-r--r--tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr2
-rw-r--r--triagebot.toml15
501 files changed, 9297 insertions, 2884 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 52f50481157..c4c96f1569b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5152,9 +5152,9 @@ dependencies = [
 
 [[package]]
 name = "stringdex"
-version = "0.0.1-alpha4"
+version = "0.0.1-alpha9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2841fd43df5b1ff1b042e167068a1fe9b163dc93041eae56ab2296859013a9a0"
+checksum = "7081029913fd7d591c0112182aba8c98ae886b4f12edb208130496cd17dc3c15"
 dependencies = [
  "stacker",
 ]
diff --git a/bootstrap.example.toml b/bootstrap.example.toml
index 16fd9241a17..eac93957797 100644
--- a/bootstrap.example.toml
+++ b/bootstrap.example.toml
@@ -856,6 +856,9 @@
 # as libstd features, this option can also be used to configure features such as optimize_for_size.
 #rust.std-features = ["panic_unwind"]
 
+# Trigger a `DebugBreak` after an internal compiler error during bootstrap on Windows
+#rust.break-on-ice = true
+
 # =============================================================================
 # Distribution options
 #
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index ea98bebd305..6dc6d1026f6 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -22,8 +22,7 @@ pub enum CommentKind {
     Block,
 }
 
-// This type must not implement `Hash` due to the unusual `PartialEq` impl below.
-#[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum InvisibleOrigin {
     // From the expansion of a metavariable in a declarative macro.
     MetaVar(MetaVarKind),
@@ -45,20 +44,6 @@ impl InvisibleOrigin {
     }
 }
 
-impl PartialEq for InvisibleOrigin {
-    #[inline]
-    fn eq(&self, _other: &InvisibleOrigin) -> bool {
-        // When we had AST-based nonterminals we couldn't compare them, and the
-        // old `Nonterminal` type had an `eq` that always returned false,
-        // resulting in this restriction:
-        // https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment
-        // This `eq` emulates that behaviour. We could consider lifting this
-        // restriction now but there are still cases involving invisible
-        // delimiters that make it harder than it first appears.
-        false
-    }
-}
-
 /// Annoyingly similar to `NonterminalKind`, but the slight differences are important.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Encodable, Decodable, Hash, HashStable_Generic)]
 pub enum MetaVarKind {
@@ -142,7 +127,8 @@ impl Delimiter {
         }
     }
 
-    // This exists because `InvisibleOrigin`s should be compared. It is only used for assertions.
+    // This exists because `InvisibleOrigin`s should not be compared. It is only used for
+    // assertions.
     pub fn eq_ignoring_invisible_origin(&self, other: &Delimiter) -> bool {
         match (self, other) {
             (Delimiter::Parenthesis, Delimiter::Parenthesis) => true,
diff --git a/compiler/rustc_attr_parsing/messages.ftl b/compiler/rustc_attr_parsing/messages.ftl
index b8a748563d5..7fa1293463c 100644
--- a/compiler/rustc_attr_parsing/messages.ftl
+++ b/compiler/rustc_attr_parsing/messages.ftl
@@ -151,7 +151,7 @@ attr_parsing_unrecognized_repr_hint =
 attr_parsing_unstable_cfg_target_compact =
     compact `cfg(target(..))` is experimental and subject to change
 
-attr_parsing_unstable_feature_bound_incompatible_stability = Item annotated with `#[unstable_feature_bound]` should not be stable
+attr_parsing_unstable_feature_bound_incompatible_stability = item annotated with `#[unstable_feature_bound]` should not be stable
     .help = If this item is meant to be stable, do not use any functions annotated with `#[unstable_feature_bound]`. Otherwise, mark this item as unstable with `#[unstable]`
 
 attr_parsing_unsupported_literal_cfg_boolean =
diff --git a/compiler/rustc_codegen_cranelift/src/driver/aot.rs b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
index 7e77781dc2f..c3adb5e767e 100644
--- a/compiler/rustc_codegen_cranelift/src/driver/aot.rs
+++ b/compiler/rustc_codegen_cranelift/src/driver/aot.rs
@@ -12,9 +12,7 @@ use cranelift_object::{ObjectBuilder, ObjectModule};
 use rustc_codegen_ssa::assert_module_sources::CguReuse;
 use rustc_codegen_ssa::back::link::ensure_removed;
 use rustc_codegen_ssa::base::determine_cgu_reuse;
-use rustc_codegen_ssa::{
-    CodegenResults, CompiledModule, CrateInfo, ModuleKind, errors as ssa_errors,
-};
+use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, errors as ssa_errors};
 use rustc_data_structures::profiling::SelfProfilerRef;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
@@ -363,7 +361,6 @@ fn emit_cgu(
         invocation_temp,
         prof,
         product.object,
-        ModuleKind::Regular,
         name.clone(),
         producer,
     )?;
@@ -372,7 +369,6 @@ fn emit_cgu(
         module_regular,
         module_global_asm: global_asm_object_file.map(|global_asm_object_file| CompiledModule {
             name: format!("{name}.asm"),
-            kind: ModuleKind::Regular,
             object: Some(global_asm_object_file),
             dwarf_object: None,
             bytecode: None,
@@ -389,7 +385,6 @@ fn emit_module(
     invocation_temp: Option<&str>,
     prof: &SelfProfilerRef,
     mut object: cranelift_object::object::write::Object<'_>,
-    kind: ModuleKind,
     name: String,
     producer_str: &str,
 ) -> Result<CompiledModule, String> {
@@ -430,7 +425,6 @@ fn emit_module(
 
     Ok(CompiledModule {
         name,
-        kind,
         object: Some(tmp_file),
         dwarf_object: None,
         bytecode: None,
@@ -485,7 +479,6 @@ fn reuse_workproduct_for_cgu(
     Ok(ModuleCodegenResult {
         module_regular: CompiledModule {
             name: cgu.name().to_string(),
-            kind: ModuleKind::Regular,
             object: Some(obj_out_regular),
             dwarf_object: None,
             bytecode: None,
@@ -495,7 +488,6 @@ fn reuse_workproduct_for_cgu(
         },
         module_global_asm: source_file_global_asm.map(|source_file| CompiledModule {
             name: cgu.name().to_string(),
-            kind: ModuleKind::Regular,
             object: Some(obj_out_global_asm),
             dwarf_object: None,
             bytecode: None,
@@ -651,7 +643,6 @@ fn emit_allocator_module(tcx: TyCtxt<'_>) -> Option<CompiledModule> {
             tcx.sess.invocation_temp.as_deref(),
             &tcx.sess.prof,
             product.object,
-            ModuleKind::Allocator,
             "allocator_shim".to_owned(),
             &crate::debuginfo::producer(tcx.sess),
         ) {
diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs
index fcee6b6df62..9d8ce2383f2 100644
--- a/compiler/rustc_codegen_gcc/src/back/lto.rs
+++ b/compiler/rustc_codegen_gcc/src/back/lto.rs
@@ -204,7 +204,7 @@ fn fat_lto(
             let path = tmp_path.path().to_path_buf().join(&module.name);
             let path = path.to_str().expect("path");
             let context = &module.module_llvm.context;
-            let config = cgcx.config(module.kind);
+            let config = &cgcx.module_config;
             // NOTE: we need to set the optimization level here in order for LTO to do its job.
             context.set_optimization_level(to_gcc_opt_level(config.opt_level));
             context.add_command_line_option("-flto=auto");
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 5affb26483a..9f2d37d39d8 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -29,8 +29,18 @@ pub(crate) fn apply_to_callsite(callsite: &Value, idx: AttributePlace, attrs: &[
 }
 
 /// Get LLVM attribute for the provided inline heuristic.
-#[inline]
-fn inline_attr<'ll>(cx: &CodegenCx<'ll, '_>, inline: InlineAttr) -> Option<&'ll Attribute> {
+pub(crate) fn inline_attr<'ll, 'tcx>(
+    cx: &CodegenCx<'ll, 'tcx>,
+    instance: ty::Instance<'tcx>,
+) -> Option<&'ll Attribute> {
+    // `optnone` requires `noinline`
+    let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
+    let inline = match (codegen_fn_attrs.inline, &codegen_fn_attrs.optimize) {
+        (_, OptimizeAttr::DoNotOptimize) => InlineAttr::Never,
+        (InlineAttr::None, _) if instance.def.requires_inline(cx.tcx) => InlineAttr::Hint,
+        (inline, _) => inline,
+    };
+
     if !cx.tcx.sess.opts.unstable_opts.inline_llvm {
         // disable LLVM inlining
         return Some(AttributeKind::NoInline.create_attr(cx.llcx));
@@ -346,14 +356,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
         OptimizeAttr::Speed => {}
     }
 
-    // `optnone` requires `noinline`
-    let inline = match (codegen_fn_attrs.inline, &codegen_fn_attrs.optimize) {
-        (_, OptimizeAttr::DoNotOptimize) => InlineAttr::Never,
-        (InlineAttr::None, _) if instance.def.requires_inline(cx.tcx) => InlineAttr::Hint,
-        (inline, _) => inline,
-    };
-    to_add.extend(inline_attr(cx, inline));
-
     if cx.sess().must_emit_unwind_tables() {
         to_add.push(uwtable_attr(cx.llcx, cx.sess().opts.unstable_opts.use_sync_unwind));
     }
@@ -488,6 +490,14 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
     let function_features =
         codegen_fn_attrs.target_features.iter().map(|f| f.name.as_str()).collect::<Vec<&str>>();
 
+    // Apply function attributes as per usual if there are no user defined
+    // target features otherwise this will get applied at the callsite.
+    if function_features.is_empty() {
+        if let Some(inline_attr) = inline_attr(cx, instance) {
+            to_add.push(inline_attr);
+        }
+    }
+
     let function_features = function_features
         .iter()
         // Convert to LLVMFeatures and filter out unavailable ones
@@ -517,6 +527,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
     let function_features = function_features.iter().map(|s| s.as_str());
     let target_features: String =
         global_features.chain(function_features).intersperse(",").collect();
+
     if !target_features.is_empty() {
         to_add.push(llvm::CreateAttrStringValue(cx.llcx, "target-features", &target_features));
     }
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index fc38c4f3e51..326b876e7e6 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -11,7 +11,7 @@ use object::{Object, ObjectSection};
 use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared};
 use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput};
 use rustc_codegen_ssa::traits::*;
-use rustc_codegen_ssa::{ModuleCodegen, ModuleKind, looks_like_rust_object_file};
+use rustc_codegen_ssa::{ModuleCodegen, looks_like_rust_object_file};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::memmap::Mmap;
 use rustc_errors::DiagCtxtHandle;
@@ -43,9 +43,7 @@ fn prepare_lto(
         .map(|symbol| CString::new(symbol.to_owned()).unwrap())
         .collect::<Vec<CString>>();
 
-    if cgcx.regular_module_config.instrument_coverage
-        || cgcx.regular_module_config.pgo_gen.enabled()
-    {
+    if cgcx.module_config.instrument_coverage || cgcx.module_config.pgo_gen.enabled() {
         // These are weak symbols that point to the profile version and the
         // profile name, which need to be treated as exported so LTO doesn't nix
         // them.
@@ -55,15 +53,15 @@ fn prepare_lto(
         symbols_below_threshold.extend(PROFILER_WEAK_SYMBOLS.iter().map(|&sym| sym.to_owned()));
     }
 
-    if cgcx.regular_module_config.sanitizer.contains(SanitizerSet::MEMORY) {
+    if cgcx.module_config.sanitizer.contains(SanitizerSet::MEMORY) {
         let mut msan_weak_symbols = Vec::new();
 
         // Similar to profiling, preserve weak msan symbol during LTO.
-        if cgcx.regular_module_config.sanitizer_recover.contains(SanitizerSet::MEMORY) {
+        if cgcx.module_config.sanitizer_recover.contains(SanitizerSet::MEMORY) {
             msan_weak_symbols.push(c"__msan_keep_going");
         }
 
-        if cgcx.regular_module_config.sanitizer_memory_track_origins != 0 {
+        if cgcx.module_config.sanitizer_memory_track_origins != 0 {
             msan_weak_symbols.push(c"__msan_track_origins");
         }
 
@@ -227,15 +225,9 @@ fn fat_lto(
     // All the other modules will be serialized and reparsed into the new
     // context, so this hopefully avoids serializing and parsing the largest
     // codegen unit.
-    //
-    // Additionally use a regular module as the base here to ensure that various
-    // file copy operations in the backend work correctly. The only other kind
-    // of module here should be an allocator one, and if your crate is smaller
-    // than the allocator module then the size doesn't really matter anyway.
     let costliest_module = in_memory
         .iter()
         .enumerate()
-        .filter(|&(_, module)| module.kind == ModuleKind::Regular)
         .map(|(i, module)| {
             let cost = unsafe { llvm::LLVMRustModuleCost(module.module_llvm.llmod()) };
             (cost, i)
@@ -583,7 +575,7 @@ pub(crate) fn run_pass_manager(
     thin: bool,
 ) {
     let _timer = cgcx.prof.generic_activity_with_arg("LLVM_lto_optimize", &*module.name);
-    let config = cgcx.config(module.kind);
+    let config = &cgcx.module_config;
 
     // Now we have one massive module inside of llmod. Time to run the
     // LTO-specific optimization passes that LLVM provides.
@@ -745,7 +737,7 @@ pub(crate) fn optimize_thin_module(
     let module_llvm = ModuleLlvm::parse(cgcx, module_name, thin_module.data(), dcx);
     let mut module = ModuleCodegen::new_regular(thin_module.name(), module_llvm);
     // Given that the newly created module lacks a thinlto buffer for embedding, we need to re-add it here.
-    if cgcx.config(ModuleKind::Regular).embed_bitcode() {
+    if cgcx.module_config.embed_bitcode() {
         module.thin_lto_buffer = Some(thin_module.data().to_vec());
     }
     {
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 37379586d58..7d0691366e6 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -1392,7 +1392,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     fn call(
         &mut self,
         llty: &'ll Type,
-        fn_attrs: Option<&CodegenFnAttrs>,
+        fn_call_attrs: Option<&CodegenFnAttrs>,
         fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>,
         llfn: &'ll Value,
         args: &[&'ll Value],
@@ -1409,10 +1409,10 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         }
 
         // Emit CFI pointer type membership test
-        self.cfi_type_test(fn_attrs, fn_abi, instance, llfn);
+        self.cfi_type_test(fn_call_attrs, fn_abi, instance, llfn);
 
         // Emit KCFI operand bundle
-        let kcfi_bundle = self.kcfi_operand_bundle(fn_attrs, fn_abi, instance, llfn);
+        let kcfi_bundle = self.kcfi_operand_bundle(fn_call_attrs, fn_abi, instance, llfn);
         if let Some(kcfi_bundle) = kcfi_bundle.as_ref().map(|b| b.as_ref()) {
             bundles.push(kcfi_bundle);
         }
@@ -1429,6 +1429,29 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                 c"".as_ptr(),
             )
         };
+
+        if let Some(instance) = instance {
+            // Attributes on the function definition being called
+            let fn_defn_attrs = self.cx.tcx.codegen_fn_attrs(instance.def_id());
+            if let Some(fn_call_attrs) = fn_call_attrs
+                && !fn_call_attrs.target_features.is_empty()
+                // If there is an inline attribute and a target feature that matches
+                // we will add the attribute to the callsite otherwise we'll omit
+                // this and not add the attribute to prevent soundness issues.
+                && let Some(inlining_rule) = attributes::inline_attr(&self.cx, instance)
+                && self.cx.tcx.is_target_feature_call_safe(
+                    &fn_call_attrs.target_features,
+                    &fn_defn_attrs.target_features,
+                )
+            {
+                attributes::apply_to_callsite(
+                    call,
+                    llvm::AttributePlace::Function,
+                    &[inlining_rule],
+                );
+            }
+        }
+
         if let Some(fn_abi) = fn_abi {
             fn_abi.apply_attrs_callsite(self, call);
         }
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 4fd6110ac4a..257c7b95666 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -217,6 +217,10 @@ pub(crate) unsafe fn create_module<'ll>(
             // LLVM 22.0 updated the default layout on avr: https://github.com/llvm/llvm-project/pull/153010
             target_data_layout = target_data_layout.replace("n8:16", "n8")
         }
+        if sess.target.arch == "nvptx64" {
+            // LLVM 22 updated the NVPTX layout to indicate 256-bit vector load/store: https://github.com/llvm/llvm-project/pull/155198
+            target_data_layout = target_data_layout.replace("-i256:256", "");
+        }
     }
 
     // Ensure the data-layout values hardcoded remain the defaults.
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 49d3dedbeab..85f71f331a4 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -383,7 +383,9 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             | sym::rotate_left
             | sym::rotate_right
             | sym::saturating_add
-            | sym::saturating_sub => {
+            | sym::saturating_sub
+            | sym::unchecked_funnel_shl
+            | sym::unchecked_funnel_shr => {
                 let ty = args[0].layout.ty;
                 if !ty.is_integral() {
                     tcx.dcx().emit_err(InvalidMonomorphization::BasicIntegerType {
@@ -424,18 +426,26 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     sym::bitreverse => {
                         self.call_intrinsic("llvm.bitreverse", &[llty], &[args[0].immediate()])
                     }
-                    sym::rotate_left | sym::rotate_right => {
-                        let is_left = name == sym::rotate_left;
-                        let val = args[0].immediate();
-                        let raw_shift = args[1].immediate();
-                        // rotate = funnel shift with first two args the same
+                    sym::rotate_left
+                    | sym::rotate_right
+                    | sym::unchecked_funnel_shl
+                    | sym::unchecked_funnel_shr => {
+                        let is_left = name == sym::rotate_left || name == sym::unchecked_funnel_shl;
+                        let lhs = args[0].immediate();
+                        let (rhs, raw_shift) =
+                            if name == sym::rotate_left || name == sym::rotate_right {
+                                // rotate = funnel shift with first two args the same
+                                (lhs, args[1].immediate())
+                            } else {
+                                (args[1].immediate(), args[2].immediate())
+                            };
                         let llvm_name = format!("llvm.fsh{}", if is_left { 'l' } else { 'r' });
 
                         // llvm expects shift to be the same type as the values, but rust
                         // always uses `u32`.
-                        let raw_shift = self.intcast(raw_shift, self.val_ty(val), false);
+                        let raw_shift = self.intcast(raw_shift, self.val_ty(lhs), false);
 
-                        self.call_intrinsic(llvm_name, &[llty], &[val, val, raw_shift])
+                        self.call_intrinsic(llvm_name, &[llty], &[lhs, rhs, raw_shift])
                     }
                     sym::saturating_add | sym::saturating_sub => {
                         let is_add = name == sym::saturating_add;
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index 44b9941691a..dd688b8b345 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -40,15 +40,15 @@ codegen_ssa_dynamic_linking_with_lto =
     .note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO
 
 codegen_ssa_error_calling_dlltool =
-    Error calling dlltool '{$dlltool_path}': {$error}
+    error calling dlltool '{$dlltool_path}': {$error}
 
 codegen_ssa_error_creating_import_library =
-    Error creating import library for {$lib_name}: {$error}
+    error creating import library for {$lib_name}: {$error}
 
 codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
 
 codegen_ssa_error_writing_def_file =
-    Error writing .DEF file: {$error}
+    error writing .DEF file: {$error}
 
 codegen_ssa_expected_name_value_pair = expected name value pair
 
@@ -264,9 +264,9 @@ codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at c
 
 codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link
 
-codegen_ssa_static_library_native_artifacts = Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
+codegen_ssa_static_library_native_artifacts = link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
 
-codegen_ssa_static_library_native_artifacts_to_file = Native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms.
+codegen_ssa_static_library_native_artifacts_to_file = native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms.
 
 codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status}
     .note = {$output}
@@ -364,13 +364,13 @@ codegen_ssa_unable_to_run = unable to run `{$util}`: {$error}
 
 codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error}
 
-codegen_ssa_unable_to_write_debugger_visualizer = Unable to write debugger visualizer file `{$path}`: {$error}
+codegen_ssa_unable_to_write_debugger_visualizer = unable to write debugger visualizer file `{$path}`: {$error}
 
 codegen_ssa_unexpected_parameter_name = unexpected parameter name
     .label = expected `{$prefix_nops}` or `{$entry_nops}`
 
 codegen_ssa_unknown_archive_kind =
-    Don't know how to build archive of type: {$kind}
+    don't know how to build archive of type: {$kind}
 
 codegen_ssa_unknown_ctarget_feature =
     unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 19c919c0e4e..48b01ea2df1 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -58,6 +58,7 @@ use super::linker::{self, Linker};
 use super::metadata::{MetadataPosition, create_wrapper_file};
 use super::rpath::{self, RPathConfig};
 use super::{apple, versioned_llvm_target};
+use crate::base::needs_allocator_shim_for_linking;
 use crate::{
     CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file,
 };
@@ -2080,9 +2081,17 @@ fn add_local_crate_regular_objects(cmd: &mut dyn Linker, codegen_results: &Codeg
 }
 
 /// Add object files for allocator code linked once for the whole crate tree.
-fn add_local_crate_allocator_objects(cmd: &mut dyn Linker, codegen_results: &CodegenResults) {
-    if let Some(obj) = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref()) {
-        cmd.add_object(obj);
+fn add_local_crate_allocator_objects(
+    cmd: &mut dyn Linker,
+    codegen_results: &CodegenResults,
+    crate_type: CrateType,
+) {
+    if needs_allocator_shim_for_linking(&codegen_results.crate_info.dependency_formats, crate_type)
+    {
+        if let Some(obj) = codegen_results.allocator_module.as_ref().and_then(|m| m.object.as_ref())
+        {
+            cmd.add_object(obj);
+        }
     }
 }
 
@@ -2281,7 +2290,7 @@ fn linker_with_args(
         codegen_results,
         metadata,
     );
-    add_local_crate_allocator_objects(cmd, codegen_results);
+    add_local_crate_allocator_objects(cmd, codegen_results, crate_type);
 
     // Avoid linking to dynamic libraries unless they satisfy some undefined symbols
     // at the point at which they are specified on the command line.
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index df1e91b12f9..a2efd420a32 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -11,8 +11,9 @@ use rustc_metadata::{
 };
 use rustc_middle::bug;
 use rustc_middle::middle::dependency_format::Linkage;
-use rustc_middle::middle::exported_symbols;
-use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportKind};
+use rustc_middle::middle::exported_symbols::{
+    self, ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
+};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
@@ -22,6 +23,8 @@ use tracing::{debug, warn};
 
 use super::command::Command;
 use super::symbol_export;
+use crate::back::symbol_export::allocator_shim_symbols;
+use crate::base::needs_allocator_shim_for_linking;
 use crate::errors;
 
 #[cfg(test)]
@@ -1827,7 +1830,7 @@ fn exported_symbols_for_non_proc_macro(
     let export_threshold = symbol_export::crates_export_threshold(&[crate_type]);
     for_each_exported_symbols_include_dep(tcx, crate_type, |symbol, info, cnum| {
         // Do not export mangled symbols from cdylibs and don't attempt to export compiler-builtins
-        // from any cdylib. The latter doesn't work anyway as we use hidden visibility for
+        // from any dylib. The latter doesn't work anyway as we use hidden visibility for
         // compiler-builtins. Most linkers silently ignore it, but ld64 gives a warning.
         if info.level.is_below_threshold(export_threshold) && !tcx.is_compiler_builtins(cnum) {
             symbols.push((
@@ -1838,6 +1841,14 @@ fn exported_symbols_for_non_proc_macro(
         }
     });
 
+    // Mark allocator shim symbols as exported only if they were generated.
+    if export_threshold == SymbolExportLevel::Rust
+        && needs_allocator_shim_for_linking(tcx.dependency_formats(()), crate_type)
+        && tcx.allocator_kind(()).is_some()
+    {
+        symbols.extend(allocator_shim_symbols(tcx));
+    }
+
     symbols
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs
index c95038375a1..f4a9037940a 100644
--- a/compiler/rustc_codegen_ssa/src/back/lto.rs
+++ b/compiler/rustc_codegen_ssa/src/back/lto.rs
@@ -1,6 +1,7 @@
 use std::ffi::CString;
 use std::sync::Arc;
 
+use rustc_ast::expand::allocator::AllocatorKind;
 use rustc_data_structures::memmap::Mmap;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, SymbolExportLevel};
@@ -8,8 +9,9 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::config::{CrateType, Lto};
 use tracing::info;
 
-use crate::back::symbol_export::{self, symbol_name_for_instance_in_crate};
+use crate::back::symbol_export::{self, allocator_shim_symbols, symbol_name_for_instance_in_crate};
 use crate::back::write::CodegenContext;
+use crate::base::allocator_kind_for_codegen;
 use crate::errors::{DynamicLinkingWithLTO, LtoDisallowed, LtoDylib, LtoProcMacro};
 use crate::traits::*;
 
@@ -94,6 +96,19 @@ pub(super) fn exported_symbols_for_lto(
             .filter_map(|&(s, info): &(ExportedSymbol<'_>, SymbolExportInfo)| {
                 if info.level.is_below_threshold(export_threshold) || info.used {
                     Some(symbol_name_for_instance_in_crate(tcx, s, cnum))
+                } else if export_threshold == SymbolExportLevel::C
+                    && info.rustc_std_internal_symbol
+                    && let Some(AllocatorKind::Default) = allocator_kind_for_codegen(tcx)
+                {
+                    // Export the __rdl_* exports for usage by the allocator shim when not using
+                    // #[global_allocator]. Most of the conditions above are only used to avoid
+                    // unnecessary expensive symbol_name_for_instance_in_crate calls.
+                    let sym = symbol_name_for_instance_in_crate(tcx, s, cnum);
+                    if sym.contains("__rdl_") || sym.contains("__rg_oom") {
+                        Some(sym)
+                    } else {
+                        None
+                    }
                 } else {
                     None
                 }
@@ -115,6 +130,11 @@ pub(super) fn exported_symbols_for_lto(
         }
     }
 
+    // Mark allocator shim symbols as exported only if they were generated.
+    if export_threshold == SymbolExportLevel::Rust && allocator_kind_for_codegen(tcx).is_some() {
+        symbols_below_threshold.extend(allocator_shim_symbols(tcx).map(|(name, _kind)| name));
+    }
+
     symbols_below_threshold
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index d8a1480e911..b49e67217fb 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -18,7 +18,7 @@ use rustc_symbol_mangling::mangle_internal_symbol;
 use rustc_target::spec::TlsModel;
 use tracing::debug;
 
-use crate::base::allocator_kind_for_codegen;
+use crate::back::symbol_export;
 
 fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
     crates_export_threshold(tcx.crate_types())
@@ -217,31 +217,6 @@ fn exported_non_generic_symbols_provider_local<'tcx>(
         ));
     }
 
-    // Mark allocator shim symbols as exported only if they were generated.
-    if allocator_kind_for_codegen(tcx).is_some() {
-        for symbol_name in ALLOCATOR_METHODS
-            .iter()
-            .map(|method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
-            .chain([
-                mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
-                mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
-                mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
-            ])
-        {
-            let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
-
-            symbols.push((
-                exported_symbol,
-                SymbolExportInfo {
-                    level: SymbolExportLevel::Rust,
-                    kind: SymbolExportKind::Text,
-                    used: false,
-                    rustc_std_internal_symbol: true,
-                },
-            ));
-        }
-    }
-
     // Sort so we get a stable incr. comp. hash.
     symbols.sort_by_cached_key(|s| s.0.symbol_name_for_local_instance(tcx));
 
@@ -516,6 +491,31 @@ pub(crate) fn provide(providers: &mut Providers) {
         upstream_monomorphizations_for_provider;
 }
 
+pub(crate) fn allocator_shim_symbols(
+    tcx: TyCtxt<'_>,
+) -> impl Iterator<Item = (String, SymbolExportKind)> {
+    ALLOCATOR_METHODS
+        .iter()
+        .map(move |method| mangle_internal_symbol(tcx, global_fn_name(method.name).as_str()))
+        .chain([
+            mangle_internal_symbol(tcx, "__rust_alloc_error_handler"),
+            mangle_internal_symbol(tcx, OomStrategy::SYMBOL),
+            mangle_internal_symbol(tcx, NO_ALLOC_SHIM_IS_UNSTABLE),
+        ])
+        .map(move |symbol_name| {
+            let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, &symbol_name));
+
+            (
+                symbol_export::exporting_symbol_name_for_instance_in_crate(
+                    tcx,
+                    exported_symbol,
+                    LOCAL_CRATE,
+                ),
+                SymbolExportKind::Text,
+            )
+        })
+}
+
 fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel {
     // We export anything that's not mangled at the "C" layer as it probably has
     // to do with ABI concerns. We do not, however, apply such treatment to
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 8586615f7c7..f637e7f58db 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -333,8 +333,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
     pub crate_types: Vec<CrateType>,
     pub output_filenames: Arc<OutputFilenames>,
     pub invocation_temp: Option<String>,
-    pub regular_module_config: Arc<ModuleConfig>,
-    pub allocator_module_config: Arc<ModuleConfig>,
+    pub module_config: Arc<ModuleConfig>,
     pub tm_factory: TargetMachineFactoryFn<B>,
     pub msvc_imps_needed: bool,
     pub is_pe_coff: bool,
@@ -372,13 +371,6 @@ impl<B: WriteBackendMethods> CodegenContext<B> {
     pub fn create_dcx(&self) -> DiagCtxt {
         DiagCtxt::new(Box::new(self.diag_emitter.clone()))
     }
-
-    pub fn config(&self, kind: ModuleKind) -> &ModuleConfig {
-        match kind {
-            ModuleKind::Regular => &self.regular_module_config,
-            ModuleKind::Allocator => &self.allocator_module_config,
-        }
-    }
 }
 
 fn generate_thin_lto_work<B: ExtraBackendMethods>(
@@ -442,6 +434,7 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
     backend: B,
     tcx: TyCtxt<'_>,
     target_cpu: String,
+    allocator_module: Option<ModuleCodegen<B::Module>>,
 ) -> OngoingCodegen<B> {
     let (coordinator_send, coordinator_receive) = channel();
 
@@ -465,6 +458,7 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
         coordinator_receive,
         Arc::new(regular_config),
         Arc::new(allocator_config),
+        allocator_module,
         coordinator_send.clone(),
     );
 
@@ -495,7 +489,7 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
 
     let _timer = sess.timer("copy_all_cgu_workproducts_to_incr_comp_cache_dir");
 
-    for module in compiled_modules.modules.iter().filter(|m| m.kind == ModuleKind::Regular) {
+    for module in &compiled_modules.modules {
         let mut files = Vec::new();
         if let Some(object_file_path) = &module.object {
             files.push((OutputType::Object.extension(), object_file_path.as_path()));
@@ -720,15 +714,6 @@ pub(crate) enum WorkItem<B: WriteBackendMethods> {
 }
 
 impl<B: WriteBackendMethods> WorkItem<B> {
-    fn module_kind(&self) -> ModuleKind {
-        match *self {
-            WorkItem::Optimize(ref m) => m.kind,
-            WorkItem::CopyPostLtoArtifacts(_) | WorkItem::FatLto { .. } | WorkItem::ThinLto(_) => {
-                ModuleKind::Regular
-            }
-        }
-    }
-
     /// Generate a short description of this work item suitable for use as a thread name.
     fn short_description(&self) -> String {
         // `pthread_setname()` on *nix ignores anything beyond the first 15
@@ -809,19 +794,12 @@ pub(crate) fn compute_per_cgu_lto_type(
     sess_lto: &Lto,
     opts: &config::Options,
     sess_crate_types: &[CrateType],
-    module_kind: ModuleKind,
 ) -> ComputedLtoType {
     // If the linker does LTO, we don't have to do it. Note that we
     // keep doing full LTO, if it is requested, as not to break the
     // assumption that the output will be a single module.
     let linker_does_lto = opts.cg.linker_plugin_lto.enabled();
 
-    // When we're automatically doing ThinLTO for multi-codegen-unit
-    // builds we don't actually want to LTO the allocator modules if
-    // it shows up. This is due to various linker shenanigans that
-    // we'll encounter later.
-    let is_allocator = module_kind == ModuleKind::Allocator;
-
     // We ignore a request for full crate graph LTO if the crate type
     // is only an rlib, as there is no full crate graph to process,
     // that'll happen later.
@@ -833,7 +811,7 @@ pub(crate) fn compute_per_cgu_lto_type(
     let is_rlib = matches!(sess_crate_types, [CrateType::Rlib]);
 
     match sess_lto {
-        Lto::ThinLocal if !linker_does_lto && !is_allocator => ComputedLtoType::Thin,
+        Lto::ThinLocal if !linker_does_lto => ComputedLtoType::Thin,
         Lto::Thin if !linker_does_lto && !is_rlib => ComputedLtoType::Thin,
         Lto::Fat if !is_rlib => ComputedLtoType::Fat,
         _ => ComputedLtoType::No,
@@ -843,23 +821,22 @@ pub(crate) fn compute_per_cgu_lto_type(
 fn execute_optimize_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     mut module: ModuleCodegen<B::Module>,
-    module_config: &ModuleConfig,
 ) -> WorkItemResult<B> {
     let dcx = cgcx.create_dcx();
     let dcx = dcx.handle();
 
-    B::optimize(cgcx, dcx, &mut module, module_config);
+    B::optimize(cgcx, dcx, &mut module, &cgcx.module_config);
 
     // After we've done the initial round of optimizations we need to
     // decide whether to synchronously codegen this module or ship it
     // back to the coordinator thread for further LTO processing (which
     // has to wait for all the initial modules to be optimized).
 
-    let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types, module.kind);
+    let lto_type = compute_per_cgu_lto_type(&cgcx.lto, &cgcx.opts, &cgcx.crate_types);
 
     // If we're doing some form of incremental LTO then we need to be sure to
     // save our module to disk first.
-    let bitcode = if cgcx.config(module.kind).emit_pre_lto_bc {
+    let bitcode = if cgcx.module_config.emit_pre_lto_bc {
         let filename = pre_lto_bitcode_filename(&module.name);
         cgcx.incr_comp_session_dir.as_ref().map(|path| path.join(&filename))
     } else {
@@ -868,7 +845,7 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
 
     match lto_type {
         ComputedLtoType::No => {
-            let module = B::codegen(cgcx, module, module_config);
+            let module = B::codegen(cgcx, module, &cgcx.module_config);
             WorkItemResult::Finished(module)
         }
         ComputedLtoType::Thin => {
@@ -899,7 +876,6 @@ fn execute_optimize_work_item<B: ExtraBackendMethods>(
 fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     module: CachedModuleCodegen,
-    module_config: &ModuleConfig,
 ) -> WorkItemResult<B> {
     let incr_comp_session_dir = cgcx.incr_comp_session_dir.as_ref().unwrap();
 
@@ -959,6 +935,7 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
         }
     };
 
+    let module_config = &cgcx.module_config;
     let should_emit_obj = module_config.emit_obj != EmitObj::None;
     let assembly = load_from_incr_cache(module_config.emit_asm, OutputType::Assembly);
     let llvm_ir = load_from_incr_cache(module_config.emit_ir, OutputType::LlvmAssembly);
@@ -971,7 +948,6 @@ fn execute_copy_from_cache_work_item<B: ExtraBackendMethods>(
     WorkItemResult::Finished(CompiledModule {
         links_from_incr_cache,
         name: module.name,
-        kind: ModuleKind::Regular,
         object,
         dwarf_object,
         bytecode,
@@ -986,7 +962,6 @@ fn execute_fat_lto_work_item<B: ExtraBackendMethods>(
     each_linked_rlib_for_lto: &[PathBuf],
     mut needs_fat_lto: Vec<FatLtoInput<B>>,
     import_only_modules: Vec<(SerializedModule<B::ModuleBuffer>, WorkProduct)>,
-    module_config: &ModuleConfig,
 ) -> WorkItemResult<B> {
     for (module, wp) in import_only_modules {
         needs_fat_lto.push(FatLtoInput::Serialized { name: wp.cgu_name, buffer: module })
@@ -998,17 +973,16 @@ fn execute_fat_lto_work_item<B: ExtraBackendMethods>(
         each_linked_rlib_for_lto,
         needs_fat_lto,
     );
-    let module = B::codegen(cgcx, module, module_config);
+    let module = B::codegen(cgcx, module, &cgcx.module_config);
     WorkItemResult::Finished(module)
 }
 
 fn execute_thin_lto_work_item<B: ExtraBackendMethods>(
     cgcx: &CodegenContext<B>,
     module: lto::ThinModule<B>,
-    module_config: &ModuleConfig,
 ) -> WorkItemResult<B> {
     let module = B::optimize_thin(cgcx, module);
-    let module = B::codegen(cgcx, module, module_config);
+    let module = B::codegen(cgcx, module, &cgcx.module_config);
     WorkItemResult::Finished(module)
 }
 
@@ -1093,6 +1067,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
     coordinator_receive: Receiver<Message<B>>,
     regular_config: Arc<ModuleConfig>,
     allocator_config: Arc<ModuleConfig>,
+    allocator_module: Option<ModuleCodegen<B::Module>>,
     tx_to_llvm_workers: Sender<Message<B>>,
 ) -> thread::JoinHandle<Result<CompiledModules, ()>> {
     let coordinator_send = tx_to_llvm_workers;
@@ -1157,8 +1132,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
         expanded_args: tcx.sess.expanded_args.clone(),
         diag_emitter: shared_emitter.clone(),
         output_filenames: Arc::clone(tcx.output_filenames(())),
-        regular_module_config: regular_config,
-        allocator_module_config: allocator_config,
+        module_config: regular_config,
         tm_factory: backend.target_machine_factory(tcx.sess, ol, backend_features),
         msvc_imps_needed: msvc_imps_needed(tcx),
         is_pe_coff: tcx.sess.target.is_like_windows,
@@ -1173,6 +1147,11 @@ fn start_executing_work<B: ExtraBackendMethods>(
         invocation_temp: sess.invocation_temp.clone(),
     };
 
+    let compiled_allocator_module = allocator_module.map(|mut allocator_module| {
+        B::optimize(&cgcx, tcx.sess.dcx(), &mut allocator_module, &allocator_config);
+        B::codegen(&cgcx, allocator_module, &allocator_config)
+    });
+
     // This is the "main loop" of parallel work happening for parallel codegen.
     // It's here that we manage parallelism, schedule work, and work with
     // messages coming from clients.
@@ -1312,7 +1291,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
         // This is where we collect codegen units that have gone all the way
         // through codegen and LLVM.
         let mut compiled_modules = vec![];
-        let mut compiled_allocator_module = None;
         let mut needs_fat_lto = Vec::new();
         let mut needs_thin_lto = Vec::new();
         let mut lto_import_only_modules = Vec::new();
@@ -1586,15 +1564,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
 
                     match result {
                         Ok(WorkItemResult::Finished(compiled_module)) => {
-                            match compiled_module.kind {
-                                ModuleKind::Regular => {
-                                    compiled_modules.push(compiled_module);
-                                }
-                                ModuleKind::Allocator => {
-                                    assert!(compiled_allocator_module.is_none());
-                                    compiled_allocator_module = Some(compiled_module);
-                                }
-                            }
+                            compiled_modules.push(compiled_module);
                         }
                         Ok(WorkItemResult::NeedsFatLto(fat_lto_input)) => {
                             assert!(!started_lto);
@@ -1722,45 +1692,38 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
     let cgcx = cgcx.clone();
 
     B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || {
-        let result = std::panic::catch_unwind(AssertUnwindSafe(|| {
-            let module_config = cgcx.config(work.module_kind());
-
-            match work {
-                WorkItem::Optimize(m) => {
-                    let _timer =
-                        cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &*m.name);
-                    execute_optimize_work_item(&cgcx, m, module_config)
-                }
-                WorkItem::CopyPostLtoArtifacts(m) => {
-                    let _timer = cgcx.prof.generic_activity_with_arg(
-                        "codegen_copy_artifacts_from_incr_cache",
-                        &*m.name,
-                    );
-                    execute_copy_from_cache_work_item(&cgcx, m, module_config)
-                }
-                WorkItem::FatLto {
-                    exported_symbols_for_lto,
-                    each_linked_rlib_for_lto,
+        let result = std::panic::catch_unwind(AssertUnwindSafe(|| match work {
+            WorkItem::Optimize(m) => {
+                let _timer =
+                    cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &*m.name);
+                execute_optimize_work_item(&cgcx, m)
+            }
+            WorkItem::CopyPostLtoArtifacts(m) => {
+                let _timer = cgcx
+                    .prof
+                    .generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &*m.name);
+                execute_copy_from_cache_work_item(&cgcx, m)
+            }
+            WorkItem::FatLto {
+                exported_symbols_for_lto,
+                each_linked_rlib_for_lto,
+                needs_fat_lto,
+                import_only_modules,
+            } => {
+                let _timer =
+                    cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", "everything");
+                execute_fat_lto_work_item(
+                    &cgcx,
+                    &exported_symbols_for_lto,
+                    &each_linked_rlib_for_lto,
                     needs_fat_lto,
                     import_only_modules,
-                } => {
-                    let _timer = cgcx
-                        .prof
-                        .generic_activity_with_arg("codegen_module_perform_lto", "everything");
-                    execute_fat_lto_work_item(
-                        &cgcx,
-                        &exported_symbols_for_lto,
-                        &each_linked_rlib_for_lto,
-                        needs_fat_lto,
-                        import_only_modules,
-                        module_config,
-                    )
-                }
-                WorkItem::ThinLto(m) => {
-                    let _timer =
-                        cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", m.name());
-                    execute_thin_lto_work_item(&cgcx, m, module_config)
-                }
+                )
+            }
+            WorkItem::ThinLto(m) => {
+                let _timer =
+                    cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", m.name());
+                execute_thin_lto_work_item(&cgcx, m)
             }
         }));
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 8abaf201aba..a9a2ae1b3db 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -17,6 +17,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_hir::{ItemId, Target};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::middle::debugger_visualizer::{DebuggerVisualizerFile, DebuggerVisualizerType};
+use rustc_middle::middle::dependency_format::Dependencies;
 use rustc_middle::middle::exported_symbols::{self, SymbolExportKind};
 use rustc_middle::middle::lang_items;
 use rustc_middle::mir::BinOp;
@@ -45,9 +46,7 @@ use crate::meth::load_vtable;
 use crate::mir::operand::OperandValue;
 use crate::mir::place::PlaceRef;
 use crate::traits::*;
-use crate::{
-    CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, ModuleKind, errors, meth, mir,
-};
+use crate::{CachedModuleCodegen, CodegenLintLevels, CrateInfo, ModuleCodegen, errors, meth, mir};
 
 pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
     match (op, signed) {
@@ -630,14 +629,30 @@ pub fn allocator_kind_for_codegen(tcx: TyCtxt<'_>) -> Option<AllocatorKind> {
     // If the crate doesn't have an `allocator_kind` set then there's definitely
     // no shim to generate. Otherwise we also check our dependency graph for all
     // our output crate types. If anything there looks like its a `Dynamic`
-    // linkage, then it's already got an allocator shim and we'll be using that
-    // one instead. If nothing exists then it's our job to generate the
-    // allocator!
-    let any_dynamic_crate = tcx.dependency_formats(()).iter().any(|(_, list)| {
+    // linkage for all crate types we may link as, then it's already got an
+    // allocator shim and we'll be using that one instead. If nothing exists
+    // then it's our job to generate the allocator! If crate types disagree
+    // about whether an allocator shim is necessary or not, we generate one
+    // and let needs_allocator_shim_for_linking decide at link time whether or
+    // not to use it for any particular linker invocation.
+    let all_crate_types_any_dynamic_crate = tcx.dependency_formats(()).iter().all(|(_, list)| {
         use rustc_middle::middle::dependency_format::Linkage;
         list.iter().any(|&linkage| linkage == Linkage::Dynamic)
     });
-    if any_dynamic_crate { None } else { tcx.allocator_kind(()) }
+    if all_crate_types_any_dynamic_crate { None } else { tcx.allocator_kind(()) }
+}
+
+/// Decide if this particular crate type needs an allocator shim linked in.
+/// This may return true even when allocator_kind_for_codegen returns false. In
+/// this case no allocator shim shall be linked.
+pub(crate) fn needs_allocator_shim_for_linking(
+    dependency_formats: &Dependencies,
+    crate_type: CrateType,
+) -> bool {
+    use rustc_middle::middle::dependency_format::Linkage;
+    let any_dynamic_crate =
+        dependency_formats[&crate_type].iter().any(|&linkage| linkage == Linkage::Dynamic);
+    !any_dynamic_crate
 }
 
 pub fn codegen_crate<B: ExtraBackendMethods>(
@@ -647,7 +662,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
 ) -> OngoingCodegen<B> {
     // Skip crate items and just output metadata in -Z no-codegen mode.
     if tcx.sess.opts.unstable_opts.no_codegen || !tcx.sess.opts.output_types.should_codegen() {
-        let ongoing_codegen = start_async_codegen(backend, tcx, target_cpu);
+        let ongoing_codegen = start_async_codegen(backend, tcx, target_cpu, None);
 
         ongoing_codegen.codegen_finished(tcx);
 
@@ -678,7 +693,27 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         }
     }
 
-    let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu);
+    // Codegen an allocator shim, if necessary.
+    let allocator_module = if let Some(kind) = allocator_kind_for_codegen(tcx) {
+        let llmod_id =
+            cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
+
+        tcx.sess.time("write_allocator_module", || {
+            let module = backend.codegen_allocator(
+                tcx,
+                &llmod_id,
+                kind,
+                // If allocator_kind is Some then alloc_error_handler_kind must
+                // also be Some.
+                tcx.alloc_error_handler_kind(()).unwrap(),
+            );
+            Some(ModuleCodegen::new_allocator(llmod_id, module))
+        })
+    } else {
+        None
+    };
+
+    let ongoing_codegen = start_async_codegen(backend.clone(), tcx, target_cpu, allocator_module);
 
     // For better throughput during parallel processing by LLVM, we used to sort
     // CGUs largest to smallest. This would lead to better thread utilization
@@ -795,35 +830,6 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
         }
     }
 
-    // Codegen an allocator shim, if necessary.
-    // Do this last to ensure the LLVM_passes timer doesn't start while no CGUs have been codegened
-    // yet for the backend to optimize.
-    if let Some(kind) = allocator_kind_for_codegen(tcx) {
-        let llmod_id =
-            cgu_name_builder.build_cgu_name(LOCAL_CRATE, &["crate"], Some("allocator")).to_string();
-        let module_llvm = tcx.sess.time("write_allocator_module", || {
-            backend.codegen_allocator(
-                tcx,
-                &llmod_id,
-                kind,
-                // If allocator_kind is Some then alloc_error_handler_kind must
-                // also be Some.
-                tcx.alloc_error_handler_kind(()).unwrap(),
-            )
-        });
-
-        ongoing_codegen.wait_for_signal_to_codegen_item();
-        ongoing_codegen.check_for_errors(tcx.sess);
-
-        // These modules are generally cheap and won't throw off scheduling.
-        let cost = 0;
-        submit_codegened_module_to_llvm(
-            &ongoing_codegen.coordinator,
-            ModuleCodegen::new_allocator(llmod_id, module_llvm),
-            cost,
-        );
-    }
-
     ongoing_codegen.codegen_finished(tcx);
 
     // Since the main thread is sometimes blocked during codegen, we keep track
@@ -1118,12 +1124,7 @@ pub fn determine_cgu_reuse<'tcx>(tcx: TyCtxt<'tcx>, cgu: &CodegenUnit<'tcx>) ->
         // We can re-use either the pre- or the post-thinlto state. If no LTO is
         // being performed then we can use post-LTO artifacts, otherwise we must
         // reuse pre-LTO artifacts
-        match compute_per_cgu_lto_type(
-            &tcx.sess.lto(),
-            &tcx.sess.opts,
-            tcx.crate_types(),
-            ModuleKind::Regular,
-        ) {
+        match compute_per_cgu_lto_type(&tcx.sess.lto(), &tcx.sess.opts, tcx.crate_types()) {
             ComputedLtoType::No => CguReuse::PostLto,
             _ => CguReuse::PreLto,
         }
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 961bb788149..008340e614d 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -428,9 +428,16 @@ fn check_result(
     // llvm/llvm-project#70563).
     if !codegen_fn_attrs.target_features.is_empty()
         && matches!(codegen_fn_attrs.inline, InlineAttr::Always)
+        && !tcx.features().target_feature_inline_always()
         && let Some(span) = interesting_spans.inline
     {
-        tcx.dcx().span_err(span, "cannot use `#[inline(always)]` with `#[target_feature]`");
+        feature_err(
+            tcx.sess,
+            sym::target_feature_inline_always,
+            span,
+            "cannot use `#[inline(always)]` with `#[target_feature]`",
+        )
+        .emit();
     }
 
     // warn that inline has no effect when no_sanitize is present
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index fe0500a5d4c..5b90ffaa056 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -120,7 +120,6 @@ impl<M> ModuleCodegen<M> {
 
         CompiledModule {
             name: self.name.clone(),
-            kind: self.kind,
             object,
             dwarf_object,
             bytecode,
@@ -134,7 +133,6 @@ impl<M> ModuleCodegen<M> {
 #[derive(Debug, Encodable, Decodable)]
 pub struct CompiledModule {
     pub name: String,
-    pub kind: ModuleKind,
     pub object: Option<PathBuf>,
     pub dwarf_object: Option<PathBuf>,
     pub bytecode: Option<PathBuf>,
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 60518dafbf2..700d7c26752 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -457,7 +457,7 @@ const_eval_validation_failure =
     it is undefined behavior to use this value
 
 const_eval_validation_failure_note =
-    The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+    the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
 
 const_eval_validation_front_matter_invalid_value = constructing invalid value
 const_eval_validation_front_matter_invalid_value_with_path = constructing invalid value at {$path}
diff --git a/compiler/rustc_driver_impl/messages.ftl b/compiler/rustc_driver_impl/messages.ftl
index 2c6a0291ac2..b62cdc35f51 100644
--- a/compiler/rustc_driver_impl/messages.ftl
+++ b/compiler/rustc_driver_impl/messages.ftl
@@ -14,7 +14,7 @@ driver_impl_ice_version = rustc {$version} running on {$triple}
 
 driver_impl_rlink_corrupt_file = corrupt metadata encountered in `{$file}`
 
-driver_impl_rlink_empty_version_number = The input does not contain version number
+driver_impl_rlink_empty_version_number = the input does not contain version number
 
 driver_impl_rlink_encoding_version_mismatch = .rlink file was produced with encoding version `{$version_array}`, but the current version is `{$rlink_version}`
 
@@ -24,6 +24,6 @@ driver_impl_rlink_rustc_version_mismatch = .rlink file was produced by rustc ver
 
 driver_impl_rlink_unable_to_read = failed to read rlink file: `{$err}`
 
-driver_impl_rlink_wrong_file_type = The input does not look like a .rlink file
+driver_impl_rlink_wrong_file_type = the input does not look like a .rlink file
 
 driver_impl_unstable_feature_usage = cannot dump feature usage metrics: {$error}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 71fc54f0d33..a56e0f3fae1 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -1160,7 +1160,7 @@ impl<'a> DiagCtxtHandle<'a> {
         // - It's only produce with JSON output.
         // - It's not emitted the usual way, via `emit_diagnostic`.
         // - The `$message_type` field is "unused_externs" rather than the usual
-        //   "diagnosic".
+        //   "diagnostic".
         //
         // We count it as a lint error because it has a lint level. The value
         // of `loud` (which comes from "unused-externs" or
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 0324057e331..ab8e059b7b7 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -77,7 +77,7 @@ use std::rc::Rc;
 
 pub(crate) use NamedMatch::*;
 pub(crate) use ParseResult::*;
-use rustc_ast::token::{self, DocComment, NonterminalKind, Token};
+use rustc_ast::token::{self, DocComment, NonterminalKind, Token, TokenKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_lint_defs::pluralize;
@@ -397,7 +397,23 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
     {
         ident1.name == ident2.name && is_raw1 == is_raw2
     } else {
-        t1.kind == t2.kind
+        // Note: we SHOULD NOT use `t1.kind == t2.kind` here, and we should instead compare the
+        // tokens using the special comparison logic below.
+        // It makes sure that variants containing `InvisibleOrigin` will
+        // never compare equal to one another.
+        //
+        // When we had AST-based nonterminals we couldn't compare them, and the
+        // old `Nonterminal` type had an `eq` that always returned false,
+        // resulting in this restriction:
+        // <https://doc.rust-lang.org/nightly/reference/macros-by-example.html#forwarding-a-matched-fragment>
+        // This comparison logic emulates that behaviour. We could consider lifting this
+        // restriction now but there are still cases involving invisible
+        // delimiters that make it harder than it first appears.
+        match (t1.kind, t2.kind) {
+            (TokenKind::OpenInvisible(_) | TokenKind::CloseInvisible(_), _)
+            | (_, TokenKind::OpenInvisible(_) | TokenKind::CloseInvisible(_)) => false,
+            (a, b) => a == b,
+        }
     }
 }
 
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 573e9aab055..4f35bf63a1a 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -642,6 +642,8 @@ declare_features! (
     (unstable, super_let, "1.88.0", Some(139076)),
     /// Allows subtrait items to shadow supertrait items.
     (unstable, supertrait_item_shadowing, "1.86.0", Some(89151)),
+    /// Allows the use of target_feature when a function is marked inline(always).
+    (unstable, target_feature_inline_always, "CURRENT_RUSTC_VERSION", Some(145574)),
     /// Allows using `#[thread_local]` on `static` items.
     (unstable, thread_local, "1.0.0", Some(29594)),
     /// Allows defining `trait X = A + B;` alias items.
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index cfc6bc2f3a0..aa2d27ab809 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -449,6 +449,9 @@ pub(crate) fn check_intrinsic_type(
         }
         sym::unchecked_shl | sym::unchecked_shr => (2, 0, vec![param(0), param(1)], param(0)),
         sym::rotate_left | sym::rotate_right => (1, 0, vec![param(0), tcx.types.u32], param(0)),
+        sym::unchecked_funnel_shl | sym::unchecked_funnel_shr => {
+            (1, 0, vec![param(0), param(0), tcx.types.u32], param(0))
+        }
         sym::unchecked_add | sym::unchecked_sub | sym::unchecked_mul => {
             (1, 0, vec![param(0), param(0)], param(0))
         }
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index f5770b7312d..2ba7ed46f92 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -490,12 +490,8 @@ fn resolve_local<'tcx>(
             //
             // Iterate up to the enclosing destruction scope to find the same scope that will also
             // be used for the result of the block itself.
-            while let Some(s) = visitor.cx.var_parent {
-                let parent = visitor.scope_tree.parent_map.get(&s).cloned();
-                if let Some(Scope { data: ScopeData::Destruction, .. }) = parent {
-                    break;
-                }
-                visitor.cx.var_parent = parent;
+            if let Some(inner_scope) = visitor.cx.var_parent {
+                (visitor.cx.var_parent, _) = visitor.scope_tree.default_temporary_scope(inner_scope)
             }
         }
     }
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 8f131f45bbd..4c820b8877b 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -13,7 +13,7 @@ use rustc_lint::LintStore;
 use rustc_middle::ty;
 use rustc_middle::ty::CurrentGcx;
 use rustc_middle::util::Providers;
-use rustc_parse::new_parser_from_source_str;
+use rustc_parse::new_parser_from_simple_source_str;
 use rustc_parse::parser::attr::AllowLeadingUnsafe;
 use rustc_query_impl::QueryCtxt;
 use rustc_query_system::query::print_query_stack;
@@ -68,7 +68,7 @@ pub(crate) fn parse_cfg(dcx: DiagCtxtHandle<'_>, cfgs: Vec<String>) -> Cfg {
                 };
             }
 
-            match new_parser_from_source_str(&psess, filename, s.to_string()) {
+            match new_parser_from_simple_source_str(&psess, filename, s.to_string()) {
                 Ok(mut parser) => match parser.parse_meta_item(AllowLeadingUnsafe::No) {
                     Ok(meta_item) if parser.token == token::Eof => {
                         if meta_item.path.segments.len() != 1 {
@@ -166,7 +166,7 @@ pub(crate) fn parse_check_cfg(dcx: DiagCtxtHandle<'_>, specs: Vec<String>) -> Ch
             error!("expected `cfg(name, values(\"value1\", \"value2\", ... \"valueN\"))`")
         };
 
-        let mut parser = match new_parser_from_source_str(&psess, filename, s.to_string()) {
+        let mut parser = match new_parser_from_simple_source_str(&psess, filename, s.to_string()) {
             Ok(parser) => parser,
             Err(errs) => {
                 errs.into_iter().for_each(|err| err.cancel());
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index ce92263babd..b79075ac09b 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -5141,3 +5141,57 @@ declare_lint! {
     "detects tail calls of functions marked with `#[track_caller]`",
     @feature_gate = explicit_tail_calls;
 }
+declare_lint! {
+    /// The `inline_always_mismatching_target_features` lint will trigger when a
+    /// function with the `#[inline(always)]` and `#[target_feature(enable = "...")]`
+    /// attributes is called and cannot be inlined due to missing target features in the caller.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,ignore (fails on x86_64)
+    /// #[inline(always)]
+    /// #[target_feature(enable = "fp16")]
+    /// unsafe fn callee() {
+    ///     // operations using fp16 types
+    /// }
+    ///
+    /// // Caller does not enable the required target feature
+    /// fn caller() {
+    ///     unsafe { callee(); }
+    /// }
+    ///
+    /// fn main() {
+    ///     caller();
+    /// }
+    /// ```
+    ///
+    /// This will produce:
+    ///
+    /// ```text
+    /// warning: call to `#[inline(always)]`-annotated `callee` requires the same target features. Function will not have `alwaysinline` attribute applied
+    ///   --> $DIR/builtin.rs:5192:14
+    ///    |
+    /// 10 |     unsafe { callee(); }
+    ///    |              ^^^^^^^^
+    ///    |
+    /// note: `fp16` target feature enabled in `callee` here but missing from `caller`
+    ///   --> $DIR/builtin.rs:5185:1
+    ///    |
+    /// 3  | #[target_feature(enable = "fp16")]
+    ///    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+    /// 4  | unsafe fn callee() {
+    ///    | ------------------
+    ///    = note: `#[warn(inline_always_mismatching_target_features)]` on by default
+    /// warning: 1 warning emitted
+    /// ```
+    ///
+    /// ### Explanation
+    ///
+    /// Inlining a function with a target feature attribute into a caller that
+    /// lacks the corresponding target feature can lead to unsound behavior.
+    /// LLVM may select the wrong instructions or registers, or reorder
+    /// operations, potentially resulting in runtime errors.
+    pub INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES,
+    Warn,
+    r#"detects when a function annotated with `#[inline(always)]` and `#[target_feature(enable = "..")]` is inlined into a caller without the required target feature"#,
+}
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 5d776ea581d..9e23da88f5e 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -412,7 +412,7 @@ impl CStore {
             match (&left_name_val, &right_name_val) {
                 (Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) {
                     cmp::Ordering::Equal => {
-                        if l.0.tech_value != r.0.tech_value {
+                        if !l.1.consistent(&tcx.sess.opts, Some(&r.1)) {
                             report_diff(
                                 &l.0.prefix,
                                 &l.0.name,
@@ -424,20 +424,28 @@ impl CStore {
                         right_name_val = None;
                     }
                     cmp::Ordering::Greater => {
-                        report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                        if !r.1.consistent(&tcx.sess.opts, None) {
+                            report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                        }
                         right_name_val = None;
                     }
                     cmp::Ordering::Less => {
-                        report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                        if !l.1.consistent(&tcx.sess.opts, None) {
+                            report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                        }
                         left_name_val = None;
                     }
                 },
                 (Some(l), None) => {
-                    report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                    if !l.1.consistent(&tcx.sess.opts, None) {
+                        report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
+                    }
                     left_name_val = None;
                 }
                 (None, Some(r)) => {
-                    report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                    if !r.1.consistent(&tcx.sess.opts, None) {
+                        report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
+                    }
                     right_name_val = None;
                 }
                 (None, None) => break,
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index 866736f74a0..8b4503073b0 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -82,7 +82,7 @@ pub enum TargetFeatureKind {
     Forced,
 }
 
-#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, HashStable)]
 pub struct TargetFeature {
     /// The name of the target feature (e.g. "avx")
     pub name: Symbol,
diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs
index 857d041224f..5367e5edd49 100644
--- a/compiler/rustc_middle/src/middle/region.rs
+++ b/compiler/rustc_middle/src/middle/region.rs
@@ -299,4 +299,43 @@ impl ScopeTree {
 
         true
     }
+
+    /// Returns the scope of non-lifetime-extended temporaries within a given scope, as well as
+    /// whether we've recorded a potential backwards-incompatible change to lint on.
+    /// Returns `None` when no enclosing temporary scope is found, such as for static items.
+    pub fn default_temporary_scope(&self, inner: Scope) -> (Option<Scope>, Option<Scope>) {
+        let mut id = inner;
+        let mut backwards_incompatible = None;
+
+        while let Some(&p) = self.parent_map.get(&id) {
+            match p.data {
+                ScopeData::Destruction => {
+                    debug!("temporary_scope({inner:?}) = {id:?} [enclosing]");
+                    return (Some(id), backwards_incompatible);
+                }
+                ScopeData::IfThenRescope | ScopeData::MatchGuard => {
+                    debug!("temporary_scope({inner:?}) = {p:?} [enclosing]");
+                    return (Some(p), backwards_incompatible);
+                }
+                ScopeData::Node
+                | ScopeData::CallSite
+                | ScopeData::Arguments
+                | ScopeData::IfThen
+                | ScopeData::Remainder(_) => {
+                    // If we haven't already passed through a backwards-incompatible node,
+                    // then check if we are passing through one now and record it if so.
+                    // This is for now only working for cases where a temporary lifetime is
+                    // *shortened*.
+                    if backwards_incompatible.is_none() {
+                        backwards_incompatible =
+                            self.backwards_incompatible_scope.get(&p.local_id).copied();
+                    }
+                    id = p
+                }
+            }
+        }
+
+        debug!("temporary_scope({inner:?}) = None");
+        (None, backwards_incompatible)
+    }
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 72ab6ac612c..97c8a0336c2 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -738,8 +738,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         )
     }
 
-    type ProbeRef = &'tcx inspect::Probe<TyCtxt<'tcx>>;
-    fn mk_probe_ref(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
+    type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
+    fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
         self.arena.alloc(probe)
     }
     fn evaluate_root_goal_for_proof_tree_raw(
diff --git a/compiler/rustc_middle/src/ty/rvalue_scopes.rs b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
index 7dfe2d28051..8b92e48ed1a 100644
--- a/compiler/rustc_middle/src/ty/rvalue_scopes.rs
+++ b/compiler/rustc_middle/src/ty/rvalue_scopes.rs
@@ -35,41 +35,8 @@ impl RvalueScopes {
         // if there's one. Static items, for instance, won't
         // have an enclosing scope, hence no scope will be
         // returned.
-        let mut id = Scope { local_id: expr_id, data: ScopeData::Node };
-        let mut backwards_incompatible = None;
-
-        while let Some(&p) = region_scope_tree.parent_map.get(&id) {
-            match p.data {
-                ScopeData::Destruction => {
-                    debug!("temporary_scope({expr_id:?}) = {id:?} [enclosing]");
-                    return (Some(id), backwards_incompatible);
-                }
-                ScopeData::IfThenRescope | ScopeData::MatchGuard => {
-                    debug!("temporary_scope({expr_id:?}) = {p:?} [enclosing]");
-                    return (Some(p), backwards_incompatible);
-                }
-                ScopeData::Node
-                | ScopeData::CallSite
-                | ScopeData::Arguments
-                | ScopeData::IfThen
-                | ScopeData::Remainder(_) => {
-                    // If we haven't already passed through a backwards-incompatible node,
-                    // then check if we are passing through one now and record it if so.
-                    // This is for now only working for cases where a temporary lifetime is
-                    // *shortened*.
-                    if backwards_incompatible.is_none() {
-                        backwards_incompatible = region_scope_tree
-                            .backwards_incompatible_scope
-                            .get(&p.local_id)
-                            .copied();
-                    }
-                    id = p
-                }
-            }
-        }
-
-        debug!("temporary_scope({expr_id:?}) = None");
-        (None, backwards_incompatible)
+        region_scope_tree
+            .default_temporary_scope(Scope { local_id: expr_id, data: ScopeData::Node })
     }
 
     /// Make an association between a sub-expression and an extended lifetime
diff --git a/compiler/rustc_mir_transform/src/check_inline_always_target_features.rs b/compiler/rustc_mir_transform/src/check_inline_always_target_features.rs
new file mode 100644
index 00000000000..abad28f0a8f
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/check_inline_always_target_features.rs
@@ -0,0 +1,88 @@
+use rustc_hir::attrs::InlineAttr;
+use rustc_middle::middle::codegen_fn_attrs::{TargetFeature, TargetFeatureKind};
+use rustc_middle::mir::{Body, TerminatorKind};
+use rustc_middle::ty::{self, TyCtxt};
+
+use crate::pass_manager::MirLint;
+
+pub(super) struct CheckInlineAlwaysTargetFeature;
+
+impl<'tcx> MirLint<'tcx> for CheckInlineAlwaysTargetFeature {
+    fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+        check_inline_always_target_features(tcx, body)
+    }
+}
+
+/// `#[target_feature]`-annotated functions can be marked `#[inline]` and will only be inlined if
+/// the target features match (as well as all of the other inlining heuristics). `#[inline(always)]`
+/// will always inline regardless of matching target features, which can result in errors from LLVM.
+/// However, it is desirable to be able to always annotate certain functions (e.g. SIMD intrinsics)
+/// as `#[inline(always)]` but check the target features match in Rust to avoid the LLVM errors.
+///
+/// We check the caller and callee target features to ensure that this can
+/// be done or emit a lint.
+#[inline]
+fn check_inline_always_target_features<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+    let caller_def_id = body.source.def_id().expect_local();
+    if !tcx.def_kind(caller_def_id).has_codegen_attrs() {
+        return;
+    }
+
+    let caller_codegen_fn_attrs = tcx.codegen_fn_attrs(caller_def_id);
+
+    for bb in body.basic_blocks.iter() {
+        let terminator = bb.terminator();
+        match &terminator.kind {
+            TerminatorKind::Call { func, .. } | TerminatorKind::TailCall { func, .. } => {
+                let fn_ty = func.ty(body, tcx);
+                let ty::FnDef(callee_def_id, _) = *fn_ty.kind() else {
+                    continue;
+                };
+
+                if !tcx.def_kind(callee_def_id).has_codegen_attrs() {
+                    continue;
+                }
+                let callee_codegen_fn_attrs = tcx.codegen_fn_attrs(callee_def_id);
+                if callee_codegen_fn_attrs.inline != InlineAttr::Always
+                    || callee_codegen_fn_attrs.target_features.is_empty()
+                {
+                    continue;
+                }
+
+                // Scan the users defined target features and ensure they
+                // match the caller.
+                if tcx.is_target_feature_call_safe(
+                    &callee_codegen_fn_attrs.target_features,
+                    &caller_codegen_fn_attrs
+                        .target_features
+                        .iter()
+                        .cloned()
+                        .chain(tcx.sess.target_features.iter().map(|feat| TargetFeature {
+                            name: *feat,
+                            kind: TargetFeatureKind::Implied,
+                        }))
+                        .collect::<Vec<_>>(),
+                ) {
+                    continue;
+                }
+
+                let callee_only: Vec<_> = callee_codegen_fn_attrs
+                    .target_features
+                    .iter()
+                    .filter(|it| !caller_codegen_fn_attrs.target_features.contains(it))
+                    .filter(|it| !matches!(it.kind, TargetFeatureKind::Implied))
+                    .map(|it| it.name.as_str())
+                    .collect();
+
+                crate::errors::emit_inline_always_target_feature_diagnostic(
+                    tcx,
+                    terminator.source_info.span,
+                    callee_def_id,
+                    caller_def_id.into(),
+                    &callee_only,
+                );
+            }
+            _ => (),
+        }
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index ad9635aae33..775f5f9a7cf 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -2,6 +2,7 @@ use rustc_errors::codes::*;
 use rustc_errors::{Diag, LintDiagnostic};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::mir::AssertKind;
+use rustc_middle::query::Key;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::{self, Lint};
 use rustc_span::def_id::DefId;
@@ -9,6 +10,46 @@ use rustc_span::{Ident, Span, Symbol};
 
 use crate::fluent_generated as fluent;
 
+/// Emit diagnostic for calls to `#[inline(always)]`-annotated functions with a
+/// `#[target_feature]` attribute where the caller enables a different set of target features.
+pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>(
+    tcx: TyCtxt<'tcx>,
+    call_span: Span,
+    callee_def_id: DefId,
+    caller_def_id: DefId,
+    callee_only: &[&'a str],
+) {
+    let callee = tcx.def_path_str(callee_def_id);
+    let caller = tcx.def_path_str(caller_def_id);
+
+    tcx.node_span_lint(
+        lint::builtin::INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES,
+        tcx.local_def_id_to_hir_id(caller_def_id.as_local().unwrap()),
+        call_span,
+        |lint| {
+            lint.primary_message(format!(
+                "call to `#[inline(always)]`-annotated `{callee}` \
+                requires the same target features to be inlined"
+            ));
+            lint.note("function will not be inlined");
+
+            lint.note(format!(
+                "the following target features are on `{callee}` but missing from `{caller}`: {}",
+                callee_only.join(", ")
+            ));
+            lint.span_note(callee_def_id.default_span(tcx), format!("`{callee}` is defined here"));
+
+            let feats = callee_only.join(",");
+            lint.span_suggestion(
+                tcx.def_span(caller_def_id).shrink_to_lo(),
+                format!("add `#[target_feature]` attribute to `{caller}`"),
+                format!("#[target_feature(enable = \"{feats}\")]\n"),
+                lint::Applicability::MaybeIncorrect,
+            );
+        },
+    );
+}
+
 #[derive(LintDiagnostic)]
 #[diag(mir_transform_unconditional_recursion)]
 #[help]
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 8f319e64916..1663dfa744f 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -117,6 +117,7 @@ declare_passes! {
     mod add_subtyping_projections : Subtyper;
     mod check_inline : CheckForceInline;
     mod check_call_recursion : CheckCallRecursion, CheckDropRecursion;
+    mod check_inline_always_target_features: CheckInlineAlwaysTargetFeature;
     mod check_alignment : CheckAlignment;
     mod check_enums : CheckEnums;
     mod check_const_item_mutation : CheckConstItemMutation;
@@ -384,6 +385,9 @@ fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
             // MIR-level lints.
             &Lint(check_inline::CheckForceInline),
             &Lint(check_call_recursion::CheckCallRecursion),
+            // Check callee's target features match callers target features when
+            // using `#[inline(always)]`
+            &Lint(check_inline_always_target_features::CheckInlineAlwaysTargetFeature),
             &Lint(check_packed_ref::CheckPackedRef),
             &Lint(check_const_item_mutation::CheckConstItemMutation),
             &Lint(function_item_references::FunctionItemReferences),
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 31106a74527..443aebbdb4d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -1275,7 +1275,7 @@ pub fn evaluate_root_goal_for_proof_tree_raw_provider<
 >(
     cx: I,
     canonical_goal: CanonicalInput<I>,
-) -> (QueryResult<I>, I::ProbeRef) {
+) -> (QueryResult<I>, I::Probe) {
     let mut inspect = inspect::ProofTreeBuilder::new();
     let canonical_result = SearchGraph::<D>::evaluate_root_goal_for_proof_tree(
         cx,
@@ -1284,7 +1284,7 @@ pub fn evaluate_root_goal_for_proof_tree_raw_provider<
         &mut inspect,
     );
     let final_revision = inspect.unwrap();
-    (canonical_result, cx.mk_probe_ref(final_revision))
+    (canonical_result, cx.mk_probe(final_revision))
 }
 
 /// Evaluate a goal to build a proof tree.
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 4ca2f57bd87..77dd313d9b8 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -58,7 +58,7 @@ parse_async_use_order_incorrect = the order of `use` and `async` is incorrect
 parse_at_dot_dot_in_struct_pattern = `@ ..` is not supported in struct patterns
     .suggestion = bind to each field separately or, if you don't need them, just remove `{$ident} @`
 
-parse_at_in_struct_pattern = Unexpected `@` in struct pattern
+parse_at_in_struct_pattern = unexpected `@` in struct pattern
     .note = struct patterns use `field: pattern` syntax to bind to fields
     .help = consider replacing `new_name @ field_name` with `field_name: new_name` if that is what you intended
 
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index 197333d942d..b790966acfd 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -62,7 +62,20 @@ pub fn new_parser_from_source_str(
     source: String,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
     let source_file = psess.source_map().new_source_file(name, source);
-    new_parser_from_source_file(psess, source_file)
+    new_parser_from_source_file(psess, source_file, FrontmatterAllowed::Yes)
+}
+
+/// Creates a new parser from a simple (no frontmatter) source string.
+///
+/// On failure, the errors must be consumed via `unwrap_or_emit_fatal`, `emit`, `cancel`,
+/// etc., otherwise a panic will occur when they are dropped.
+pub fn new_parser_from_simple_source_str(
+    psess: &ParseSess,
+    name: FileName,
+    source: String,
+) -> Result<Parser<'_>, Vec<Diag<'_>>> {
+    let source_file = psess.source_map().new_source_file(name, source);
+    new_parser_from_source_file(psess, source_file, FrontmatterAllowed::No)
 }
 
 /// Creates a new parser from a filename. On failure, the errors must be consumed via
@@ -96,7 +109,7 @@ pub fn new_parser_from_file<'a>(
         }
         err.emit();
     });
-    new_parser_from_source_file(psess, source_file)
+    new_parser_from_source_file(psess, source_file, FrontmatterAllowed::Yes)
 }
 
 pub fn utf8_error<E: EmissionGuarantee>(
@@ -147,9 +160,10 @@ pub fn utf8_error<E: EmissionGuarantee>(
 fn new_parser_from_source_file(
     psess: &ParseSess,
     source_file: Arc<SourceFile>,
+    frontmatter_allowed: FrontmatterAllowed,
 ) -> Result<Parser<'_>, Vec<Diag<'_>>> {
     let end_pos = source_file.end_position();
-    let stream = source_file_to_stream(psess, source_file, None, FrontmatterAllowed::Yes)?;
+    let stream = source_file_to_stream(psess, source_file, None, frontmatter_allowed)?;
     let mut parser = Parser::new(psess, stream, None);
     if parser.token == token::Eof {
         parser.token.span = Span::new(end_pos, end_pos, parser.token.span.ctxt(), None);
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index 498d9a405fa..afd08319738 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -687,6 +687,7 @@ passes_unused_var_maybe_capture_ref = unused variable: `{$name}`
 
 passes_unused_var_remove_field = unused variable: `{$name}`
 passes_unused_var_remove_field_suggestion = try removing the field
+passes_unused_var_typo = you might have meant to pattern match on the similarly named {$kind} `{$item_name}`
 
 passes_unused_variable_args_in_macro = `{$name}` is captured in macro and introduced a unused variable
 
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 680e2a26d84..23dcabef1a1 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1367,6 +1367,22 @@ pub(crate) struct UnusedVarRemoveFieldSugg {
 #[note]
 pub(crate) struct UnusedVarAssignedOnly {
     pub name: String,
+    #[subdiagnostic]
+    pub typo: Option<PatternTypo>,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+    passes_unused_var_typo,
+    style = "verbose",
+    applicability = "machine-applicable"
+)]
+pub(crate) struct PatternTypo {
+    #[suggestion_part(code = "{code}")]
+    pub span: Span,
+    pub code: String,
+    pub item_name: String,
+    pub kind: String,
 }
 
 #[derive(LintDiagnostic)]
@@ -1434,6 +1450,8 @@ pub(crate) struct UnusedVariableTryPrefix {
     #[subdiagnostic]
     pub sugg: UnusedVariableSugg,
     pub name: String,
+    #[subdiagnostic]
+    pub typo: Option<PatternTypo>,
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index ae16a51bc69..1b2ffb5b3db 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -95,8 +95,10 @@ use rustc_hir::{Expr, HirId, HirIdMap, HirIdSet, find_attr};
 use rustc_index::IndexVec;
 use rustc_middle::query::Providers;
 use rustc_middle::span_bug;
+use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, RootVariableMinCaptureList, Ty, TyCtxt};
 use rustc_session::lint;
+use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::{BytePos, Span, Symbol};
 use tracing::{debug, instrument};
 
@@ -1688,6 +1690,51 @@ impl<'tcx> Liveness<'_, 'tcx> {
             let is_assigned =
                 if ln == self.exit_ln { false } else { self.assigned_on_exit(ln, var) };
 
+            let mut typo = None;
+            for (hir_id, _, span) in &hir_ids_and_spans {
+                let ty = self.typeck_results.node_type(*hir_id);
+                if let ty::Adt(adt, _) = ty.peel_refs().kind() {
+                    let name = Symbol::intern(&name);
+                    let adt_def = self.ir.tcx.adt_def(adt.did());
+                    let variant_names: Vec<_> = adt_def
+                        .variants()
+                        .iter()
+                        .filter(|v| matches!(v.ctor, Some((CtorKind::Const, _))))
+                        .map(|v| v.name)
+                        .collect();
+                    if let Some(name) = find_best_match_for_name(&variant_names, name, None)
+                        && let Some(variant) = adt_def.variants().iter().find(|v| {
+                            v.name == name && matches!(v.ctor, Some((CtorKind::Const, _)))
+                        })
+                    {
+                        typo = Some(errors::PatternTypo {
+                            span: *span,
+                            code: with_no_trimmed_paths!(self.ir.tcx.def_path_str(variant.def_id)),
+                            kind: self.ir.tcx.def_descr(variant.def_id).to_string(),
+                            item_name: variant.name.to_string(),
+                        });
+                    }
+                }
+            }
+            if typo.is_none() {
+                for (hir_id, _, span) in &hir_ids_and_spans {
+                    let ty = self.typeck_results.node_type(*hir_id);
+                    // Look for consts of the same type with similar names as well, not just unit
+                    // structs and variants.
+                    for def_id in self.ir.tcx.hir_body_owners() {
+                        if let DefKind::Const = self.ir.tcx.def_kind(def_id)
+                            && self.ir.tcx.type_of(def_id).instantiate_identity() == ty
+                        {
+                            typo = Some(errors::PatternTypo {
+                                span: *span,
+                                code: with_no_trimmed_paths!(self.ir.tcx.def_path_str(def_id)),
+                                kind: "constant".to_string(),
+                                item_name: self.ir.tcx.item_name(def_id).to_string(),
+                            });
+                        }
+                    }
+                }
+            }
             if is_assigned {
                 self.ir.tcx.emit_node_span_lint(
                     lint::builtin::UNUSED_VARIABLES,
@@ -1696,7 +1743,7 @@ impl<'tcx> Liveness<'_, 'tcx> {
                         .into_iter()
                         .map(|(_, _, ident_span)| ident_span)
                         .collect::<Vec<_>>(),
-                    errors::UnusedVarAssignedOnly { name },
+                    errors::UnusedVarAssignedOnly { name, typo },
                 )
             } else if can_remove {
                 let spans = hir_ids_and_spans
@@ -1788,6 +1835,7 @@ impl<'tcx> Liveness<'_, 'tcx> {
                             name,
                             sugg,
                             string_interp: suggestions,
+                            typo,
                         },
                     );
                 }
diff --git a/compiler/rustc_query_system/messages.ftl b/compiler/rustc_query_system/messages.ftl
index f48dc60afa0..f686608034c 100644
--- a/compiler/rustc_query_system/messages.ftl
+++ b/compiler/rustc_query_system/messages.ftl
@@ -18,8 +18,8 @@ query_system_cycle_usage = cycle used when {$usage}
 query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node}
     .help = This is a known issue with the compiler. Run {$run_cmd} to allow your project to compile
 
-query_system_increment_compilation_note1 = Please follow the instructions below to create a bug report with the provided information
-query_system_increment_compilation_note2 = See <https://github.com/rust-lang/rust/issues/84970> for more information
+query_system_increment_compilation_note1 = please follow the instructions below to create a bug report with the provided information
+query_system_increment_compilation_note2 = see <https://github.com/rust-lang/rust/issues/84970> for more information
 
 query_system_overflow_note = query depth increased by {$depth} when {$desc}
 
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 47280a93677..0e566e20a12 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -470,6 +470,8 @@ resolve_variable_bound_with_different_mode =
     .label = bound in different ways
     .first_binding_span = first binding
 
+resolve_variable_is_a_typo = you might have meant to use the similarly named previously used binding `{$typo}`
+
 resolve_variable_is_not_bound_in_all_patterns =
     variable `{$name}` is not bound in all patterns
 
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 5dfc4292a38..abbacc70b3e 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -661,8 +661,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             ResolutionError::VariableNotBoundInPattern(binding_error, parent_scope) => {
                 let BindingError { name, target, origin, could_be_path } = binding_error;
 
-                let target_sp = target.iter().copied().collect::<Vec<_>>();
-                let origin_sp = origin.iter().copied().collect::<Vec<_>>();
+                let mut target_sp = target.iter().map(|pat| pat.span).collect::<Vec<_>>();
+                target_sp.sort();
+                target_sp.dedup();
+                let mut origin_sp = origin.iter().map(|(span, _)| *span).collect::<Vec<_>>();
+                origin_sp.sort();
+                origin_sp.dedup();
 
                 let msp = MultiSpan::from_spans(target_sp.clone());
                 let mut err = self
@@ -671,8 +675,35 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 for sp in target_sp {
                     err.subdiagnostic(errors::PatternDoesntBindName { span: sp, name });
                 }
-                for sp in origin_sp {
-                    err.subdiagnostic(errors::VariableNotInAllPatterns { span: sp });
+                for sp in &origin_sp {
+                    err.subdiagnostic(errors::VariableNotInAllPatterns { span: *sp });
+                }
+                let mut suggested_typo = false;
+                if !target.iter().all(|pat| matches!(pat.kind, ast::PatKind::Ident(..)))
+                    && !origin.iter().all(|(_, pat)| matches!(pat.kind, ast::PatKind::Ident(..)))
+                {
+                    // The check above is so that when we encounter `match foo { (a | b) => {} }`,
+                    // we don't suggest `(a | a) => {}`, which would never be what the user wants.
+                    let mut target_visitor = BindingVisitor::default();
+                    for pat in &target {
+                        target_visitor.visit_pat(pat);
+                    }
+                    target_visitor.identifiers.sort();
+                    target_visitor.identifiers.dedup();
+                    let mut origin_visitor = BindingVisitor::default();
+                    for (_, pat) in &origin {
+                        origin_visitor.visit_pat(pat);
+                    }
+                    origin_visitor.identifiers.sort();
+                    origin_visitor.identifiers.dedup();
+                    // Find if the binding could have been a typo
+                    if let Some(typo) =
+                        find_best_match_for_name(&target_visitor.identifiers, name.name, None)
+                        && !origin_visitor.identifiers.contains(&typo)
+                    {
+                        err.subdiagnostic(errors::PatternBindingTypo { spans: origin_sp, typo });
+                        suggested_typo = true;
+                    }
                 }
                 if could_be_path {
                     let import_suggestions = self.lookup_import_candidates(
@@ -693,10 +724,86 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         },
                     );
 
-                    if import_suggestions.is_empty() {
+                    if import_suggestions.is_empty() && !suggested_typo {
+                        let kinds = [
+                            DefKind::Ctor(CtorOf::Variant, CtorKind::Const),
+                            DefKind::Ctor(CtorOf::Struct, CtorKind::Const),
+                            DefKind::Const,
+                            DefKind::AssocConst,
+                        ];
+                        let mut local_names = vec![];
+                        self.add_module_candidates(
+                            parent_scope.module,
+                            &mut local_names,
+                            &|res| matches!(res, Res::Def(_, _)),
+                            None,
+                        );
+                        let local_names: FxHashSet<_> = local_names
+                            .into_iter()
+                            .filter_map(|s| match s.res {
+                                Res::Def(_, def_id) => Some(def_id),
+                                _ => None,
+                            })
+                            .collect();
+
+                        let mut local_suggestions = vec![];
+                        let mut suggestions = vec![];
+                        for kind in kinds {
+                            if let Some(suggestion) = self.early_lookup_typo_candidate(
+                                ScopeSet::All(Namespace::ValueNS),
+                                &parent_scope,
+                                name,
+                                &|res: Res| match res {
+                                    Res::Def(k, _) => k == kind,
+                                    _ => false,
+                                },
+                            ) && let Res::Def(kind, mut def_id) = suggestion.res
+                            {
+                                if let DefKind::Ctor(_, _) = kind {
+                                    def_id = self.tcx.parent(def_id);
+                                }
+                                let kind = kind.descr(def_id);
+                                if local_names.contains(&def_id) {
+                                    // The item is available in the current scope. Very likely to
+                                    // be a typo. Don't use the full path.
+                                    local_suggestions.push((
+                                        suggestion.candidate,
+                                        suggestion.candidate.to_string(),
+                                        kind,
+                                    ));
+                                } else {
+                                    suggestions.push((
+                                        suggestion.candidate,
+                                        self.def_path_str(def_id),
+                                        kind,
+                                    ));
+                                }
+                            }
+                        }
+                        let suggestions = if !local_suggestions.is_empty() {
+                            // There is at least one item available in the current scope that is a
+                            // likely typo. We only show those.
+                            local_suggestions
+                        } else {
+                            suggestions
+                        };
+                        for (name, sugg, kind) in suggestions {
+                            err.span_suggestion_verbose(
+                                span,
+                                format!(
+                                    "you might have meant to use the similarly named {kind} `{name}`",
+                                ),
+                                sugg,
+                                Applicability::MaybeIncorrect,
+                            );
+                            suggested_typo = true;
+                        }
+                    }
+                    if import_suggestions.is_empty() && !suggested_typo {
                         let help_msg = format!(
-                            "if you meant to match on a variant or a `const` item, consider \
-                             making the path in the pattern qualified: `path::to::ModOrType::{name}`",
+                            "if you meant to match on a unit struct, unit variant or a `const` \
+                             item, consider making the path in the pattern qualified: \
+                             `path::to::ModOrType::{name}`",
                         );
                         err.span_help(span, help_msg);
                     }
@@ -1016,6 +1123,39 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
         .emit()
     }
 
+    fn def_path_str(&self, mut def_id: DefId) -> String {
+        // We can't use `def_path_str` in resolve.
+        let mut path = vec![def_id];
+        while let Some(parent) = self.tcx.opt_parent(def_id) {
+            def_id = parent;
+            path.push(def_id);
+            if def_id.is_top_level_module() {
+                break;
+            }
+        }
+        // We will only suggest importing directly if it is accessible through that path.
+        path.into_iter()
+            .rev()
+            .map(|def_id| {
+                self.tcx
+                    .opt_item_name(def_id)
+                    .map(|name| {
+                        match (
+                            def_id.is_top_level_module(),
+                            def_id.is_local(),
+                            self.tcx.sess.edition(),
+                        ) {
+                            (true, true, Edition::Edition2015) => String::new(),
+                            (true, true, _) => kw::Crate.to_string(),
+                            (true, false, _) | (false, _, _) => name.to_string(),
+                        }
+                    })
+                    .unwrap_or_else(|| "_".to_string())
+            })
+            .collect::<Vec<String>>()
+            .join("::")
+    }
+
     pub(crate) fn add_scope_set_candidates(
         &mut self,
         suggestions: &mut Vec<TypoSuggestion>,
@@ -3396,7 +3536,7 @@ impl UsePlacementFinder {
     }
 }
 
-impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
+impl<'tcx> Visitor<'tcx> for UsePlacementFinder {
     fn visit_crate(&mut self, c: &Crate) {
         if self.target_module == CRATE_NODE_ID {
             let inject = c.spans.inject_use_span;
@@ -3424,6 +3564,22 @@ impl<'tcx> visit::Visitor<'tcx> for UsePlacementFinder {
     }
 }
 
+#[derive(Default)]
+struct BindingVisitor {
+    identifiers: Vec<Symbol>,
+    spans: FxHashMap<Symbol, Vec<Span>>,
+}
+
+impl<'tcx> Visitor<'tcx> for BindingVisitor {
+    fn visit_pat(&mut self, pat: &ast::Pat) {
+        if let ast::PatKind::Ident(_, ident, _) = pat.kind {
+            self.identifiers.push(ident.name);
+            self.spans.entry(ident.name).or_default().push(ident.span);
+        }
+        visit::walk_pat(self, pat);
+    }
+}
+
 fn search_for_any_use_in_items(items: &[Box<ast::Item>]) -> Option<Span> {
     for item in items {
         if let ItemKind::Use(..) = item.kind
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 63d6fa23a14..72be94e58db 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -986,6 +986,18 @@ pub(crate) struct VariableNotInAllPatterns {
     pub(crate) span: Span,
 }
 
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(
+    resolve_variable_is_a_typo,
+    applicability = "maybe-incorrect",
+    style = "verbose"
+)]
+pub(crate) struct PatternBindingTypo {
+    #[suggestion_part(code = "{typo}")]
+    pub(crate) spans: Vec<Span>,
+    pub(crate) typo: Symbol,
+}
+
 #[derive(Diagnostic)]
 #[diag(resolve_name_defined_multiple_time)]
 #[note]
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 6a12fafcb1e..521fef2b9d4 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -8,7 +8,6 @@
 
 use std::assert_matches::debug_assert_matches;
 use std::borrow::Cow;
-use std::collections::BTreeSet;
 use std::collections::hash_map::Entry;
 use std::mem::{replace, swap, take};
 
@@ -3682,31 +3681,30 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         // 2) Record any missing bindings or binding mode inconsistencies.
         for (map_outer, pat_outer) in not_never_pats.iter() {
             // Check against all arms except for the same pattern which is always self-consistent.
-            let inners = not_never_pats
-                .iter()
-                .filter(|(_, pat)| pat.id != pat_outer.id)
-                .flat_map(|(map, _)| map);
-
-            for (&name, binding_inner) in inners {
-                match map_outer.get(&name) {
-                    None => {
-                        // The inner binding is missing in the outer.
-                        let binding_error =
-                            missing_vars.entry(name).or_insert_with(|| BindingError {
-                                name,
-                                origin: BTreeSet::new(),
-                                target: BTreeSet::new(),
-                                could_be_path: name.as_str().starts_with(char::is_uppercase),
-                            });
-                        binding_error.origin.insert(binding_inner.span);
-                        binding_error.target.insert(pat_outer.span);
-                    }
-                    Some(binding_outer) => {
-                        if binding_outer.annotation != binding_inner.annotation {
-                            // The binding modes in the outer and inner bindings differ.
-                            inconsistent_vars
-                                .entry(name)
-                                .or_insert((binding_inner.span, binding_outer.span));
+            let inners = not_never_pats.iter().filter(|(_, pat)| pat.id != pat_outer.id);
+
+            for (map, pat) in inners {
+                for (&name, binding_inner) in map {
+                    match map_outer.get(&name) {
+                        None => {
+                            // The inner binding is missing in the outer.
+                            let binding_error =
+                                missing_vars.entry(name).or_insert_with(|| BindingError {
+                                    name,
+                                    origin: Default::default(),
+                                    target: Default::default(),
+                                    could_be_path: name.as_str().starts_with(char::is_uppercase),
+                                });
+                            binding_error.origin.push((binding_inner.span, (***pat).clone()));
+                            binding_error.target.push((***pat_outer).clone());
+                        }
+                        Some(binding_outer) => {
+                            if binding_outer.annotation != binding_inner.annotation {
+                                // The binding modes in the outer and inner bindings differ.
+                                inconsistent_vars
+                                    .entry(name)
+                                    .or_insert((binding_inner.span, binding_outer.span));
+                            }
                         }
                     }
                 }
@@ -3719,7 +3717,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 v.could_be_path = false;
             }
             self.report_error(
-                *v.origin.iter().next().unwrap(),
+                v.origin.iter().next().unwrap().0,
                 ResolutionError::VariableNotBoundInPattern(v, self.parent_scope),
             );
         }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 9674c0356c2..0dea6ae3327 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -230,8 +230,8 @@ enum Used {
 #[derive(Debug)]
 struct BindingError {
     name: Ident,
-    origin: BTreeSet<Span>,
-    target: BTreeSet<Span>,
+    origin: Vec<(Span, ast::Pat)>,
+    target: Vec<ast::Pat>,
     could_be_path: bool,
 }
 
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 6d5be2d92cd..69facde6936 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -83,10 +83,77 @@ pub struct TargetModifier {
     pub value_name: String,
 }
 
+mod target_modifier_consistency_check {
+    use super::*;
+    pub(super) fn sanitizer(l: &TargetModifier, r: Option<&TargetModifier>) -> bool {
+        let mut lparsed: SanitizerSet = Default::default();
+        let lval = if l.value_name.is_empty() { None } else { Some(l.value_name.as_str()) };
+        parse::parse_sanitizers(&mut lparsed, lval);
+
+        let mut rparsed: SanitizerSet = Default::default();
+        let rval = r.filter(|v| !v.value_name.is_empty()).map(|v| v.value_name.as_str());
+        parse::parse_sanitizers(&mut rparsed, rval);
+
+        // Some sanitizers need to be target modifiers, and some do not.
+        // For now, we should mark all sanitizers as target modifiers except for these:
+        // AddressSanitizer, LeakSanitizer
+        let tmod_sanitizers = SanitizerSet::MEMORY
+            | SanitizerSet::THREAD
+            | SanitizerSet::HWADDRESS
+            | SanitizerSet::CFI
+            | SanitizerSet::MEMTAG
+            | SanitizerSet::SHADOWCALLSTACK
+            | SanitizerSet::KCFI
+            | SanitizerSet::KERNELADDRESS
+            | SanitizerSet::SAFESTACK
+            | SanitizerSet::DATAFLOW;
+
+        lparsed & tmod_sanitizers == rparsed & tmod_sanitizers
+    }
+    pub(super) fn sanitizer_cfi_normalize_integers(
+        opts: &Options,
+        l: &TargetModifier,
+        r: Option<&TargetModifier>,
+    ) -> bool {
+        // For kCFI, the helper flag -Zsanitizer-cfi-normalize-integers should also be a target modifier
+        if opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) {
+            if let Some(r) = r {
+                return l.extend().tech_value == r.extend().tech_value;
+            } else {
+                return false;
+            }
+        }
+        true
+    }
+}
+
 impl TargetModifier {
     pub fn extend(&self) -> ExtendedTargetModifierInfo {
         self.opt.reparse(&self.value_name)
     }
+    // Custom consistency check for target modifiers (or default `l.tech_value == r.tech_value`)
+    // When other is None, consistency with default value is checked
+    pub fn consistent(&self, opts: &Options, other: Option<&TargetModifier>) -> bool {
+        assert!(other.is_none() || self.opt == other.unwrap().opt);
+        match self.opt {
+            OptionsTargetModifiers::UnstableOptions(unstable) => match unstable {
+                UnstableOptionsTargetModifiers::sanitizer => {
+                    return target_modifier_consistency_check::sanitizer(self, other);
+                }
+                UnstableOptionsTargetModifiers::sanitizer_cfi_normalize_integers => {
+                    return target_modifier_consistency_check::sanitizer_cfi_normalize_integers(
+                        opts, self, other,
+                    );
+                }
+                _ => {}
+            },
+            _ => {}
+        };
+        match other {
+            Some(other) => self.extend().tech_value == other.extend().tech_value,
+            None => false,
+        }
+    }
 }
 
 fn tmod_push_impl(
@@ -2504,13 +2571,13 @@ written to standard error output)"),
     retpoline_external_thunk: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
         "enables retpoline-external-thunk, retpoline-indirect-branches and retpoline-indirect-calls \
         target features (default: no)"),
-    sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
+    sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER],
         "use a sanitizer"),
     sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED],
         "enable canonical jump tables (default: yes)"),
     sanitizer_cfi_generalize_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable generalizing pointer types (default: no)"),
-    sanitizer_cfi_normalize_integers: Option<bool> = (None, parse_opt_bool, [TRACKED],
+    sanitizer_cfi_normalize_integers: Option<bool> = (None, parse_opt_bool, [TRACKED TARGET_MODIFIER],
         "enable normalizing integer types (default: no)"),
     sanitizer_dataflow_abilist: Vec<String> = (Vec::new(), parse_comma_list, [TRACKED],
         "additional ABI list files that control how shadow parameters are passed (comma separated)"),
diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs
index c32593a6d95..bb2cda77dff 100644
--- a/compiler/rustc_span/src/analyze_source_file.rs
+++ b/compiler/rustc_span/src/analyze_source_file.rs
@@ -81,8 +81,8 @@ cfg_select! {
                 // use `loadu`, which supports unaligned loading.
                 let chunk = unsafe { _mm_loadu_si128(chunk.as_ptr() as *const __m128i) };
 
-                // For character in the chunk, see if its byte value is < 0, which
-                // indicates that it's part of a UTF-8 char.
+                // For each character in the chunk, see if its byte value is < 0,
+                // which indicates that it's part of a UTF-8 char.
                 let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
                 // Create a bit mask from the comparison results.
                 let multibyte_mask = _mm_movemask_epi8(multibyte_test);
@@ -132,8 +132,111 @@ cfg_select! {
             }
         }
     }
+    target_arch = "loongarch64" => {
+        fn analyze_source_file_dispatch(
+            src: &str,
+            lines: &mut Vec<RelativeBytePos>,
+            multi_byte_chars: &mut Vec<MultiByteChar>,
+        ) {
+            use std::arch::is_loongarch_feature_detected;
+
+            if is_loongarch_feature_detected!("lsx") {
+                unsafe {
+                    analyze_source_file_lsx(src, lines, multi_byte_chars);
+                }
+            } else {
+                analyze_source_file_generic(
+                    src,
+                    src.len(),
+                    RelativeBytePos::from_u32(0),
+                    lines,
+                    multi_byte_chars,
+                );
+            }
+        }
+
+        /// Checks 16 byte chunks of text at a time. If the chunk contains
+        /// something other than printable ASCII characters and newlines, the
+        /// function falls back to the generic implementation. Otherwise it uses
+        /// LSX intrinsics to quickly find all newlines.
+        #[target_feature(enable = "lsx")]
+        unsafe fn analyze_source_file_lsx(
+            src: &str,
+            lines: &mut Vec<RelativeBytePos>,
+            multi_byte_chars: &mut Vec<MultiByteChar>,
+        ) {
+            use std::arch::loongarch64::*;
+
+            const CHUNK_SIZE: usize = 16;
+
+            let (chunks, tail) = src.as_bytes().as_chunks::<CHUNK_SIZE>();
+
+            // This variable keeps track of where we should start decoding a
+            // chunk. If a multi-byte character spans across chunk boundaries,
+            // we need to skip that part in the next chunk because we already
+            // handled it.
+            let mut intra_chunk_offset = 0;
+
+            for (chunk_index, chunk) in chunks.iter().enumerate() {
+                // All LSX memory instructions support unaligned access, so using
+                // vld is fine.
+                let chunk = unsafe { lsx_vld::<0>(chunk.as_ptr() as *const i8) };
+
+                // For each character in the chunk, see if its byte value is < 0,
+                // which indicates that it's part of a UTF-8 char.
+                let multibyte_mask = lsx_vmskltz_b(chunk);
+                // Create a bit mask from the comparison results.
+                let multibyte_mask = lsx_vpickve2gr_w::<0>(multibyte_mask);
+
+                // If the bit mask is all zero, we only have ASCII chars here:
+                if multibyte_mask == 0 {
+                    assert!(intra_chunk_offset == 0);
+
+                    // Check for newlines in the chunk
+                    let newlines_test = lsx_vseqi_b::<{b'\n' as i32}>(chunk);
+                    let newlines_mask = lsx_vmskltz_b(newlines_test);
+                    let mut newlines_mask = lsx_vpickve2gr_w::<0>(newlines_mask);
+
+                    let output_offset = RelativeBytePos::from_usize(chunk_index * CHUNK_SIZE + 1);
+
+                    while newlines_mask != 0 {
+                        let index = newlines_mask.trailing_zeros();
+
+                        lines.push(RelativeBytePos(index) + output_offset);
+
+                        // Clear the bit, so we can find the next one.
+                        newlines_mask &= newlines_mask - 1;
+                    }
+                } else {
+                    // The slow path.
+                    // There are multibyte chars in here, fallback to generic decoding.
+                    let scan_start = chunk_index * CHUNK_SIZE + intra_chunk_offset;
+                    intra_chunk_offset = analyze_source_file_generic(
+                        &src[scan_start..],
+                        CHUNK_SIZE - intra_chunk_offset,
+                        RelativeBytePos::from_usize(scan_start),
+                        lines,
+                        multi_byte_chars,
+                    );
+                }
+            }
+
+            // There might still be a tail left to analyze
+            let tail_start = src.len() - tail.len() + intra_chunk_offset;
+            if tail_start < src.len() {
+                analyze_source_file_generic(
+                    &src[tail_start..],
+                    src.len() - tail_start,
+                    RelativeBytePos::from_usize(tail_start),
+                    lines,
+                    multi_byte_chars,
+                );
+            }
+        }
+    }
     _ => {
-        // The target (or compiler version) does not support SSE2 ...
+        // The target (or compiler version) does not support vector instructions
+        // our specialized implementations need (x86 SSE2, loongarch64 LSX)...
         fn analyze_source_file_dispatch(
             src: &str,
             lines: &mut Vec<RelativeBytePos>,
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index ae6755f0764..8907c5e4c4a 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -18,6 +18,7 @@
 // tidy-alphabetical-start
 #![allow(internal_features)]
 #![cfg_attr(bootstrap, feature(round_char_boundary))]
+#![cfg_attr(target_arch = "loongarch64", feature(stdarch_loongarch))]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(array_windows)]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 77260d07c99..e5108d8b7e9 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -2162,6 +2162,7 @@ symbols! {
         target_family,
         target_feature,
         target_feature_11,
+        target_feature_inline_always,
         target_has_atomic,
         target_has_atomic_equal_alignment,
         target_has_atomic_load_store,
@@ -2280,6 +2281,8 @@ symbols! {
         unboxed_closures,
         unchecked_add,
         unchecked_div,
+        unchecked_funnel_shl,
+        unchecked_funnel_shr,
         unchecked_mul,
         unchecked_rem,
         unchecked_shl,
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
index f1b6fa123de..cd55576ef81 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_msvc.rs
@@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
         llvm_target: "aarch64-pc-windows-msvc".into(),
         metadata: TargetMetadata {
             description: Some("ARM64 Windows MSVC".into()),
-            tier: Some(2),
+            tier: Some(1),
             host_tools: Some(true),
             std: Some(true),
         },
diff --git a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
index 598f0f19f0d..cada0dd640a 100644
--- a/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
+++ b/compiler/rustc_target/src/spec/targets/nvptx64_nvidia_cuda.rs
@@ -6,7 +6,7 @@ use crate::spec::{
 pub(crate) fn target() -> Target {
     Target {
         arch: "nvptx64".into(),
-        data_layout: "e-p6:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64".into(),
+        data_layout: "e-p6:32:32-i64:64-i128:128-i256:256-v16:16-v32:32-n16:32:64".into(),
         llvm_target: "nvptx64-nvidia-cuda".into(),
         metadata: TargetMetadata {
             description: Some("--emit=asm generates PTX code that runs on NVIDIA GPUs".into()),
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index f5448baf8c0..3355c0c2104 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -1,3 +1,4 @@
+use std::borrow::Borrow;
 use std::fmt::Debug;
 use std::hash::Hash;
 use std::ops::Deref;
@@ -383,12 +384,12 @@ pub trait Interner:
         defining_anchor: Self::LocalDefId,
     ) -> Self::LocalDefIds;
 
-    type ProbeRef: Copy + Debug + Hash + Eq + Deref<Target = inspect::Probe<Self>>;
-    fn mk_probe_ref(self, probe: inspect::Probe<Self>) -> Self::ProbeRef;
+    type Probe: Debug + Hash + Eq + Borrow<inspect::Probe<Self>>;
+    fn mk_probe(self, probe: inspect::Probe<Self>) -> Self::Probe;
     fn evaluate_root_goal_for_proof_tree_raw(
         self,
         canonical_goal: CanonicalInput<Self>,
-    ) -> (QueryResult<Self>, Self::ProbeRef);
+    ) -> (QueryResult<Self>, Self::Probe);
 }
 
 /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
diff --git a/compiler/rustc_type_ir/src/solve/inspect.rs b/compiler/rustc_type_ir/src/solve/inspect.rs
index 5452ac44158..3af2f8dbaf2 100644
--- a/compiler/rustc_type_ir/src/solve/inspect.rs
+++ b/compiler/rustc_type_ir/src/solve/inspect.rs
@@ -49,7 +49,7 @@ pub type CanonicalState<I, T> = Canonical<I, State<I, T>>;
 pub struct GoalEvaluation<I: Interner> {
     pub uncanonicalized_goal: Goal<I, I::Predicate>,
     pub orig_values: Vec<I::GenericArg>,
-    pub final_revision: I::ProbeRef,
+    pub final_revision: I::Probe,
     pub result: QueryResult<I>,
 }
 
diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs
index fd05f9ca464..b0027e964e4 100644
--- a/library/alloc/src/raw_vec/mod.rs
+++ b/library/alloc/src/raw_vec/mod.rs
@@ -468,10 +468,6 @@ impl<A: Allocator> RawVecInner<A> {
             return Ok(Self::new_in(alloc, elem_layout.alignment()));
         }
 
-        if let Err(err) = alloc_guard(layout.size()) {
-            return Err(err);
-        }
-
         let result = match init {
             AllocInit::Uninitialized => alloc.allocate(layout),
             #[cfg(not(no_global_oom_handling))]
@@ -662,7 +658,7 @@ impl<A: Allocator> RawVecInner<A> {
         let new_layout = layout_array(cap, elem_layout)?;
 
         let ptr = finish_grow(new_layout, self.current_memory(elem_layout), &mut self.alloc)?;
-        // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
+        // SAFETY: layout_array would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
 
         unsafe { self.set_ptr_and_cap(ptr, cap) };
         Ok(())
@@ -684,7 +680,7 @@ impl<A: Allocator> RawVecInner<A> {
         let new_layout = layout_array(cap, elem_layout)?;
 
         let ptr = finish_grow(new_layout, self.current_memory(elem_layout), &mut self.alloc)?;
-        // SAFETY: finish_grow would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
+        // SAFETY: layout_array would have resulted in a capacity overflow if we tried to allocate more than `isize::MAX` items
         unsafe {
             self.set_ptr_and_cap(ptr, cap);
         }
@@ -771,8 +767,6 @@ fn finish_grow<A>(
 where
     A: Allocator,
 {
-    alloc_guard(new_layout.size())?;
-
     let memory = if let Some((ptr, old_layout)) = current_memory {
         debug_assert_eq!(old_layout.align(), new_layout.align());
         unsafe {
@@ -799,23 +793,6 @@ fn handle_error(e: TryReserveError) -> ! {
     }
 }
 
-// We need to guarantee the following:
-// * We don't ever allocate `> isize::MAX` byte-size objects.
-// * We don't overflow `usize::MAX` and actually allocate too little.
-//
-// On 64-bit we just need to check for overflow since trying to allocate
-// `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add
-// an extra guard for this in case we're running on a platform which can use
-// all 4GB in user-space, e.g., PAE or x32.
-#[inline]
-fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
-    if usize::BITS < 64 && alloc_size > isize::MAX as usize {
-        Err(CapacityOverflow.into())
-    } else {
-        Ok(())
-    }
-}
-
 #[inline]
 fn layout_array(cap: usize, elem_layout: Layout) -> Result<Layout, TryReserveError> {
     elem_layout.repeat(cap).map(|(layout, _pad)| layout).map_err(|_| CapacityOverflow.into())
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 4cdc046f71e..d14419a23a1 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -48,6 +48,7 @@ pub use iter::IntoIter;
 /// assert_eq!(strings, ["Hello there!", "Hello there!"]);
 /// ```
 #[inline]
+#[must_use = "cloning is often expensive and is not expected to have side effects"]
 #[stable(feature = "array_repeat", since = "CURRENT_RUSTC_VERSION")]
 pub fn repeat<T: Clone, const N: usize>(val: T) -> [T; N] {
     from_trusted_iterator(repeat_n(val, N))
diff --git a/library/core/src/intrinsics/fallback.rs b/library/core/src/intrinsics/fallback.rs
index eec5c4d646d..96928325328 100644
--- a/library/core/src/intrinsics/fallback.rs
+++ b/library/core/src/intrinsics/fallback.rs
@@ -148,3 +148,76 @@ impl_disjoint_bitor! {
     u8, u16, u32, u64, u128, usize,
     i8, i16, i32, i64, i128, isize,
 }
+
+#[const_trait]
+#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
+pub trait FunnelShift: Copy + 'static {
+    /// See [`super::unchecked_funnel_shl`]; we just need the trait indirection to handle
+    /// different types since calling intrinsics with generics doesn't work.
+    unsafe fn unchecked_funnel_shl(self, rhs: Self, shift: u32) -> Self;
+
+    /// See [`super::unchecked_funnel_shr`]; we just need the trait indirection to handle
+    /// different types since calling intrinsics with generics doesn't work.
+    unsafe fn unchecked_funnel_shr(self, rhs: Self, shift: u32) -> Self;
+}
+
+macro_rules! impl_funnel_shifts {
+    ($($type:ident),*) => {$(
+        #[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
+        impl const FunnelShift for $type {
+            #[cfg_attr(miri, track_caller)]
+            #[inline]
+            unsafe fn unchecked_funnel_shl(self, rhs: Self, shift: u32) -> Self {
+                // This implementation is also used by Miri so we have to check the precondition.
+                // SAFETY: this is guaranteed by the caller
+                unsafe { super::assume(shift < $type::BITS) };
+                if shift == 0 {
+                    self
+                } else {
+                    // SAFETY:
+                    //  - `shift < T::BITS`, which satisfies `unchecked_shl`
+                    //  - this also ensures that `T::BITS - shift < T::BITS` (shift = 0 is checked
+                    //    above), which satisfies `unchecked_shr`
+                    //  - because the types are unsigned, the combination are disjoint bits (this is
+                    //    not true if they're signed, since SHR will fill in the empty space with a
+                    //    sign bit, not zero)
+                    unsafe {
+                        super::disjoint_bitor(
+                            super::unchecked_shl(self, shift),
+                            super::unchecked_shr(rhs, $type::BITS - shift),
+                        )
+                    }
+                }
+            }
+
+            #[cfg_attr(miri, track_caller)]
+            #[inline]
+            unsafe fn unchecked_funnel_shr(self, rhs: Self, shift: u32) -> Self {
+                // This implementation is also used by Miri so we have to check the precondition.
+                // SAFETY: this is guaranteed by the caller
+                unsafe { super::assume(shift < $type::BITS) };
+                if shift == 0 {
+                    rhs
+                } else {
+                    // SAFETY:
+                    //  - `shift < T::BITS`, which satisfies `unchecked_shr`
+                    //  - this also ensures that `T::BITS - shift < T::BITS` (shift = 0 is checked
+                    //    above), which satisfies `unchecked_shl`
+                    //  - because the types are unsigned, the combination are disjoint bits (this is
+                    //    not true if they're signed, since SHR will fill in the empty space with a
+                    //    sign bit, not zero)
+                    unsafe {
+                        super::disjoint_bitor(
+                            super::unchecked_shl(self, $type::BITS - shift),
+                            super::unchecked_shr(rhs, shift),
+                        )
+                    }
+                }
+            }
+        }
+    )*};
+}
+
+impl_funnel_shifts! {
+    u8, u16, u32, u64, u128, usize
+}
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 904aa52c784..bffffbc29c1 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -2102,6 +2102,61 @@ pub const fn saturating_add<T: Copy>(a: T, b: T) -> T;
 #[rustc_intrinsic]
 pub const fn saturating_sub<T: Copy>(a: T, b: T) -> T;
 
+/// Funnel Shift left.
+///
+/// Concatenates `a` and `b` (with `a` in the most significant half),
+/// creating an integer twice as wide. Then shift this integer left
+/// by `shift`), and extract the most significant half. If `a` and `b`
+/// are the same, this is equivalent to a rotate left operation.
+///
+/// It is undefined behavior if `shift` is greater than or equal to the
+/// bit size of `T`.
+///
+/// Safe versions of this intrinsic are available on the integer primitives
+/// via the `funnel_shl` method. For example, [`u32::funnel_shl`].
+#[rustc_intrinsic]
+#[rustc_nounwind]
+#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
+#[unstable(feature = "funnel_shifts", issue = "145686")]
+#[track_caller]
+#[miri::intrinsic_fallback_is_spec]
+pub const unsafe fn unchecked_funnel_shl<T: [const] fallback::FunnelShift>(
+    a: T,
+    b: T,
+    shift: u32,
+) -> T {
+    // SAFETY: caller ensures that `shift` is in-range
+    unsafe { a.unchecked_funnel_shl(b, shift) }
+}
+
+/// Funnel Shift right.
+///
+/// Concatenates `a` and `b` (with `a` in the most significant half),
+/// creating an integer twice as wide. Then shift this integer right
+/// by `shift` (taken modulo the bit size of `T`), and extract the
+/// least significant half. If `a` and `b` are the same, this is equivalent
+/// to a rotate right operation.
+///
+/// It is undefined behavior if `shift` is greater than or equal to the
+/// bit size of `T`.
+///
+/// Safer versions of this intrinsic are available on the integer primitives
+/// via the `funnel_shr` method. For example, [`u32::funnel_shr`]
+#[rustc_intrinsic]
+#[rustc_nounwind]
+#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
+#[unstable(feature = "funnel_shifts", issue = "145686")]
+#[track_caller]
+#[miri::intrinsic_fallback_is_spec]
+pub const unsafe fn unchecked_funnel_shr<T: [const] fallback::FunnelShift>(
+    a: T,
+    b: T,
+    shift: u32,
+) -> T {
+    // SAFETY: caller ensures that `shift` is in-range
+    unsafe { a.unchecked_funnel_shr(b, shift) }
+}
+
 /// This is an implementation detail of [`crate::ptr::read`] and should
 /// not be used anywhere else.  See its comments for why this exists.
 ///
diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs
index 943b88e2330..3ebdf7b4727 100644
--- a/library/core/src/iter/adapters/chain.rs
+++ b/library/core/src/iter/adapters/chain.rs
@@ -321,6 +321,7 @@ impl<A: Default, B: Default> Default for Chain<A, B> {
     ///
     /// // take requires `Default`
     /// let _: Chain<_, _> = mem::take(&mut foo.0);
+    /// ```
     fn default() -> Self {
         Chain::new(Default::default(), Default::default())
     }
diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs
index a6522659620..a55de75d56c 100644
--- a/library/core/src/iter/adapters/peekable.rs
+++ b/library/core/src/iter/adapters/peekable.rs
@@ -317,6 +317,108 @@ impl<I: Iterator> Peekable<I> {
     {
         self.next_if(|next| next == expected)
     }
+
+    /// Consumes the next value of this iterator and applies a function `f` on it,
+    /// returning the result if the closure returns `Ok`.
+    ///
+    /// Otherwise if the closure returns `Err` the value is put back for the next iteration.
+    ///
+    /// The content of the `Err` variant is typically the original value of the closure,
+    /// but this is not required. If a different value is returned,
+    /// the next `peek()` or `next()` call will result in this new value.
+    /// This is similar to modifying the output of `peek_mut()`.
+    ///
+    /// If the closure panics, the next value will always be consumed and dropped
+    /// even if the panic is caught, because the closure never returned an `Err` value to put back.
+    ///
+    /// # Examples
+    ///
+    /// Parse the leading decimal number from an iterator of characters.
+    /// ```
+    /// #![feature(peekable_next_if_map)]
+    /// let mut iter = "125 GOTO 10".chars().peekable();
+    /// let mut line_num = 0_u32;
+    /// while let Some(digit) = iter.next_if_map(|c| c.to_digit(10).ok_or(c)) {
+    ///     line_num = line_num * 10 + digit;
+    /// }
+    /// assert_eq!(line_num, 125);
+    /// assert_eq!(iter.collect::<String>(), " GOTO 10");
+    /// ```
+    ///
+    /// Matching custom types.
+    /// ```
+    /// #![feature(peekable_next_if_map)]
+    ///
+    /// #[derive(Debug, PartialEq, Eq)]
+    /// enum Node {
+    ///     Comment(String),
+    ///     Red(String),
+    ///     Green(String),
+    ///     Blue(String),
+    /// }
+    ///
+    /// /// Combines all consecutive `Comment` nodes into a single one.
+    /// fn combine_comments(nodes: Vec<Node>) -> Vec<Node> {
+    ///     let mut result = Vec::with_capacity(nodes.len());
+    ///     let mut iter = nodes.into_iter().peekable();
+    ///     let mut comment_text = None::<String>;
+    ///     loop {
+    ///         // Typically the closure in .next_if_map() matches on the input,
+    ///         //  extracts the desired pattern into an `Ok`,
+    ///         //  and puts the rest into an `Err`.
+    ///         while let Some(text) = iter.next_if_map(|node| match node {
+    ///             Node::Comment(text) => Ok(text),
+    ///             other => Err(other),
+    ///         }) {
+    ///             comment_text.get_or_insert_default().push_str(&text);
+    ///         }
+    ///
+    ///         if let Some(text) = comment_text.take() {
+    ///             result.push(Node::Comment(text));
+    ///         }
+    ///         if let Some(node) = iter.next() {
+    ///             result.push(node);
+    ///         } else {
+    ///             break;
+    ///         }
+    ///     }
+    ///     result
+    /// }
+    ///# assert_eq!( // hiding the test to avoid cluttering the documentation.
+    ///#     combine_comments(vec![
+    ///#         Node::Comment("The".to_owned()),
+    ///#         Node::Comment("Quick".to_owned()),
+    ///#         Node::Comment("Brown".to_owned()),
+    ///#         Node::Red("Fox".to_owned()),
+    ///#         Node::Green("Jumped".to_owned()),
+    ///#         Node::Comment("Over".to_owned()),
+    ///#         Node::Blue("The".to_owned()),
+    ///#         Node::Comment("Lazy".to_owned()),
+    ///#         Node::Comment("Dog".to_owned()),
+    ///#     ]),
+    ///#     vec![
+    ///#         Node::Comment("TheQuickBrown".to_owned()),
+    ///#         Node::Red("Fox".to_owned()),
+    ///#         Node::Green("Jumped".to_owned()),
+    ///#         Node::Comment("Over".to_owned()),
+    ///#         Node::Blue("The".to_owned()),
+    ///#         Node::Comment("LazyDog".to_owned()),
+    ///#     ],
+    ///# )
+    /// ```
+    #[unstable(feature = "peekable_next_if_map", issue = "143702")]
+    pub fn next_if_map<R>(&mut self, f: impl FnOnce(I::Item) -> Result<R, I::Item>) -> Option<R> {
+        let unpeek = if let Some(item) = self.next() {
+            match f(item) {
+                Ok(result) => return Some(result),
+                Err(item) => Some(item),
+            }
+        } else {
+            None
+        };
+        self.peeked = Some(unpeek);
+        None
+    }
 }
 
 #[unstable(feature = "trusted_len", issue = "37572")]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 82506379cac..c306011bdda 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -156,6 +156,7 @@
 #![feature(f128)]
 #![feature(freeze_impls)]
 #![feature(fundamental)]
+#![feature(funnel_shifts)]
 #![feature(if_let_guard)]
 #![feature(intra_doc_pointers)]
 #![feature(intrinsics)]
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 25864db5fea..db70fb65d44 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1285,7 +1285,7 @@ macro_rules! int_impl {
         ///
         /// ```should_panic
         #[doc = concat!("let _ = ", stringify!($SelfT), "::MIN.strict_neg();")]
-        ///
+        /// ```
         #[stable(feature = "strict_overflow_ops", since = "CURRENT_RUSTC_VERSION")]
         #[rustc_const_stable(feature = "strict_overflow_ops", since = "CURRENT_RUSTC_VERSION")]
         #[must_use = "this returns the result of the operation, \
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 69c6a7dbd89..54d5a63633c 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -454,6 +454,9 @@ impl u8 {
         rot = 2,
         rot_op = "0x82",
         rot_result = "0xa",
+        fsh_op = "0x36",
+        fshl_result = "0x8",
+        fshr_result = "0x8d",
         swap_op = "0x12",
         swapped = "0x12",
         reversed = "0x48",
@@ -1088,6 +1091,9 @@ impl u16 {
         rot = 4,
         rot_op = "0xa003",
         rot_result = "0x3a",
+        fsh_op = "0x2de",
+        fshl_result = "0x30",
+        fshr_result = "0x302d",
         swap_op = "0x1234",
         swapped = "0x3412",
         reversed = "0x2c48",
@@ -1135,6 +1141,9 @@ impl u32 {
         rot = 8,
         rot_op = "0x10000b3",
         rot_result = "0xb301",
+        fsh_op = "0x2fe78e45",
+        fshl_result = "0xb32f",
+        fshr_result = "0xb32fe78e",
         swap_op = "0x12345678",
         swapped = "0x78563412",
         reversed = "0x1e6a2c48",
@@ -1158,6 +1167,9 @@ impl u64 {
         rot = 12,
         rot_op = "0xaa00000000006e1",
         rot_result = "0x6e10aa",
+        fsh_op = "0x2fe78e45983acd98",
+        fshl_result = "0x6e12fe",
+        fshr_result = "0x6e12fe78e45983ac",
         swap_op = "0x1234567890123456",
         swapped = "0x5634129078563412",
         reversed = "0x6a2c48091e6a2c48",
@@ -1181,6 +1193,9 @@ impl u128 {
         rot = 16,
         rot_op = "0x13f40000000000000000000000004f76",
         rot_result = "0x4f7613f4",
+        fsh_op = "0x2fe78e45983acd98039000008736273",
+        fshl_result = "0x4f7602fe",
+        fshr_result = "0x4f7602fe78e45983acd9803900000873",
         swap_op = "0x12345678901234567890123456789012",
         swapped = "0x12907856341290785634129078563412",
         reversed = "0x48091e6a2c48091e6a2c48091e6a2c48",
@@ -1207,6 +1222,9 @@ impl usize {
         rot = 4,
         rot_op = "0xa003",
         rot_result = "0x3a",
+        fsh_op = "0x2fe78e45983acd98039000008736273",
+        fshl_result = "0x4f7602fe",
+        fshr_result = "0x4f7602fe78e45983acd9803900000873",
         swap_op = "0x1234",
         swapped = "0x3412",
         reversed = "0x2c48",
@@ -1231,6 +1249,9 @@ impl usize {
         rot = 8,
         rot_op = "0x10000b3",
         rot_result = "0xb301",
+        fsh_op = "0x2fe78e45",
+        fshl_result = "0xb32f",
+        fshr_result = "0xb32fe78e",
         swap_op = "0x12345678",
         swapped = "0x78563412",
         reversed = "0x1e6a2c48",
@@ -1255,6 +1276,9 @@ impl usize {
         rot = 12,
         rot_op = "0xaa00000000006e1",
         rot_result = "0x6e10aa",
+        fsh_op = "0x2fe78e45983acd98",
+        fshl_result = "0x6e12fe",
+        fshr_result = "0x6e12fe78e45983ac",
         swap_op = "0x1234567890123456",
         swapped = "0x5634129078563412",
         reversed = "0x6a2c48091e6a2c48",
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index c1e656fdea2..0ce9c259c40 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -14,6 +14,9 @@ macro_rules! uint_impl {
         rot = $rot:literal,
         rot_op = $rot_op:literal,
         rot_result = $rot_result:literal,
+        fsh_op = $fsh_op:literal,
+        fshl_result = $fshl_result:literal,
+        fshr_result = $fshr_result:literal,
         swap_op = $swap_op:literal,
         swapped = $swapped:literal,
         reversed = $reversed:literal,
@@ -375,6 +378,76 @@ macro_rules! uint_impl {
             return intrinsics::rotate_right(self, n);
         }
 
+        /// Performs a left funnel shift (concatenates `self` with `rhs`, with `self`
+        /// making up the most significant half, then shifts the combined value left
+        /// by `n`, and most significant half is extracted to produce the result).
+        ///
+        /// Please note this isn't the same operation as the `<<` shifting operator or
+        /// [`rotate_left`](Self::rotate_left), although `a.funnel_shl(a, n)` is *equivalent*
+        /// to `a.rotate_left(n)`.
+        ///
+        /// # Panics
+        ///
+        /// If `n` is greater than or equal to the number of bits in `self`
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(funnel_shifts)]
+        #[doc = concat!("let a = ", $rot_op, stringify!($SelfT), ";")]
+        #[doc = concat!("let b = ", $fsh_op, stringify!($SelfT), ";")]
+        #[doc = concat!("let m = ", $fshl_result, ";")]
+        ///
+        #[doc = concat!("assert_eq!(a.funnel_shl(b, ", $rot, "), m);")]
+        /// ```
+        #[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
+        #[unstable(feature = "funnel_shifts", issue = "145686")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        pub const fn funnel_shl(self, rhs: Self, n: u32) -> Self {
+            assert!(n < Self::BITS, "attempt to funnel shift left with overflow");
+            // SAFETY: just checked that `shift` is in-range
+            unsafe { intrinsics::unchecked_funnel_shl(self, rhs, n) }
+        }
+
+        /// Performs a right funnel shift (concatenates `self` and `rhs`, with `self`
+        /// making up the most significant half, then shifts the combined value right
+        /// by `n`, and least significant half is extracted to produce the result).
+        ///
+        /// Please note this isn't the same operation as the `>>` shifting operator or
+        /// [`rotate_right`](Self::rotate_right), although `a.funnel_shr(a, n)` is *equivalent*
+        /// to `a.rotate_right(n)`.
+        ///
+        /// # Panics
+        ///
+        /// If `n` is greater than or equal to the number of bits in `self`
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        ///
+        /// ```
+        /// #![feature(funnel_shifts)]
+        #[doc = concat!("let a = ", $rot_op, stringify!($SelfT), ";")]
+        #[doc = concat!("let b = ", $fsh_op, stringify!($SelfT), ";")]
+        #[doc = concat!("let m = ", $fshr_result, ";")]
+        ///
+        #[doc = concat!("assert_eq!(a.funnel_shr(b, ", $rot, "), m);")]
+        /// ```
+        #[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
+        #[unstable(feature = "funnel_shifts", issue = "145686")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline(always)]
+        pub const fn funnel_shr(self, rhs: Self, n: u32) -> Self {
+            assert!(n < Self::BITS, "attempt to funnel shift right with overflow");
+            // SAFETY: just checked that `shift` is in-range
+            unsafe { intrinsics::unchecked_funnel_shr(self, rhs, n) }
+        }
+
         /// Reverses the byte order of the integer.
         ///
         /// # Examples
@@ -1620,7 +1693,7 @@ macro_rules! uint_impl {
         ///
         /// ```should_panic
         #[doc = concat!("let _ = 1", stringify!($SelfT), ".strict_neg();")]
-        ///
+        /// ```
         #[stable(feature = "strict_overflow_ops", since = "CURRENT_RUSTC_VERSION")]
         #[rustc_const_stable(feature = "strict_overflow_ops", since = "CURRENT_RUSTC_VERSION")]
         #[must_use = "this returns the result of the operation, \
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index c0a27775694..58a9431bd84 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -836,6 +836,7 @@ pub trait RangeBounds<T: ?Sized> {
     /// assert!(!(0.0..1.0).contains(&f32::NAN));
     /// assert!(!(0.0..f32::NAN).contains(&0.5));
     /// assert!(!(f32::NAN..1.0).contains(&0.5));
+    /// ```
     #[inline]
     #[stable(feature = "range_contains", since = "1.35.0")]
     fn contains<U>(&self, item: &U) -> bool
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 3fe4b08d459..ce6eee4f911 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -106,6 +106,7 @@ impl<T: PointeeSized> *mut T {
     ///
     /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`.
     /// println!("{:?}", unsafe { &*bad });
+    /// ```
     #[unstable(feature = "set_ptr_value", issue = "75091")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[inline]
diff --git a/library/coretests/tests/iter/adapters/peekable.rs b/library/coretests/tests/iter/adapters/peekable.rs
index 7f4341b8902..f0549e8d6c2 100644
--- a/library/coretests/tests/iter/adapters/peekable.rs
+++ b/library/coretests/tests/iter/adapters/peekable.rs
@@ -271,3 +271,89 @@ fn test_peekable_non_fused() {
     assert_eq!(iter.peek(), None);
     assert_eq!(iter.next_back(), None);
 }
+
+#[test]
+fn test_peekable_next_if_map_mutation() {
+    fn collatz((mut num, mut len): (u64, u32)) -> Result<u32, (u64, u32)> {
+        let jump = num.trailing_zeros();
+        num >>= jump;
+        len += jump;
+        if num == 1 { Ok(len) } else { Err((3 * num + 1, len + 1)) }
+    }
+
+    let mut iter = once((3, 0)).peekable();
+    assert_eq!(iter.peek(), Some(&(3, 0)));
+    assert_eq!(iter.next_if_map(collatz), None);
+    assert_eq!(iter.peek(), Some(&(10, 1)));
+    assert_eq!(iter.next_if_map(collatz), None);
+    assert_eq!(iter.peek(), Some(&(16, 3)));
+    assert_eq!(iter.next_if_map(collatz), Some(7));
+    assert_eq!(iter.peek(), None);
+    assert_eq!(iter.next_if_map(collatz), None);
+}
+
+#[test]
+#[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+fn test_peekable_next_if_map_panic() {
+    use core::cell::Cell;
+    use std::panic::{AssertUnwindSafe, catch_unwind};
+
+    struct BitsetOnDrop<'a> {
+        value: u32,
+        cell: &'a Cell<u32>,
+    }
+    impl<'a> Drop for BitsetOnDrop<'a> {
+        fn drop(&mut self) {
+            self.cell.update(|v| v | self.value);
+        }
+    }
+
+    let cell = &Cell::new(0);
+    let mut it = [
+        BitsetOnDrop { value: 1, cell },
+        BitsetOnDrop { value: 2, cell },
+        BitsetOnDrop { value: 4, cell },
+        BitsetOnDrop { value: 8, cell },
+    ]
+    .into_iter()
+    .peekable();
+
+    // sanity check, .peek() won't consume the value, .next() will transfer ownership.
+    let item = it.peek().unwrap();
+    assert_eq!(item.value, 1);
+    assert_eq!(cell.get(), 0);
+    let item = it.next().unwrap();
+    assert_eq!(item.value, 1);
+    assert_eq!(cell.get(), 0);
+    drop(item);
+    assert_eq!(cell.get(), 1);
+
+    // next_if_map returning Ok should transfer the value out.
+    let item = it.next_if_map(Ok).unwrap();
+    assert_eq!(item.value, 2);
+    assert_eq!(cell.get(), 1);
+    drop(item);
+    assert_eq!(cell.get(), 3);
+
+    // next_if_map returning Err should not drop anything.
+    assert_eq!(it.next_if_map::<()>(Err), None);
+    assert_eq!(cell.get(), 3);
+    assert_eq!(it.peek().unwrap().value, 4);
+    assert_eq!(cell.get(), 3);
+
+    // next_if_map panicking should consume and drop the item.
+    let result = catch_unwind({
+        let mut it = AssertUnwindSafe(&mut it);
+        move || it.next_if_map::<()>(|_| panic!())
+    });
+    assert!(result.is_err());
+    assert_eq!(cell.get(), 7);
+    assert_eq!(it.next().unwrap().value, 8);
+    assert_eq!(cell.get(), 15);
+    assert!(it.peek().is_none());
+
+    // next_if_map should *not* execute the closure if the iterator is exhausted.
+    assert!(it.next_if_map::<()>(|_| panic!()).is_none());
+    assert!(it.peek().is_none());
+    assert_eq!(cell.get(), 15);
+}
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index ffb96b5a7cf..b5658a9970f 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -50,6 +50,7 @@
 #![feature(fmt_internals)]
 #![feature(formatting_options)]
 #![feature(freeze)]
+#![feature(funnel_shifts)]
 #![feature(future_join)]
 #![feature(generic_assert_internals)]
 #![feature(hasher_prefixfree_extras)]
@@ -82,6 +83,7 @@
 #![feature(numfmt)]
 #![feature(option_reduce)]
 #![feature(pattern)]
+#![feature(peekable_next_if_map)]
 #![feature(pointer_is_aligned_to)]
 #![feature(portable_simd)]
 #![feature(ptr_metadata)]
diff --git a/library/coretests/tests/num/uint_macros.rs b/library/coretests/tests/num/uint_macros.rs
index c7d10ea4d88..63be8a45b5c 100644
--- a/library/coretests/tests/num/uint_macros.rs
+++ b/library/coretests/tests/num/uint_macros.rs
@@ -104,6 +104,19 @@ macro_rules! uint_module {
                 assert_eq_const_safe!($T: C.rotate_left(128), C);
             }
 
+            fn test_funnel_shift() {
+                // Shifting by 0 should have no effect
+                assert_eq_const_safe!($T: <$T>::funnel_shl(A, B, 0), A);
+                assert_eq_const_safe!($T: <$T>::funnel_shr(A, B, 0), B);
+
+                assert_eq_const_safe!($T: <$T>::funnel_shl(_0, _1, 4), 0b1111);
+                assert_eq_const_safe!($T: <$T>::funnel_shr(_0, _1, 4), _1 >> 4);
+                assert_eq_const_safe!($T: <$T>::funnel_shl(_1, _0, 4), _1 << 4);
+
+                assert_eq_const_safe!($T: <$T>::funnel_shl(_1, _1, 4), <$T>::rotate_left(_1, 4));
+                assert_eq_const_safe!($T: <$T>::funnel_shr(_1, _1, 4), <$T>::rotate_right(_1, 4));
+            }
+
             fn test_swap_bytes() {
                 assert_eq_const_safe!($T: A.swap_bytes().swap_bytes(), A);
                 assert_eq_const_safe!($T: B.swap_bytes().swap_bytes(), B);
@@ -151,6 +164,29 @@ macro_rules! uint_module {
         }
 
         #[test]
+        #[should_panic = "attempt to funnel shift left with overflow"]
+        fn test_funnel_shl_overflow() {
+            let _ = <$T>::funnel_shl(A, B, $T::BITS);
+        }
+
+        #[test]
+        #[should_panic = "attempt to funnel shift right with overflow"]
+        fn test_funnel_shr_overflow() {
+            let _ = <$T>::funnel_shr(A, B, $T::BITS);
+        }
+
+        #[test]
+        fn test_funnel_shifts_runtime() {
+            for i in 0..$T::BITS - 1 {
+                assert_eq!(<$T>::funnel_shl(A, 0, i), A << i);
+                assert_eq!(<$T>::funnel_shl(A, A, i), A.rotate_left(i));
+
+                assert_eq!(<$T>::funnel_shr(0, A, i), A >> i);
+                assert_eq!(<$T>::funnel_shr(A, A, i), A.rotate_right(i));
+            }
+        }
+
+        #[test]
         fn test_isolate_highest_one() {
             const BITS: $T = <$T>::MAX;
             const MOST_SIG_ONE: $T = 1 << (<$T>::BITS - 1);
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/int.rs b/library/portable-simd/crates/core_simd/src/simd/num/int.rs
index d25050c3e4b..e7253313f03 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/int.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/int.rs
@@ -58,6 +58,7 @@ pub trait SimdInt: Copy + Sealed {
     /// let sat = x.saturating_sub(max);
     /// assert_eq!(unsat, Simd::from_array([1, MAX, MIN, 0]));
     /// assert_eq!(sat, Simd::from_array([MIN, MIN, MIN, 0]));
+    /// ```
     fn saturating_sub(self, second: Self) -> Self;
 
     /// Lanewise absolute value, implemented in Rust.
diff --git a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
index 45d978068b6..e3ba8658bd8 100644
--- a/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/num/uint.rs
@@ -55,6 +55,7 @@ pub trait SimdUint: Copy + Sealed {
     /// let sat = x.saturating_sub(max);
     /// assert_eq!(unsat, Simd::from_array([3, 2, 1, 0]));
     /// assert_eq!(sat, Simd::splat(0));
+    /// ```
     fn saturating_sub(self, second: Self) -> Self;
 
     /// Lanewise absolute difference.
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 5e51d5e5211..f4431cedd18 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -492,6 +492,85 @@ fn file_test_io_read_write_at() {
 
 #[test]
 #[cfg(unix)]
+fn test_read_buf_at() {
+    use crate::os::unix::fs::FileExt;
+
+    let tmpdir = tmpdir();
+    let filename = tmpdir.join("file_rt_io_file_test_read_buf_at.txt");
+    {
+        let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
+        let mut file = check!(oo.open(&filename));
+        check!(file.write_all(b"0123456789"));
+    }
+    {
+        let mut file = check!(File::open(&filename));
+        let mut buf: [MaybeUninit<u8>; 5] = [MaybeUninit::uninit(); 5];
+        let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+
+        // Fill entire buffer with potentially short reads
+        while buf.unfilled().capacity() > 0 {
+            let len = buf.len();
+            check!(file.read_buf_at(buf.unfilled(), 2 + len as u64));
+            assert!(!buf.filled().is_empty());
+            assert!(b"23456".starts_with(buf.filled()));
+            assert_eq!(check!(file.stream_position()), 0);
+        }
+        assert_eq!(buf.filled(), b"23456");
+
+        // Already full
+        check!(file.read_buf_at(buf.unfilled(), 3));
+        check!(file.read_buf_at(buf.unfilled(), 10));
+        assert_eq!(buf.filled(), b"23456");
+        assert_eq!(check!(file.stream_position()), 0);
+
+        // Read past eof is noop
+        check!(file.read_buf_at(buf.clear().unfilled(), 10));
+        assert_eq!(buf.filled(), b"");
+        check!(file.read_buf_at(buf.clear().unfilled(), 11));
+        assert_eq!(buf.filled(), b"");
+        assert_eq!(check!(file.stream_position()), 0);
+    }
+    check!(fs::remove_file(&filename));
+}
+
+#[test]
+#[cfg(unix)]
+fn test_read_buf_exact_at() {
+    use crate::os::unix::fs::FileExt;
+
+    let tmpdir = tmpdir();
+    let filename = tmpdir.join("file_rt_io_file_test_read_buf_exact_at.txt");
+    {
+        let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
+        let mut file = check!(oo.open(&filename));
+        check!(file.write_all(b"0123456789"));
+    }
+    {
+        let mut file = check!(File::open(&filename));
+        let mut buf: [MaybeUninit<u8>; 5] = [MaybeUninit::uninit(); 5];
+        let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+
+        // Exact read
+        check!(file.read_buf_exact_at(buf.unfilled(), 2));
+        assert_eq!(buf.filled(), b"23456");
+        assert_eq!(check!(file.stream_position()), 0);
+
+        // Already full
+        check!(file.read_buf_exact_at(buf.unfilled(), 3));
+        check!(file.read_buf_exact_at(buf.unfilled(), 10));
+        assert_eq!(buf.filled(), b"23456");
+        assert_eq!(check!(file.stream_position()), 0);
+
+        // Non-empty exact read past eof fails
+        let err = file.read_buf_exact_at(buf.clear().unfilled(), 6).unwrap_err();
+        assert_eq!(err.kind(), ErrorKind::UnexpectedEof);
+        assert_eq!(check!(file.stream_position()), 0);
+    }
+    check!(fs::remove_file(&filename));
+}
+
+#[test]
+#[cfg(unix)]
 fn set_get_unix_permissions() {
     use crate::os::unix::fs::PermissionsExt;
 
@@ -567,6 +646,39 @@ fn file_test_io_seek_read_write() {
 }
 
 #[test]
+#[cfg(windows)]
+fn test_seek_read_buf() {
+    use crate::os::windows::fs::FileExt;
+
+    let tmpdir = tmpdir();
+    let filename = tmpdir.join("file_rt_io_file_test_seek_read_buf.txt");
+    {
+        let oo = OpenOptions::new().create_new(true).write(true).read(true).clone();
+        let mut file = check!(oo.open(&filename));
+        check!(file.write_all(b"0123456789"));
+    }
+    {
+        let mut file = check!(File::open(&filename));
+        let mut buf: [MaybeUninit<u8>; 1] = [MaybeUninit::uninit()];
+        let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+
+        // Seek read
+        check!(file.seek_read_buf(buf.unfilled(), 8));
+        assert_eq!(buf.filled(), b"8");
+        assert_eq!(check!(file.stream_position()), 9);
+
+        // Empty seek read
+        check!(file.seek_read_buf(buf.unfilled(), 0));
+        assert_eq!(buf.filled(), b"8");
+
+        // Seek read past eof
+        check!(file.seek_read_buf(buf.clear().unfilled(), 10));
+        assert_eq!(buf.filled(), b"");
+    }
+    check!(fs::remove_file(&filename));
+}
+
+#[test]
 fn file_test_read_buf() {
     let tmpdir = tmpdir();
     let filename = &tmpdir.join("test");
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index a4b63462053..99b380c4793 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -294,6 +294,7 @@
 #![feature(f128)]
 #![feature(ffi_const)]
 #![feature(formatting_options)]
+#![feature(funnel_shifts)]
 #![feature(hash_map_internals)]
 #![feature(hash_map_macro)]
 #![feature(if_let_guard)]
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index b776df3dde1..1d1a138b302 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -11,6 +11,7 @@ use super::platform::fs::MetadataExt as _;
 // Used for `File::read` on intra-doc links
 use crate::ffi::OsStr;
 use crate::fs::{self, OpenOptions, Permissions};
+use crate::io::BorrowedCursor;
 use crate::os::unix::io::{AsFd, AsRawFd};
 use crate::path::Path;
 use crate::sealed::Sealed;
@@ -130,6 +131,91 @@ pub trait FileExt {
         if !buf.is_empty() { Err(io::Error::READ_EXACT_EOF) } else { Ok(()) }
     }
 
+    /// Reads some bytes starting from a given offset into the buffer.
+    ///
+    /// This equivalent to the [`read_at`](FileExt::read_at) method, except that it is passed a
+    /// [`BorrowedCursor`] rather than `&mut [u8]` to allow use with uninitialized buffers. The new
+    /// data will be appended to any existing contents of `buf`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(core_io_borrowed_buf)]
+    /// #![feature(read_buf_at)]
+    ///
+    /// use std::io;
+    /// use std::io::BorrowedBuf;
+    /// use std::fs::File;
+    /// use std::mem::MaybeUninit;
+    /// use std::os::unix::prelude::*;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut file = File::open("pi.txt")?;
+    ///
+    ///     // Read some bytes starting from offset 2
+    ///     let mut buf: [MaybeUninit<u8>; 10] = [MaybeUninit::uninit(); 10];
+    ///     let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+    ///     file.read_buf_at(buf.unfilled(), 2)?;
+    ///
+    ///     assert!(buf.filled().starts_with(b"1"));
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "read_buf_at", issue = "140771")]
+    fn read_buf_at(&self, buf: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        io::default_read_buf(|b| self.read_at(b, offset), buf)
+    }
+
+    /// Reads the exact number of bytes required to fill the buffer from a given offset.
+    ///
+    /// This is equivalent to the [`read_exact_at`](FileExt::read_exact_at) method, except that it
+    /// is passed a [`BorrowedCursor`] rather than `&mut [u8]` to allow use with uninitialized
+    /// buffers. The new data will be appended to any existing contents of `buf`.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(core_io_borrowed_buf)]
+    /// #![feature(read_buf_at)]
+    ///
+    /// use std::io;
+    /// use std::io::BorrowedBuf;
+    /// use std::fs::File;
+    /// use std::mem::MaybeUninit;
+    /// use std::os::unix::prelude::*;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut file = File::open("pi.txt")?;
+    ///
+    ///     // Read exactly 10 bytes starting from offset 2
+    ///     let mut buf: [MaybeUninit<u8>; 10] = [MaybeUninit::uninit(); 10];
+    ///     let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+    ///     file.read_buf_exact_at(buf.unfilled(), 2)?;
+    ///
+    ///     assert_eq!(buf.filled(), b"1415926535");
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "read_buf_at", issue = "140771")]
+    fn read_buf_exact_at(&self, mut buf: BorrowedCursor<'_>, mut offset: u64) -> io::Result<()> {
+        while buf.capacity() > 0 {
+            let prev_written = buf.written();
+            match self.read_buf_at(buf.reborrow(), offset) {
+                Ok(()) => {}
+                Err(e) if e.is_interrupted() => {}
+                Err(e) => return Err(e),
+            }
+            let n = buf.written() - prev_written;
+            offset += n as u64;
+            if n == 0 {
+                return Err(io::Error::READ_EXACT_EOF);
+            }
+        }
+        Ok(())
+    }
+
     /// Writes a number of bytes starting from a given offset.
     ///
     /// Returns the number of bytes written.
@@ -264,6 +350,9 @@ impl FileExt for fs::File {
     fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
         self.as_inner().read_at(buf, offset)
     }
+    fn read_buf_at(&self, buf: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        self.as_inner().read_buf_at(buf, offset)
+    }
     fn read_vectored_at(&self, bufs: &mut [io::IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
         self.as_inner().read_vectored_at(bufs, offset)
     }
diff --git a/library/std/src/os/windows/fs.rs b/library/std/src/os/windows/fs.rs
index ddb8dbd8fee..b445f368aeb 100644
--- a/library/std/src/os/windows/fs.rs
+++ b/library/std/src/os/windows/fs.rs
@@ -5,6 +5,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::fs::{self, Metadata, OpenOptions};
+use crate::io::BorrowedCursor;
 use crate::path::Path;
 use crate::sealed::Sealed;
 use crate::sys_common::{AsInner, AsInnerMut, IntoInner};
@@ -49,6 +50,44 @@ pub trait FileExt {
     #[stable(feature = "file_offset", since = "1.15.0")]
     fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
 
+    /// Seeks to a given position and reads some bytes into the buffer.
+    ///
+    /// This is equivalent to the [`seek_read`](FileExt::seek_read) method, except that it is passed
+    /// a [`BorrowedCursor`] rather than `&mut [u8]` to allow use with uninitialized buffers. The
+    /// new data will be appended to any existing contents of `buf`.
+    ///
+    /// Reading beyond the end of the file will always succeed without reading any bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(core_io_borrowed_buf)]
+    /// #![feature(read_buf_at)]
+    ///
+    /// use std::io;
+    /// use std::io::BorrowedBuf;
+    /// use std::fs::File;
+    /// use std::mem::MaybeUninit;
+    /// use std::os::windows::prelude::*;
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut file = File::open("pi.txt")?;
+    ///
+    ///     // Read some bytes starting from offset 2
+    ///     let mut buf: [MaybeUninit<u8>; 10] = [MaybeUninit::uninit(); 10];
+    ///     let mut buf = BorrowedBuf::from(buf.as_mut_slice());
+    ///     file.seek_read_buf(buf.unfilled(), 2)?;
+    ///
+    ///     assert!(buf.filled().starts_with(b"1"));
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    #[unstable(feature = "read_buf_at", issue = "140771")]
+    fn seek_read_buf(&self, buf: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        io::default_read_buf(|b| self.seek_read(b, offset), buf)
+    }
+
     /// Seeks to a given position and writes a number of bytes.
     ///
     /// Returns the number of bytes written.
@@ -89,6 +128,10 @@ impl FileExt for fs::File {
         self.as_inner().read_at(buf, offset)
     }
 
+    fn seek_read_buf(&self, buf: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        self.as_inner().read_buf_at(buf, offset)
+    }
+
     fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
         self.as_inner().write_at(buf, offset)
     }
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 5ccea1c972c..19663e4a9df 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1575,8 +1575,6 @@ impl PathBuf {
     /// # Examples
     ///
     /// ```
-    /// #![feature(path_add_extension)]
-    ///
     /// use std::path::{Path, PathBuf};
     ///
     /// let mut p = PathBuf::from("/feel/the");
@@ -1596,7 +1594,7 @@ impl PathBuf {
     /// p.add_extension("");
     /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
     /// ```
-    #[unstable(feature = "path_add_extension", issue = "127292")]
+    #[stable(feature = "path_add_extension", since = "CURRENT_RUSTC_VERSION")]
     pub fn add_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
         self._add_extension(extension.as_ref())
     }
@@ -2109,7 +2107,7 @@ impl PartialEq for PathBuf {
 impl cmp::PartialEq<str> for PathBuf {
     #[inline]
     fn eq(&self, other: &str) -> bool {
-        &*self == other
+        Path::eq(self, other)
     }
 }
 
@@ -2880,8 +2878,6 @@ impl Path {
     /// # Examples
     ///
     /// ```
-    /// #![feature(path_add_extension)]
-    ///
     /// use std::path::{Path, PathBuf};
     ///
     /// let path = Path::new("foo.rs");
@@ -2892,7 +2888,7 @@ impl Path {
     /// assert_eq!(path.with_added_extension("xz"), PathBuf::from("foo.tar.gz.xz"));
     /// assert_eq!(path.with_added_extension("").with_added_extension("txt"), PathBuf::from("foo.tar.gz.txt"));
     /// ```
-    #[unstable(feature = "path_add_extension", issue = "127292")]
+    #[stable(feature = "path_add_extension", since = "CURRENT_RUSTC_VERSION")]
     pub fn with_added_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
         let mut new_path = self.to_path_buf();
         new_path.add_extension(extension);
diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs
index a12f692e754..2b2dfe48e89 100644
--- a/library/std/src/sys/fd/unix.rs
+++ b/library/std/src/sys/fd/unix.rs
@@ -18,6 +18,21 @@ use libc::off_t as off64_t;
 ))]
 use libc::off64_t;
 
+cfg_select! {
+    any(
+        all(target_os = "linux", not(target_env = "musl")),
+        target_os = "android",
+        target_os = "hurd",
+    ) => {
+        // Prefer explicit pread64 for 64-bit offset independently of libc
+        // #[cfg(gnu_file_offset_bits64)].
+        use libc::pread64;
+    }
+    _ => {
+        use libc::pread as pread64;
+    }
+}
+
 use crate::cmp;
 use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read};
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
@@ -146,42 +161,47 @@ impl FileDesc {
         (&mut me).read_to_end(buf)
     }
 
-    #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
     pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
-        #[cfg(not(any(
-            all(target_os = "linux", not(target_env = "musl")),
-            target_os = "android",
-            target_os = "hurd"
-        )))]
-        use libc::pread as pread64;
-        #[cfg(any(
-            all(target_os = "linux", not(target_env = "musl")),
-            target_os = "android",
-            target_os = "hurd"
-        ))]
-        use libc::pread64;
-
-        unsafe {
-            cvt(pread64(
+        cvt(unsafe {
+            pread64(
                 self.as_raw_fd(),
                 buf.as_mut_ptr() as *mut libc::c_void,
                 cmp::min(buf.len(), READ_LIMIT),
-                offset as off64_t,
-            ))
-            .map(|n| n as usize)
-        }
+                offset as off64_t, // EINVAL if offset + count overflows
+            )
+        })
+        .map(|n| n as usize)
     }
 
     pub fn read_buf(&self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
+        // SAFETY: `cursor.as_mut()` starts with `cursor.capacity()` writable bytes
         let ret = cvt(unsafe {
             libc::read(
                 self.as_raw_fd(),
-                cursor.as_mut().as_mut_ptr() as *mut libc::c_void,
+                cursor.as_mut().as_mut_ptr().cast::<libc::c_void>(),
+                cmp::min(cursor.capacity(), READ_LIMIT),
+            )
+        })?;
+
+        // SAFETY: `ret` bytes were written to the initialized portion of the buffer
+        unsafe {
+            cursor.advance_unchecked(ret as usize);
+        }
+        Ok(())
+    }
+
+    pub fn read_buf_at(&self, mut cursor: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        // SAFETY: `cursor.as_mut()` starts with `cursor.capacity()` writable bytes
+        let ret = cvt(unsafe {
+            pread64(
+                self.as_raw_fd(),
+                cursor.as_mut().as_mut_ptr().cast::<libc::c_void>(),
                 cmp::min(cursor.capacity(), READ_LIMIT),
+                offset as off64_t, // EINVAL if offset + count overflows
             )
         })?;
 
-        // Safety: `ret` bytes were written to the initialized portion of the buffer
+        // SAFETY: `ret` bytes were written to the initialized portion of the buffer
         unsafe {
             cursor.advance_unchecked(ret as usize);
         }
@@ -369,7 +389,6 @@ impl FileDesc {
         )))
     }
 
-    #[cfg_attr(target_os = "vxworks", allow(unused_unsafe))]
     pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
         #[cfg(not(any(
             all(target_os = "linux", not(target_env = "musl")),
diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs
index a89c3bbacfb..3b525406223 100644
--- a/library/std/src/sys/fs/unix.rs
+++ b/library/std/src/sys/fs/unix.rs
@@ -1463,6 +1463,10 @@ impl File {
         self.0.read_buf(cursor)
     }
 
+    pub fn read_buf_at(&self, cursor: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        self.0.read_buf_at(cursor, offset)
+    }
+
     pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result<usize> {
         self.0.read_vectored_at(bufs, offset)
     }
diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs
index bac278f7c8f..ccfe410627f 100644
--- a/library/std/src/sys/fs/windows.rs
+++ b/library/std/src/sys/fs/windows.rs
@@ -605,6 +605,10 @@ impl File {
         self.handle.read_buf(cursor)
     }
 
+    pub fn read_buf_at(&self, cursor: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        self.handle.read_buf_at(cursor, offset)
+    }
+
     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
         self.handle.write(buf)
     }
diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs
index 82a880faf5f..76c8aa939d3 100644
--- a/library/std/src/sys/pal/windows/handle.rs
+++ b/library/std/src/sys/pal/windows/handle.rs
@@ -136,6 +136,19 @@ impl Handle {
         }
     }
 
+    pub fn read_buf_at(&self, mut cursor: BorrowedCursor<'_>, offset: u64) -> io::Result<()> {
+        // SAFETY: `cursor.as_mut()` starts with `cursor.capacity()` writable bytes
+        let read = unsafe {
+            self.synchronous_read(cursor.as_mut().as_mut_ptr(), cursor.capacity(), Some(offset))
+        }?;
+
+        // SAFETY: `read` bytes were written to the initialized portion of the buffer
+        unsafe {
+            cursor.advance_unchecked(read);
+        }
+        Ok(())
+    }
+
     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
         let mut me = self;
 
diff --git a/library/std/tests/path.rs b/library/std/tests/path.rs
index e1576a0d423..fa76c50597b 100644
--- a/library/std/tests/path.rs
+++ b/library/std/tests/path.rs
@@ -1,4 +1,4 @@
-#![feature(clone_to_uninit, path_add_extension, maybe_uninit_slice, normalize_lexically)]
+#![feature(clone_to_uninit, maybe_uninit_slice, normalize_lexically)]
 
 use std::clone::CloneToUninit;
 use std::ffi::OsStr;
@@ -2526,3 +2526,9 @@ fn normalize_lexically() {
         check_err(r"\\?\UNC\server\share\a\..\..");
     }
 }
+
+#[test]
+/// See issue#146183
+fn compare_path_to_str() {
+    assert!(&PathBuf::from("x") == "x");
+}
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 1535d087033..fe832652d25 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -269,14 +269,14 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
 
 [[package]]
 name = "filetime"
-version = "0.2.25"
+version = "0.2.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
+checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed"
 dependencies = [
  "cfg-if",
  "libc",
  "libredox",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -322,11 +322,11 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
 [[package]]
 name = "home"
-version = "0.5.9"
+version = "0.5.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
+checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
 dependencies = [
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -364,12 +364,12 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
 
 [[package]]
 name = "junction"
-version = "1.2.0"
+version = "1.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72bbdfd737a243da3dfc1f99ee8d6e166480f17ab4ac84d7c34aacd73fc7bd16"
+checksum = "c52f6e1bf39a7894f618c9d378904a11dbd7e10fe3ec20d1173600e79b1408d8"
 dependencies = [
  "scopeguard",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -434,6 +434,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
+name = "normpath"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
 name = "ntapi"
 version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -497,12 +506,13 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
 
 [[package]]
 name = "opener"
-version = "0.5.2"
+version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005"
+checksum = "771b9704f8cd8b424ec747a320b30b47517a6966ba2c7da90047c16f4a962223"
 dependencies = [
  "bstr",
- "winapi",
+ "normpath",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -757,15 +767,15 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.19.0"
+version = "3.21.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600"
+checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e"
 dependencies = [
  "fastrand",
  "getrandom",
  "once_cell",
  "rustix",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -929,11 +939,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
 [[package]]
 name = "winapi-util"
-version = "0.1.9"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
+checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
 dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -1045,20 +1055,20 @@ dependencies = [
 
 [[package]]
 name = "windows-sys"
-version = "0.52.0"
+version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.52.6",
 ]
 
 [[package]]
 name = "windows-sys"
-version = "0.59.0"
+version = "0.60.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
 dependencies = [
- "windows-targets",
+ "windows-targets 0.53.2",
 ]
 
 [[package]]
@@ -1067,14 +1077,30 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
 dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_gnullvm",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
+ "windows_aarch64_gnullvm 0.52.6",
+ "windows_aarch64_msvc 0.52.6",
+ "windows_i686_gnu 0.52.6",
+ "windows_i686_gnullvm 0.52.6",
+ "windows_i686_msvc 0.52.6",
+ "windows_x86_64_gnu 0.52.6",
+ "windows_x86_64_gnullvm 0.52.6",
+ "windows_x86_64_msvc 0.52.6",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.53.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
+dependencies = [
+ "windows_aarch64_gnullvm 0.53.0",
+ "windows_aarch64_msvc 0.53.0",
+ "windows_i686_gnu 0.53.0",
+ "windows_i686_gnullvm 0.53.0",
+ "windows_i686_msvc 0.53.0",
+ "windows_x86_64_gnu 0.53.0",
+ "windows_x86_64_gnullvm 0.53.0",
+ "windows_x86_64_msvc 0.53.0",
 ]
 
 [[package]]
@@ -1084,48 +1110,96 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
 
 [[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
+
+[[package]]
 name = "windows_aarch64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
 
 [[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
+
+[[package]]
 name = "windows_i686_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
 
 [[package]]
+name = "windows_i686_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
+
+[[package]]
 name = "windows_i686_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
 
 [[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
+
+[[package]]
 name = "windows_i686_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
 
 [[package]]
+name = "windows_i686_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
+
+[[package]]
 name = "windows_x86_64_gnu"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
 
 [[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
+
+[[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
 
 [[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
+
+[[package]]
 name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
 [[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
+
+[[package]]
 name = "wit-bindgen-rt"
 version = "0.39.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index c7175584465..9a76a7dda2a 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -42,7 +42,7 @@ home = "0.5"
 ignore = "0.4"
 libc = "0.2"
 object = { version = "0.36.3", default-features = false, features = ["archive", "coff", "read_core", "std", "unaligned"] }
-opener = "0.5"
+opener = "0.8"
 semver = "1.0"
 serde = "1.0"
 # Directly use serde_derive rather than through the derive feature of serde to allow building both
@@ -67,7 +67,7 @@ tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter
 tempfile = { version = "3.15.0", optional = true }
 
 [target.'cfg(windows)'.dependencies.junction]
-version = "1.0.0"
+version = "1.3.0"
 
 [target.'cfg(windows)'.dependencies.windows]
 version = "0.61"
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index a604e7c0585..49d12b64da5 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -389,7 +389,7 @@ impl Step for Rustc {
 
 /// Represents a compiler that can check something.
 ///
-/// If the compiler was created for `Mode::ToolRustc` or `Mode::Codegen`, it will also contain
+/// If the compiler was created for `Mode::ToolRustcPrivate` or `Mode::Codegen`, it will also contain
 /// .rmeta artifacts from rustc that was already checked using `build_compiler`.
 ///
 /// All steps that use this struct in a "general way" (i.e. they don't know exactly what kind of
@@ -469,7 +469,7 @@ pub fn prepare_compiler_for_check(
                 build_compiler
             }
         }
-        Mode::ToolRustc | Mode::Codegen => {
+        Mode::ToolRustcPrivate | Mode::Codegen => {
             // Check Rustc to produce the required rmeta artifacts for rustc_private, and then
             // return the build compiler that was used to check rustc.
             // We do not need to check examples/tests/etc. of Rustc for rustc_private, so we pass
@@ -767,19 +767,22 @@ fn run_tool_check_step(
 tool_check_step!(Rustdoc {
     path: "src/tools/rustdoc",
     alt_path: "src/librustdoc",
-    mode: |_builder| Mode::ToolRustc
+    mode: |_builder| Mode::ToolRustcPrivate
 });
 // Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
 // of a submodule. Since the SourceType only drives the deny-warnings
 // behavior, treat it as in-tree so that any new warnings in clippy will be
 // rejected.
-tool_check_step!(Clippy { path: "src/tools/clippy", mode: |_builder| Mode::ToolRustc });
-tool_check_step!(Miri { path: "src/tools/miri", mode: |_builder| Mode::ToolRustc });
-tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: |_builder| Mode::ToolRustc });
-tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: |_builder| Mode::ToolRustc });
+tool_check_step!(Clippy { path: "src/tools/clippy", mode: |_builder| Mode::ToolRustcPrivate });
+tool_check_step!(Miri { path: "src/tools/miri", mode: |_builder| Mode::ToolRustcPrivate });
+tool_check_step!(CargoMiri {
+    path: "src/tools/miri/cargo-miri",
+    mode: |_builder| Mode::ToolRustcPrivate
+});
+tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: |_builder| Mode::ToolRustcPrivate });
 tool_check_step!(RustAnalyzer {
     path: "src/tools/rust-analyzer",
-    mode: |_builder| Mode::ToolRustc,
+    mode: |_builder| Mode::ToolRustcPrivate,
     allow_features: tool::RustAnalyzer::ALLOW_FEATURES,
     enable_features: ["in-rust-tree"],
 });
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index 05f8b240291..2083c675e1f 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -366,8 +366,13 @@ impl Step for CodegenGcc {
         );
         self.build_compiler.configure_cargo(&mut cargo);
 
-        let _guard =
-            builder.msg(Kind::Clippy, "rustc_codegen_gcc", Mode::ToolRustc, build_compiler, target);
+        let _guard = builder.msg(
+            Kind::Clippy,
+            "rustc_codegen_gcc",
+            Mode::ToolRustcPrivate,
+            build_compiler,
+            target,
+        );
 
         let stamp = BuildStamp::new(&builder.cargo_out(build_compiler, Mode::Codegen, target))
             .with_prefix("rustc_codegen_gcc-check");
@@ -478,8 +483,8 @@ lint_any!(
     Bootstrap, "src/bootstrap", "bootstrap", Mode::ToolTarget;
     BuildHelper, "src/build_helper", "build_helper", Mode::ToolTarget;
     BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolTarget;
-    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", Mode::ToolRustc;
-    Clippy, "src/tools/clippy", "clippy", Mode::ToolRustc;
+    CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", Mode::ToolRustcPrivate;
+    Clippy, "src/tools/clippy", "clippy", Mode::ToolRustcPrivate;
     CollectLicenseMetadata, "src/tools/collect-license-metadata", "collect-license-metadata", Mode::ToolTarget;
     Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolTarget;
     CoverageDump, "src/tools/coverage-dump", "coverage-dump", Mode::ToolTarget;
@@ -487,14 +492,14 @@ lint_any!(
     Jsondoclint, "src/tools/jsondoclint", "jsondoclint", Mode::ToolTarget;
     LintDocs, "src/tools/lint-docs", "lint-docs", Mode::ToolTarget;
     LlvmBitcodeLinker, "src/tools/llvm-bitcode-linker", "llvm-bitcode-linker", Mode::ToolTarget;
-    Miri, "src/tools/miri", "miri", Mode::ToolRustc;
+    Miri, "src/tools/miri", "miri", Mode::ToolRustcPrivate;
     MiroptTestTools, "src/tools/miropt-test-tools", "miropt-test-tools", Mode::ToolTarget;
     OptDist, "src/tools/opt-dist", "opt-dist", Mode::ToolTarget;
     RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolTarget;
     RemoteTestServer, "src/tools/remote-test-server", "remote-test-server", Mode::ToolTarget;
-    RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer", Mode::ToolRustc;
-    Rustdoc, "src/librustdoc", "clippy", Mode::ToolRustc;
-    Rustfmt, "src/tools/rustfmt", "rustfmt", Mode::ToolRustc;
+    RustAnalyzer, "src/tools/rust-analyzer", "rust-analyzer", Mode::ToolRustcPrivate;
+    Rustdoc, "src/librustdoc", "clippy", Mode::ToolRustcPrivate;
+    Rustfmt, "src/tools/rustfmt", "rustfmt", Mode::ToolRustcPrivate;
     RustInstaller, "src/tools/rust-installer", "rust-installer", Mode::ToolTarget;
     Tidy, "src/tools/tidy", "tidy", Mode::ToolTarget;
     TestFloatParse, "src/tools/test-float-parse", "test-float-parse", Mode::ToolStd;
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index f113dd7683d..820dda5a652 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -823,6 +823,18 @@ pub struct RustcDev {
     target: TargetSelection,
 }
 
+impl RustcDev {
+    pub fn new(builder: &Builder<'_>, target: TargetSelection) -> Self {
+        Self {
+            // We currently always ship a stage 2 rustc-dev component, so we build it with the
+            // stage 1 compiler. This might change in the future.
+            // The precise stage used here is important, so we hard-code it.
+            build_compiler: builder.compiler(1, builder.config.host_target),
+            target,
+        }
+    }
+}
+
 impl Step for RustcDev {
     type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
@@ -833,13 +845,7 @@ impl Step for RustcDev {
     }
 
     fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(RustcDev {
-            // We currently always ship a stage 2 rustc-dev component, so we build it with the
-            // stage 1 compiler. This might change in the future.
-            // The precise stage used here is important, so we hard-code it.
-            build_compiler: run.builder.compiler(1, run.builder.config.host_target),
-            target: run.target,
-        });
+        run.builder.ensure(RustcDev::new(run.builder, run.target));
     }
 
     fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> {
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 0789eefa894..eb198a0051a 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -995,7 +995,7 @@ macro_rules! tool_doc {
                     // Build rustc docs so that we generate relative links.
                     run.builder.ensure(Rustc::from_build_compiler(run.builder, compilers.build_compiler(), target));
 
-                    (compilers.build_compiler(), Mode::ToolRustc)
+                    (compilers.build_compiler(), Mode::ToolRustcPrivate)
                 } else {
                     // bootstrap/host tools have to be documented with the stage 0 compiler
                     (prepare_doc_compiler(run.builder, run.builder.host_target, 1), Mode::ToolBootstrap)
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index d47c1495838..83ed7430c39 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -205,6 +205,7 @@ pub(crate) fn is_ci_llvm_available_for_target(
         // tier 1
         ("aarch64-unknown-linux-gnu", false),
         ("aarch64-apple-darwin", false),
+        ("aarch64-pc-windows-msvc", false),
         ("i686-pc-windows-gnu", false),
         ("i686-pc-windows-msvc", false),
         ("i686-unknown-linux-gnu", false),
@@ -213,7 +214,6 @@ pub(crate) fn is_ci_llvm_available_for_target(
         ("x86_64-pc-windows-gnu", true),
         ("x86_64-pc-windows-msvc", true),
         // tier 2 with host tools
-        ("aarch64-pc-windows-msvc", false),
         ("aarch64-unknown-linux-musl", false),
         ("arm-unknown-linux-gnueabi", false),
         ("arm-unknown-linux-gnueabihf", false),
diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs
index d9de6b7ef96..9f7248b80f7 100644
--- a/src/bootstrap/src/core/build_steps/run.rs
+++ b/src/bootstrap/src/core/build_steps/run.rs
@@ -161,7 +161,7 @@ impl Step for Miri {
         let mut miri = tool::prepare_tool_cargo(
             builder,
             compilers.build_compiler(),
-            Mode::ToolRustc,
+            Mode::ToolRustcPrivate,
             host,
             Kind::Run,
             "src/tools/miri",
@@ -487,7 +487,7 @@ impl Step for Rustfmt {
         let mut rustfmt = tool::prepare_tool_cargo(
             builder,
             rustfmt_build.build_compiler,
-            Mode::ToolRustc,
+            Mode::ToolRustcPrivate,
             host,
             Kind::Run,
             "src/tools/rustfmt",
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index ee2cbe9385e..cb81d738666 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -455,7 +455,7 @@ impl Step for RustAnalyzer {
         let mut cargo = tool::prepare_tool_cargo(
             builder,
             self.compilers.build_compiler(),
-            Mode::ToolRustc,
+            Mode::ToolRustcPrivate,
             host,
             Kind::Test,
             crate_path,
@@ -518,7 +518,7 @@ impl Step for Rustfmt {
         let mut cargo = tool::prepare_tool_cargo(
             builder,
             build_compiler,
-            Mode::ToolRustc,
+            Mode::ToolRustcPrivate,
             target,
             Kind::Test,
             "src/tools/rustfmt",
@@ -571,7 +571,8 @@ impl Miri {
         cargo.env("MIRI_SYSROOT", &miri_sysroot);
 
         let mut cargo = BootstrapCommand::from(cargo);
-        let _guard = builder.msg(Kind::Build, "miri sysroot", Mode::ToolRustc, compiler, target);
+        let _guard =
+            builder.msg(Kind::Build, "miri sysroot", Mode::ToolRustcPrivate, compiler, target);
         cargo.run(builder);
 
         // # Determine where Miri put its sysroot.
@@ -648,7 +649,7 @@ impl Step for Miri {
         let mut cargo = tool::prepare_tool_cargo(
             builder,
             miri.build_compiler,
-            Mode::ToolRustc,
+            Mode::ToolRustcPrivate,
             host,
             Kind::Test,
             "src/tools/miri",
@@ -861,7 +862,7 @@ impl Step for Clippy {
         let mut cargo = tool::prepare_tool_cargo(
             builder,
             build_compiler,
-            Mode::ToolRustc,
+            Mode::ToolRustcPrivate,
             target,
             Kind::Test,
             "src/tools/clippy",
@@ -872,7 +873,7 @@ impl Step for Clippy {
         cargo.env("RUSTC_TEST_SUITE", builder.rustc(build_compiler));
         cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(build_compiler));
         let host_libs =
-            builder.stage_out(build_compiler, Mode::ToolRustc).join(builder.cargo_dir());
+            builder.stage_out(build_compiler, Mode::ToolRustcPrivate).join(builder.cargo_dir());
         cargo.env("HOST_LIBS", host_libs);
 
         // Build the standard library that the tests can use.
@@ -2411,7 +2412,7 @@ impl BookTest {
         let libs = if !self.dependencies.is_empty() {
             let mut lib_paths = vec![];
             for dep in self.dependencies {
-                let mode = Mode::ToolRustc;
+                let mode = Mode::ToolRustcPrivate;
                 let target = builder.config.host_target;
                 let cargo = tool::prepare_tool_cargo(
                     builder,
@@ -2996,7 +2997,7 @@ impl Step for CrateRustdoc {
         let mut cargo = tool::prepare_tool_cargo(
             builder,
             compiler,
-            Mode::ToolRustc,
+            Mode::ToolRustcPrivate,
             target,
             builder.kind,
             "src/tools/rustdoc",
@@ -3182,6 +3183,7 @@ impl Step for Distcheck {
     ///   check steps from those sources.
     /// - Check that selected dist components (`rust-src` only at the moment) at least have expected
     ///   directory shape and crate manifests that cargo can generate a lockfile from.
+    /// - Check that we can run `cargo metadata` on the workspace in the `rustc-dev` component
     ///
     /// FIXME(#136822): dist components are under-tested.
     fn run(self, builder: &Builder<'_>) {
@@ -3189,61 +3191,91 @@ impl Step for Distcheck {
         // local source code, built artifacts or configuration by accident
         let root_dir = std::env::temp_dir().join("distcheck");
 
-        // Check that we can build some basic things from the plain source tarball
-        builder.info("Distcheck plain source tarball");
-        let plain_src_tarball = builder.ensure(dist::PlainSourceTarball);
-        let plain_src_dir = root_dir.join("distcheck-plain-src");
-        builder.clear_dir(&plain_src_dir);
-
-        let configure_args: Vec<String> = std::env::var("DISTCHECK_CONFIGURE_ARGS")
-            .map(|args| args.split(" ").map(|s| s.to_string()).collect::<Vec<String>>())
-            .unwrap_or_default();
-
-        command("tar")
-            .arg("-xf")
-            .arg(plain_src_tarball.tarball())
-            .arg("--strip-components=1")
-            .current_dir(&plain_src_dir)
-            .run(builder);
-        command("./configure")
-            .arg("--set")
-            .arg("rust.omit-git-hash=false")
-            .args(&configure_args)
-            .arg("--enable-vendor")
-            .current_dir(&plain_src_dir)
-            .run(builder);
-        command(helpers::make(&builder.config.host_target.triple))
-            .arg("check")
-            // Do not run the build as if we were in CI, otherwise git would be assumed to be
-            // present, but we build from a tarball here
-            .env("GITHUB_ACTIONS", "0")
-            .current_dir(&plain_src_dir)
-            .run(builder);
-
-        // Now make sure that rust-src has all of libstd's dependencies
-        builder.info("Distcheck rust-src");
-        let src_tarball = builder.ensure(dist::Src);
-        let src_dir = root_dir.join("distcheck-src");
-        builder.clear_dir(&src_dir);
-
-        command("tar")
-            .arg("-xf")
-            .arg(src_tarball.tarball())
-            .arg("--strip-components=1")
-            .current_dir(&src_dir)
-            .run(builder);
-
-        let toml = src_dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml");
-        command(&builder.initial_cargo)
-            // Will read the libstd Cargo.toml
-            // which uses the unstable `public-dependency` feature.
-            .env("RUSTC_BOOTSTRAP", "1")
-            .arg("generate-lockfile")
-            .arg("--manifest-path")
-            .arg(&toml)
-            .current_dir(&src_dir)
-            .run(builder);
-    }
+        distcheck_plain_source_tarball(builder, &root_dir.join("distcheck-rustc-src"));
+        distcheck_rust_src(builder, &root_dir.join("distcheck-rust-src"));
+        distcheck_rustc_dev(builder, &root_dir.join("distcheck-rustc-dev"));
+    }
+}
+
+/// Check that we can build some basic things from the plain source tarball
+fn distcheck_plain_source_tarball(builder: &Builder<'_>, plain_src_dir: &Path) {
+    builder.info("Distcheck plain source tarball");
+    let plain_src_tarball = builder.ensure(dist::PlainSourceTarball);
+    builder.clear_dir(plain_src_dir);
+
+    let configure_args: Vec<String> = std::env::var("DISTCHECK_CONFIGURE_ARGS")
+        .map(|args| args.split(" ").map(|s| s.to_string()).collect::<Vec<String>>())
+        .unwrap_or_default();
+
+    command("tar")
+        .arg("-xf")
+        .arg(plain_src_tarball.tarball())
+        .arg("--strip-components=1")
+        .current_dir(plain_src_dir)
+        .run(builder);
+    command("./configure")
+        .arg("--set")
+        .arg("rust.omit-git-hash=false")
+        .args(&configure_args)
+        .arg("--enable-vendor")
+        .current_dir(plain_src_dir)
+        .run(builder);
+    command(helpers::make(&builder.config.host_target.triple))
+        .arg("check")
+        // Do not run the build as if we were in CI, otherwise git would be assumed to be
+        // present, but we build from a tarball here
+        .env("GITHUB_ACTIONS", "0")
+        .current_dir(plain_src_dir)
+        .run(builder);
+}
+
+/// Check that rust-src has all of libstd's dependencies
+fn distcheck_rust_src(builder: &Builder<'_>, src_dir: &Path) {
+    builder.info("Distcheck rust-src");
+    let src_tarball = builder.ensure(dist::Src);
+    builder.clear_dir(src_dir);
+
+    command("tar")
+        .arg("-xf")
+        .arg(src_tarball.tarball())
+        .arg("--strip-components=1")
+        .current_dir(src_dir)
+        .run(builder);
+
+    let toml = src_dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml");
+    command(&builder.initial_cargo)
+        // Will read the libstd Cargo.toml
+        // which uses the unstable `public-dependency` feature.
+        .env("RUSTC_BOOTSTRAP", "1")
+        .arg("generate-lockfile")
+        .arg("--manifest-path")
+        .arg(&toml)
+        .current_dir(src_dir)
+        .run(builder);
+}
+
+/// Check that rustc-dev's compiler crate source code can be loaded with `cargo metadata`
+fn distcheck_rustc_dev(builder: &Builder<'_>, dir: &Path) {
+    builder.info("Distcheck rustc-dev");
+    let tarball = builder.ensure(dist::RustcDev::new(builder, builder.host_target)).unwrap();
+    builder.clear_dir(dir);
+
+    command("tar")
+        .arg("-xf")
+        .arg(tarball.tarball())
+        .arg("--strip-components=1")
+        .current_dir(dir)
+        .run(builder);
+
+    command(&builder.initial_cargo)
+        .arg("metadata")
+        .arg("--manifest-path")
+        .arg("rustc-dev/lib/rustlib/rustc-src/rust/compiler/rustc/Cargo.toml")
+        .env("RUSTC_BOOTSTRAP", "1")
+        // We might not have a globally available `rustc` binary on CI
+        .env("RUSTC", &builder.initial_rustc)
+        .current_dir(dir)
+        .run(builder);
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3294,9 +3326,7 @@ impl Step for Bootstrap {
             .env("INSTA_WORKSPACE_ROOT", &builder.src)
             .env("RUSTC_BOOTSTRAP", "1");
 
-        // bootstrap tests are racy on directory creation so just run them one at a time.
-        // Since there's not many this shouldn't be a problem.
-        run_cargo_test(cargo, &["--test-threads=1"], &[], None, host, builder);
+        run_cargo_test(cargo, &[], &[], None, host, builder);
     }
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 65c4c499086..c5308034fe3 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -82,7 +82,7 @@ impl Step for ToolBuild {
         let path = self.path;
 
         match self.mode {
-            Mode::ToolRustc => {
+            Mode::ToolRustcPrivate => {
                 // FIXME: remove this, it's only needed for download-rustc...
                 if !self.build_compiler.is_forced_compiler() && builder.download_rustc() {
                     builder.std(self.build_compiler, self.build_compiler.host);
@@ -123,7 +123,7 @@ impl Step for ToolBuild {
 
         // Rustc tools (miri, clippy, cargo, rustfmt, rust-analyzer)
         // could use the additional optimizations.
-        if self.mode == Mode::ToolRustc && is_lto_stage(&self.build_compiler) {
+        if self.mode == Mode::ToolRustcPrivate && is_lto_stage(&self.build_compiler) {
             let lto = match builder.config.rust_lto {
                 RustcLto::Off => Some("off"),
                 RustcLto::Thin => Some("thin"),
@@ -607,7 +607,7 @@ impl Step for ErrorIndex {
             build_compiler: self.compilers.build_compiler,
             target: self.compilers.target(),
             tool: "error_index_generator",
-            mode: Mode::ToolRustc,
+            mode: Mode::ToolRustcPrivate,
             path: "src/tools/error_index_generator",
             source_type: SourceType::InTree,
             extra_features: Vec::new(),
@@ -671,7 +671,7 @@ impl Step for RemoteTestServer {
 /// Represents `Rustdoc` that either comes from the external stage0 sysroot or that is built
 /// locally.
 /// Rustdoc is special, because it both essentially corresponds to a `Compiler` (that can be
-/// externally provided), but also to a `ToolRustc` tool.
+/// externally provided), but also to a `ToolRustcPrivate` tool.
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Rustdoc {
     /// If the stage of `target_compiler` is `0`, then rustdoc is externally provided.
@@ -759,7 +759,7 @@ impl Step for Rustdoc {
                 // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
                 // rustdoc a different name.
                 tool: "rustdoc_tool_binary",
-                mode: Mode::ToolRustc,
+                mode: Mode::ToolRustcPrivate,
                 path: "src/tools/rustdoc",
                 source_type: SourceType::InTree,
                 extra_features,
@@ -1048,7 +1048,7 @@ impl Step for RustAnalyzer {
             build_compiler,
             target,
             tool: "rust-analyzer",
-            mode: Mode::ToolRustc,
+            mode: Mode::ToolRustcPrivate,
             path: "src/tools/rust-analyzer",
             extra_features: vec!["in-rust-tree".to_owned()],
             source_type: SourceType::InTree,
@@ -1105,7 +1105,7 @@ impl Step for RustAnalyzerProcMacroSrv {
             build_compiler: self.compilers.build_compiler,
             target: self.compilers.target(),
             tool: "rust-analyzer-proc-macro-srv",
-            mode: Mode::ToolRustc,
+            mode: Mode::ToolRustcPrivate,
             path: "src/tools/rust-analyzer/crates/proc-macro-srv-cli",
             extra_features: vec!["in-rust-tree".to_owned()],
             source_type: SourceType::InTree,
@@ -1352,7 +1352,7 @@ impl RustcPrivateCompilers {
     }
 }
 
-/// Creates a step that builds an extended `Mode::ToolRustc` tool
+/// Creates a step that builds an extended `Mode::ToolRustcPrivate` tool
 /// and installs it into the sysroot of a corresponding compiler.
 macro_rules! tool_rustc_extended {
     (
@@ -1466,7 +1466,7 @@ fn build_extended_rustc_tool(
         build_compiler,
         target,
         tool: tool_name,
-        mode: Mode::ToolRustc,
+        mode: Mode::ToolRustcPrivate,
         path,
         extra_features,
         source_type: SourceType::InTree,
diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs
index cdf6fe573e5..cca0c803e63 100644
--- a/src/bootstrap/src/core/builder/cargo.rs
+++ b/src/bootstrap/src/core/builder/cargo.rs
@@ -533,7 +533,7 @@ impl Builder<'_> {
         if cmd_kind == Kind::Doc {
             let my_out = match mode {
                 // This is the intended out directory for compiler documentation.
-                Mode::Rustc | Mode::ToolRustc | Mode::ToolBootstrap => {
+                Mode::Rustc | Mode::ToolRustcPrivate | Mode::ToolBootstrap => {
                     self.compiler_doc_out(target)
                 }
                 Mode::Std => {
@@ -583,7 +583,7 @@ impl Builder<'_> {
 
         // We synthetically interpret a stage0 compiler used to build tools as a
         // "raw" compiler in that it's the exact snapshot we download. For things like
-        // ToolRustc, we would have to use the artificial stage0-sysroot compiler instead.
+        // ToolRustcPrivate, we would have to use the artificial stage0-sysroot compiler instead.
         let use_snapshot =
             mode == Mode::ToolBootstrap || (mode == Mode::ToolTarget && build_compiler_stage == 0);
         assert!(!use_snapshot || build_compiler_stage == 0 || self.local_rebuild);
@@ -643,7 +643,8 @@ impl Builder<'_> {
         // sysroot. Passing this cfg enables raw-dylib support instead, which makes the native
         // library unnecessary. This can be removed when windows-rs enables raw-dylib
         // unconditionally.
-        if let Mode::Rustc | Mode::ToolRustc | Mode::ToolBootstrap | Mode::ToolTarget = mode {
+        if let Mode::Rustc | Mode::ToolRustcPrivate | Mode::ToolBootstrap | Mode::ToolTarget = mode
+        {
             rustflags.arg("--cfg=windows_raw_dylib");
         }
 
@@ -657,7 +658,7 @@ impl Builder<'_> {
         // - rust-analyzer, due to the rowan crate
         // so we exclude an entire category of steps here due to lack of fine-grained control over
         // rustflags.
-        if self.config.rust_randomize_layout && mode != Mode::ToolRustc {
+        if self.config.rust_randomize_layout && mode != Mode::ToolRustcPrivate {
             rustflags.arg("-Zrandomize-layout");
         }
 
@@ -717,7 +718,7 @@ impl Builder<'_> {
 
         match mode {
             Mode::Std | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTarget => {}
-            Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
+            Mode::Rustc | Mode::Codegen | Mode::ToolRustcPrivate => {
                 // Build proc macros both for the host and the target unless proc-macros are not
                 // supported by the target.
                 if target != compiler.host && cmd_kind != Kind::Check {
@@ -778,7 +779,7 @@ impl Builder<'_> {
                 "binary-dep-depinfo,proc_macro_span,proc_macro_span_shrink,proc_macro_diagnostic"
                     .to_string()
             }
-            Mode::Std | Mode::Rustc | Mode::Codegen | Mode::ToolRustc => String::new(),
+            Mode::Std | Mode::Rustc | Mode::Codegen | Mode::ToolRustcPrivate => String::new(),
         };
 
         cargo.arg("-j").arg(self.jobs().to_string());
@@ -825,7 +826,7 @@ impl Builder<'_> {
             // rustc step and one that we just built. This isn't always a
             // problem, somehow -- not really clear why -- but we know that this
             // fixes things.
-            Mode::ToolRustc => metadata.push_str("tool-rustc"),
+            Mode::ToolRustcPrivate => metadata.push_str("tool-rustc"),
             // Same for codegen backends.
             Mode::Codegen => metadata.push_str("codegen"),
             _ => {}
@@ -877,8 +878,11 @@ impl Builder<'_> {
             .env("RUSTC_LIBDIR", libdir)
             .env("RUSTDOC", self.bootstrap_out.join("rustdoc"))
             .env("RUSTDOC_REAL", rustdoc_path)
-            .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir())
-            .env("RUSTC_BREAK_ON_ICE", "1");
+            .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir());
+
+        if self.config.rust_break_on_ice {
+            cargo.env("RUSTC_BREAK_ON_ICE", "1");
+        }
 
         // Set RUSTC_WRAPPER to the bootstrap shim, which switches between beta and in-tree
         // sysroot depending on whether we're building build scripts.
@@ -917,7 +921,7 @@ impl Builder<'_> {
         let debuginfo_level = match mode {
             Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
             Mode::Std => self.config.rust_debuginfo_level_std,
-            Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc | Mode::ToolTarget => {
+            Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustcPrivate | Mode::ToolTarget => {
                 self.config.rust_debuginfo_level_tools
             }
         };
@@ -930,7 +934,7 @@ impl Builder<'_> {
             match mode {
                 Mode::Std => self.config.std_debug_assertions,
                 Mode::Rustc | Mode::Codegen => self.config.rustc_debug_assertions,
-                Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc | Mode::ToolTarget => {
+                Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustcPrivate | Mode::ToolTarget => {
                     self.config.tools_debug_assertions
                 }
             }
@@ -1005,7 +1009,7 @@ impl Builder<'_> {
             }
             Mode::Std
             | Mode::ToolBootstrap
-            | Mode::ToolRustc
+            | Mode::ToolRustcPrivate
             | Mode::ToolStd
             | Mode::ToolTarget => {
                 if let Some(ref map_to) =
@@ -1078,7 +1082,7 @@ impl Builder<'_> {
         // requirement, but the `-L` library path is not propagated across
         // separate Cargo projects. We can add LLVM's library path to the
         // rustc args as a workaround.
-        if (mode == Mode::ToolRustc || mode == Mode::Codegen)
+        if (mode == Mode::ToolRustcPrivate || mode == Mode::Codegen)
             && let Some(llvm_config) = self.llvm_config(target)
         {
             let llvm_libdir =
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index ef01f14f5e9..9e8c13eb4de 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -10,8 +10,8 @@ use crate::core::build_steps::doc::DocumentationFormat;
 use crate::core::config::Config;
 use crate::utils::cache::ExecutedStep;
 use crate::utils::helpers::get_host_target;
-use crate::utils::tests::ConfigBuilder;
 use crate::utils::tests::git::{GitCtx, git_test};
+use crate::utils::tests::{ConfigBuilder, TestCtx};
 
 static TEST_TRIPLE_1: &str = "i686-unknown-haiku";
 static TEST_TRIPLE_2: &str = "i686-unknown-hurd-gnu";
@@ -22,38 +22,13 @@ fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
 }
 
 fn configure_with_args(cmd: &[&str], host: &[&str], target: &[&str]) -> Config {
-    let cmd = cmd.iter().copied().map(String::from).collect::<Vec<_>>();
-    let mut config = Config::parse(Flags::parse(&cmd));
-    // don't save toolstates
-    config.save_toolstates = None;
-    config.set_dry_run(DryRun::SelfCheck);
-
-    // Ignore most submodules, since we don't need them for a dry run, and the
-    // tests run much faster without them.
-    //
-    // The src/doc/book submodule is needed because TheBook step tries to
-    // access files even during a dry-run (may want to consider just skipping
-    // that in a dry run).
-    let submodule_build = Build::new(Config {
-        // don't include LLVM, so CI doesn't require ninja/cmake to be installed
-        rust_codegen_backends: vec![],
-        ..Config::parse(Flags::parse(&["check".to_owned()]))
-    });
-    submodule_build.require_submodule("src/doc/book", None);
-    config.submodules = Some(false);
-
-    config.ninja_in_file = false;
-    // try to avoid spurious failures in dist where we create/delete each others file
-    // HACK: rather than pull in `tempdir`, use the one that cargo has conveniently created for us
-    let dir = Path::new(env!("OUT_DIR"))
-        .join("tmp-rustbuild-tests")
-        .join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
-    t!(fs::create_dir_all(&dir));
-    config.out = dir;
-    config.host_target = TargetSelection::from_user(TEST_TRIPLE_1);
-    config.hosts = host.iter().map(|s| TargetSelection::from_user(s)).collect();
-    config.targets = target.iter().map(|s| TargetSelection::from_user(s)).collect();
-    config
+    TestCtx::new()
+        .config(cmd[0])
+        .args(&cmd[1..])
+        .hosts(host)
+        .targets(target)
+        .args(&["--build", TEST_TRIPLE_1])
+        .create_config()
 }
 
 fn first<A, B>(v: Vec<(A, B)>) -> Vec<A> {
@@ -547,8 +522,8 @@ mod snapshot {
 
     use crate::core::build_steps::{compile, dist, doc, test, tool};
     use crate::core::builder::tests::{
-        RenderConfig, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, configure_with_args,
-        first, host_target, render_steps, run_build,
+        RenderConfig, TEST_TRIPLE_1, TEST_TRIPLE_2, TEST_TRIPLE_3, configure, first, host_target,
+        render_steps, run_build,
     };
     use crate::core::builder::{Builder, Kind, StepDescription, StepMetadata};
     use crate::core::config::TargetSelection;
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index d12cc962187..678a9b63952 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -221,6 +221,7 @@ pub struct Config {
     pub rust_lto: RustcLto,
     pub rust_validate_mir_opts: Option<u32>,
     pub rust_std_features: BTreeSet<String>,
+    pub rust_break_on_ice: bool,
     pub llvm_profile_use: Option<String>,
     pub llvm_profile_generate: bool,
     pub llvm_libunwind_default: Option<LlvmLibunwind>,
@@ -550,6 +551,7 @@ impl Config {
             strip: rust_strip,
             lld_mode: rust_lld_mode,
             std_features: rust_std_features,
+            break_on_ice: rust_break_on_ice,
         } = toml.rust.unwrap_or_default();
 
         let Llvm {
@@ -1269,6 +1271,7 @@ impl Config {
             reproducible_artifacts: flags_reproducible_artifact,
             reuse: build_reuse.map(PathBuf::from),
             rust_analyzer_info,
+            rust_break_on_ice: rust_break_on_ice.unwrap_or(true),
             rust_codegen_backends: rust_codegen_backends
                 .map(|backends| parse_codegen_backends(backends, "rust"))
                 .unwrap_or(vec![CodegenBackendKind::Llvm]),
diff --git a/src/bootstrap/src/core/config/toml/rust.rs b/src/bootstrap/src/core/config/toml/rust.rs
index c54df456d52..4832a1d37b7 100644
--- a/src/bootstrap/src/core/config/toml/rust.rs
+++ b/src/bootstrap/src/core/config/toml/rust.rs
@@ -65,6 +65,7 @@ define_config! {
         lto: Option<String> = "lto",
         validate_mir_opts: Option<u32> = "validate-mir-opts",
         std_features: Option<BTreeSet<String>> = "std-features",
+        break_on_ice: Option<bool> = "break-on-ice",
     }
 }
 
@@ -355,6 +356,7 @@ pub fn check_incompatible_options_for_ci_rustc(
         download_rustc: _,
         validate_mir_opts: _,
         frame_pointers: _,
+        break_on_ice: _,
     } = ci_rust_config;
 
     // There are two kinds of checks for CI rustc incompatible options:
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 59c0f9faaca..a2aeed20948 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -85,12 +85,12 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
 const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (Some(Mode::Rustc), "bootstrap", None),
     (Some(Mode::Codegen), "bootstrap", None),
-    (Some(Mode::ToolRustc), "bootstrap", None),
+    (Some(Mode::ToolRustcPrivate), "bootstrap", None),
     (Some(Mode::ToolStd), "bootstrap", None),
     (Some(Mode::Rustc), "llvm_enzyme", None),
     (Some(Mode::Codegen), "llvm_enzyme", None),
-    (Some(Mode::ToolRustc), "llvm_enzyme", None),
-    (Some(Mode::ToolRustc), "rust_analyzer", None),
+    (Some(Mode::ToolRustcPrivate), "llvm_enzyme", None),
+    (Some(Mode::ToolRustcPrivate), "rust_analyzer", None),
     (Some(Mode::ToolStd), "rust_analyzer", None),
     // Any library specific cfgs like `target_os`, `target_arch` should be put in
     // priority the `[lints.rust.unexpected_cfgs.check-cfg]` table
@@ -334,17 +334,18 @@ pub enum Mode {
     /// compiletest which needs libtest.
     ToolStd,
 
-    /// Build a tool which uses the locally built rustc and the target std,
+    /// Build a tool which uses the `rustc_private` mechanism, and thus
+    /// the locally built rustc rlib artifacts,
     /// placing the output in the "stageN-tools" directory. This is used for
-    /// anything that needs a fully functional rustc, such as rustdoc, clippy,
-    /// cargo, rustfmt, miri, etc.
-    ToolRustc,
+    /// everything that links to rustc as a library, such as rustdoc, clippy,
+    /// rustfmt, miri, etc.
+    ToolRustcPrivate,
 }
 
 impl Mode {
     pub fn is_tool(&self) -> bool {
         match self {
-            Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd | Mode::ToolTarget => true,
+            Mode::ToolBootstrap | Mode::ToolRustcPrivate | Mode::ToolStd | Mode::ToolTarget => true,
             Mode::Std | Mode::Codegen | Mode::Rustc => false,
         }
     }
@@ -353,7 +354,7 @@ impl Mode {
         match self {
             Mode::Std | Mode::Codegen => true,
             Mode::ToolBootstrap
-            | Mode::ToolRustc
+            | Mode::ToolRustcPrivate
             | Mode::ToolStd
             | Mode::ToolTarget
             | Mode::Rustc => false,
@@ -924,7 +925,7 @@ impl Build {
             Mode::Rustc => (Some(build_compiler.stage + 1), "rustc"),
             Mode::Codegen => (Some(build_compiler.stage + 1), "codegen"),
             Mode::ToolBootstrap => bootstrap_tool(),
-            Mode::ToolStd | Mode::ToolRustc => (Some(build_compiler.stage + 1), "tools"),
+            Mode::ToolStd | Mode::ToolRustcPrivate => (Some(build_compiler.stage + 1), "tools"),
             Mode::ToolTarget => {
                 // If we're not cross-compiling (the common case), share the target directory with
                 // bootstrap tools to reuse the build cache.
@@ -1145,7 +1146,7 @@ impl Build {
                 | Mode::ToolBootstrap
                 | Mode::ToolTarget
                 | Mode::ToolStd
-                | Mode::ToolRustc,
+                | Mode::ToolRustcPrivate,
             )
             | None => target_and_stage.stage + 1,
         };
diff --git a/src/bootstrap/src/utils/cc_detect/tests.rs b/src/bootstrap/src/utils/cc_detect/tests.rs
index bed03c18aaa..a6233e6b61c 100644
--- a/src/bootstrap/src/utils/cc_detect/tests.rs
+++ b/src/bootstrap/src/utils/cc_detect/tests.rs
@@ -3,7 +3,8 @@ use std::{env, iter};
 
 use super::*;
 use crate::core::config::{Target, TargetSelection};
-use crate::{Build, Config, Flags};
+use crate::utils::tests::TestCtx;
+use crate::{Build, Config, Flags, t};
 
 #[test]
 fn test_ndk_compiler_c() {
@@ -68,7 +69,8 @@ fn test_language_clang() {
 
 #[test]
 fn test_new_cc_build() {
-    let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
+    let config = TestCtx::new().config("build").create_config();
+    let build = Build::new(config);
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let cfg = new_cc_build(&build, target.clone());
     let compiler = cfg.get_compiler();
@@ -77,7 +79,8 @@ fn test_new_cc_build() {
 
 #[test]
 fn test_default_compiler_wasi() {
-    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
+    let config = TestCtx::new().config("build").create_config();
+    let mut build = Build::new(config);
     let target = TargetSelection::from_user("wasm32-wasi");
     let wasi_sdk = PathBuf::from("/wasi-sdk");
     build.wasi_sdk_path = Some(wasi_sdk.clone());
@@ -98,7 +101,8 @@ fn test_default_compiler_wasi() {
 
 #[test]
 fn test_default_compiler_fallback() {
-    let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
+    let config = TestCtx::new().config("build").create_config();
+    let build = Build::new(config);
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let mut cfg = cc::Build::new();
     let result = default_compiler(&mut cfg, Language::C, target, &build);
@@ -107,7 +111,8 @@ fn test_default_compiler_fallback() {
 
 #[test]
 fn test_find_target_with_config() {
-    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
+    let config = TestCtx::new().config("build").create_config();
+    let mut build = Build::new(config);
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let mut target_config = Target::default();
     target_config.cc = Some(PathBuf::from("dummy-cc"));
@@ -128,7 +133,8 @@ fn test_find_target_with_config() {
 
 #[test]
 fn test_find_target_without_config() {
-    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
+    let config = TestCtx::new().config("build").create_config();
+    let mut build = Build::new(config);
     let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     build.config.target_config.clear();
     fill_target_compiler(&mut build, target.clone());
@@ -141,7 +147,8 @@ fn test_find_target_without_config() {
 
 #[test]
 fn test_find() {
-    let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
+    let config = TestCtx::new().config("build").create_config();
+    let mut build = Build::new(config);
     let target1 = TargetSelection::from_user("x86_64-unknown-linux-gnu");
     let target2 = TargetSelection::from_user("x86_64-unknown-openbsd");
     build.targets.push(target1.clone());
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 2cc2fb486fa..01309072927 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -536,4 +536,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "It is no longer possible to `x test` with stage 0, except for running compiletest and opting into `build.compiletest-allow-stage0`.",
     },
+    ChangeInfo {
+        change_id: 145976,
+        severity: ChangeSeverity::Info,
+        summary: "Added a new option `rust.break-on-ice` to control if internal compiler errors cause a debug break on Windows.",
+    },
 ];
diff --git a/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md b/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md
index 41d0cf8d9fb..c3660e24b15 100644
--- a/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md
+++ b/src/doc/rustc-dev-guide/src/building/bootstrapping/writing-tools-in-bootstrap.md
@@ -11,11 +11,8 @@ There are three types of tools you can write in bootstrap:
   Use this for tools that rely on the locally built std. The output goes into the "stageN-tools" directory.
   This mode is rarely used, mainly for `compiletest` which requires `libtest`.
 
-- **`Mode::ToolRustc`**
-  Use this for tools that depend on both the locally built `rustc` and the target `std`. This is more complex than
-  the other modes because the tool must be built with the same compiler used for `rustc` and placed in the "stageN-tools"
-  directory. When you choose `Mode::ToolRustc`, `ToolBuild` implementation takes care of this automatically.
-  If you need to use the builder’s compiler for something specific, you can get it from `ToolBuildResult`, which is
+- **`Mode::ToolRustcPrivate`**
+  Use this for tools that use the `rustc_private` mechanism, and thus depend on the locally built `rustc` and its rlib artifacts. This is more complex than the other modes because the tool must be built with the same compiler used for `rustc` and placed in the "stageN-tools" directory. When you choose `Mode::ToolRustcPrivate`, `ToolBuild` implementation takes care of this automatically. If you need to use the builder’s compiler for something specific, you can get it from `ToolBuildResult`, which is
   returned by the tool's [`Step`].
 
 Regardless of the tool type you must return `ToolBuildResult` from the tool’s [`Step`] implementation and use `ToolBuild` inside it.
diff --git a/src/doc/rustc/src/command-line-arguments/print-options.md b/src/doc/rustc/src/command-line-arguments/print-options.md
index fed19d6b667..f37b27d88c3 100644
--- a/src/doc/rustc/src/command-line-arguments/print-options.md
+++ b/src/doc/rustc/src/command-line-arguments/print-options.md
@@ -184,7 +184,7 @@ Example:
 
 ```bash
 $ rustc --print native-static-libs --crate-type staticlib a.rs
-note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
+note: link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
 
 note: native-static-libs: -lgcc_s -lutil [REDACTED] -lpthread -lm -ldl -lc
 ```
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index dfe193e6e8a..6c5b48d8c8f 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -33,6 +33,7 @@ All tier 1 targets with host tools support the full standard library.
 target | notes
 -------|-------
 [`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+)
+[`aarch64-pc-windows-msvc`](platform-support/windows-msvc.md) | ARM64 Windows MSVC
 `aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1+, glibc 2.17+)
 [`i686-pc-windows-msvc`](platform-support/windows-msvc.md) | 32-bit MSVC (Windows 10+, Windows Server 2016+, Pentium 4) [^x86_32-floats-return-ABI] [^win32-msvc-alignment]
 `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+, Pentium 4) [^x86_32-floats-return-ABI]
@@ -88,7 +89,6 @@ so Rustup may install the documentation for a similar tier 1 target instead.
 target | notes
 -------|-------
 [`aarch64-pc-windows-gnullvm`](platform-support/windows-gnullvm.md) | ARM64 MinGW (Windows 10+), LLVM ABI
-[`aarch64-pc-windows-msvc`](platform-support/windows-msvc.md) | ARM64 Windows MSVC
 [`aarch64-unknown-linux-musl`](platform-support/aarch64-unknown-linux-musl.md) | ARM64 Linux with musl 1.2.3
 [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ARM64 OpenHarmony
 `arm-unknown-linux-gnueabi` | Armv6 Linux (kernel 3.2+, glibc 2.17)
diff --git a/src/doc/rustc/src/platform-support/windows-msvc.md b/src/doc/rustc/src/platform-support/windows-msvc.md
index 71dc4ddc2e6..826c75b79c5 100644
--- a/src/doc/rustc/src/platform-support/windows-msvc.md
+++ b/src/doc/rustc/src/platform-support/windows-msvc.md
@@ -4,13 +4,10 @@ Windows MSVC targets.
 
 **Tier 1 with host tools:**
 
+- `aarch64-pc-windows-msvc`: Windows on ARM64.
 - `i686-pc-windows-msvc`: Windows on 32-bit x86.
 - `x86_64-pc-windows-msvc`: Windows on 64-bit x86.
 
-**Tier 2 with host tools:**
-
-- `aarch64-pc-windows-msvc`: Windows on ARM64.
-
 ## Target maintainers
 
 [@ChrisDenton](https://github.com/ChrisDenton)
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index 8d7f7341c2e..46a3a1602ac 100755
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -247,7 +247,7 @@ class CachedFiles(object):
             paths = list(Path(self.root).glob(path))
             if len(paths) != 1:
                 raise FailedCheck("glob path does not resolve to one file")
-            path = str(paths[0])
+            return str(paths[0])
         return os.path.join(self.root, path)
 
     def get_file(self, path):
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 5d36ffc2d3a..f37a8d85361 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -21,7 +21,7 @@ rustdoc-json-types = { path = "../rustdoc-json-types" }
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 smallvec = "1.8.1"
-stringdex = { version = "0.0.1-alpha4" }
+stringdex = { version = "0.0.1-alpha9" }
 tempfile = "3"
 threadpool = "1.8.1"
 tracing = "0.1"
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 450ac04b40d..d7f6fa347be 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -454,15 +454,22 @@ impl Options {
             return None;
         }
 
-        let mut emit = Vec::new();
+        let mut emit = FxIndexMap::<_, EmitType>::default();
         for list in matches.opt_strs("emit") {
             for kind in list.split(',') {
                 match kind.parse() {
-                    Ok(kind) => emit.push(kind),
+                    Ok(kind) => {
+                        // De-duplicate emit types and the last wins.
+                        // Only one instance for each type is allowed
+                        // regardless the actual data it carries.
+                        // This matches rustc's `--emit` behavior.
+                        emit.insert(std::mem::discriminant(&kind), kind);
+                    }
                     Err(()) => dcx.fatal(format!("unrecognized emission type: {kind}")),
                 }
             }
         }
+        let emit = emit.into_values().collect::<Vec<_>>();
 
         let show_coverage = matches.opt_present("show-coverage");
         let output_format_s = matches.opt_str("output-format");
@@ -814,7 +821,8 @@ impl Options {
 
         let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx);
         let with_examples = matches.opt_strs("with-examples");
-        let call_locations = crate::scrape_examples::load_call_locations(with_examples, dcx);
+        let call_locations =
+            crate::scrape_examples::load_call_locations(with_examples, dcx, &mut loaded_paths);
         let doctest_build_args = matches.opt_strs("doctest-build-arg");
 
         let unstable_features =
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 5da37c97c6a..b01b596da68 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -1212,7 +1212,7 @@ class DocSearch {
      * will never fulfill.
      */
     async buildIndex() {
-        const nn = this.database.getIndex("normalizedName");
+        const nn = this.database.getData("normalizedName");
         if (!nn) {
             return;
         }
@@ -3722,7 +3722,7 @@ class DocSearch {
              * @returns {AsyncGenerator<rustdoc.ResultObject>}
              */
             async function*(currentCrate) {
-                const index = this.database.getIndex("normalizedName");
+                const index = this.database.getData("normalizedName");
                 if (!index) {
                     return;
                 }
@@ -3851,8 +3851,7 @@ class DocSearch {
                 };
                 if (elem.normalizedPathLast === "") {
                     // faster full-table scan for this specific case.
-                    const nameData = this.database.getData("name");
-                    const l = nameData ? nameData.length : 0;
+                    const l = index.length;
                     for (let id = 0; id < l; ++id) {
                         if (!idDuplicates.has(id)) {
                             idDuplicates.add(id);
@@ -3954,7 +3953,7 @@ class DocSearch {
              * @returns {AsyncGenerator<rustdoc.ResultObject>}
              */
             async function*(inputs, output, typeInfo, currentCrate) {
-                const index = this.database.getIndex("normalizedName");
+                const index = this.database.getData("normalizedName");
                 if (!index) {
                     return;
                 }
diff --git a/src/librustdoc/html/static/js/stringdex.d.ts b/src/librustdoc/html/static/js/stringdex.d.ts
index cf9a8b6b564..2eb1fdf95d8 100644
--- a/src/librustdoc/html/static/js/stringdex.d.ts
+++ b/src/librustdoc/html/static/js/stringdex.d.ts
@@ -5,18 +5,9 @@ declare namespace stringdex {
      * The client interface to Stringdex.
      */
     interface Database {
-        getIndex(colname: string): SearchTree|undefined;
         getData(colname: string): DataColumn|undefined;
     }
     /**
-     * A search index file.
-     */
-    interface SearchTree {
-        trie(): Trie;
-        search(name: Uint8Array|string): Promise<Trie?>;
-        searchLev(name: Uint8Array|string): AsyncGenerator<Trie>;
-    }
-    /**
      * A compressed node in the search tree.
      *
      * This object logically addresses two interleaved trees:
@@ -29,9 +20,7 @@ declare namespace stringdex {
         matches(): RoaringBitmap;
         substringMatches(): AsyncGenerator<RoaringBitmap>;
         prefixMatches(): AsyncGenerator<RoaringBitmap>;
-        keys(): Uint8Array;
         keysExcludeSuffixOnly(): Uint8Array;
-        children(): [number, Promise<Trie>][];
         childrenExcludeSuffixOnly(): [number, Promise<Trie>][];
         child(id: number): Promise<Trie>?;
     }
@@ -41,6 +30,8 @@ declare namespace stringdex {
     interface DataColumn {
         isEmpty(id: number): boolean;
         at(id: number): Promise<Uint8Array|undefined>;
+        search(name: Uint8Array|string): Promise<Trie?>;
+        searchLev(name: Uint8Array|string): AsyncGenerator<Trie>;
         length: number,
     }
     /**
diff --git a/src/librustdoc/html/static/js/stringdex.js b/src/librustdoc/html/static/js/stringdex.js
index cb956d926db..b7f605a1035 100644
--- a/src/librustdoc/html/static/js/stringdex.js
+++ b/src/librustdoc/html/static/js/stringdex.js
@@ -1,3 +1,4 @@
+// ignore-tidy-filelength
 /**
  * @import * as stringdex from "./stringdex.d.ts"
  */
@@ -486,6 +487,63 @@ class RoaringBitmap {
         return mid === -1 ? false : this.containers[mid].contains(value);
     }
     /**
+     * @param {number} keyvalue
+     * @returns {RoaringBitmap}
+     */
+    remove(keyvalue) {
+        const key = keyvalue >> 16;
+        const value = keyvalue & 0xFFFF;
+        const mid = this.getContainerId(key);
+        if (mid === -1) {
+            return this;
+        }
+        const container = this.containers[mid];
+        if (!container.contains(value)) {
+            return this;
+        }
+        const newCardinality = (this.keysAndCardinalities[(mid * 4) + 2] |
+            (this.keysAndCardinalities[(mid * 4) + 3] << 8));
+        const l = this.containers.length;
+        const m = l - (newCardinality === 0 ? 1 : 0);
+        const result = new RoaringBitmap(null, 0);
+        result.keysAndCardinalities = new Uint8Array(m * 4);
+        let j = 0;
+        for (let i = 0; i < l; i += 1) {
+            if (i === mid) {
+                if (newCardinality !== 0) {
+                    result.keysAndCardinalities[(j * 4) + 0] = key;
+                    result.keysAndCardinalities[(j * 4) + 1] = key >> 8;
+                    const card = newCardinality - 1;
+                    result.keysAndCardinalities[(j * 4) + 2] = card;
+                    result.keysAndCardinalities[(j * 4) + 3] = card >> 8;
+                    const newContainer = new RoaringBitmapArray(
+                        newCardinality,
+                        new Uint8Array(newCardinality * 2),
+                    );
+                    let newContainerSlot = 0;
+                    for (const containerValue of container.values()) {
+                        if (containerValue !== value) {
+                            newContainer.array[newContainerSlot] = value & 0xFF;
+                            newContainerSlot += 1;
+                            newContainer.array[newContainerSlot] = value >> 8;
+                            newContainerSlot += 1;
+                        }
+                    }
+                    result.containers.push(newContainer);
+                    j += 1;
+                }
+            } else {
+                result.keysAndCardinalities[(j * 4) + 0] = this.keysAndCardinalities[(i * 4) + 0];
+                result.keysAndCardinalities[(j * 4) + 1] = this.keysAndCardinalities[(i * 4) + 1];
+                result.keysAndCardinalities[(j * 4) + 2] = this.keysAndCardinalities[(i * 4) + 2];
+                result.keysAndCardinalities[(j * 4) + 3] = this.keysAndCardinalities[(i * 4) + 3];
+                result.containers.push(this.containers[i]);
+                j += 1;
+            }
+        }
+        return result;
+    }
+    /**
      * @param {number} key
      * @returns {number}
      */
@@ -878,6 +936,46 @@ function bitCount(n) {
 /*eslint-enable */
 
 /**
+ * https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm
+ */
+class Uint8ArraySearchPattern {
+    /** @param {Uint8Array} needle */
+    constructor(needle) {
+        this.needle = needle;
+        this.skipTable = [];
+        const m = needle.length;
+        for (let i = 0; i < 256; i += 1) {
+            this.skipTable.push(m);
+        }
+        for (let i = 0; i < m - 1; i += 1) {
+            this.skipTable[needle[i]] = m - 1 - i;
+        }
+    }
+    /**
+     * @param {Uint8Array} haystack
+     * @returns {boolean}
+     */
+    matches(haystack) {
+        const needle = this.needle;
+        const skipTable = this.skipTable;
+        const m = needle.length;
+        const n = haystack.length;
+
+        let skip = 0;
+        search: while (n - skip >= m) {
+            for (let i = m - 1; i >= 0; i -= 1) {
+                if (haystack[skip + i] !== needle[i]) {
+                    skip += skipTable[haystack[skip + m  - 1]];
+                    continue search;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+}
+
+/**
  * @param {stringdex.Hooks} hooks
  * @returns {Promise<stringdex.Database>}
  */
@@ -887,12 +985,6 @@ function loadDatabase(hooks) {
         rr_: function(data) {
             const dataObj = JSON.parse(data);
             for (const colName of Object.keys(dataObj)) {
-                if (Object.hasOwn(dataObj[colName], "I")) {
-                    registry.searchTreeRoots.set(
-                        colName,
-                        makeSearchTreeFromBase64(dataObj[colName].I)[1],
-                    );
-                }
                 if (Object.hasOwn(dataObj[colName], "N")) {
                     const counts = [];
                     const countsstring = dataObj[colName]["N"];
@@ -915,6 +1007,9 @@ function loadDatabase(hooks) {
                         makeUint8ArrayFromBase64(dataObj[colName]["H"]),
                         new RoaringBitmap(makeUint8ArrayFromBase64(dataObj[colName]["E"]), 0),
                         colName,
+                        Object.hasOwn(dataObj[colName], "I") ?
+                            makeSearchTreeFromBase64(dataObj[colName].I)[1] :
+                            null,
                     ));
                 }
             }
@@ -978,7 +1073,7 @@ function loadDatabase(hooks) {
      *      searchTreePromises: HashTable<Promise<SearchTree>>;
      *      dataColumnLoadPromiseCallbacks: HashTable<function(any, Uint8Array[]?): any>;
      *      dataColumns: Map<string, DataColumn>;
-     *      dataColumnsBuckets: Map<string, HashTable<Promise<Uint8Array[]>>>;
+     *      dataColumnsBuckets: HashTable<Promise<Uint8Array[]>>;
      *      searchTreeLoadByNodeID: function(Uint8Array): Promise<SearchTree>;
      *      searchTreeRootCallback?: function(any, Database?): any;
      *      dataLoadByNameAndHash: function(string, Uint8Array): Promise<Uint8Array[]>;
@@ -990,7 +1085,7 @@ function loadDatabase(hooks) {
         searchTreePromises: new HashTable(),
         dataColumnLoadPromiseCallbacks: new HashTable(),
         dataColumns: new Map(),
-        dataColumnsBuckets: new Map(),
+        dataColumnsBuckets: new HashTable(),
         searchTreeLoadByNodeID: function(nodeid) {
             const existingPromise = registry.searchTreePromises.get(nodeid);
             if (existingPromise) {
@@ -1022,7 +1117,7 @@ function loadDatabase(hooks) {
                 const data = (nodeid[0] & 0x20) !== 0 ?
                     Uint8Array.of(((nodeid[0] & 0x0f) << 4) | (nodeid[1] >> 4)) :
                     EMPTY_UINT8;
-                newPromise = Promise.resolve(new SearchTree(
+                newPromise = Promise.resolve(new PrefixSearchTree(
                     EMPTY_SEARCH_TREE_BRANCHES,
                     EMPTY_SEARCH_TREE_BRANCHES,
                     data,
@@ -1058,12 +1153,7 @@ function loadDatabase(hooks) {
             return newPromise;
         },
         dataLoadByNameAndHash: function(name, hash) {
-            let dataColumnBuckets = registry.dataColumnsBuckets.get(name);
-            if (dataColumnBuckets === undefined) {
-                dataColumnBuckets = new HashTable();
-                registry.dataColumnsBuckets.set(name, dataColumnBuckets);
-            }
-            const existingBucket = dataColumnBuckets.get(hash);
+            const existingBucket = registry.dataColumnsBuckets.get(hash);
             if (existingBucket) {
                 return existingBucket;
             }
@@ -1091,16 +1181,17 @@ function loadDatabase(hooks) {
                     hooks.loadDataByNameAndHash(name, hashHex);
                 }
             });
-            dataColumnBuckets.set(hash, newBucket);
+            registry.dataColumnsBuckets.set(hash, newBucket);
             return newBucket;
         },
     };
 
     /**
      * The set of child subtrees.
+     * @template ST
      * @type {{
      *    nodeids: Uint8Array,
-     *    subtrees: Array<Promise<SearchTree>|null>,
+     *    subtrees: Array<Promise<ST>|null>,
      * }}
      */
     class SearchTreeBranches {
@@ -1128,7 +1219,7 @@ function loadDatabase(hooks) {
             );
         }
         // https://github.com/microsoft/TypeScript/issues/17227
-        /** @returns {Generator<[number, Promise<SearchTree>|null]>} */
+        /** @returns {Generator<[number, Promise<ST>|null]>} */
         entries() {
             throw new Error();
         }
@@ -1157,10 +1248,12 @@ function loadDatabase(hooks) {
     /**
      * A sorted array of search tree branches.
      *
+     * @template ST
+     * @extends SearchTreeBranches<ST>
      * @type {{
      *    keys: Uint8Array,
      *    nodeids: Uint8Array,
-     *    subtrees: Array<Promise<SearchTree>|null>,
+     *    subtrees: Array<Promise<ST>|null>,
      * }}
      */
     class SearchTreeBranchesArray extends SearchTreeBranches {
@@ -1179,7 +1272,7 @@ function loadDatabase(hooks) {
                 i += 1;
             }
         }
-        /** @returns {Generator<[number, Promise<SearchTree>|null]>} */
+        /** @returns {Generator<[number, Promise<ST>|null]>} */
         * entries() {
             let i = 0;
             const l = this.keys.length;
@@ -1246,12 +1339,16 @@ function loadDatabase(hooks) {
     }
 
     /**
+     * @template ST
      * @param {number[]} alphabitmap_chars
      * @param {number} width
-     * @return {(typeof SearchTreeBranches)&{"ALPHABITMAP_CHARS": number[], "width": number}}
+     * @return {(typeof SearchTreeBranches<ST>)&{"ALPHABITMAP_CHARS": number[], "width": number}}
      */
     function makeSearchTreeBranchesAlphaBitmapClass(alphabitmap_chars, width) {
         const bitwidth = width * 8;
+        /**
+         * @extends SearchTreeBranches<ST>
+         */
         const cls = class SearchTreeBranchesAlphaBitmap extends SearchTreeBranches {
             /**
              * @param {number} bitmap
@@ -1265,7 +1362,7 @@ function loadDatabase(hooks) {
                 this.bitmap = bitmap;
                 this.nodeids = nodeids;
             }
-            /** @returns {Generator<[number, Promise<SearchTree>|null]>} */
+            /** @returns {Generator<[number, Promise<ST>|null]>} */
             * entries() {
                 let i = 0;
                 let j = 0;
@@ -1295,15 +1392,7 @@ function loadDatabase(hooks) {
              * @returns {number}
              */
             getKey(branch_index) {
-                //return this.getKeys()[branch_index];
-                let alpha_index = 0;
-                while (branch_index >= 0) {
-                    if (this.bitmap & (1 << alpha_index)) {
-                        branch_index -= 1;
-                    }
-                    alpha_index += 1;
-                }
-                return alphabitmap_chars[alpha_index];
+                return this.getKeys()[branch_index];
             }
             /**
              * @returns {Uint8Array}
@@ -1326,20 +1415,35 @@ function loadDatabase(hooks) {
         return cls;
     }
 
+    /**
+     * @template ST
+     * @type {(typeof SearchTreeBranches<any>)&{"ALPHABITMAP_CHARS": number[], "width": number}}
+     */
     const SearchTreeBranchesShortAlphaBitmap =
         makeSearchTreeBranchesAlphaBitmapClass(SHORT_ALPHABITMAP_CHARS, 3);
 
+    /**
+     * @template ST
+     * @type {(typeof SearchTreeBranches<any>)&{"ALPHABITMAP_CHARS": number[], "width": number}}
+     */
     const SearchTreeBranchesLongAlphaBitmap =
         makeSearchTreeBranchesAlphaBitmapClass(LONG_ALPHABITMAP_CHARS, 4);
 
     /**
-     * A [suffix tree], used for name-based search.
+     * @typedef {PrefixSearchTree|SuffixSearchTree} SearchTree
+     * @typedef {PrefixTrie|SuffixTrie} Trie
+     */
+
+    /**
+     * An interleaved [prefix] and [suffix tree],
+     * used for name-based search.
      *
-     * This data structure is used to drive substring matches,
+     * This data structure is used to drive prefix matches,
      * such as matching the query "link" to `LinkedList`,
      * and Lev-distance matches, such as matching the
      * query "hahsmap" to `HashMap`.
      *
+     * [prefix tree]: https://en.wikipedia.org/wiki/Prefix_tree
      * [suffix tree]: https://en.wikipedia.org/wiki/Suffix_tree
      *
      * branches
@@ -1358,17 +1462,17 @@ function loadDatabase(hooks) {
      *   will include these.
      *
      * @type {{
-     *     might_have_prefix_branches: SearchTreeBranches,
-     *     branches: SearchTreeBranches,
+     *     might_have_prefix_branches: SearchTreeBranches<SearchTree>,
+     *     branches: SearchTreeBranches<SearchTree>,
      *     data: Uint8Array,
      *     leaves_suffix: RoaringBitmap,
      *     leaves_whole: RoaringBitmap,
      * }}
      */
-    class SearchTree {
+    class PrefixSearchTree {
         /**
-         * @param {SearchTreeBranches} branches
-         * @param {SearchTreeBranches} might_have_prefix_branches
+         * @param {SearchTreeBranches<SearchTree>} branches
+         * @param {SearchTreeBranches<SearchTree>} might_have_prefix_branches
          * @param {Uint8Array} data
          * @param {RoaringBitmap} leaves_whole
          * @param {RoaringBitmap} leaves_suffix
@@ -1392,25 +1496,31 @@ function loadDatabase(hooks) {
          * A Trie pointer refers to a single node in a logical decompressed search tree
          * (the real search tree is compressed).
          *
-         * @return {Trie}
+         * @param {DataColumn} dataColumn
+         * @param {Uint8ArraySearchPattern} searchPattern
+         * @return {PrefixTrie}
          */
-        trie() {
-            return new Trie(this, 0);
+        trie(dataColumn, searchPattern) {
+            return new PrefixTrie(this, 0, dataColumn, searchPattern);
         }
 
         /**
          * Return the trie representing `name`
          * @param {Uint8Array|string} name
+         * @param {DataColumn} dataColumn
          * @returns {Promise<Trie?>}
          */
-        async search(name) {
+        async search(name, dataColumn) {
             if (typeof name === "string") {
                 const utf8encoder = new TextEncoder();
                 name = utf8encoder.encode(name);
             }
-            let trie = this.trie();
+            const searchPattern = new Uint8ArraySearchPattern(name);
+            /** @type {Trie} */
+            let trie = this.trie(dataColumn, searchPattern);
             for (const datum of name) {
                 // code point definitely exists
+                /** @type {Promise<Trie>?} */
                 const newTrie = trie.child(datum);
                 if (newTrie) {
                     trie = await newTrie;
@@ -1423,26 +1533,28 @@ function loadDatabase(hooks) {
 
         /**
          * @param {Uint8Array|string} name
+         * @param {DataColumn} dataColumn
          * @returns {AsyncGenerator<Trie>}
          */
-        async* searchLev(name) {
+        async* searchLev(name, dataColumn) {
             if (typeof name === "string") {
                 const utf8encoder = new TextEncoder();
                 name = utf8encoder.encode(name);
             }
             const w = name.length;
             if (w < 3) {
-                const trie = await this.search(name);
+                const trie = await this.search(name, dataColumn);
                 if (trie !== null) {
                     yield trie;
                 }
                 return;
             }
+            const searchPattern = new Uint8ArraySearchPattern(name);
             const levParams = w >= 6 ?
                 new Lev2TParametricDescription(w) :
                 new Lev1TParametricDescription(w);
             /** @type {Array<[Promise<Trie>, number]>} */
-            const stack = [[Promise.resolve(this.trie()), 0]];
+            const stack = [[Promise.resolve(this.trie(dataColumn, searchPattern)), 0]];
             const n = levParams.n;
             while (stack.length !== 0) {
                 // It's not empty
@@ -1475,20 +1587,29 @@ function loadDatabase(hooks) {
                 }
             }
         }
+
+        /** @returns {RoaringBitmap} */
+        getCurrentLeaves() {
+            return this.leaves_whole.union(this.leaves_suffix);
+        }
     }
 
     /**
      * A representation of a set of strings in the search index,
      * as a subset of the entire tree.
      */
-    class Trie {
+    class PrefixTrie {
         /**
-         * @param {SearchTree} tree
+         * @param {PrefixSearchTree} tree
          * @param {number} offset
+         * @param {DataColumn} dataColumn
+         * @param {Uint8ArraySearchPattern} searchPattern
          */
-        constructor(tree, offset) {
+        constructor(tree, offset, dataColumn, searchPattern) {
             this.tree = tree;
             this.offset = offset;
+            this.dataColumn = dataColumn;
+            this.searchPattern = searchPattern;
         }
 
         /**
@@ -1514,7 +1635,28 @@ function loadDatabase(hooks) {
                 const current_layer = layer;
                 layer = [];
                 for await (const tree of current_layer) {
-                    yield tree.leaves_whole.union(tree.leaves_suffix);
+                    /** @type {number[]?} */
+                    let rejected = null;
+                    let leaves = tree.getCurrentLeaves();
+                    for (const leaf of leaves.entries()) {
+                        const haystack = await this.dataColumn.at(leaf);
+                        if (haystack === undefined || !this.searchPattern.matches(haystack)) {
+                            if (!rejected) {
+                                rejected = [];
+                            }
+                            rejected.push(leaf);
+                        }
+                    }
+                    if (rejected) {
+                        if (leaves.cardinality() !== rejected.length) {
+                            for (const rej of rejected) {
+                                leaves = leaves.remove(rej);
+                            }
+                            yield leaves;
+                        }
+                    } else {
+                        yield leaves;
+                    }
                 }
                 /** @type {HashTable<[number, SearchTree][]>} */
                 const subnodes = new HashTable();
@@ -1548,12 +1690,14 @@ function loadDatabase(hooks) {
                     const res = registry.searchTreeLoadByNodeID(newnode);
                     for (const [byte, node] of subnode_list) {
                         const branches = node.branches;
-                        const might_have_prefix_branches = node.might_have_prefix_branches;
                         const i = branches.getIndex(byte);
                         branches.subtrees[i] = res;
-                        const mhpI = might_have_prefix_branches.getIndex(byte);
-                        if (mhpI !== -1) {
-                            might_have_prefix_branches.subtrees[mhpI] = res;
+                        if (node instanceof PrefixSearchTree) {
+                            const might_have_prefix_branches = node.might_have_prefix_branches;
+                            const mhpI = might_have_prefix_branches.getIndex(byte);
+                            if (mhpI !== -1) {
+                                might_have_prefix_branches.subtrees[mhpI] = res;
+                            }
                         }
                     }
                     layer.push(res);
@@ -1581,6 +1725,9 @@ function loadDatabase(hooks) {
                 // if we want to do them in order)
                 for (const {node, len} of current_layer) {
                     const tree = await node;
+                    if (!(tree instanceof PrefixSearchTree)) {
+                        continue;
+                    }
                     const length = len + tree.data.length;
                     if (minLength === null || length < minLength) {
                         minLength = length;
@@ -1637,10 +1784,13 @@ function loadDatabase(hooks) {
                     }
                 }
                 // if we still have more subtrees to walk, then keep going
-                /** @type {HashTable<{byte: number, tree: SearchTree, len: number}[]>} */
+                /** @type {HashTable<{byte: number, tree: PrefixSearchTree, len: number}[]>} */
                 const subnodes = new HashTable();
                 for await (const {node, len} of current_layer) {
                     const tree = await node;
+                    if (!(tree instanceof PrefixSearchTree)) {
+                        continue;
+                    }
                     const length = len + tree.data.length;
                     const mhp_branches = tree.might_have_prefix_branches;
                     const l = mhp_branches.subtrees.length;
@@ -1663,8 +1813,6 @@ function loadDatabase(hooks) {
                                     subnode_list.push({byte, tree, len});
                                 }
                             }
-                        } else {
-                            throw new Error(`malformed tree; index ${i} does not exist`);
                         }
                     }
                 }
@@ -1728,14 +1876,21 @@ function loadDatabase(hooks) {
                             this.tree.might_have_prefix_branches.subtrees[mhpI] = node;
                         }
                     }
-                    nodes.push([k, node.then(node => node.trie())]);
+                    nodes.push([k, node.then(node => {
+                        return node.trie(this.dataColumn, this.searchPattern);
+                    })]);
                     i += 1;
                 }
                 return nodes;
             } else {
                 /** @type {number} */
                 const codePoint = data[this.offset];
-                const trie = new Trie(this.tree, this.offset + 1);
+                const trie = new PrefixTrie(
+                    this.tree,
+                    this.offset + 1,
+                    this.dataColumn,
+                    this.searchPattern,
+                );
                 return [[codePoint, Promise.resolve(trie)]];
             }
         }
@@ -1777,14 +1932,21 @@ function loadDatabase(hooks) {
                         this.tree.might_have_prefix_branches.subtrees[i] = node;
                         this.tree.branches.subtrees[this.tree.branches.getIndex(k)] = node;
                     }
-                    nodes.push([k, node.then(node => node.trie())]);
+                    nodes.push([k, node.then(node => {
+                        return node.trie(this.dataColumn, this.searchPattern);
+                    })]);
                     i += 1;
                 }
                 return nodes;
             } else {
                 /** @type {number} */
                 const codePoint = data[this.offset];
-                const trie = new Trie(this.tree, this.offset + 1);
+                const trie = new PrefixTrie(
+                    this.tree,
+                    this.offset + 1,
+                    this.dataColumn,
+                    this.searchPattern,
+                );
                 return [[codePoint, Promise.resolve(trie)]];
             }
         }
@@ -1811,10 +1973,275 @@ function loadDatabase(hooks) {
                             this.tree.might_have_prefix_branches.subtrees[mhpI] = branch;
                         }
                     }
-                    return branch.then(branch => branch.trie());
+                    return branch.then(branch => branch.trie(this.dataColumn, this.searchPattern));
                 }
             } else if (this.tree.data[this.offset] === byte) {
-                return Promise.resolve(new Trie(this.tree, this.offset + 1));
+                return Promise.resolve(new PrefixTrie(
+                    this.tree,
+                    this.offset + 1,
+                    this.dataColumn,
+                    this.searchPattern,
+                ));
+            }
+            return null;
+        }
+    }
+    /**
+     * A [suffix tree], used for name-based search.
+     *
+     * This data structure is used to drive substring matches,
+     * such as matching the query "inked" to `LinkedList`.
+     *
+     * [suffix tree]: https://en.wikipedia.org/wiki/Suffix_tree
+     *
+     * Suffix trees do not actually carry the intermediate data
+     * between branches, so, in order to validate the results,
+     * they must go through a filtering step at the end.
+     * Suffix trees also cannot match lev and exact matches,
+     * so those just return empty sets.
+     *
+     * branches
+     * : A sorted-array map of subtrees.
+     *
+     * dataLen
+     * : The length of the substring used by this node.
+     *
+     * leaves_suffix
+     * : The IDs of every entry that matches. Levenshtein matches
+     *   won't include these.
+     *
+     * @type {{
+     *     branches: SearchTreeBranches<SearchTree>,
+     *     dataLen: number,
+     *     leaves_suffix: RoaringBitmap,
+     * }}
+     */
+    class SuffixSearchTree {
+        /**
+         * @param {SearchTreeBranches<SearchTree>} branches
+         * @param {number} dataLen
+         * @param {RoaringBitmap} leaves_suffix
+         */
+        constructor(
+            branches,
+            dataLen,
+            leaves_suffix,
+        ) {
+            this.branches = branches;
+            this.dataLen = dataLen;
+            this.leaves_suffix = leaves_suffix;
+        }
+        /**
+         * Returns the Trie for the root node.
+         *
+         * A Trie pointer refers to a single node in a logical decompressed search tree
+         * (the real search tree is compressed).
+         *
+         * @param {DataColumn} dataColumn
+         * @param {Uint8ArraySearchPattern} searchPattern
+         * @return {Trie}
+         */
+        trie(dataColumn, searchPattern) {
+            return new SuffixTrie(this, 0, dataColumn, searchPattern);
+        }
+
+        /**
+         * Return the trie representing `name`
+         * @param {Uint8Array|string} name
+         * @param {DataColumn} dataColumn
+         * @returns {Promise<Trie?>}
+         */
+        async search(name, dataColumn) {
+            if (typeof name === "string") {
+                const utf8encoder = new TextEncoder();
+                name = utf8encoder.encode(name);
+            }
+            const searchPattern = new Uint8ArraySearchPattern(name);
+            let trie = this.trie(dataColumn, searchPattern);
+            for (const datum of name) {
+                // code point definitely exists
+                const newTrie = trie.child(datum);
+                if (newTrie) {
+                    trie = await newTrie;
+                } else {
+                    return null;
+                }
+            }
+            return trie;
+        }
+
+        /**
+         * @param {Uint8Array|string} _name
+         * @param {DataColumn} _dataColumn
+         * @returns {AsyncGenerator<Trie>}
+         */
+        async* searchLev(_name, _dataColumn) {
+            // this function only returns whole-string matches,
+            // which pure-suffix nodes don't have, so is
+            // intentionally blank
+        }
+
+        /** @returns {RoaringBitmap} */
+        getCurrentLeaves() {
+            return this.leaves_suffix;
+        }
+    }
+
+    /**
+     * A representation of a set of strings in the search index,
+     * as a subset of the entire tree (suffix-only).
+     */
+    class SuffixTrie {
+        /**
+         * @param {SuffixSearchTree} tree
+         * @param {number} offset
+         * @param {DataColumn} dataColumn
+         * @param {Uint8ArraySearchPattern} searchPattern
+         */
+        constructor(tree, offset, dataColumn, searchPattern) {
+            this.tree = tree;
+            this.offset = offset;
+            this.dataColumn = dataColumn;
+            this.searchPattern = searchPattern;
+        }
+
+        /**
+         * All exact matches for the string represented by this node.
+         * Since pure-suffix nodes have no exactly-matching children,
+         * this function returns the empty bitmap.
+         * @returns {RoaringBitmap}
+         */
+        matches() {
+            return EMPTY_BITMAP;
+        }
+
+        /**
+         * All matches for strings that contain the string represented by this node.
+         * @returns {AsyncGenerator<RoaringBitmap>}
+         */
+        async* substringMatches() {
+            /** @type {Promise<SearchTree>[]} */
+            let layer = [Promise.resolve(this.tree)];
+            while (layer.length) {
+                const current_layer = layer;
+                layer = [];
+                for await (const tree of current_layer) {
+                    /** @type {number[]?} */
+                    let rejected = null;
+                    let leaves = tree.getCurrentLeaves();
+                    for (const leaf of leaves.entries()) {
+                        const haystack = await this.dataColumn.at(leaf);
+                        if (haystack === undefined || !this.searchPattern.matches(haystack)) {
+                            if (!rejected) {
+                                rejected = [];
+                            }
+                            rejected.push(leaf);
+                        }
+                    }
+                    if (rejected) {
+                        if (leaves.cardinality() !== rejected.length) {
+                            for (const rej of rejected) {
+                                leaves = leaves.remove(rej);
+                            }
+                            yield leaves;
+                        }
+                    } else {
+                        yield leaves;
+                    }
+                }
+                /** @type {HashTable<[number, SearchTree][]>} */
+                const subnodes = new HashTable();
+                for await (const node of current_layer) {
+                    const branches = node.branches;
+                    const l = branches.subtrees.length;
+                    for (let i = 0; i < l; ++i) {
+                        const subtree = branches.subtrees[i];
+                        if (subtree) {
+                            layer.push(subtree);
+                        } else if (subtree === null) {
+                            const newnode = branches.getNodeID(i);
+                            if (!newnode) {
+                                throw new Error(`malformed tree; no node for index ${i}`);
+                            } else {
+                                let subnode_list = subnodes.get(newnode);
+                                if (!subnode_list) {
+                                    subnode_list = [[i, node]];
+                                    subnodes.set(newnode, subnode_list);
+                                } else {
+                                    subnode_list.push([i, node]);
+                                }
+                            }
+                        } else {
+                            throw new Error(`malformed tree; index ${i} does not exist`);
+                        }
+                    }
+                }
+                for (const [newnode, subnode_list] of subnodes.entries()) {
+                    const res = registry.searchTreeLoadByNodeID(newnode);
+                    for (const [i, node] of subnode_list) {
+                        const branches = node.branches;
+                        branches.subtrees[i] = res;
+                    }
+                    layer.push(res);
+                }
+            }
+        }
+
+        /**
+         * All matches for strings that start with the string represented by this node.
+         * Since this is a pure-suffix node, there aren't any.
+         * @returns {AsyncGenerator<RoaringBitmap>}
+         */
+        async* prefixMatches() {
+            // this function only returns prefix matches,
+            // which pure-suffix nodes don't have, so is
+            // intentionally blank
+        }
+
+        /**
+         * Returns all keys that are children of this node.
+         * @returns {Uint8Array}
+         */
+        keysExcludeSuffixOnly() {
+            return EMPTY_UINT8;
+        }
+
+        /**
+         * Returns all nodes that are direct children of this node.
+         * @returns {[number, Promise<Trie>][]}
+         */
+        childrenExcludeSuffixOnly() {
+            return [];
+        }
+
+        /**
+         * Returns a single node that is a direct child of this node.
+         * @param {number} byte
+         * @returns {Promise<Trie>?}
+         */
+        child(byte) {
+            if (this.offset === this.tree.dataLen) {
+                const i = this.tree.branches.getIndex(byte);
+                if (i !== -1) {
+                    /** @type {Promise<SearchTree>?} */
+                    let branch = this.tree.branches.subtrees[i];
+                    if (branch === null) {
+                        const newnode = this.tree.branches.getNodeID(i);
+                        if (!newnode) {
+                            throw new Error(`malformed tree; no node for key ${byte}`);
+                        }
+                        branch = registry.searchTreeLoadByNodeID(newnode);
+                        this.tree.branches.subtrees[i] = branch;
+                    }
+                    return branch.then(branch => branch.trie(this.dataColumn, this.searchPattern));
+                }
+            } else {
+                return Promise.resolve(new SuffixTrie(
+                    this.tree,
+                    this.offset + 1,
+                    this.dataColumn,
+                    this.searchPattern,
+                ));
             }
             return null;
         }
@@ -1827,8 +2254,10 @@ function loadDatabase(hooks) {
          * @param {Uint8Array} hashes
          * @param {RoaringBitmap} emptyset
          * @param {string} name
+         * @param {SearchTree?} searchTree
          */
-        constructor(counts, hashes, emptyset, name) {
+        constructor(counts, hashes, emptyset, name, searchTree) {
+            this.searchTree = searchTree;
             this.hashes = hashes;
             this.emptyset = emptyset;
             this.name = name;
@@ -1883,7 +2312,7 @@ function loadDatabase(hooks) {
                     const {hash, end} = this.buckets[idx];
                     let data = this.buckets[idx].data;
                     if (data === null) {
-                        const dataSansEmptyset = await registry.dataLoadByNameAndHash(
+                        const dataSansEmptysetOrig = await registry.dataLoadByNameAndHash(
                             this.name,
                             hash,
                         );
@@ -1893,6 +2322,7 @@ function loadDatabase(hooks) {
                         if (data !== null) {
                             return (await data)[id - start];
                         }
+                        const dataSansEmptyset = [...dataSansEmptysetOrig];
                         /** @type {(Uint8Array[])|null} */
                         let dataWithEmptyset = null;
                         let pos = start;
@@ -1924,6 +2354,24 @@ function loadDatabase(hooks) {
                 }
             }
         }
+        /**
+         * Search by exact substring
+         * @param {Uint8Array|string} name
+         * @returns {Promise<Trie?>}
+         */
+        async search(name) {
+            return await (this.searchTree ? this.searchTree.search(name, this) : null);
+        }
+        /**
+         * Search by whole, inexact match
+         * @param {Uint8Array|string} name
+         * @returns {AsyncGenerator<Trie>}
+         */
+        async *searchLev(name) {
+            if (this.searchTree) {
+                yield* this.searchTree.searchLev(name, this);
+            }
+        }
     }
 
     class Database {
@@ -2015,7 +2463,7 @@ function loadDatabase(hooks) {
         const data_history = [];
         let canonical = EMPTY_UINT8;
         /** @type {SearchTree} */
-        let tree = new SearchTree(
+        let tree = new PrefixSearchTree(
             EMPTY_SEARCH_TREE_BRANCHES,
             EMPTY_SEARCH_TREE_BRANCHES,
             EMPTY_UINT8,
@@ -2029,8 +2477,8 @@ function loadDatabase(hooks) {
          * @returns {{
          *     "cpbranches": Uint8Array,
          *     "csbranches": Uint8Array,
-         *     "might_have_prefix_branches": SearchTreeBranches,
-         *     "branches": SearchTreeBranches,
+         *     "might_have_prefix_branches": SearchTreeBranches<SearchTree>,
+         *     "branches": SearchTreeBranches<SearchTree>,
          *     "cpnodes": Uint8Array,
          *     "csnodes": Uint8Array,
          *     "consumed_len_bytes": number,
@@ -2051,6 +2499,12 @@ function loadDatabase(hooks) {
             const start_point = i;
             let cplen;
             let cslen;
+            /**
+             * @type {(
+             *   typeof SearchTreeBranches<SearchTree> &
+             *   {"ALPHABITMAP_CHARS": number[], "width": number}
+             * )?}
+             */
             let alphabitmap = null;
             if (is_pure_suffixes_only_node) {
                 cplen = 0;
@@ -2299,6 +2753,8 @@ function loadDatabase(hooks) {
                 if (is_data_compressed) {
                     data = data_history[data_history.length - dlen - 1];
                     dlen = data.length;
+                } else if (is_pure_suffixes_only_node) {
+                    data = EMPTY_UINT8;
                 } else {
                     data = dlen === 0 ?
                         EMPTY_UINT8 :
@@ -2319,80 +2775,109 @@ function loadDatabase(hooks) {
                 let whole;
                 let suffix;
                 if (is_pure_suffixes_only_node) {
-                    whole = EMPTY_BITMAP;
                     suffix = input[i] === 0 ?
                         EMPTY_BITMAP1 :
                         new RoaringBitmap(input, i);
                     i += suffix.consumed_len_bytes;
-                } else if (input[i] === 0xff) {
-                    whole = EMPTY_BITMAP;
-                    suffix = EMPTY_BITMAP1;
-                    i += 1;
+                    tree = new SuffixSearchTree(
+                        branches,
+                        dlen,
+                        suffix,
+                    );
+                    const clen = (
+                        3 + // lengths of children and data
+                        csnodes.length +
+                        csbranches.length +
+                        suffix.consumed_len_bytes
+                    );
+                    if (canonical.length < clen) {
+                        canonical = new Uint8Array(clen);
+                    }
+                    let ci = 0;
+                    canonical[ci] = 1;
+                    ci += 1;
+                    canonical[ci] = dlen;
+                    ci += 1;
+                    canonical[ci] = input[coffset]; // suffix child count
+                    ci += 1;
+                    canonical.set(csnodes, ci);
+                    ci += csnodes.length;
+                    canonical.set(csbranches, ci);
+                    ci += csbranches.length;
+                    const leavesOffset = i - suffix.consumed_len_bytes;
+                    for (let j = leavesOffset; j < i; j += 1) {
+                        canonical[ci + j - leavesOffset] = input[j];
+                    }
+                    siphashOfBytes(canonical.subarray(0, clen), 0, 0, 0, 0, hash);
                 } else {
-                    whole = input[i] === 0 ?
-                        EMPTY_BITMAP1 :
-                        new RoaringBitmap(input, i);
-                    i += whole.consumed_len_bytes;
-                    suffix = input[i] === 0 ?
-                        EMPTY_BITMAP1 :
-                        new RoaringBitmap(input, i);
-                    i += suffix.consumed_len_bytes;
-                }
-                tree = new SearchTree(
-                    branches,
-                    might_have_prefix_branches,
-                    data,
-                    whole,
-                    suffix,
-                );
-                const clen = (
-                    (is_pure_suffixes_only_node ? 3 : 4) + // lengths of children and data
-                    dlen +
-                    cpnodes.length + csnodes.length +
-                    cpbranches.length + csbranches.length +
-                    whole.consumed_len_bytes +
-                    suffix.consumed_len_bytes
-                );
-                if (canonical.length < clen) {
-                    canonical = new Uint8Array(clen);
-                }
-                let ci = 0;
-                canonical[ci] = is_pure_suffixes_only_node ? 1 : 0;
-                ci += 1;
-                canonical[ci] = dlen;
-                ci += 1;
-                canonical.set(data, ci);
-                ci += dlen;
-                canonical[ci] = input[coffset];
-                ci += 1;
-                if (!is_pure_suffixes_only_node) {
-                    canonical[ci] = input[coffset + 1];
+                    if (input[i] === 0xff) {
+                        whole = EMPTY_BITMAP;
+                        suffix = EMPTY_BITMAP1;
+                        i += 1;
+                    } else {
+                        whole = input[i] === 0 ?
+                            EMPTY_BITMAP1 :
+                            new RoaringBitmap(input, i);
+                        i += whole.consumed_len_bytes;
+                        suffix = input[i] === 0 ?
+                            EMPTY_BITMAP1 :
+                            new RoaringBitmap(input, i);
+                        i += suffix.consumed_len_bytes;
+                    }
+                    tree = new PrefixSearchTree(
+                        branches,
+                        might_have_prefix_branches,
+                        data,
+                        whole,
+                        suffix,
+                    );
+                    const clen = (
+                        4 + // lengths of children and data
+                        dlen +
+                        cpnodes.length + csnodes.length +
+                        cpbranches.length + csbranches.length +
+                        whole.consumed_len_bytes +
+                        suffix.consumed_len_bytes
+                    );
+                    if (canonical.length < clen) {
+                        canonical = new Uint8Array(clen);
+                    }
+                    let ci = 0;
+                    canonical[ci] = 0;
                     ci += 1;
+                    canonical[ci] = dlen;
+                    ci += 1;
+                    canonical.set(data, ci);
+                    ci += data.length;
+                    canonical[ci] = input[coffset]; // prefix child count
+                    ci += 1;
+                    canonical[ci] = input[coffset + 1]; // suffix child count
+                    ci += 1;
+                    canonical.set(cpnodes, ci);
+                    ci += cpnodes.length;
+                    canonical.set(csnodes, ci);
+                    ci += csnodes.length;
+                    canonical.set(cpbranches, ci);
+                    ci += cpbranches.length;
+                    canonical.set(csbranches, ci);
+                    ci += csbranches.length;
+                    const leavesOffset = i - whole.consumed_len_bytes - suffix.consumed_len_bytes;
+                    for (let j = leavesOffset; j < i; j += 1) {
+                        canonical[ci + j - leavesOffset] = input[j];
+                    }
+                    siphashOfBytes(canonical.subarray(0, clen), 0, 0, 0, 0, hash);
                 }
-                canonical.set(cpnodes, ci);
-                ci += cpnodes.length;
-                canonical.set(csnodes, ci);
-                ci += csnodes.length;
-                canonical.set(cpbranches, ci);
-                ci += cpbranches.length;
-                canonical.set(csbranches, ci);
-                ci += csbranches.length;
-                const leavesOffset = i - whole.consumed_len_bytes - suffix.consumed_len_bytes;
-                for (let j = leavesOffset; j < i; j += 1) {
-                    canonical[ci + j - leavesOffset] = input[j];
-                }
-                siphashOfBytes(canonical.subarray(0, clen), 0, 0, 0, 0, hash);
                 hash[2] &= 0x7f;
             } else {
                 // uncompressed node
                 const dlen = input [i + 1];
                 i += 2;
-                if (dlen === 0) {
+                if (dlen === 0 || is_pure_suffixes_only_node) {
                     data = EMPTY_UINT8;
                 } else {
                     data = new Uint8Array(input.buffer, i + input.byteOffset, dlen);
+                    i += dlen;
                 }
-                i += dlen;
                 const {
                     consumed_len_bytes: branches_consumed_len_bytes,
                     branches,
@@ -2427,13 +2912,19 @@ function loadDatabase(hooks) {
                     i - start,
                 ), 0, 0, 0, 0, hash);
                 hash[2] &= 0x7f;
-                tree = new SearchTree(
-                    branches,
-                    might_have_prefix_branches,
-                    data,
-                    whole,
-                    suffix,
-                );
+                tree = is_pure_suffixes_only_node ?
+                    new SuffixSearchTree(
+                        branches,
+                        dlen,
+                        suffix,
+                    ) :
+                    new PrefixSearchTree(
+                        branches,
+                        might_have_prefix_branches,
+                        data,
+                        whole,
+                        suffix,
+                    );
             }
             hash_history.push({hash: truncatedHash.slice(), used: false});
             if (data.length !== 0) {
@@ -2454,20 +2945,22 @@ function loadDatabase(hooks) {
                 }
                 j += 1;
             }
-            const tree_mhp_branch_nodeids = tree.might_have_prefix_branches.nodeids;
-            const tree_mhp_branch_subtrees = tree.might_have_prefix_branches.subtrees;
-            j = 0;
-            lb = tree.might_have_prefix_branches.subtrees.length;
-            while (j < lb) {
-                // node id with a 1 in its most significant bit is inlined, and, so
-                // it won't be in the stash
-                if ((tree_mhp_branch_nodeids[j * 6] & 0x80) === 0) {
-                    const subtree = stash.getWithOffsetKey(tree_mhp_branch_nodeids, j * 6);
-                    if (subtree !== undefined) {
-                        tree_mhp_branch_subtrees[j] = Promise.resolve(subtree);
+            if (tree instanceof PrefixSearchTree) {
+                const tree_mhp_branch_nodeids = tree.might_have_prefix_branches.nodeids;
+                const tree_mhp_branch_subtrees = tree.might_have_prefix_branches.subtrees;
+                j = 0;
+                lb = tree.might_have_prefix_branches.subtrees.length;
+                while (j < lb) {
+                    // node id with a 1 in its most significant bit is inlined, and, so
+                    // it won't be in the stash
+                    if ((tree_mhp_branch_nodeids[j * 6] & 0x80) === 0) {
+                        const subtree = stash.getWithOffsetKey(tree_mhp_branch_nodeids, j * 6);
+                        if (subtree !== undefined) {
+                            tree_mhp_branch_subtrees[j] = Promise.resolve(subtree);
+                        }
                     }
+                    j += 1;
                 }
-                j += 1;
             }
             if (i !== l) {
                 stash.set(truncatedHash, tree);
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index 16034c11827..471e966e2c2 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -333,14 +333,11 @@ pub(crate) fn run(
 pub(crate) fn load_call_locations(
     with_examples: Vec<String>,
     dcx: DiagCtxtHandle<'_>,
+    loaded_paths: &mut Vec<PathBuf>,
 ) -> AllCallLocations {
     let mut all_calls: AllCallLocations = FxIndexMap::default();
     for path in with_examples {
-        // FIXME: Figure out why this line is causing this feature to crash in specific contexts.
-        // Full issue backlog is available here: <https://github.com/rust-lang/rust/pull/144600>.
-        //
-        // Can be checked with `tests/run-make/rustdoc-scrape-examples-paths`.
-        // loaded_paths.push(path.clone().into());
+        loaded_paths.push(path.clone().into());
         let bytes = match fs::read(&path) {
             Ok(bytes) => bytes,
             Err(e) => dcx.fatal(format!("failed to load examples: {e}")),
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject a6c58d43051d01d83f55a3e61ef5f5b2b0dd6bd
+Subproject 761c4658d0079d607e6d33cf0c060e61a617cad
diff --git a/src/tools/clippy/.cargo/config.toml b/src/tools/clippy/.cargo/config.toml
index d9c635df5dc..a09bf95e87b 100644
--- a/src/tools/clippy/.cargo/config.toml
+++ b/src/tools/clippy/.cargo/config.toml
@@ -23,3 +23,10 @@ split-debuginfo = "unpacked"
 rustflags = ["--remap-path-prefix", "=clippy_dev"]
 [profile.dev.package.lintcheck]
 rustflags = ["--remap-path-prefix", "=lintcheck"]
+
+# quine-mc_cluskey makes up a significant part of the runtime in dogfood
+# due to the number of conditions in the clippy_lints crate
+# and enabling optimizations for that specific dependency helps a bit
+# without increasing total build times.
+[profile.dev.package.quine-mc_cluskey]
+opt-level = 3
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index bc60b1c57f7..eb2a76a8183 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -30,6 +30,8 @@ Current stable, released 2025-08-07
 * Removed superseded lints: `transmute_float_to_int`, `transmute_int_to_char`,
   `transmute_int_to_float`, `transmute_num_to_bytes` (now in rustc)
   [#14703](https://github.com/rust-lang/rust-clippy/pull/14703)
+* Move [`uninlined_format_args`] to `pedantic` (from `style`, now allow-by-default)
+  [#15287](https://github.com/rust-lang/rust-clippy/pull/15287)
 
 ### Enhancements
 
@@ -74,6 +76,9 @@ Current stable, released 2025-08-07
   [#14719](https://github.com/rust-lang/rust-clippy/pull/14719)
 * [`unnecessary_to_owned`] fixed FP when map key is a reference
   [#14834](https://github.com/rust-lang/rust-clippy/pull/14834)
+* [`swap_with_temporary`]: fix false positive leading to different semantics
+  being suggested, and use the right number of dereferences in suggestion
+  [#15172](https://github.com/rust-lang/rust-clippy/pull/15172)
 
 ### ICE Fixes
 
@@ -6707,6 +6712,7 @@ Released 2018-09-13
 [`check-inconsistent-struct-field-initializers`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-inconsistent-struct-field-initializers
 [`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
 [`cognitive-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cognitive-complexity-threshold
+[`const-literal-digits-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#const-literal-digits-threshold
 [`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros
 [`disallowed-methods`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-methods
 [`disallowed-names`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-names
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 05590ff7b1c..c2d080cd96a 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -485,6 +485,16 @@ The maximum cognitive complexity a function can have
 * [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity)
 
 
+## `const-literal-digits-threshold`
+The minimum digits a const float literal must have to supress the `excessive_precicion` lint
+
+**Default Value:** `30`
+
+---
+**Affected lints:**
+* [`excessive_precision`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision)
+
+
 ## `disallowed-macros`
 The list of disallowed macros, written as fully qualified paths.
 
@@ -555,7 +565,7 @@ default configuration of Clippy. By default, any configuration will replace the
 * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
 * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "PowerPC", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "NixOS", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "InfiniBand", "RoCE", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "PowerPC", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "NixOS", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
@@ -873,7 +883,6 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
 * [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics)
 * [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
-* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
 * [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
 * [`question_mark`](https://rust-lang.github.io/rust-clippy/master/index.html#question_mark)
 * [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
@@ -881,7 +890,6 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`repeat_vec_with_capacity`](https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity)
 * [`same_item_push`](https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push)
 * [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
-* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
 * [`to_digit_is_some`](https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some)
 * [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
 * [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
diff --git a/src/tools/clippy/clippy.toml b/src/tools/clippy/clippy.toml
index 77573105d86..d9bcfd17606 100644
--- a/src/tools/clippy/clippy.toml
+++ b/src/tools/clippy/clippy.toml
@@ -6,12 +6,12 @@ lint-commented-code = true
 
 [[disallowed-methods]]
 path = "rustc_lint::context::LintContext::lint"
-reason = "this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead"
+reason = "this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead"
 
 [[disallowed-methods]]
 path = "rustc_lint::context::LintContext::span_lint"
-reason = "this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead"
+reason = "this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead"
 
 [[disallowed-methods]]
 path = "rustc_middle::ty::context::TyCtxt::node_span_lint"
-reason = "this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead"
+reason = "this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead"
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 2ad3f2efcdd..2f28f6175ad 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -33,6 +33,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
     "GPLv2", "GPLv3",
     "GitHub", "GitLab",
     "IPv4", "IPv6",
+    "InfiniBand", "RoCE",
     "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript",
     "PowerPC", "WebAssembly",
     "NaN", "NaNs",
@@ -569,6 +570,9 @@ define_Conf! {
     /// The maximum cognitive complexity a function can have
     #[lints(cognitive_complexity)]
     cognitive_complexity_threshold: u64 = 25,
+    /// The minimum digits a const float literal must have to supress the `excessive_precicion` lint
+    #[lints(excessive_precision)]
+    const_literal_digits_threshold: usize = 30,
     /// DEPRECATED LINT: CYCLOMATIC_COMPLEXITY.
     ///
     /// Use the Cognitive Complexity lint instead.
@@ -775,7 +779,6 @@ define_Conf! {
         needless_borrow,
         non_std_lazy_statics,
         option_as_ref_deref,
-        option_map_unwrap_or,
         ptr_as_ptr,
         question_mark,
         redundant_field_names,
@@ -783,7 +786,6 @@ define_Conf! {
         repeat_vec_with_capacity,
         same_item_push,
         seek_from_current,
-        seek_rewind,
         to_digit_is_some,
         transmute_ptr_to_ref,
         tuple_array_conversions,
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index b9e6de79cc0..70184ee2ca5 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -27,6 +27,10 @@ url = "2.2"
 [dev-dependencies]
 walkdir = "2.3"
 
+[lints.rust.unexpected_cfgs]
+level = "warn"
+check-cfg = ['cfg(bootstrap)']
+
 [package.metadata.rust-analyzer]
 # This crate uses #[feature(rustc_private)]
 rustc_private = true
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
index 6f2a6a36a38..08253b0c499 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
@@ -3,10 +3,10 @@ use clippy_utils::macros::{PanicExpn, find_assert_args, root_macro_call_first_no
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{has_debug_impl, is_copy, is_type_diagnostic_item};
 use clippy_utils::usage::local_used_after_expr;
-use clippy_utils::{is_expr_final_block_expr, path_res, sym};
+use clippy_utils::{path_res, sym};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::declare_lint_pass;
@@ -77,17 +77,20 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates {
                 _ => return,
             };
             span_lint_and_then(cx, ASSERTIONS_ON_RESULT_STATES, macro_call.span, message, |diag| {
-                let semicolon = if is_expr_final_block_expr(cx.tcx, e) { ";" } else { "" };
                 let mut app = Applicability::MachineApplicable;
-                diag.span_suggestion(
-                    macro_call.span,
-                    "replace with",
-                    format!(
-                        "{}.{replacement}(){semicolon}",
-                        snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0
-                    ),
-                    app,
-                );
+                let recv = snippet_with_context(cx, recv.span, condition.span.ctxt(), "..", &mut app).0;
+
+                // `assert!` doesn't return anything, but `Result::unwrap(_err)` does, so we might need to add a
+                // semicolon to the suggestion to avoid leaking the type
+                let sugg = match cx.tcx.parent_hir_node(e.hir_id) {
+                    // trailing expr of a block
+                    Node::Block(..) => format!("{recv}.{replacement}();"),
+                    // already has a trailing semicolon
+                    Node::Stmt(..) => format!("{recv}.{replacement}()"),
+                    // this is the last-resort option, because it's rather verbose
+                    _ => format!("{{ {recv}.{replacement}(); }}"),
+                };
+                diag.span_suggestion(macro_call.span, "replace with", sugg, app);
             });
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/async_yields_async.rs b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
index 013819b0da8..1a10db291cd 100644
--- a/src/tools/clippy/clippy_lints/src/async_yields_async.rs
+++ b/src/tools/clippy/clippy_lints/src/async_yields_async.rs
@@ -1,8 +1,12 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
-use clippy_utils::source::snippet;
+use clippy_utils::is_expr_async_block;
+use clippy_utils::source::walk_span_to_context;
+use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::implements_trait;
 use rustc_errors::Applicability;
-use rustc_hir::{Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, QPath};
+use rustc_hir::{
+    Block, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, QPath,
+};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
@@ -87,31 +91,37 @@ impl<'tcx> LateLintPass<'tcx> for AsyncYieldsAsync {
         let expr_ty = typeck_results.expr_ty(body_expr);
 
         if implements_trait(cx, expr_ty, future_trait_def_id, &[]) {
-            let return_expr_span = match &body_expr.kind {
-                // XXXkhuey there has to be a better way.
-                ExprKind::Block(block, _) => block.expr.map(|e| e.span),
-                ExprKind::Path(QPath::Resolved(_, path)) => Some(path.span),
-                _ => None,
+            let (return_expr, return_expr_span) = match &body_expr.kind {
+                ExprKind::Block(Block { expr: Some(e), .. }, _) => (*e, e.span),
+                ExprKind::Path(QPath::Resolved(_, path)) => (body_expr, path.span),
+                _ => return,
             };
-            if let Some(return_expr_span) = return_expr_span {
-                span_lint_hir_and_then(
-                    cx,
-                    ASYNC_YIELDS_ASYNC,
-                    body_expr.hir_id,
-                    return_expr_span,
-                    "an async construct yields a type which is itself awaitable",
-                    |db| {
-                        db.span_label(body_expr.span, "outer async construct");
-                        db.span_label(return_expr_span, "awaitable value not awaited");
-                        db.span_suggestion(
-                            return_expr_span,
-                            "consider awaiting this value",
-                            format!("{}.await", snippet(cx, return_expr_span, "..")),
-                            Applicability::MaybeIncorrect,
-                        );
-                    },
-                );
+
+            let return_expr_span = walk_span_to_context(return_expr_span, expr.span.ctxt()).unwrap_or(return_expr_span);
+            let mut applicability = Applicability::MaybeIncorrect;
+            let mut return_expr_snip =
+                Sugg::hir_with_context(cx, return_expr, expr.span.ctxt(), "..", &mut applicability);
+            if !is_expr_async_block(return_expr) {
+                return_expr_snip = return_expr_snip.maybe_paren();
             }
+
+            span_lint_hir_and_then(
+                cx,
+                ASYNC_YIELDS_ASYNC,
+                body_expr.hir_id,
+                return_expr_span,
+                "an async construct yields a type which is itself awaitable",
+                |db| {
+                    db.span_label(body_expr.span, "outer async construct");
+                    db.span_label(return_expr_span, "awaitable value not awaited");
+                    db.span_suggestion(
+                        return_expr_span,
+                        "consider awaiting this value",
+                        format!("{return_expr_snip}.await"),
+                        applicability,
+                    );
+                },
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/bool_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_comparison.rs
new file mode 100644
index 00000000000..722095909a6
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/bool_comparison.rs
@@ -0,0 +1,179 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{is_expn_of, peel_blocks, sym};
+use rustc_ast::ast::LitKind;
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::declare_lint_pass;
+use rustc_span::Span;
+use rustc_span::source_map::Spanned;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for expressions of the form `x == true`,
+    /// `x != true` and order comparisons such as `x < true` (or vice versa) and
+    /// suggest using the variable directly.
+    ///
+    /// ### Why is this bad?
+    /// Unnecessary code.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// if x == true {}
+    /// if y == false {}
+    /// ```
+    /// use `x` directly:
+    /// ```rust,ignore
+    /// if x {}
+    /// if !y {}
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub BOOL_COMPARISON,
+    complexity,
+    "comparing a variable to a boolean, e.g., `if x == true` or `if x != true`"
+}
+
+declare_lint_pass!(BoolComparison => [BOOL_COMPARISON]);
+
+impl<'tcx> LateLintPass<'tcx> for BoolComparison {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
+        if e.span.from_expansion() {
+            return;
+        }
+
+        if let ExprKind::Binary(Spanned { node, .. }, left_side, right_side) = e.kind
+            && is_expn_of(left_side.span, sym::cfg).is_none()
+            && is_expn_of(right_side.span, sym::cfg).is_none()
+            && cx.typeck_results().expr_ty(left_side).is_bool()
+            && cx.typeck_results().expr_ty(right_side).is_bool()
+        {
+            let ignore_case = None::<(fn(_) -> _, &str)>;
+            let ignore_no_literal = None::<(fn(_, _) -> _, &str)>;
+            match node {
+                BinOpKind::Eq => {
+                    let true_case = Some((|h| h, "equality checks against true are unnecessary"));
+                    let false_case = Some((
+                        |h: Sugg<'tcx>| !h,
+                        "equality checks against false can be replaced by a negation",
+                    ));
+                    check_comparison(cx, e, true_case, false_case, true_case, false_case, ignore_no_literal);
+                },
+                BinOpKind::Ne => {
+                    let true_case = Some((
+                        |h: Sugg<'tcx>| !h,
+                        "inequality checks against true can be replaced by a negation",
+                    ));
+                    let false_case = Some((|h| h, "inequality checks against false are unnecessary"));
+                    check_comparison(cx, e, true_case, false_case, true_case, false_case, ignore_no_literal);
+                },
+                BinOpKind::Lt => check_comparison(
+                    cx,
+                    e,
+                    ignore_case,
+                    Some((|h| h, "greater than checks against false are unnecessary")),
+                    Some((
+                        |h: Sugg<'tcx>| !h,
+                        "less than comparison against true can be replaced by a negation",
+                    )),
+                    ignore_case,
+                    Some((
+                        |l: Sugg<'tcx>, r: Sugg<'tcx>| (!l).bit_and(&r),
+                        "order comparisons between booleans can be simplified",
+                    )),
+                ),
+                BinOpKind::Gt => check_comparison(
+                    cx,
+                    e,
+                    Some((
+                        |h: Sugg<'tcx>| !h,
+                        "less than comparison against true can be replaced by a negation",
+                    )),
+                    ignore_case,
+                    ignore_case,
+                    Some((|h| h, "greater than checks against false are unnecessary")),
+                    Some((
+                        |l: Sugg<'tcx>, r: Sugg<'tcx>| l.bit_and(&(!r)),
+                        "order comparisons between booleans can be simplified",
+                    )),
+                ),
+                _ => (),
+            }
+        }
+    }
+}
+
+fn check_comparison<'a, 'tcx>(
+    cx: &LateContext<'tcx>,
+    e: &'tcx Expr<'_>,
+    left_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    left_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    right_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    right_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    no_literal: Option<(impl FnOnce(Sugg<'a>, Sugg<'a>) -> Sugg<'a>, &'static str)>,
+) {
+    if let ExprKind::Binary(_, left_side, right_side) = e.kind {
+        let mut applicability = Applicability::MachineApplicable;
+        // Eliminate parentheses in `e` by using the lo pos of lhs and hi pos of rhs,
+        // calling `source_callsite` make sure macros are handled correctly, see issue #9907
+        let binop_span = left_side.span.source_callsite().to(right_side.span.source_callsite());
+
+        match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
+            (Some(true), None) => left_true.map_or((), |(h, m)| {
+                suggest_bool_comparison(cx, binop_span, right_side, applicability, m, h);
+            }),
+            (None, Some(true)) => right_true.map_or((), |(h, m)| {
+                suggest_bool_comparison(cx, binop_span, left_side, applicability, m, h);
+            }),
+            (Some(false), None) => left_false.map_or((), |(h, m)| {
+                suggest_bool_comparison(cx, binop_span, right_side, applicability, m, h);
+            }),
+            (None, Some(false)) => right_false.map_or((), |(h, m)| {
+                suggest_bool_comparison(cx, binop_span, left_side, applicability, m, h);
+            }),
+            (None, None) => no_literal.map_or((), |(h, m)| {
+                let left_side = Sugg::hir_with_context(cx, left_side, binop_span.ctxt(), "..", &mut applicability);
+                let right_side = Sugg::hir_with_context(cx, right_side, binop_span.ctxt(), "..", &mut applicability);
+                span_lint_and_sugg(
+                    cx,
+                    BOOL_COMPARISON,
+                    binop_span,
+                    m,
+                    "try",
+                    h(left_side, right_side).into_string(),
+                    applicability,
+                );
+            }),
+            _ => (),
+        }
+    }
+}
+
+fn suggest_bool_comparison<'a, 'tcx>(
+    cx: &LateContext<'tcx>,
+    span: Span,
+    expr: &Expr<'_>,
+    mut app: Applicability,
+    message: &'static str,
+    conv_hint: impl FnOnce(Sugg<'a>) -> Sugg<'a>,
+) {
+    let hint = Sugg::hir_with_context(cx, expr, span.ctxt(), "..", &mut app);
+    span_lint_and_sugg(
+        cx,
+        BOOL_COMPARISON,
+        span,
+        message,
+        "try",
+        conv_hint(hint).into_string(),
+        app,
+    );
+}
+
+fn fetch_bool_expr(expr: &Expr<'_>) -> Option<bool> {
+    if let ExprKind::Lit(lit_ptr) = peel_blocks(expr).kind
+        && let LitKind::Bool(value) = lit_ptr.node
+    {
+        return Some(value);
+    }
+    None
+}
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index a1543cabd2f..d78da9396fa 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -8,17 +8,12 @@ use rustc_middle::ty::{self, Ty};
 
 use super::CAST_PTR_ALIGNMENT;
 
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
-    if let ExprKind::Cast(cast_expr, cast_to) = expr.kind {
-        if is_hir_ty_cfg_dependant(cx, cast_to) {
-            return;
-        }
-        let (cast_from, cast_to) = (
-            cx.typeck_results().expr_ty(cast_expr),
-            cx.typeck_results().expr_ty(expr),
-        );
-        lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
-    } else if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) {
+    lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
+}
+
+pub(super) fn check_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>) {
+    if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind
         && method_path.ident.name == sym::cast
         && let Some(generic_args) = method_path.args
         && let [GenericArg::Type(cast_to)] = generic_args.args
@@ -74,14 +69,13 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
         ExprKind::Call(func, [arg, ..]) if arg.hir_id == e.hir_id => {
             if let ExprKind::Path(path) = &func.kind
                 && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
+                && let Some(name) = cx.tcx.get_diagnostic_name(def_id)
                 && matches!(
-                    cx.tcx.get_diagnostic_name(def_id),
-                    Some(
-                        sym::ptr_write_unaligned
-                            | sym::ptr_read_unaligned
-                            | sym::intrinsics_unaligned_volatile_load
-                            | sym::intrinsics_unaligned_volatile_store
-                    )
+                    name,
+                    sym::ptr_write_unaligned
+                        | sym::ptr_read_unaligned
+                        | sym::intrinsics_unaligned_volatile_load
+                        | sym::intrinsics_unaligned_volatile_store
                 )
             {
                 true
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
index 46b0c88d3fe..bce7b4c69cc 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
@@ -1,10 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
+use clippy_utils::{get_parent_expr, is_no_std_crate};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
+use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc_middle::ty::{self, Ty};
 use rustc_span::sym;
 
@@ -42,13 +44,52 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
         let mut applicability = Applicability::MachineApplicable;
         let ptr = snippet_with_context(cx, ptr_arg.span, ctxt, "ptr", &mut applicability).0;
         let len = snippet_with_context(cx, len_arg.span, ctxt, "len", &mut applicability).0;
+        let krate = if is_no_std_crate(cx) { "core" } else { "std" };
         span_lint_and_sugg(
             cx,
             CAST_SLICE_FROM_RAW_PARTS,
             span,
             format!("casting the result of `{func}` to {cast_to}"),
             "replace with",
-            format!("core::ptr::slice_{func}({ptr}, {len})"),
+            format!("{krate}::ptr::slice_{func}({ptr}, {len})"),
+            applicability,
+        );
+    }
+}
+
+/// Checks for implicit cast from slice reference to raw slice pointer.
+pub(super) fn check_implicit_cast(cx: &LateContext<'_>, expr: &Expr<'_>) {
+    if let ExprKind::Call(fun, [ptr_arg, len_arg]) = expr.peel_blocks().kind
+        && let ExprKind::Path(ref qpath) = fun.kind
+        && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
+        && let Some(rpk) = raw_parts_kind(cx, fun_def_id)
+        && !matches!(get_parent_expr(cx, expr).map(|e| e.kind), Some(ExprKind::Cast(..)))
+        && let [deref, borrow] = cx.typeck_results().expr_adjustments(expr)
+        && matches!(deref.kind, Adjust::Deref(..))
+        && let Adjustment {
+            kind: Adjust::Borrow(AutoBorrow::RawPtr(..)),
+            target,
+        } = borrow
+        && let ty::RawPtr(pointee_ty, _) = target.kind()
+        && pointee_ty.is_slice()
+        && !expr.span.from_expansion()
+    {
+        let func = match rpk {
+            RawPartsKind::Immutable => "from_raw_parts",
+            RawPartsKind::Mutable => "from_raw_parts_mut",
+        };
+        let mut applicability = Applicability::MachineApplicable;
+        let ctxt = expr.span.ctxt();
+        let ptr = snippet_with_context(cx, ptr_arg.span, ctxt, "ptr", &mut applicability).0;
+        let len = snippet_with_context(cx, len_arg.span, ctxt, "len", &mut applicability).0;
+        let krate = if is_no_std_crate(cx) { "core" } else { "std" };
+        span_lint_and_sugg(
+            cx,
+            CAST_SLICE_FROM_RAW_PARTS,
+            expr.span,
+            format!("implicitly casting the result of `{func}` to `{target}`"),
+            "replace_with",
+            format!("{krate}::ptr::slice_{func}({ptr}, {len})"),
             applicability,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index e25df9dd249..d2e62ee56e4 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -873,7 +873,9 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             }
             char_lit_as_u8::check(cx, expr, cast_from_expr, cast_to);
             cast_slice_from_raw_parts::check(cx, expr, cast_from_expr, cast_to, self.msrv);
+            cast_ptr_alignment::check(cx, expr, cast_from, cast_to);
             ptr_cast_constness::check(cx, expr, cast_from_expr, cast_from, cast_to, self.msrv);
+            ptr_as_ptr::check(cx, expr, cast_from_expr, cast_from, cast_to_hir, cast_to, self.msrv);
             as_ptr_cast_mut::check(cx, expr, cast_from_expr, cast_to);
             fn_to_numeric_cast_any::check(cx, expr, cast_from_expr, cast_from, cast_to);
             confusing_method_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
@@ -911,8 +913,10 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
         if self.msrv.meets(cx, msrvs::RAW_REF_OP) {
             borrow_as_ptr::check_implicit_cast(cx, expr);
         }
-        cast_ptr_alignment::check(cx, expr);
-        ptr_as_ptr::check(cx, expr, self.msrv);
+        if self.msrv.meets(cx, msrvs::PTR_SLICE_RAW_PARTS) {
+            cast_slice_from_raw_parts::check_implicit_cast(cx, expr);
+        }
+        cast_ptr_alignment::check_cast_method(cx, expr);
         cast_slice_different_sizes::check(cx, expr, self.msrv);
         ptr_cast_constness::check_null_ptr_cast_method(cx, expr);
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index 89075409098..d012380cb76 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -4,9 +4,9 @@ use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Mutability, QPath, TyKind};
+use rustc_hir::{self as hir, Expr, ExprKind, QPath, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty;
+use rustc_middle::ty::{self, Ty};
 use rustc_span::{Span, sym};
 
 use super::PTR_AS_PTR;
@@ -26,13 +26,18 @@ impl OmitFollowedCastReason<'_> {
     }
 }
 
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Msrv) {
-    if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind
-        && let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr))
-        && let ty::RawPtr(_, from_mutbl) = cast_from.kind()
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &Expr<'tcx>,
+    cast_from_expr: &Expr<'_>,
+    cast_from: Ty<'_>,
+    cast_to_hir: &hir::Ty<'_>,
+    cast_to: Ty<'tcx>,
+    msrv: Msrv,
+) {
+    if let ty::RawPtr(_, from_mutbl) = cast_from.kind()
         && let ty::RawPtr(to_pointee_ty, to_mutbl) = cast_to.kind()
-        && matches!((from_mutbl, to_mutbl),
-            (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut))
+        && from_mutbl == to_mutbl
         // The `U` in `pointer::cast` have to be `Sized`
         // as explained here: https://github.com/rust-lang/rust/issues/60602.
         && to_pointee_ty.is_sized(cx.tcx, cx.typing_env())
@@ -40,7 +45,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Msrv)
         && !is_from_proc_macro(cx, expr)
     {
         let mut app = Applicability::MachineApplicable;
-        let turbofish = match &cast_to_hir_ty.kind {
+        let turbofish = match &cast_to_hir.kind {
             TyKind::Infer(()) => String::new(),
             TyKind::Ptr(mut_ty) => {
                 if matches!(mut_ty.ty.kind, TyKind::Infer(())) {
@@ -58,16 +63,14 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Msrv)
         // following `cast` does not compile because it fails to infer what type is expected
         // as type argument to `std::ptr::ptr_null` or `std::ptr::ptr_null_mut`, so
         // we omit following `cast`:
-        let omit_cast = if let ExprKind::Call(func, []) = cast_expr.kind
+        let omit_cast = if let ExprKind::Call(func, []) = cast_from_expr.kind
             && let ExprKind::Path(ref qpath @ QPath::Resolved(None, path)) = func.kind
             && let Some(method_defid) = path.res.opt_def_id()
         {
-            if cx.tcx.is_diagnostic_item(sym::ptr_null, method_defid) {
-                OmitFollowedCastReason::Null(qpath)
-            } else if cx.tcx.is_diagnostic_item(sym::ptr_null_mut, method_defid) {
-                OmitFollowedCastReason::NullMut(qpath)
-            } else {
-                OmitFollowedCastReason::None
+            match cx.tcx.get_diagnostic_name(method_defid) {
+                Some(sym::ptr_null) => OmitFollowedCastReason::Null(qpath),
+                Some(sym::ptr_null_mut) => OmitFollowedCastReason::NullMut(qpath),
+                _ => OmitFollowedCastReason::None,
             }
         } else {
             OmitFollowedCastReason::None
@@ -78,7 +81,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Msrv)
             let method = snippet_with_applicability(cx, qpath_span_without_turbofish(method), "..", &mut app);
             ("try call directly", format!("{method}{turbofish}()"))
         } else {
-            let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
+            let cast_expr_sugg = Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), "_", &mut app);
 
             (
                 "try `pointer::cast`, a safer alternative",
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
index c0c0a47f855..c0f13f5e578 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
@@ -1,9 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{std_or_core, sym};
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Mutability, QPath};
+use rustc_hir::{self as hir, Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 
@@ -12,26 +13,23 @@ use super::PTR_CAST_CONSTNESS;
 pub(super) fn check<'tcx>(
     cx: &LateContext<'_>,
     expr: &Expr<'_>,
-    cast_expr: &Expr<'_>,
+    cast_from_expr: &Expr<'_>,
     cast_from: Ty<'tcx>,
     cast_to: Ty<'tcx>,
     msrv: Msrv,
 ) {
     if let ty::RawPtr(from_ty, from_mutbl) = cast_from.kind()
         && let ty::RawPtr(to_ty, to_mutbl) = cast_to.kind()
-        && matches!(
-            (from_mutbl, to_mutbl),
-            (Mutability::Not, Mutability::Mut) | (Mutability::Mut, Mutability::Not)
-        )
+        && from_mutbl != to_mutbl
         && from_ty == to_ty
         && !from_ty.has_erased_regions()
     {
-        if let ExprKind::Call(func, []) = cast_expr.kind
+        if let ExprKind::Call(func, []) = cast_from_expr.kind
             && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
             && let Some(defid) = path.res.opt_def_id()
             && let Some(prefix) = std_or_core(cx)
             && let mut app = Applicability::MachineApplicable
-            && let sugg = format!("{}", Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app))
+            && let sugg = snippet_with_applicability(cx, cast_from_expr.span, "_", &mut app)
             && let Some((_, after_lt)) = sugg.split_once("::<")
             && let Some((source, target, target_func)) = match cx.tcx.get_diagnostic_name(defid) {
                 Some(sym::ptr_null) => Some(("const", "mutable", "null_mut")),
@@ -53,11 +51,17 @@ pub(super) fn check<'tcx>(
 
         if msrv.meets(cx, msrvs::POINTER_CAST_CONSTNESS) {
             let mut app = Applicability::MachineApplicable;
-            let sugg = Sugg::hir_with_context(cx, cast_expr, expr.span.ctxt(), "_", &mut app);
-            let constness = match *to_mutbl {
-                Mutability::Not => "const",
-                Mutability::Mut => "mut",
+            let sugg = if let ExprKind::Cast(nested_from, nested_hir_ty) = cast_from_expr.kind
+                && let hir::TyKind::Ptr(ptr_ty) = nested_hir_ty.kind
+                && let hir::TyKind::Infer(()) = ptr_ty.ty.kind
+            {
+                // `(foo as *const _).cast_mut()` fails method name resolution
+                // avoid this by `as`-ing the full type
+                Sugg::hir_with_context(cx, nested_from, expr.span.ctxt(), "_", &mut app).as_ty(cast_from)
+            } else {
+                Sugg::hir_with_context(cx, cast_from_expr, expr.span.ctxt(), "_", &mut app)
             };
+            let constness = to_mutbl.ptr_str();
 
             span_lint_and_sugg(
                 cx,
@@ -73,8 +77,8 @@ pub(super) fn check<'tcx>(
 }
 
 pub(super) fn check_null_ptr_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>) {
-    if let ExprKind::MethodCall(method, cast_expr, [], _) = expr.kind
-        && let ExprKind::Call(func, []) = cast_expr.kind
+    if let ExprKind::MethodCall(method, cast_from_expr, [], _) = expr.kind
+        && let ExprKind::Call(func, []) = cast_from_expr.kind
         && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
         && let Some(defid) = path.res.opt_def_id()
         && let method = match (cx.tcx.get_diagnostic_name(defid), method.ident.name) {
@@ -84,7 +88,7 @@ pub(super) fn check_null_ptr_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>)
         }
         && let Some(prefix) = std_or_core(cx)
         && let mut app = Applicability::MachineApplicable
-        && let sugg = format!("{}", Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app))
+        && let sugg = snippet_with_applicability(cx, cast_from_expr.span, "_", &mut app)
         && let Some((_, after_lt)) = sugg.split_once("::<")
     {
         span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 8f95c63a854..7646aa48b77 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -23,8 +23,8 @@ declare_clippy_lint! {
     ///
     /// ### Known problems
     /// 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
+    /// calculate using modern technology. This lint has been left in
+    /// `restriction` so as to not mislead users into using this lint as a
     /// measurement tool.
     ///
     /// For more detailed information, see [rust-clippy#3793](https://github.com/rust-lang/rust-clippy/issues/3793)
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index e67e8d9070f..d0c7443a4a4 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -35,6 +35,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
     crate::await_holding_invalid::AWAIT_HOLDING_REFCELL_REF_INFO,
     crate::blocks_in_conditions::BLOCKS_IN_CONDITIONS_INFO,
     crate::bool_assert_comparison::BOOL_ASSERT_COMPARISON_INFO,
+    crate::bool_comparison::BOOL_COMPARISON_INFO,
     crate::bool_to_int_with_if::BOOL_TO_INT_WITH_IF_INFO,
     crate::booleans::NONMINIMAL_BOOL_INFO,
     crate::booleans::OVERLY_COMPLEX_BOOL_EXPR_INFO,
@@ -538,7 +539,6 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
     crate::mutex_atomic::MUTEX_ATOMIC_INFO,
     crate::mutex_atomic::MUTEX_INTEGER_INFO,
     crate::needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE_INFO,
-    crate::needless_bool::BOOL_COMPARISON_INFO,
     crate::needless_bool::NEEDLESS_BOOL_INFO,
     crate::needless_bool::NEEDLESS_BOOL_ASSIGN_INFO,
     crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 7580d6cab66..06c2393e0a3 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -10,7 +10,7 @@ use rustc_hir::{
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
-use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty, TypeckResults};
+use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty, TypeckResults, VariantDef};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
 
@@ -85,6 +85,13 @@ fn contains_trait_object(ty: Ty<'_>) -> bool {
     }
 }
 
+fn determine_derive_macro(cx: &LateContext<'_>, is_const: bool) -> Option<&'static str> {
+    (!is_const)
+        .then_some("derive")
+        .or_else(|| cx.tcx.features().enabled(sym::derive_const).then_some("derive_const"))
+}
+
+#[expect(clippy::too_many_arguments)]
 fn check_struct<'tcx>(
     cx: &LateContext<'tcx>,
     item: &'tcx Item<'_>,
@@ -93,6 +100,7 @@ fn check_struct<'tcx>(
     adt_def: AdtDef<'_>,
     ty_args: GenericArgsRef<'_>,
     typeck_results: &'tcx TypeckResults<'tcx>,
+    is_const: bool,
 ) {
     if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind
         && let Some(PathSegment { args, .. }) = p.segments.last()
@@ -125,14 +133,18 @@ fn check_struct<'tcx>(
         ExprKind::Tup(fields) => fields.iter().all(is_default_without_adjusts),
         ExprKind::Call(callee, args) if is_path_self(callee) => args.iter().all(is_default_without_adjusts),
         ExprKind::Struct(_, fields, _) => fields.iter().all(|ef| is_default_without_adjusts(ef.expr)),
-        _ => false,
+        _ => return,
     };
 
-    if should_emit {
+    if should_emit && let Some(derive_snippet) = determine_derive_macro(cx, is_const) {
         let struct_span = cx.tcx.def_span(adt_def.did());
+        let indent_enum = indent_of(cx, struct_span).unwrap_or(0);
         let suggestions = vec![
             (item.span, String::new()), // Remove the manual implementation
-            (struct_span.shrink_to_lo(), "#[derive(Default)]\n".to_string()), // Add the derive attribute
+            (
+                struct_span.shrink_to_lo(),
+                format!("#[{derive_snippet}(Default)]\n{}", " ".repeat(indent_enum)),
+            ), // Add the derive attribute
         ];
 
         span_lint_and_then(cx, DERIVABLE_IMPLS, item.span, "this `impl` can be derived", |diag| {
@@ -145,11 +157,41 @@ fn check_struct<'tcx>(
     }
 }
 
-fn check_enum<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>, func_expr: &Expr<'_>, adt_def: AdtDef<'_>) {
-    if let ExprKind::Path(QPath::Resolved(None, p)) = &peel_blocks(func_expr).kind
-        && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), id) = p.res
-        && let variant_id = cx.tcx.parent(id)
-        && let Some(variant_def) = adt_def.variants().iter().find(|v| v.def_id == variant_id)
+fn extract_enum_variant<'tcx>(
+    cx: &LateContext<'tcx>,
+    func_expr: &'tcx Expr<'tcx>,
+    adt_def: AdtDef<'tcx>,
+) -> Option<&'tcx VariantDef> {
+    match &peel_blocks(func_expr).kind {
+        ExprKind::Path(QPath::Resolved(None, p))
+            if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), id) = p.res
+                && let variant_id = cx.tcx.parent(id)
+                && let Some(variant_def) = adt_def.variants().iter().find(|v| v.def_id == variant_id) =>
+        {
+            Some(variant_def)
+        },
+        ExprKind::Path(QPath::TypeRelative(ty, segment))
+            if let TyKind::Path(QPath::Resolved(None, p)) = &ty.kind
+                && let Res::SelfTyAlias {
+                    is_trait_impl: true, ..
+                } = p.res
+                && let variant_ident = segment.ident
+                && let Some(variant_def) = adt_def.variants().iter().find(|v| v.ident(cx.tcx) == variant_ident) =>
+        {
+            Some(variant_def)
+        },
+        _ => None,
+    }
+}
+
+fn check_enum<'tcx>(
+    cx: &LateContext<'tcx>,
+    item: &'tcx Item<'tcx>,
+    func_expr: &'tcx Expr<'tcx>,
+    adt_def: AdtDef<'tcx>,
+    is_const: bool,
+) {
+    if let Some(variant_def) = extract_enum_variant(cx, func_expr, adt_def)
         && variant_def.fields.is_empty()
         && !variant_def.is_field_list_non_exhaustive()
     {
@@ -158,11 +200,15 @@ fn check_enum<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>, func_expr: &Ex
         let variant_span = cx.tcx.def_span(variant_def.def_id);
         let indent_variant = indent_of(cx, variant_span).unwrap_or(0);
 
+        let Some(derive_snippet) = determine_derive_macro(cx, is_const) else {
+            return;
+        };
+
         let suggestions = vec![
             (item.span, String::new()), // Remove the manual implementation
             (
                 enum_span.shrink_to_lo(),
-                format!("#[derive(Default)]\n{}", " ".repeat(indent_enum)),
+                format!("#[{derive_snippet}(Default)]\n{}", " ".repeat(indent_enum)),
             ), // Add the derive attribute
             (
                 variant_span.shrink_to_lo(),
@@ -201,10 +247,20 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
             && !attrs.iter().any(|attr| attr.doc_str().is_some())
             && cx.tcx.hir_attrs(impl_item_hir).is_empty()
         {
+            let is_const = of_trait.constness == hir::Constness::Const;
             if adt_def.is_struct() {
-                check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b));
+                check_struct(
+                    cx,
+                    item,
+                    self_ty,
+                    func_expr,
+                    adt_def,
+                    args,
+                    cx.tcx.typeck_body(*b),
+                    is_const,
+                );
             } else if adt_def.is_enum() && self.msrv.meets(cx, msrvs::DEFAULT_ENUM_ATTRIBUTE) {
-                check_enum(cx, item, func_expr, adt_def);
+                check_enum(cx, item, func_expr, adt_def, is_const);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index 182cb4e46d2..a5ec6777b43 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -1,4 +1,4 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context};
 use clippy_utils::ty::is_copy;
 use clippy_utils::visitors::for_each_expr;
@@ -194,7 +194,17 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass {
         if let Some(sugg) = sugg {
             span_lint_and_sugg(cx, MAP_ENTRY, expr.span, lint_msg, "try", sugg, app);
         } else {
-            span_lint(cx, MAP_ENTRY, expr.span, lint_msg);
+            span_lint_and_help(
+                cx,
+                MAP_ENTRY,
+                expr.span,
+                lint_msg,
+                None,
+                format!(
+                    "consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.{}.html#entry-api",
+                    map_ty.name()
+                ),
+            );
         }
     }
 }
@@ -254,35 +264,28 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
         _ => None,
     });
 
-    match expr.kind {
-        ExprKind::MethodCall(
-            _,
+    if let ExprKind::MethodCall(_, map, [arg], _) = expr.kind
+        && let Expr {
+            kind: ExprKind::AddrOf(_, _, key),
+            span: key_span,
+            ..
+        } = arg
+        && key_span.eq_ctxt(expr.span)
+    {
+        let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
+        let expr = ContainsExpr {
+            negated,
             map,
-            [
-                Expr {
-                    kind: ExprKind::AddrOf(_, _, key),
-                    span: key_span,
-                    ..
-                },
-            ],
-            _,
-        ) if key_span.eq_ctxt(expr.span) => {
-            let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
-            let expr = ContainsExpr {
-                negated,
-                map,
-                key,
-                call_ctxt: expr.span.ctxt(),
-            };
-            if cx.tcx.is_diagnostic_item(sym::btreemap_contains_key, id) {
-                Some((MapType::BTree, expr))
-            } else if cx.tcx.is_diagnostic_item(sym::hashmap_contains_key, id) {
-                Some((MapType::Hash, expr))
-            } else {
-                None
-            }
-        },
-        _ => None,
+            key,
+            call_ctxt: expr.span.ctxt(),
+        };
+        match cx.tcx.get_diagnostic_name(id) {
+            Some(sym::btreemap_contains_key) => Some((MapType::BTree, expr)),
+            Some(sym::hashmap_contains_key) => Some((MapType::Hash, expr)),
+            _ => None,
+        }
+    } else {
+        None
     }
 }
 
@@ -311,7 +314,9 @@ struct InsertExpr<'tcx> {
 fn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {
     if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {
         let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
-        if cx.tcx.is_diagnostic_item(sym::btreemap_insert, id) || cx.tcx.is_diagnostic_item(sym::hashmap_insert, id) {
+        if let Some(insert) = cx.tcx.get_diagnostic_name(id)
+            && matches!(insert, sym::btreemap_insert | sym::hashmap_insert)
+        {
             Some(InsertExpr { map, key, value })
         } else {
             None
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 0eefc2f6109..2da1c2bad11 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -12,6 +12,7 @@ use rustc_hir::attrs::AttributeKind;
 use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind, find_attr};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{
     self, Binder, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, Ty, TypeVisitableExt, TypeckResults,
 };
@@ -148,10 +149,9 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
             {
                 return;
             }
-            let callee_ty_adjusted = typeck
-                .expr_adjustments(callee)
-                .last()
-                .map_or(callee_ty, |a| a.target.peel_refs());
+
+            let callee_ty_adjustments = typeck.expr_adjustments(callee);
+            let callee_ty_adjusted = callee_ty_adjustments.last().map_or(callee_ty, |a| a.target);
 
             let sig = match callee_ty_adjusted.kind() {
                 ty::FnDef(def, _) => {
@@ -230,7 +230,20 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
                                     },
                                     _ => (),
                                 }
+                            } else if let n_refs =
+                                callee_ty_adjustments
+                                    .iter()
+                                    .rev()
+                                    .fold(0, |acc, adjustment| match adjustment.kind {
+                                        Adjust::Deref(Some(_)) => acc + 1,
+                                        Adjust::Deref(_) if acc > 0 => acc + 1,
+                                        _ => acc,
+                                    })
+                                && n_refs > 0
+                            {
+                                snippet = format!("{}{snippet}", "*".repeat(n_refs));
                             }
+
                             let replace_with = match callee_ty_adjusted.kind() {
                                 ty::FnDef(def, _) => cx.tcx.def_descr(*def),
                                 _ => "function",
diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs
index ccaf38aee4d..6178addfff1 100644
--- a/src/tools/clippy/clippy_lints/src/float_literal.rs
+++ b/src/tools/clippy/clippy_lints/src/float_literal.rs
@@ -1,11 +1,12 @@
+use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::numeric_literal;
+use clippy_utils::{ExprUseNode, expr_use_ctxt, numeric_literal};
 use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, FloatTy};
-use rustc_session::declare_lint_pass;
+use rustc_session::impl_lint_pass;
 use std::fmt;
 
 declare_clippy_lint! {
@@ -13,6 +14,8 @@ declare_clippy_lint! {
     /// Checks for float literals with a precision greater
     /// than that supported by the underlying type.
     ///
+    /// The lint is suppressed for literals with over `const_literal_digits_threshold` digits.
+    ///
     /// ### Why is this bad?
     /// Rust will truncate the literal silently.
     ///
@@ -58,7 +61,21 @@ declare_clippy_lint! {
     "lossy whole number float literals"
 }
 
-declare_lint_pass!(FloatLiteral => [EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL]);
+pub struct FloatLiteral {
+    const_literal_digits_threshold: usize,
+}
+
+impl_lint_pass!(FloatLiteral => [
+    EXCESSIVE_PRECISION, LOSSY_FLOAT_LITERAL
+]);
+
+impl FloatLiteral {
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            const_literal_digits_threshold: conf.const_literal_digits_threshold,
+        }
+    }
+}
 
 impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
@@ -126,13 +143,25 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
                         },
                     );
                 }
-            } else if digits > max as usize && count_digits(&float_str) < count_digits(sym_str) {
+            } else if digits > max as usize && count_digits(&float_str) < digits {
+                if digits >= self.const_literal_digits_threshold
+                    && matches!(expr_use_ctxt(cx, expr).use_node(cx), ExprUseNode::ConstStatic(_))
+                {
+                    // If a big enough number of digits is specified and it's a constant
+                    // we assume the user is definining a constant, and excessive precision is ok
+                    return;
+                }
                 span_lint_and_then(
                     cx,
                     EXCESSIVE_PRECISION,
                     expr.span,
                     "float has excessive precision",
                     |diag| {
+                        if digits >= self.const_literal_digits_threshold
+                            && let Some(let_stmt) = maybe_let_stmt(cx, expr)
+                        {
+                            diag.span_note(let_stmt.span, "consider making it a `const` item");
+                        }
                         diag.span_suggestion_verbose(
                             expr.span,
                             "consider changing the type or truncating it to",
@@ -196,3 +225,11 @@ impl FloatFormat {
         }
     }
 }
+
+fn maybe_let_stmt<'a>(cx: &LateContext<'a>, expr: &hir::Expr<'_>) -> Option<&'a hir::LetStmt<'a>> {
+    let parent = cx.tcx.parent_hir_node(expr.hir_id);
+    match parent {
+        hir::Node::LetStmt(let_stmt) => Some(let_stmt),
+        _ => None,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs
index ca5ea901814..5a40af42194 100644
--- a/src/tools/clippy/clippy_lints/src/functions/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs
@@ -535,7 +535,7 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
         def_id: LocalDefId,
     ) {
         let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
-        too_many_arguments::check_fn(cx, kind, decl, span, hir_id, self.too_many_arguments_threshold);
+        too_many_arguments::check_fn(cx, kind, decl, hir_id, def_id, self.too_many_arguments_threshold);
         too_many_lines::check_fn(cx, kind, body, span, def_id, self.too_many_lines_threshold);
         not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, def_id);
         misnamed_getters::check_fn(cx, kind, decl, body, span);
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
index 48d050aa36a..6c3c3d354ec 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
@@ -1,5 +1,7 @@
 use rustc_abi::ExternAbi;
-use rustc_hir::{self as hir, intravisit};
+use rustc_hir as hir;
+use rustc_hir::def_id::LocalDefId;
+use rustc_hir::intravisit::FnKind;
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
@@ -10,39 +12,18 @@ use super::TOO_MANY_ARGUMENTS;
 
 pub(super) fn check_fn(
     cx: &LateContext<'_>,
-    kind: intravisit::FnKind<'_>,
+    kind: FnKind<'_>,
     decl: &hir::FnDecl<'_>,
-    span: Span,
     hir_id: hir::HirId,
+    def_id: LocalDefId,
     too_many_arguments_threshold: u64,
 ) {
     // don't warn for implementations, it's not their fault
-    if !is_trait_impl_item(cx, hir_id) {
+    if !is_trait_impl_item(cx, hir_id)
         // don't lint extern functions decls, it's not their fault either
-        match kind {
-            intravisit::FnKind::Method(
-                _,
-                &hir::FnSig {
-                    header: hir::FnHeader {
-                        abi: ExternAbi::Rust, ..
-                    },
-                    ..
-                },
-            )
-            | intravisit::FnKind::ItemFn(
-                _,
-                _,
-                hir::FnHeader {
-                    abi: ExternAbi::Rust, ..
-                },
-            ) => check_arg_number(
-                cx,
-                decl,
-                span.with_hi(decl.output.span().hi()),
-                too_many_arguments_threshold,
-            ),
-            _ => {},
-        }
+        && kind.header().is_some_and(|header| header.abi == ExternAbi::Rust)
+    {
+        check_arg_number(cx, decl, cx.tcx.def_span(def_id), too_many_arguments_threshold);
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index 7158f9419c1..b50d91f1014 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -2,16 +2,16 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::eager_or_lazy::switch_to_eager_eval;
 use clippy_utils::msrvs::{self, Msrv};
-use clippy_utils::source::snippet_with_context;
+use clippy_utils::source::{snippet_with_applicability, snippet_with_context, walk_span_to_context};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
     contains_return, expr_adjustment_requires_coercion, higher, is_else_clause, is_in_const_context, is_res_lang_ctor,
-    path_res, peel_blocks,
+    path_res, peel_blocks, sym,
 };
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -71,21 +71,21 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
             && let ExprKind::Block(then_block, _) = then.kind
             && let Some(then_expr) = then_block.expr
             && let ExprKind::Call(then_call, [then_arg]) = then_expr.kind
-            && let ctxt = expr.span.ctxt()
-            && then_expr.span.ctxt() == ctxt
+            && !expr.span.from_expansion()
+            && !then_expr.span.from_expansion()
             && is_res_lang_ctor(cx, path_res(cx, then_call), OptionSome)
             && is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
             && !is_else_clause(cx.tcx, expr)
             && !is_in_const_context(cx)
-            && !expr.span.in_external_macro(cx.sess().source_map())
             && self.msrv.meets(cx, msrvs::BOOL_THEN)
             && !contains_return(then_block.stmts)
         {
             let method_name = if switch_to_eager_eval(cx, expr) && self.msrv.meets(cx, msrvs::BOOL_THEN_SOME) {
-                "then_some"
+                sym::then_some
             } else {
-                "then"
+                sym::then
             };
+            let ctxt = expr.span.ctxt();
 
             span_lint_and_then(
                 cx,
@@ -98,16 +98,18 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
                     }
 
                     let mut app = Applicability::MachineApplicable;
-                    let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app)
+                    let cond_snip = Sugg::hir_with_context(cx, cond, ctxt, "[condition]", &mut app)
                         .maybe_paren()
                         .to_string();
                     let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0;
-                    let method_body = if let Some(first_stmt) = then_block.stmts.first() {
-                        let (block_snippet, _) =
-                            snippet_with_context(cx, first_stmt.span.until(then_arg.span), ctxt, "..", &mut app);
-                        let closure = if method_name == "then" { "|| " } else { "" };
-                        format!("{closure} {{ {block_snippet}; {arg_snip} }}")
-                    } else if method_name == "then" {
+                    let method_body = if let Some(first_stmt) = then_block.stmts.first()
+                        && let Some(first_stmt_span) = walk_span_to_context(first_stmt.span, ctxt)
+                    {
+                        let block_snippet =
+                            snippet_with_applicability(cx, first_stmt_span.until(then_expr.span), "..", &mut app);
+                        let closure = if method_name == sym::then { "|| " } else { "" };
+                        format!("{closure} {{ {} {arg_snip} }}", block_snippet.trim_end())
+                    } else if method_name == sym::then {
                         (std::borrow::Cow::Borrowed("|| ") + arg_snip).into_owned()
                     } else {
                         arg_snip.into_owned()
diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
index 91f65d0b79c..13117f60abd 100644
--- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
+++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::ty;
+use clippy_utils::{is_path_diagnostic_item, ty};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -107,8 +107,7 @@ impl LateLintPass<'_> for InstantSubtraction {
 
 fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
     if let ExprKind::Call(fn_expr, []) = expr_block.kind
-        && let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
-        && cx.tcx.is_diagnostic_item(sym::instant_now, fn_id)
+        && is_path_diagnostic_item(cx, fn_expr, sym::instant_now)
     {
         true
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs
index 8707612fbdd..48ce1afc6e6 100644
--- a/src/tools/clippy/clippy_lints/src/large_include_file.rs
+++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs
@@ -64,8 +64,8 @@ impl LateLintPass<'_> for LargeIncludeFile {
             }
             && len as u64 > self.max_file_size
             && let Some(macro_call) = root_macro_call_first_node(cx, expr)
-            && (cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id)
-                || cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id))
+            && let Some(macro_name) = cx.tcx.get_diagnostic_name(macro_call.def_id)
+            && matches!(macro_name, sym::include_bytes_macro | sym::include_str_macro)
         {
             #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 57deb011f2b..f44a5fdf715 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -355,12 +355,15 @@ fn parse_len_output<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option<Le
             return Some(LenOutput::Integral);
         }
 
-        if let Res::Def(_, def_id) = res {
-            if cx.tcx.is_diagnostic_item(sym::Option, def_id) && is_first_generic_integral(segment) {
-                return Some(LenOutput::Option(def_id));
-            } else if cx.tcx.is_diagnostic_item(sym::Result, def_id) && is_first_generic_integral(segment) {
-                return Some(LenOutput::Result(def_id));
+        if let Res::Def(_, def_id) = res
+            && let Some(res) = match cx.tcx.get_diagnostic_name(def_id) {
+                Some(sym::Option) => Some(LenOutput::Option(def_id)),
+                Some(sym::Result) => Some(LenOutput::Result(def_id)),
+                _ => None,
             }
+            && is_first_generic_integral(segment)
+        {
+            return Some(res);
         }
 
         return None;
@@ -368,11 +371,10 @@ fn parse_len_output<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option<Le
 
     match *sig.output().kind() {
         ty::Int(_) | ty::Uint(_) => Some(LenOutput::Integral),
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) => {
-            subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did()))
-        },
-        ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => {
-            subs.type_at(0).is_integral().then(|| LenOutput::Result(adt.did()))
+        ty::Adt(adt, subs) if subs.type_at(0).is_integral() => match cx.tcx.get_diagnostic_name(adt.did()) {
+            Some(sym::Option) => Some(LenOutput::Option(adt.did())),
+            Some(sym::Result) => Some(LenOutput::Result(adt.did())),
+            _ => None,
         },
         _ => None,
     }
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index c8594cf35e2..a89cf3fdc1e 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -84,6 +84,7 @@ mod attrs;
 mod await_holding_invalid;
 mod blocks_in_conditions;
 mod bool_assert_comparison;
+mod bool_comparison;
 mod bool_to_int_with_if;
 mod booleans;
 mod borrow_deref_ref;
@@ -474,10 +475,10 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
     store.register_late_pass(move |_| Box::new(types::Types::new(conf)));
     store.register_late_pass(move |_| Box::new(booleans::NonminimalBool::new(conf)));
     store.register_late_pass(|_| Box::new(enum_clike::UnportableVariant));
-    store.register_late_pass(|_| Box::new(float_literal::FloatLiteral));
+    store.register_late_pass(move |_| Box::new(float_literal::FloatLiteral::new(conf)));
     store.register_late_pass(|_| Box::new(ptr::Ptr));
     store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
-    store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
+    store.register_late_pass(|_| Box::new(bool_comparison::BoolComparison));
     store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
     store.register_late_pass(|_| Box::new(misc::LintPass));
     store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
@@ -655,7 +656,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
     store.register_early_pass(move || Box::new(nonstandard_macro_braces::MacroBraces::new(conf)));
     store.register_late_pass(|_| Box::<macro_use::MacroUseImports>::default());
     store.register_late_pass(|_| Box::new(pattern_type_mismatch::PatternTypeMismatch));
-    store.register_late_pass(|_| Box::new(unwrap_in_result::UnwrapInResult));
+    store.register_late_pass(|_| Box::<unwrap_in_result::UnwrapInResult>::default());
     store.register_late_pass(|_| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned));
     store.register_late_pass(|_| Box::new(async_yields_async::AsyncYieldsAsync));
     let attrs = attr_storage.clone();
diff --git a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
index a71e6963f8c..74c0b178018 100644
--- a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
@@ -4,7 +4,8 @@ use hir::intravisit::{Visitor, walk_expr};
 use rustc_ast::Label;
 use rustc_errors::Applicability;
 use rustc_hir::{
-    self as hir, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, Expr, ExprKind, FnRetTy, FnSig, Node, TyKind,
+    self as hir, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnRetTy,
+    FnSig, Node, TyKind,
 };
 use rustc_lint::{LateContext, LintContext};
 use rustc_span::sym;
@@ -73,7 +74,11 @@ fn is_inside_unawaited_async_block(cx: &LateContext<'_>, expr: &Expr<'_>) -> boo
         if let Node::Expr(Expr {
             kind:
                 ExprKind::Closure(Closure {
-                    kind: ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)),
+                    kind:
+                        ClosureKind::Coroutine(CoroutineKind::Desugared(
+                            CoroutineDesugaring::Async,
+                            CoroutineSource::Block | CoroutineSource::Closure,
+                        )),
                     ..
                 }),
             ..
diff --git a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
index a9944d64ce2..8a2d0036203 100644
--- a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
@@ -1,10 +1,10 @@
 use super::MISSING_SPIN_LOOP;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::std_or_core;
+use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Expr, ExprKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty;
 use rustc_span::sym;
 
 fn unpack_cond<'tcx>(cond: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
@@ -39,8 +39,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
     ) = body.kind
         && let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind
         && [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name)
-        && let ty::Adt(def, _args) = cx.typeck_results().expr_ty(callee).kind()
-        && cx.tcx.is_diagnostic_item(sym::AtomicBool, def.did())
+        && let callee_ty = cx.typeck_results().expr_ty(callee)
+        && is_type_diagnostic_item(cx, callee_ty, sym::AtomicBool)
         && let Some(std_or_core) = std_or_core(cx)
     {
         span_lint_and_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 7bb684d65bb..11edb929d70 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::has_iter_method;
 use clippy_utils::visitors::is_local_used;
-use clippy_utils::{SpanlessEq, contains_name, higher, is_integer_const, sugg};
+use clippy_utils::{SpanlessEq, contains_name, higher, is_integer_const, peel_hir_expr_while, sugg};
 use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_errors::Applicability;
@@ -253,12 +253,38 @@ struct VarVisitor<'a, 'tcx> {
 
 impl<'tcx> VarVisitor<'_, 'tcx> {
     fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) -> bool {
-        let index_used_directly = matches!(idx.kind, ExprKind::Path(_));
+        let mut used_cnt = 0;
+        // It is `true` if all indices are direct
+        let mut index_used_directly = true;
+
+        // Handle initial index
+        if is_local_used(self.cx, idx, self.var) {
+            used_cnt += 1;
+            index_used_directly &= matches!(idx.kind, ExprKind::Path(_));
+        }
+        // Handle nested indices
+        let seqexpr = peel_hir_expr_while(seqexpr, |e| {
+            if let ExprKind::Index(e, idx, _) = e.kind {
+                if is_local_used(self.cx, idx, self.var) {
+                    used_cnt += 1;
+                    index_used_directly &= matches!(idx.kind, ExprKind::Path(_));
+                }
+                Some(e)
+            } else {
+                None
+            }
+        });
+
+        match used_cnt {
+            0 => return true,
+            n if n > 1 => self.nonindex = true, // Optimize code like `a[i][i]`
+            _ => {},
+        }
+
         if let ExprKind::Path(ref seqpath) = seqexpr.kind
             // the indexed container is referenced by a name
             && let QPath::Resolved(None, seqvar) = *seqpath
             && seqvar.segments.len() == 1
-            && is_local_used(self.cx, idx, self.var)
         {
             if self.prefer_mutable {
                 self.indexed_mut.insert(seqvar.segments[0].ident.name);
@@ -312,7 +338,6 @@ impl<'tcx> VarVisitor<'_, 'tcx> {
 impl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         if let ExprKind::MethodCall(meth, args_0, [args_1, ..], _) = &expr.kind
-            // a range index op
             && let Some(trait_id) = self
                 .cx
                 .typeck_results()
diff --git a/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs b/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs
index 51e21aa9734..13b93d2c009 100644
--- a/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/unused_enumerate_index.rs
@@ -1,12 +1,12 @@
 use super::UNUSED_ENUMERATE_INDEX;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{pat_is_wild, sugg};
 use rustc_errors::Applicability;
 use rustc_hir::def::DefKind;
 use rustc_hir::{Expr, ExprKind, Pat, PatKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty;
 use rustc_span::sym;
 
 /// Checks for the `UNUSED_ENUMERATE_INDEX` lint.
@@ -17,8 +17,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>, arg: &Expr<'_
         && let ExprKind::MethodCall(_method, self_arg, [], _) = arg.kind
         && let ty = cx.typeck_results().expr_ty(arg)
         && pat_is_wild(cx, &index.kind, body)
-        && let ty::Adt(base, _) = *ty.kind()
-        && cx.tcx.is_diagnostic_item(sym::Enumerate, base.did())
+        && is_type_diagnostic_item(cx, ty, sym::Enumerate)
         && let Some((DefKind::AssocFn, call_id)) = cx.typeck_results().type_dependent_def(arg.hir_id)
         && cx.tcx.is_diagnostic_item(sym::enumerate_method, call_id)
     {
diff --git a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
index ac8c88f0205..2eebb2430fd 100644
--- a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
@@ -97,11 +97,12 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
             return;
         }
 
-        if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro) {
-            if let ExprKind::Match(recv, [arm, ..], _) = expr.kind {
-                let range = check_pat(&arm.pat.kind);
-                check_is_ascii(cx, macro_call.span, recv, &range, None);
-            }
+        let (arg, span, range) = if let Some(macro_call) = matching_root_macro_call(cx, expr.span, sym::matches_macro)
+            && let ExprKind::Match(recv, [arm, ..], _) = expr.kind
+        {
+            let recv = peel_ref_operators(cx, recv);
+            let range = check_pat(&arm.pat.kind);
+            (recv, macro_call.span, range)
         } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind
             && path.ident.name == sym::contains
             && let Some(higher::Range {
@@ -112,10 +113,14 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
             && !matches!(cx.typeck_results().expr_ty(arg).peel_refs().kind(), ty::Param(_))
         {
             let arg = peel_ref_operators(cx, arg);
-            let ty_sugg = get_ty_sugg(cx, arg);
             let range = check_expr_range(start, end);
-            check_is_ascii(cx, expr.span, arg, &range, ty_sugg);
-        }
+            (arg, expr.span, range)
+        } else {
+            return;
+        };
+
+        let ty_sugg = get_ty_sugg(cx, arg);
+        check_is_ascii(cx, span, arg, &range, ty_sugg);
     }
 }
 
@@ -146,9 +151,8 @@ fn check_is_ascii(
         CharRange::HexDigit => "is_ascii_hexdigit",
         CharRange::Otherwise | CharRange::LowerHexLetter | CharRange::UpperHexLetter => return,
     };
-    let default_snip = "..";
     let mut app = Applicability::MachineApplicable;
-    let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_paren();
+    let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), "_", &mut app).maybe_paren();
     let mut suggestion = vec![(span, format!("{recv}.{sugg}()"))];
     if let Some((ty_span, ty)) = ty_sugg {
         suggestion.push((ty_span, format!("{recv}: {ty}")));
@@ -182,7 +186,7 @@ fn check_pat(pat_kind: &PatKind<'_>) -> CharRange {
                 CharRange::Otherwise
             }
         },
-        PatKind::Range(Some(start), Some(end), kind) if *kind == RangeEnd::Included => check_range(start, end),
+        PatKind::Range(Some(start), Some(end), RangeEnd::Included) => check_range(start, end),
         _ => CharRange::Otherwise,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index 98e8b1f5cf9..7fb88763e64 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -123,8 +123,8 @@ fn check_iter(
 ) {
     if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
         && let Some(copied_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
-        && (cx.tcx.is_diagnostic_item(sym::iter_copied, copied_def_id)
-            || cx.tcx.is_diagnostic_item(sym::iter_cloned, copied_def_id))
+        && let Some(copied_name) = cx.tcx.get_diagnostic_name(copied_def_id)
+        && matches!(copied_name, sym::iter_copied | sym::iter_cloned)
         && let hir::ExprKind::MethodCall(_, iter_expr, [_], _) = &filter_expr.kind
         && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)
         && cx.tcx.is_diagnostic_item(sym::iter_filter, filter_def_id)
@@ -243,9 +243,9 @@ fn make_sugg(
 }
 
 fn match_acceptable_sym(cx: &LateContext<'_>, collect_def_id: DefId) -> bool {
-    ACCEPTABLE_METHODS
-        .iter()
-        .any(|&method| cx.tcx.is_diagnostic_item(method, collect_def_id))
+    cx.tcx
+        .get_diagnostic_name(collect_def_id)
+        .is_some_and(|collect_name| ACCEPTABLE_METHODS.contains(&collect_name))
 }
 
 fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: Msrv) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 6bf43a1c6d4..07cce4046ca 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -75,12 +75,10 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
             && let ExprKind::Path(target_path) = &target_arg.kind
             && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(cond.hir_id)
         {
-            let strip_kind = if cx.tcx.is_diagnostic_item(sym::str_starts_with, method_def_id) {
-                StripKind::Prefix
-            } else if cx.tcx.is_diagnostic_item(sym::str_ends_with, method_def_id) {
-                StripKind::Suffix
-            } else {
-                return;
+            let strip_kind = match cx.tcx.get_diagnostic_name(method_def_id) {
+                Some(sym::str_starts_with) => StripKind::Prefix,
+                Some(sym::str_ends_with) => StripKind::Suffix,
+                _ => return,
             };
             let target_res = cx.qpath_res(target_path, target_arg.hir_id);
             if target_res == Res::Err {
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index af6a1b07a49..39e5289c62a 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -116,8 +116,10 @@ fn is_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
 /// The expression inside a closure may or may not have surrounding braces and
 /// semicolons, which causes problems when generating a suggestion. Given an
 /// expression that evaluates to '()' or '!', recursively remove useless braces
-/// and semi-colons until is suitable for including in the suggestion template
-fn reduce_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Span> {
+/// and semi-colons until is suitable for including in the suggestion template.
+/// The `bool` is `true` when the resulting `span` needs to be enclosed in an
+/// `unsafe` block.
+fn reduce_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<(Span, bool)> {
     if !is_unit_expression(cx, expr) {
         return None;
     }
@@ -125,22 +127,24 @@ fn reduce_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<
     match expr.kind {
         hir::ExprKind::Call(_, _) | hir::ExprKind::MethodCall(..) => {
             // Calls can't be reduced any more
-            Some(expr.span)
+            Some((expr.span, false))
         },
         hir::ExprKind::Block(block, _) => {
+            let is_unsafe = matches!(block.rules, hir::BlockCheckMode::UnsafeBlock(_));
             match (block.stmts, block.expr.as_ref()) {
                 ([], Some(inner_expr)) => {
                     // If block only contains an expression,
                     // reduce `{ X }` to `X`
                     reduce_unit_expression(cx, inner_expr)
+                        .map(|(span, inner_is_unsafe)| (span, inner_is_unsafe || is_unsafe))
                 },
                 ([inner_stmt], None) => {
                     // If block only contains statements,
                     // reduce `{ X; }` to `X` or `X;`
                     match inner_stmt.kind {
-                        hir::StmtKind::Let(local) => Some(local.span),
-                        hir::StmtKind::Expr(e) => Some(e.span),
-                        hir::StmtKind::Semi(..) => Some(inner_stmt.span),
+                        hir::StmtKind::Let(local) => Some((local.span, is_unsafe)),
+                        hir::StmtKind::Expr(e) => Some((e.span, is_unsafe)),
+                        hir::StmtKind::Semi(..) => Some((inner_stmt.span, is_unsafe)),
                         hir::StmtKind::Item(..) => None,
                     }
                 },
@@ -228,10 +232,11 @@ fn lint_map_unit_fn(
         let msg = suggestion_msg("closure", map_type);
 
         span_lint_and_then(cx, lint, expr.span, msg, |diag| {
-            if let Some(reduced_expr_span) = reduce_unit_expression(cx, closure_expr) {
+            if let Some((reduced_expr_span, is_unsafe)) = reduce_unit_expression(cx, closure_expr) {
                 let mut applicability = Applicability::MachineApplicable;
+                let (prefix_is_unsafe, suffix_is_unsafe) = if is_unsafe { ("unsafe { ", " }") } else { ("", "") };
                 let suggestion = format!(
-                    "if let {0}({1}) = {2} {{ {3} }}",
+                    "if let {0}({1}) = {2} {{ {prefix_is_unsafe}{3}{suffix_is_unsafe} }}",
                     variant,
                     snippet_with_applicability(cx, binding.pat.span, "_", &mut applicability),
                     snippet_with_applicability(cx, var_arg.span, "_", &mut applicability),
diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
index 5b50efad3e4..aaf559fc443 100644
--- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
@@ -4,20 +4,22 @@ use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::snippet;
 use clippy_utils::visitors::is_local_used;
 use clippy_utils::{
-    SpanlessEq, is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt, peel_ref_operators,
+    SpanlessEq, get_ref_operators, is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt,
+    peel_ref_operators,
 };
+use rustc_ast::BorrowKind;
 use rustc_errors::MultiSpan;
 use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, Expr, HirId, Pat, PatExpr, PatExprKind, PatKind};
+use rustc_hir::{Arm, Expr, ExprKind, HirId, Pat, PatExpr, PatExprKind, PatKind};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
 use super::{COLLAPSIBLE_MATCH, pat_contains_disallowed_or};
 
-pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], msrv: Msrv) {
+pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>], msrv: Msrv) {
     if let Some(els_arm) = arms.iter().rfind(|arm| arm_is_wild_like(cx, arm)) {
         for arm in arms {
-            check_arm(cx, true, arm.pat, arm.body, arm.guard, Some(els_arm.body), msrv);
+            check_arm(cx, true, arm.pat, expr, arm.body, arm.guard, Some(els_arm.body), msrv);
         }
     }
 }
@@ -27,15 +29,18 @@ pub(super) fn check_if_let<'tcx>(
     pat: &'tcx Pat<'_>,
     body: &'tcx Expr<'_>,
     else_expr: Option<&'tcx Expr<'_>>,
+    let_expr: &'tcx Expr<'_>,
     msrv: Msrv,
 ) {
-    check_arm(cx, false, pat, body, None, else_expr, msrv);
+    check_arm(cx, false, pat, let_expr, body, None, else_expr, msrv);
 }
 
+#[allow(clippy::too_many_arguments)]
 fn check_arm<'tcx>(
     cx: &LateContext<'tcx>,
     outer_is_match: bool,
     outer_pat: &'tcx Pat<'tcx>,
+    outer_cond: &'tcx Expr<'tcx>,
     outer_then_body: &'tcx Expr<'tcx>,
     outer_guard: Option<&'tcx Expr<'tcx>>,
     outer_else_body: Option<&'tcx Expr<'tcx>>,
@@ -82,6 +87,9 @@ fn check_arm<'tcx>(
             },
             IfLetOrMatch::Match(_, arms, ..) => !arms.iter().any(|arm| is_local_used(cx, arm, binding_id)),
         }
+        // Check if the inner expression contains any borrows/dereferences
+        && let ref_types = get_ref_operators(cx, inner_scrutinee)
+        && let Some(method) = build_ref_method_chain(ref_types)
     {
         let msg = format!(
             "this `{}` can be collapsed into the outer `{}`",
@@ -103,6 +111,10 @@ fn check_arm<'tcx>(
             let mut help_span = MultiSpan::from_spans(vec![binding_span, inner_then_pat.span]);
             help_span.push_span_label(binding_span, "replace this binding");
             help_span.push_span_label(inner_then_pat.span, format!("with this pattern{replace_msg}"));
+            if !method.is_empty() {
+                let outer_cond_msg = format!("use: `{}{}`", snippet(cx, outer_cond.span, ".."), method);
+                help_span.push_span_label(outer_cond.span, outer_cond_msg);
+            }
             diag.span_help(
                 help_span,
                 "the outer pattern can be modified to include the inner pattern",
@@ -148,3 +160,30 @@ fn find_pat_binding_and_is_innermost_parent_pat_struct(pat: &Pat<'_>, hir_id: Hi
     });
     (span, is_innermost_parent_pat_struct)
 }
+
+/// Builds a chain of reference-manipulation method calls (e.g., `.as_ref()`, `.as_mut()`,
+/// `.copied()`) based on reference operators
+fn build_ref_method_chain(expr: Vec<&Expr<'_>>) -> Option<String> {
+    let mut req_method_calls = String::new();
+
+    for ref_operator in expr {
+        match ref_operator.kind {
+            ExprKind::AddrOf(BorrowKind::Raw, _, _) => {
+                return None;
+            },
+            ExprKind::AddrOf(_, m, _) if m.is_mut() => {
+                req_method_calls.push_str(".as_mut()");
+            },
+            ExprKind::AddrOf(_, _, _) => {
+                req_method_calls.push_str(".as_ref()");
+            },
+            // Deref operator is the only operator that this function should have received
+            ExprKind::Unary(_, _) => {
+                req_method_calls.push_str(".copied()");
+            },
+            _ => (),
+        }
+    }
+
+    Some(req_method_calls)
+}
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index c128fc40b73..6f49c552411 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -1073,7 +1073,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                 significant_drop_in_scrutinee::check_match(cx, expr, ex, arms, source);
             }
 
-            collapsible_match::check_match(cx, arms, self.msrv);
+            collapsible_match::check_match(cx, ex, arms, self.msrv);
             if !from_expansion {
                 // These don't depend on a relationship between multiple arms
                 match_wild_err_arm::check(cx, ex, arms);
@@ -1137,7 +1137,14 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                 match_ref_pats::check(cx, ex, arms.iter().map(|el| el.pat), expr);
             }
         } else if let Some(if_let) = higher::IfLet::hir(cx, expr) {
-            collapsible_match::check_if_let(cx, if_let.let_pat, if_let.if_then, if_let.if_else, self.msrv);
+            collapsible_match::check_if_let(
+                cx,
+                if_let.let_pat,
+                if_let.if_then,
+                if_let.if_else,
+                if_let.let_expr,
+                self.msrv,
+            );
             significant_drop_in_scrutinee::check_if_let(cx, expr, if_let.let_expr, if_let.if_then, if_let.if_else);
             if !from_expansion {
                 if let Some(else_expr) = if_let.if_else {
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 027dd7ce053..81fecc87256 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -226,11 +226,12 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default)]
 enum SigDropHolder {
     /// No values with significant drop present in this expression.
     ///
     /// Expressions that we've emitted lints do not count.
+    #[default]
     None,
     /// Some field in this expression references to values with significant drop.
     ///
@@ -244,12 +245,6 @@ enum SigDropHolder {
     Moved,
 }
 
-impl Default for SigDropHolder {
-    fn default() -> Self {
-        Self::None
-    }
-}
-
 struct SigDropHelper<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     parent_expr: Option<&'tcx Expr<'tcx>>,
diff --git a/src/tools/clippy/clippy_lints/src/matches/try_err.rs b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
index ff7769af1df..af90cb5e673 100644
--- a/src/tools/clippy/clippy_lints/src/matches/try_err.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::option_arg_ty;
 use clippy_utils::{get_parent_expr, is_res_lang_ctor, path_res};
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::ResultErr;
@@ -28,25 +28,15 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
         && is_res_lang_ctor(cx, path_res(cx, err_fun), ResultErr)
         && let Some(return_ty) = find_return_type(cx, &expr.kind)
     {
-        let prefix;
-        let suffix;
-        let err_ty;
-
-        if let Some(ty) = result_error_type(cx, return_ty) {
-            prefix = "Err(";
-            suffix = ")";
-            err_ty = ty;
+        let (prefix, suffix, err_ty) = if let Some(ty) = result_error_type(cx, return_ty) {
+            ("Err(", ")", ty)
         } else if let Some(ty) = poll_result_error_type(cx, return_ty) {
-            prefix = "Poll::Ready(Err(";
-            suffix = "))";
-            err_ty = ty;
+            ("Poll::Ready(Err(", "))", ty)
         } else if let Some(ty) = poll_option_result_error_type(cx, return_ty) {
-            prefix = "Poll::Ready(Some(Err(";
-            suffix = ")))";
-            err_ty = ty;
+            ("Poll::Ready(Some(Err(", ")))", ty)
         } else {
             return;
-        }
+        };
 
         span_lint_and_then(
             cx,
@@ -88,8 +78,8 @@ fn find_return_type<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx ExprKind<'_>) -> O
 
 /// Extracts the error type from Result<T, E>.
 fn result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
-    if let ty::Adt(_, subst) = ty.kind()
-        && is_type_diagnostic_item(cx, ty, sym::Result)
+    if let ty::Adt(def, subst) = ty.kind()
+        && cx.tcx.is_diagnostic_item(sym::Result, def.did())
     {
         Some(subst.type_at(1))
     } else {
@@ -101,11 +91,9 @@ fn result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'t
 fn poll_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
     if let ty::Adt(def, subst) = ty.kind()
         && cx.tcx.lang_items().get(LangItem::Poll) == Some(def.did())
-        && let ready_ty = subst.type_at(0)
-        && let ty::Adt(ready_def, ready_subst) = ready_ty.kind()
-        && cx.tcx.is_diagnostic_item(sym::Result, ready_def.did())
     {
-        Some(ready_subst.type_at(1))
+        let ready_ty = subst.type_at(0);
+        result_error_type(cx, ready_ty)
     } else {
         None
     }
@@ -116,13 +104,9 @@ fn poll_option_result_error_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) ->
     if let ty::Adt(def, subst) = ty.kind()
         && cx.tcx.lang_items().get(LangItem::Poll) == Some(def.did())
         && let ready_ty = subst.type_at(0)
-        && let ty::Adt(ready_def, ready_subst) = ready_ty.kind()
-        && cx.tcx.is_diagnostic_item(sym::Option, ready_def.did())
-        && let some_ty = ready_subst.type_at(0)
-        && let ty::Adt(some_def, some_subst) = some_ty.kind()
-        && cx.tcx.is_diagnostic_item(sym::Result, some_def.did())
+        && let Some(some_ty) = option_arg_ty(cx, ready_ty)
     {
-        Some(some_subst.type_at(1))
+        result_error_type(cx, some_ty)
     } else {
         None
     }
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index 28efd2038b3..e39916f733d 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -215,7 +215,8 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
         && let ExprKind::Path(ref repl_func_qpath) = repl_func.kind
         && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id()
     {
-        if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) {
+        let repl_name = cx.tcx.get_diagnostic_name(repl_def_id);
+        if repl_name == Some(sym::mem_uninitialized) {
             let Some(top_crate) = std_or_core(cx) else { return };
             let mut applicability = Applicability::MachineApplicable;
             span_lint_and_sugg(
@@ -230,9 +231,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
                 ),
                 applicability,
             );
-        } else if cx.tcx.is_diagnostic_item(sym::mem_zeroed, repl_def_id)
-            && !cx.typeck_results().expr_ty(src).is_primitive()
-        {
+        } else if repl_name == Some(sym::mem_zeroed) && !cx.typeck_results().expr_ty(src).is_primitive() {
             span_lint_and_help(
                 cx,
                 MEM_REPLACE_WITH_UNINIT,
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
index 96e2de0dc1c..65583c6a981 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
@@ -24,9 +24,10 @@ pub(super) fn check(
         && let Some(name) = cx.tcx.get_diagnostic_name(adt.did())
     {
         let caller_type = match name {
-            sym::Rc => "Rc",
-            sym::Arc => "Arc",
-            sym::RcWeak | sym::ArcWeak => "Weak",
+            sym::Rc => "std::rc::Rc",
+            sym::Arc => "std::sync::Arc",
+            sym::RcWeak => "std::rc::Weak",
+            sym::ArcWeak => "std::sync::Weak",
             _ => return,
         };
         span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
index 5b8457bdd16..2da0f8341b1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -233,18 +233,16 @@ impl<'tcx> OffendingFilterExpr<'tcx> {
             // the latter only calls `effect` once
             let side_effect_expr_span = receiver.can_have_side_effects().then_some(receiver.span);
 
-            if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name == sym::is_some {
-                Some(Self::IsSome {
+            match (cx.tcx.get_diagnostic_name(recv_ty.did()), path.ident.name) {
+                (Some(sym::Option), sym::is_some) => Some(Self::IsSome {
                     receiver,
                     side_effect_expr_span,
-                })
-            } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name == sym::is_ok {
-                Some(Self::IsOk {
+                }),
+                (Some(sym::Result), sym::is_ok) => Some(Self::IsOk {
                     receiver,
                     side_effect_expr_span,
-                })
-            } else {
-                None
+                }),
+                _ => None,
             }
         } else if matching_root_macro_call(cx, expr.span, sym::matches_macro).is_some()
             // we know for a fact that the wildcard pattern is the second arm
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
index 9a62b719a8f..fa8f9d640ee 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
@@ -24,32 +24,29 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) ->
     let ty::Adt(adt, substs) = cx.typeck_results().expr_ty(iter).kind() else {
         return None;
     };
-    let did = adt.did();
 
-    if cx.tcx.is_diagnostic_item(sym::ArrayIntoIter, did) {
-        // For array::IntoIter<T, const N: usize>, the length is the second generic
-        // parameter.
-        substs.const_at(1).try_to_target_usize(cx.tcx).map(u128::from)
-    } else if cx.tcx.is_diagnostic_item(sym::SliceIter, did)
-        && let ExprKind::MethodCall(_, recv, ..) = iter.kind
-    {
-        if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() {
-            // For slice::Iter<'_, T>, the receiver might be an array literal: [1,2,3].iter().skip(..)
-            len.try_to_target_usize(cx.tcx).map(u128::from)
-        } else if let Some(args) = VecArgs::hir(cx, expr_or_init(cx, recv)) {
-            match args {
-                VecArgs::Vec(vec) => vec.len().try_into().ok(),
-                VecArgs::Repeat(_, len) => expr_as_u128(cx, len),
+    match cx.tcx.get_diagnostic_name(adt.did()) {
+        Some(sym::ArrayIntoIter) => {
+            // For array::IntoIter<T, const N: usize>, the length is the second generic
+            // parameter.
+            substs.const_at(1).try_to_target_usize(cx.tcx).map(u128::from)
+        },
+        Some(sym::SliceIter) if let ExprKind::MethodCall(_, recv, ..) = iter.kind => {
+            if let ty::Array(_, len) = cx.typeck_results().expr_ty(recv).peel_refs().kind() {
+                // For slice::Iter<'_, T>, the receiver might be an array literal: [1,2,3].iter().skip(..)
+                len.try_to_target_usize(cx.tcx).map(u128::from)
+            } else if let Some(args) = VecArgs::hir(cx, expr_or_init(cx, recv)) {
+                match args {
+                    VecArgs::Vec(vec) => vec.len().try_into().ok(),
+                    VecArgs::Repeat(_, len) => expr_as_u128(cx, len),
+                }
+            } else {
+                None
             }
-        } else {
-            None
-        }
-    } else if cx.tcx.is_diagnostic_item(sym::IterEmpty, did) {
-        Some(0)
-    } else if cx.tcx.is_diagnostic_item(sym::IterOnce, did) {
-        Some(1)
-    } else {
-        None
+        },
+        Some(sym::IterEmpty) => Some(0),
+        Some(sym::IterOnce) => Some(1),
+        _ => None,
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
index f7bb8c1d696..750f933330a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
@@ -50,10 +50,10 @@ fn try_get_caller_ty_name_and_method_name(
         }
     } else {
         if let ty::Adt(adt, _) = cx.typeck_results().expr_ty(caller_expr).kind() {
-            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) {
-                return Some(("Option", "and_then"));
-            } else if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) {
-                return Some(("Result", "and_then"));
+            match cx.tcx.get_diagnostic_name(adt.did()) {
+                Some(sym::Option) => return Some(("Option", "and_then")),
+                Some(sym::Result) => return Some(("Result", "and_then")),
+                _ => {},
             }
         }
         None
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
index 98def66ca14..a98cfff8bfb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
@@ -1,14 +1,16 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_expr_untyped_identity_function, is_trait_method, path_to_local};
-use rustc_ast::BindingMode;
+use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
+use clippy_utils::{is_expr_untyped_identity_function, is_mutable, is_trait_method, path_to_local_with_projections};
 use rustc_errors::Applicability;
-use rustc_hir::{self as hir, Node, PatKind};
-use rustc_lint::LateContext;
+use rustc_hir::{self as hir, ExprKind, Node, PatKind};
+use rustc_lint::{LateContext, LintContext};
 use rustc_span::{Span, Symbol, sym};
 
 use super::MAP_IDENTITY;
 
+const MSG: &str = "unnecessary map of the identity function";
+
 pub(super) fn check(
     cx: &LateContext<'_>,
     expr: &hir::Expr<'_>,
@@ -23,26 +25,70 @@ pub(super) fn check(
         || is_type_diagnostic_item(cx, caller_ty, sym::Result)
         || is_type_diagnostic_item(cx, caller_ty, sym::Option))
         && is_expr_untyped_identity_function(cx, map_arg)
-        && let Some(sugg_span) = expr.span.trim_start(caller.span)
+        && let Some(call_span) = expr.span.trim_start(caller.span)
     {
-        // If the result of `.map(identity)` is used as a mutable reference,
-        // the caller must not be an immutable binding.
-        if cx.typeck_results().expr_ty_adjusted(expr).is_mutable_ptr()
-            && let Some(hir_id) = path_to_local(caller)
-            && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
-            && !matches!(pat.kind, PatKind::Binding(BindingMode::MUT, ..))
-        {
-            return;
-        }
+        let main_sugg = (call_span, String::new());
+        let mut app = if is_copy(cx, caller_ty) {
+            // there is technically a behavioral change here for `Copy` iterators, where
+            // `iter.map(|x| x).next()` would mutate a temporary copy of the iterator and
+            // changing it to `iter.next()` mutates iter directly
+            Applicability::Unspecified
+        } else {
+            Applicability::MachineApplicable
+        };
+
+        let needs_to_be_mutable = cx.typeck_results().expr_ty_adjusted(expr).is_mutable_ptr();
+        if needs_to_be_mutable && !is_mutable(cx, caller) {
+            if let Some(hir_id) = path_to_local_with_projections(caller)
+                && let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
+                && let PatKind::Binding(_, _, ident, _) = pat.kind
+            {
+                // We can reach the binding -- suggest making it mutable
+                let suggs = vec![main_sugg, (ident.span.shrink_to_lo(), String::from("mut "))];
+
+                let ident = snippet_with_applicability(cx.sess(), ident.span, "_", &mut app);
 
-        span_lint_and_sugg(
-            cx,
-            MAP_IDENTITY,
-            sugg_span,
-            "unnecessary map of the identity function",
-            format!("remove the call to `{name}`"),
-            String::new(),
-            Applicability::MachineApplicable,
-        );
+                span_lint_and_then(cx, MAP_IDENTITY, call_span, MSG, |diag| {
+                    diag.multipart_suggestion(
+                        format!("remove the call to `{name}`, and make `{ident}` mutable"),
+                        suggs,
+                        app,
+                    );
+                });
+            } else {
+                // If we can't make the binding mutable, prevent the suggestion from being automatically applied,
+                // and add a complementary help message.
+                app = Applicability::Unspecified;
+
+                let method_requiring_mut = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id)
+                    && let ExprKind::MethodCall(method, ..) = expr.kind
+                {
+                    Some(method.ident)
+                } else {
+                    None
+                };
+
+                span_lint_and_then(cx, MAP_IDENTITY, call_span, MSG, |diag| {
+                    diag.span_suggestion(main_sugg.0, format!("remove the call to `{name}`"), main_sugg.1, app);
+
+                    let note = if let Some(method_requiring_mut) = method_requiring_mut {
+                        format!("this must be made mutable to use `{method_requiring_mut}`")
+                    } else {
+                        "this must be made mutable".to_string()
+                    };
+                    diag.span_note(caller.span, note);
+                });
+            }
+        } else {
+            span_lint_and_sugg(
+                cx,
+                MAP_IDENTITY,
+                main_sugg.0,
+                MSG,
+                format!("remove the call to `{name}`"),
+                main_sugg.1,
+                app,
+            );
+        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 63ee922acfa..906ead16fd0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -38,17 +38,13 @@ pub(super) fn check(
     ];
 
     let is_deref = match map_arg.kind {
-        hir::ExprKind::Path(ref expr_qpath) => {
-            cx.qpath_res(expr_qpath, map_arg.hir_id)
-                .opt_def_id()
-                .is_some_and(|fun_def_id| {
-                    cx.tcx.is_diagnostic_item(sym::deref_method, fun_def_id)
-                        || cx.tcx.is_diagnostic_item(sym::deref_mut_method, fun_def_id)
-                        || deref_aliases
-                            .iter()
-                            .any(|&sym| cx.tcx.is_diagnostic_item(sym, fun_def_id))
-                })
-        },
+        hir::ExprKind::Path(ref expr_qpath) => cx
+            .qpath_res(expr_qpath, map_arg.hir_id)
+            .opt_def_id()
+            .and_then(|fun_def_id| cx.tcx.get_diagnostic_name(fun_def_id))
+            .is_some_and(|fun_name| {
+                matches!(fun_name, sym::deref_method | sym::deref_mut_method) || deref_aliases.contains(&fun_name)
+            }),
         hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
             let closure_body = cx.tcx.hir_body(body);
             let closure_expr = peel_blocks(closure_body.value);
@@ -63,13 +59,11 @@ pub(super) fn check(
                             .map(|x| &x.kind)
                             .collect::<Box<[_]>>()
                         && let [ty::adjustment::Adjust::Deref(None), ty::adjustment::Adjust::Borrow(_)] = *adj
+                        && let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap()
+                        && let Some(method_name) = cx.tcx.get_diagnostic_name(method_did)
                     {
-                        let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap();
-                        cx.tcx.is_diagnostic_item(sym::deref_method, method_did)
-                            || cx.tcx.is_diagnostic_item(sym::deref_mut_method, method_did)
-                            || deref_aliases
-                                .iter()
-                                .any(|&sym| cx.tcx.is_diagnostic_item(sym, method_did))
+                        matches!(method_name, sym::deref_method | sym::deref_mut_method)
+                            || deref_aliases.contains(&method_name)
                     } else {
                         false
                     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs
index 3e64e15dc86..1a760ea733d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs
@@ -62,7 +62,7 @@ fn get_content_if_ctor_matches(cx: &LateContext<'_>, expr: &Expr<'_>, item: Lang
     if let ExprKind::Call(some_expr, [arg]) = expr.kind
         && is_res_lang_ctor(cx, path_res(cx, some_expr), item)
     {
-        Some(arg.span)
+        Some(arg.span.source_callsite())
     } else {
         None
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs
index 407f2e80aff..6738bbf0a12 100644
--- a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs
@@ -31,8 +31,8 @@ fn parse_fails_on_trailing_newline(ty: Ty<'_>) -> bool {
 }
 
 pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {
-    if let Some(recv_adt) = cx.typeck_results().expr_ty(recv).ty_adt_def()
-        && cx.tcx.is_diagnostic_item(sym::Stdin, recv_adt.did())
+    let recv_ty = cx.typeck_results().expr_ty(recv);
+    if is_type_diagnostic_item(cx, recv_ty, sym::Stdin)
         && let ExprKind::Path(QPath::Resolved(_, path)) = arg.peel_borrows().kind
         && let Res::Local(local_id) = path.res
     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
index ccdf5529d53..ef3d7acdc01 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
@@ -5,10 +5,10 @@ use rustc_span::sym;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
     if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
-        if cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id) {
-            single_char_push_string::check(cx, expr, receiver, args);
-        } else if cx.tcx.is_diagnostic_item(sym::string_insert_str, fn_def_id) {
-            single_char_insert_string::check(cx, expr, receiver, args);
+        match cx.tcx.get_diagnostic_name(fn_def_id) {
+            Some(sym::string_push_str) => single_char_push_string::check(cx, expr, receiver, args),
+            Some(sym::string_insert_str) => single_char_insert_string::check(cx, expr, receiver, args),
+            _ => {},
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
index ce7aefed01f..ffc237e3c24 100644
--- a/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
@@ -1,11 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_diag_trait_item;
 use clippy_utils::source::snippet_with_context;
+use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
-use rustc_middle::ty::{self};
 use rustc_span::sym;
 
 use super::SUSPICIOUS_TO_OWNED;
@@ -14,8 +14,7 @@ pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) -
     if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
         && is_diag_trait_item(cx, method_def_id, sym::ToOwned)
         && let input_type = cx.typeck_results().expr_ty(expr)
-        && let ty::Adt(adt, _) = cx.typeck_results().expr_ty(expr).kind()
-        && cx.tcx.is_diagnostic_item(sym::Cow, adt.did())
+        && is_type_diagnostic_item(cx, input_type, sym::Cow)
     {
         let mut app = Applicability::MaybeIncorrect;
         let recv_snip = snippet_with_context(cx, recv.span, expr.span.ctxt(), "..", &mut app).0;
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs
index 413881d5ec9..b87d81b7102 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs
@@ -22,7 +22,8 @@ pub(super) fn check<'tcx>(
     let typeck_results = cx.typeck_results();
     let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.typing_env(), typeck_results);
     if let Some(id) = typeck_results.type_dependent_def_id(expr.hir_id)
-        && (cx.tcx.is_diagnostic_item(sym::cmp_ord_min, id) || cx.tcx.is_diagnostic_item(sym::cmp_ord_max, id))
+        && let Some(fn_name) = cx.tcx.get_diagnostic_name(id)
+        && matches!(fn_name, sym::cmp_ord_min | sym::cmp_ord_max)
     {
         if let Some((left, ConstantSource::Local | ConstantSource::CoreConstant)) = ecx.eval_with_source(recv)
             && let Some((right, ConstantSource::Local | ConstantSource::CoreConstant)) = ecx.eval_with_source(arg)
diff --git a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
index af466fe091c..af4ade3cc0f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::{SpanRangeExt, snippet};
+use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{expr_or_init, is_trait_method, pat_is_wild};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, FnDecl, PatKind, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty::AdtDef;
 use rustc_span::{Span, sym};
 
 use crate::loops::UNUSED_ENUMERATE_INDEX;
@@ -39,9 +39,8 @@ use crate::loops::UNUSED_ENUMERATE_INDEX;
 /// * `closure_arg`: The argument to the map function call containing the closure/function to apply
 pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>, closure_arg: &Expr<'_>) {
     let recv_ty = cx.typeck_results().expr_ty(recv);
-    if let Some(recv_ty_defid) = recv_ty.ty_adt_def().map(AdtDef::did)
-        // If we call a method on a `std::iter::Enumerate` instance
-        && cx.tcx.is_diagnostic_item(sym::Enumerate, recv_ty_defid)
+    // If we call a method on a `std::iter::Enumerate` instance
+    if is_type_diagnostic_item(cx, recv_ty, sym::Enumerate)
         // If we are calling a method of the `Iterator` trait
         && is_trait_method(cx, call_expr, sym::Iterator)
         // And the map argument is a closure
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index d02952eb487..28555a61090 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -1,4 +1,4 @@
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::diagnostics::{span_lint, span_lint_hir};
 use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, Attribute, find_attr};
@@ -64,14 +64,20 @@ declare_clippy_lint! {
     "detects missing `#[inline]` attribute for public callables (functions, trait methods, methods...)"
 }
 
-fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[Attribute], sp: Span, desc: &'static str) {
+fn check_missing_inline_attrs(
+    cx: &LateContext<'_>,
+    attrs: &[Attribute],
+    sp: Span,
+    desc: &'static str,
+    hir_id: Option<hir::HirId>,
+) {
     if !find_attr!(attrs, AttributeKind::Inline(..)) {
-        span_lint(
-            cx,
-            MISSING_INLINE_IN_PUBLIC_ITEMS,
-            sp,
-            format!("missing `#[inline]` for {desc}"),
-        );
+        let msg = format!("missing `#[inline]` for {desc}");
+        if let Some(hir_id) = hir_id {
+            span_lint_hir(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, hir_id, sp, msg);
+        } else {
+            span_lint(cx, MISSING_INLINE_IN_PUBLIC_ITEMS, sp, msg);
+        }
     }
 }
 
@@ -103,17 +109,9 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
 
                 let desc = "a function";
                 let attrs = cx.tcx.hir_attrs(it.hir_id());
-                check_missing_inline_attrs(cx, attrs, it.span, desc);
+                check_missing_inline_attrs(cx, attrs, it.span, desc, None);
             },
-            hir::ItemKind::Trait(
-                ref _constness,
-                ref _is_auto,
-                ref _unsafe,
-                _ident,
-                _generics,
-                _bounds,
-                trait_items,
-            ) => {
+            hir::ItemKind::Trait(.., trait_items) => {
                 // note: we need to check if the trait is exported so we can't use
                 // `LateLintPass::check_trait_item` here.
                 for &tit in trait_items {
@@ -127,7 +125,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
                                 let desc = "a default trait method";
                                 let item = cx.tcx.hir_trait_item(tit);
                                 let attrs = cx.tcx.hir_attrs(item.hir_id());
-                                check_missing_inline_attrs(cx, attrs, item.span, desc);
+                                check_missing_inline_attrs(cx, attrs, item.span, desc, Some(tit.hir_id()));
                             }
                         },
                     }
@@ -182,7 +180,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
         }
 
         let attrs = cx.tcx.hir_attrs(impl_item.hir_id());
-        check_missing_inline_attrs(cx, attrs, impl_item.span, desc);
+        check_missing_inline_attrs(cx, attrs, impl_item.span, desc, None);
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs
index 31f51b45754..ec93ef97cfa 100644
--- a/src/tools/clippy/clippy_lints/src/mut_reference.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs
@@ -1,4 +1,6 @@
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
+use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
@@ -83,13 +85,18 @@ fn check_arguments<'tcx>(
         let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
         for (argument, parameter) in iter::zip(arguments, parameters) {
             if let ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not) = parameter.kind()
-                && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) = argument.kind
+                && let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, arg) = argument.kind
             {
-                span_lint(
+                let mut applicability = Applicability::MachineApplicable;
+                let sugg = Sugg::hir_with_applicability(cx, arg, "_", &mut applicability).addr();
+                span_lint_and_sugg(
                     cx,
                     UNNECESSARY_MUT_PASSED,
                     argument.span,
                     format!("the {fn_kind} `{name}` doesn't need a mutable reference"),
+                    "remove this `mut`",
+                    sugg.to_string(),
+                    applicability,
                 );
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index 6ae26156bc4..854e927aa2f 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -2,16 +2,14 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt,
-    is_receiver_of_method_call, peel_blocks, peel_blocks_with_stmt, span_contains_comment, sym,
+    SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_parent_stmt, is_receiver_of_method_call,
+    peel_blocks, peel_blocks_with_stmt, span_contains_comment,
 };
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
+use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::Span;
-use rustc_span::source_map::Spanned;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -52,31 +50,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for expressions of the form `x == true`,
-    /// `x != true` and order comparisons such as `x < true` (or vice versa) and
-    /// suggest using the variable directly.
-    ///
-    /// ### Why is this bad?
-    /// Unnecessary code.
-    ///
-    /// ### Example
-    /// ```rust,ignore
-    /// if x == true {}
-    /// if y == false {}
-    /// ```
-    /// use `x` directly:
-    /// ```rust,ignore
-    /// if x {}
-    /// if !y {}
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub BOOL_COMPARISON,
-    complexity,
-    "comparing a variable to a boolean, e.g., `if x == true` or `if x != true`"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks for expressions of the form `if c { x = true } else { x = false }`
     /// (or vice versa) and suggest assigning the variable directly from the
     /// condition.
@@ -224,201 +197,6 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
     }
 }
 
-declare_lint_pass!(BoolComparison => [BOOL_COMPARISON]);
-
-impl<'tcx> LateLintPass<'tcx> for BoolComparison {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
-        if e.span.from_expansion() {
-            return;
-        }
-
-        if let ExprKind::Binary(Spanned { node, .. }, ..) = e.kind {
-            let ignore_case = None::<(fn(_) -> _, &str)>;
-            let ignore_no_literal = None::<(fn(_, _) -> _, &str)>;
-            match node {
-                BinOpKind::Eq => {
-                    let true_case = Some((|h| h, "equality checks against true are unnecessary"));
-                    let false_case = Some((
-                        |h: Sugg<'tcx>| !h,
-                        "equality checks against false can be replaced by a negation",
-                    ));
-                    check_comparison(cx, e, true_case, false_case, true_case, false_case, ignore_no_literal);
-                },
-                BinOpKind::Ne => {
-                    let true_case = Some((
-                        |h: Sugg<'tcx>| !h,
-                        "inequality checks against true can be replaced by a negation",
-                    ));
-                    let false_case = Some((|h| h, "inequality checks against false are unnecessary"));
-                    check_comparison(cx, e, true_case, false_case, true_case, false_case, ignore_no_literal);
-                },
-                BinOpKind::Lt => check_comparison(
-                    cx,
-                    e,
-                    ignore_case,
-                    Some((|h| h, "greater than checks against false are unnecessary")),
-                    Some((
-                        |h: Sugg<'tcx>| !h,
-                        "less than comparison against true can be replaced by a negation",
-                    )),
-                    ignore_case,
-                    Some((
-                        |l: Sugg<'tcx>, r: Sugg<'tcx>| (!l).bit_and(&r),
-                        "order comparisons between booleans can be simplified",
-                    )),
-                ),
-                BinOpKind::Gt => check_comparison(
-                    cx,
-                    e,
-                    Some((
-                        |h: Sugg<'tcx>| !h,
-                        "less than comparison against true can be replaced by a negation",
-                    )),
-                    ignore_case,
-                    ignore_case,
-                    Some((|h| h, "greater than checks against false are unnecessary")),
-                    Some((
-                        |l: Sugg<'tcx>, r: Sugg<'tcx>| l.bit_and(&(!r)),
-                        "order comparisons between booleans can be simplified",
-                    )),
-                ),
-                _ => (),
-            }
-        }
-    }
-}
-
-struct ExpressionInfoWithSpan {
-    one_side_is_unary_not: bool,
-    left_span: Span,
-    right_span: Span,
-}
-
-fn is_unary_not(e: &Expr<'_>) -> (bool, Span) {
-    if let ExprKind::Unary(UnOp::Not, operand) = e.kind {
-        return (true, operand.span);
-    }
-    (false, e.span)
-}
-
-fn one_side_is_unary_not<'tcx>(left_side: &'tcx Expr<'_>, right_side: &'tcx Expr<'_>) -> ExpressionInfoWithSpan {
-    let left = is_unary_not(left_side);
-    let right = is_unary_not(right_side);
-
-    ExpressionInfoWithSpan {
-        one_side_is_unary_not: left.0 != right.0,
-        left_span: left.1,
-        right_span: right.1,
-    }
-}
-
-fn check_comparison<'a, 'tcx>(
-    cx: &LateContext<'tcx>,
-    e: &'tcx Expr<'_>,
-    left_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
-    left_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
-    right_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
-    right_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
-    no_literal: Option<(impl FnOnce(Sugg<'a>, Sugg<'a>) -> Sugg<'a>, &'static str)>,
-) {
-    if let ExprKind::Binary(op, left_side, right_side) = e.kind {
-        let (l_ty, r_ty) = (
-            cx.typeck_results().expr_ty(left_side),
-            cx.typeck_results().expr_ty(right_side),
-        );
-        if is_expn_of(left_side.span, sym::cfg).is_some() || is_expn_of(right_side.span, sym::cfg).is_some() {
-            return;
-        }
-        if l_ty.is_bool() && r_ty.is_bool() {
-            let mut applicability = Applicability::MachineApplicable;
-            // Eliminate parentheses in `e` by using the lo pos of lhs and hi pos of rhs,
-            // calling `source_callsite` make sure macros are handled correctly, see issue #9907
-            let binop_span = left_side
-                .span
-                .source_callsite()
-                .with_hi(right_side.span.source_callsite().hi());
-
-            if op.node == BinOpKind::Eq {
-                let expression_info = one_side_is_unary_not(left_side, right_side);
-                if expression_info.one_side_is_unary_not {
-                    span_lint_and_sugg(
-                        cx,
-                        BOOL_COMPARISON,
-                        binop_span,
-                        "this comparison might be written more concisely",
-                        "try simplifying it as shown",
-                        format!(
-                            "{} != {}",
-                            snippet_with_applicability(
-                                cx,
-                                expression_info.left_span.source_callsite(),
-                                "..",
-                                &mut applicability
-                            ),
-                            snippet_with_applicability(
-                                cx,
-                                expression_info.right_span.source_callsite(),
-                                "..",
-                                &mut applicability
-                            )
-                        ),
-                        applicability,
-                    );
-                }
-            }
-
-            match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {
-                (Some(true), None) => left_true.map_or((), |(h, m)| {
-                    suggest_bool_comparison(cx, binop_span, right_side, applicability, m, h);
-                }),
-                (None, Some(true)) => right_true.map_or((), |(h, m)| {
-                    suggest_bool_comparison(cx, binop_span, left_side, applicability, m, h);
-                }),
-                (Some(false), None) => left_false.map_or((), |(h, m)| {
-                    suggest_bool_comparison(cx, binop_span, right_side, applicability, m, h);
-                }),
-                (None, Some(false)) => right_false.map_or((), |(h, m)| {
-                    suggest_bool_comparison(cx, binop_span, left_side, applicability, m, h);
-                }),
-                (None, None) => no_literal.map_or((), |(h, m)| {
-                    let left_side = Sugg::hir_with_applicability(cx, left_side, "..", &mut applicability);
-                    let right_side = Sugg::hir_with_applicability(cx, right_side, "..", &mut applicability);
-                    span_lint_and_sugg(
-                        cx,
-                        BOOL_COMPARISON,
-                        binop_span,
-                        m,
-                        "try simplifying it as shown",
-                        h(left_side, right_side).into_string(),
-                        applicability,
-                    );
-                }),
-                _ => (),
-            }
-        }
-    }
-}
-
-fn suggest_bool_comparison<'a, 'tcx>(
-    cx: &LateContext<'tcx>,
-    span: Span,
-    expr: &Expr<'_>,
-    mut app: Applicability,
-    message: &'static str,
-    conv_hint: impl FnOnce(Sugg<'a>) -> Sugg<'a>,
-) {
-    let hint = Sugg::hir_with_context(cx, expr, span.ctxt(), "..", &mut app);
-    span_lint_and_sugg(
-        cx,
-        BOOL_COMPARISON,
-        span,
-        message,
-        "try simplifying it as shown",
-        conv_hint(hint).into_string(),
-        app,
-    );
-}
-
 enum Expression {
     Bool(bool),
     RetBool(bool),
diff --git a/src/tools/clippy/clippy_lints/src/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
index a67545e419c..3a6ccc2bca9 100644
--- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
@@ -1,6 +1,6 @@
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_expr};
-use rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind};
+use rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
@@ -70,12 +70,24 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
             && has_iter_method(cx, cx.typeck_results().expr_ty(iter_recv)).is_some()
             // Skip the lint if the body is not block because this is simpler than `for` loop.
             // e.g. `v.iter().for_each(f)` is simpler and clearer than using `for` loop.
-            && let ExprKind::Closure(&Closure { body, .. }) = for_each_arg.kind
+            && let ExprKind::Closure(&Closure { body, fn_decl, .. }) = for_each_arg.kind
             && let body = cx.tcx.hir_body(body)
             // Skip the lint if the body is not safe, so as not to suggest `for … in … unsafe {}`
             // and suggesting `for … in … { unsafe { } }` is a little ugly.
             && !matches!(body.value.kind, ExprKind::Block(Block { rules: BlockCheckMode::UnsafeBlock(_), .. }, ..))
         {
+            let mut applicability = Applicability::MachineApplicable;
+
+            // If any closure parameter has an explicit type specified, applying the lint would necessarily
+            // remove that specification, possibly breaking type inference
+            if fn_decl
+                .inputs
+                .iter()
+                .any(|input| matches!(input.kind, TyKind::Infer(..)))
+            {
+                applicability = Applicability::MaybeIncorrect;
+            }
+
             let mut ret_collector = RetCollector::default();
             ret_collector.visit_expr(body.value);
 
@@ -84,18 +96,16 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessForEach {
                 return;
             }
 
-            let (mut applicability, ret_suggs) = if ret_collector.spans.is_empty() {
-                (Applicability::MachineApplicable, None)
+            let ret_suggs = if ret_collector.spans.is_empty() {
+                None
             } else {
-                (
-                    Applicability::MaybeIncorrect,
-                    Some(
-                        ret_collector
-                            .spans
-                            .into_iter()
-                            .map(|span| (span, "continue".to_string()))
-                            .collect(),
-                    ),
+                applicability = Applicability::MaybeIncorrect;
+                Some(
+                    ret_collector
+                        .spans
+                        .into_iter()
+                        .map(|span| (span, "continue".to_string()))
+                        .collect(),
                 )
             };
 
diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
index 04b09276966..ba67dc62abb 100644
--- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -134,7 +134,8 @@ impl LateLintPass<'_> for NonCanonicalImpls {
             return;
         }
 
-        if cx.tcx.is_diagnostic_item(sym::Clone, trait_impl.def_id)
+        let trait_name = cx.tcx.get_diagnostic_name(trait_impl.def_id);
+        if trait_name == Some(sym::Clone)
             && let Some(copy_def_id) = cx.tcx.get_diagnostic_item(sym::Copy)
             && implements_trait(cx, trait_impl.self_ty(), copy_def_id, &[])
         {
@@ -170,12 +171,8 @@ impl LateLintPass<'_> for NonCanonicalImpls {
                     String::new(),
                     Applicability::MaybeIncorrect,
                 );
-
-                return;
             }
-        }
-
-        if cx.tcx.is_diagnostic_item(sym::PartialOrd, trait_impl.def_id)
+        } else if trait_name == Some(sym::PartialOrd)
             && impl_item.ident.name == sym::partial_cmp
             && let Some(ord_def_id) = cx.tcx.get_diagnostic_item(sym::Ord)
             && implements_trait(cx, trait_impl.self_ty(), ord_def_id, &[])
diff --git a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
index 23a1622f30f..cb934466bd8 100644
--- a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
+++ b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
@@ -43,13 +43,11 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
         match &expr.kind {
             ExprKind::MethodCall(path, func, [param], _) => {
                 if let Some(adt) = cx.typeck_results().expr_ty(func).peel_refs().ty_adt_def()
-                    && ((path.ident.name == sym::mode
-                        && matches!(
-                            cx.tcx.get_diagnostic_name(adt.did()),
-                            Some(sym::FsOpenOptions | sym::DirBuilder)
-                        ))
-                        || (path.ident.name == sym::set_mode
-                            && cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did())))
+                    && matches!(
+                        (cx.tcx.get_diagnostic_name(adt.did()), path.ident.name),
+                        (Some(sym::FsOpenOptions | sym::DirBuilder), sym::mode)
+                            | (Some(sym::FsPermissions), sym::set_mode)
+                    )
                     && let ExprKind::Lit(_) = param.kind
                     && param.span.eq_ctxt(expr.span)
                     && param
diff --git a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
index 7317c62df7f..2d303e40bd1 100644
--- a/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/assign_op_pattern.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::msrvs::Msrv;
+use clippy_utils::qualify_min_const_fn::is_stable_const_fn;
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::visitors::for_each_expr_without_closures;
@@ -20,7 +21,7 @@ pub(super) fn check<'tcx>(
     expr: &'tcx hir::Expr<'_>,
     assignee: &'tcx hir::Expr<'_>,
     e: &'tcx hir::Expr<'_>,
-    _msrv: Msrv,
+    msrv: Msrv,
 ) {
     if let hir::ExprKind::Binary(op, l, r) = &e.kind {
         let lint = |assignee: &hir::Expr<'_>, rhs: &hir::Expr<'_>| {
@@ -43,10 +44,28 @@ pub(super) fn check<'tcx>(
                     }
                 }
 
-                // Skip if the trait is not stable in const contexts
-                // FIXME: reintroduce a better check after this is merged back into Clippy
+                // Skip if the trait or the implementation is not stable in const contexts
                 if is_in_const_context(cx) {
-                    return;
+                    if cx
+                        .tcx
+                        .associated_item_def_ids(trait_id)
+                        .first()
+                        .is_none_or(|binop_id| !is_stable_const_fn(cx, *binop_id, msrv))
+                    {
+                        return;
+                    }
+
+                    let impls = cx.tcx.non_blanket_impls_for_ty(trait_id, rty).collect::<Vec<_>>();
+                    if impls.is_empty()
+                        || impls.into_iter().any(|impl_id| {
+                            cx.tcx
+                                .associated_item_def_ids(impl_id)
+                                .first()
+                                .is_none_or(|fn_id| !is_stable_const_fn(cx, *fn_id, msrv))
+                        })
+                    {
+                        return;
+                    }
                 }
 
                 span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
index 22ec4fe60fb..604f8f5da0b 100644
--- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
@@ -47,14 +47,10 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool)
             (arg, arg.span)
         },
         ExprKind::Call(path, [arg])
-            if path_def_id(cx, path).is_some_and(|did| {
-                if cx.tcx.is_diagnostic_item(sym::from_str_method, did) {
-                    true
-                } else if cx.tcx.is_diagnostic_item(sym::from_fn, did) {
-                    !is_copy(cx, typeck.expr_ty(expr))
-                } else {
-                    false
-                }
+            if path_def_id(cx, path).is_some_and(|did| match cx.tcx.get_diagnostic_name(did) {
+                Some(sym::from_str_method) => true,
+                Some(sym::from_fn) => !is_copy(cx, typeck.expr_ty(expr)),
+                _ => false,
             }) =>
         {
             (arg, arg.span)
diff --git a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
index 047a5a0159c..17fa8017c97 100644
--- a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
@@ -34,10 +34,11 @@ pub(crate) fn check<'tcx>(
             val_r,
         ) = lhs.kind
 
-        // right hand side matches either f32::EPSILON or f64::EPSILON
+        // right hand side matches _::EPSILON
         && let ExprKind::Path(ref epsilon_path) = rhs.kind
         && let Res::Def(DefKind::AssocConst, def_id) = cx.qpath_res(epsilon_path, rhs.hir_id)
-        && ([sym::f32_epsilon, sym::f64_epsilon].into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, def_id)))
+        && let Some(sym) = cx.tcx.get_diagnostic_name(def_id)
+        && matches!(sym, sym::f16_epsilon | sym::f32_epsilon | sym::f64_epsilon | sym::f128_epsilon)
 
         // values of the subtractions on the left hand side are of the type float
         && let t_val_l = cx.typeck_results().expr_ty(val_l)
diff --git a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
index 449d3da7639..43db0085f2e 100644
--- a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
+++ b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_in_test;
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
+use clippy_utils::{is_in_test, is_inside_always_const_context};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
@@ -99,7 +99,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if let Some(macro_call) = root_macro_call_first_node(cx, expr) {
             if is_panic(cx, macro_call.def_id) {
-                if cx.tcx.hir_is_inside_const_context(expr.hir_id)
+                if is_inside_always_const_context(cx.tcx, expr.hir_id)
                     || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)
                 {
                     return;
@@ -140,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
             && let Res::Def(DefKind::Fn, def_id) = expr_path.res
             && cx.tcx.is_diagnostic_item(sym::panic_any, def_id)
         {
-            if cx.tcx.hir_is_inside_const_context(expr.hir_id)
+            if is_inside_always_const_context(cx.tcx, expr.hir_id)
                 || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)
             {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index e57b8cc2d84..1d58cdd26d8 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::fn_has_unsatisfiable_preds;
 use clippy_utils::mir::{LocalUsage, PossibleBorrowerMap, visit_local_usage};
 use clippy_utils::source::SpanRangeExt;
-use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
+use clippy_utils::ty::{has_drop, is_copy, is_type_lang_item, walk_ptrs_ty_depth};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl, LangItem, def_id};
@@ -96,14 +96,13 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
             let (fn_def_id, arg, arg_ty, clone_ret) =
                 unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind));
 
+            let fn_name = cx.tcx.get_diagnostic_name(fn_def_id);
+
             let from_borrow = cx.tcx.lang_items().get(LangItem::CloneFn) == Some(fn_def_id)
-                || cx.tcx.is_diagnostic_item(sym::to_owned_method, fn_def_id)
-                || (cx.tcx.is_diagnostic_item(sym::to_string_method, fn_def_id)
-                    && is_type_lang_item(cx, arg_ty, LangItem::String));
+                || fn_name == Some(sym::to_owned_method)
+                || (fn_name == Some(sym::to_string_method) && is_type_lang_item(cx, arg_ty, LangItem::String));
 
-            let from_deref = !from_borrow
-                && (cx.tcx.is_diagnostic_item(sym::path_to_pathbuf, fn_def_id)
-                    || cx.tcx.is_diagnostic_item(sym::os_str_to_os_string, fn_def_id));
+            let from_deref = !from_borrow && matches!(fn_name, Some(sym::path_to_pathbuf | sym::os_str_to_os_string));
 
             if !from_borrow && !from_deref {
                 continue;
@@ -148,8 +147,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
                     is_call_with_ref_arg(cx, mir, &pred_terminator.kind)
                     && res == cloned
                     && cx.tcx.is_diagnostic_item(sym::deref_method, pred_fn_def_id)
-                    && (is_type_diagnostic_item(cx, pred_arg_ty, sym::PathBuf)
-                        || is_type_diagnostic_item(cx, pred_arg_ty, sym::OsString))
+                    && let ty::Adt(pred_arg_def, _) = pred_arg_ty.kind()
+                    && let Some(pred_arg_name) = cx.tcx.get_diagnostic_name(pred_arg_def.did())
+                    && matches!(pred_arg_name, sym::PathBuf | sym::OsString)
                 {
                     (pred_arg, res)
                 } else {
diff --git a/src/tools/clippy/clippy_lints/src/semicolon_block.rs b/src/tools/clippy/clippy_lints/src/semicolon_block.rs
index db91c57b181..1dea8f17c34 100644
--- a/src/tools/clippy/clippy_lints/src/semicolon_block.rs
+++ b/src/tools/clippy/clippy_lints/src/semicolon_block.rs
@@ -155,6 +155,11 @@ impl LateLintPass<'_> for SemicolonBlock {
                 kind: ExprKind::Block(block, _),
                 ..
             }) if !block.span.from_expansion() => {
+                let attrs = cx.tcx.hir_attrs(stmt.hir_id);
+                if !attrs.is_empty() && !cx.tcx.features().stmt_expr_attributes() {
+                    return;
+                }
+
                 if let Some(tail) = block.expr {
                     self.semicolon_inside_block(cx, block, tail, stmt.span);
                 }
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 e9534bc63a6..8c4a50041e6 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
@@ -126,6 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
             && !is_from_proc_macro(cx, &first_segment.ident)
             && !matches!(def_kind, DefKind::Macro(_))
             && let Some(last_segment) = path.segments.last()
+            && let Res::Def(DefKind::Mod, crate_def_id) = first_segment.res
+            && crate_def_id.is_crate_root()
         {
             let (lint, used_mod, replace_with) = match first_segment.ident.name {
                 sym::std => match cx.tcx.crate_name(def_id.krate) {
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 490e6c974ae..57d5900b045 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -457,7 +457,8 @@ impl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace {
 }
 
 fn is_one_of_trim_diagnostic_items(cx: &LateContext<'_>, trim_def_id: DefId) -> bool {
-    cx.tcx.is_diagnostic_item(sym::str_trim, trim_def_id)
-        || cx.tcx.is_diagnostic_item(sym::str_trim_start, trim_def_id)
-        || cx.tcx.is_diagnostic_item(sym::str_trim_end, trim_def_id)
+    matches!(
+        cx.tcx.get_diagnostic_name(trim_def_id),
+        Some(sym::str_trim | sym::str_trim_start | sym::str_trim_end)
+    )
 }
diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
index 08f36a2ed5d..543f3c45e14 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
@@ -1,8 +1,12 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use std::borrow::Cow;
+
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::{HasSession, SpanRangeExt as _};
 use rustc_errors::Applicability;
-use rustc_hir::{GenericArg, HirId, LetStmt, Node, Path, TyKind};
+use rustc_hir::{Expr, GenericArg, HirId, LetStmt, Node, Path, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty::Ty;
+use rustc_middle::ty::{self, Ty};
+use rustc_span::Span;
 
 use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
 
@@ -38,6 +42,7 @@ fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool {
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
     path: &Path<'tcx>,
+    arg: &Expr<'tcx>,
     from_ty: Ty<'tcx>,
     to_ty: Ty<'tcx>,
     expr_hir_id: HirId,
@@ -68,14 +73,48 @@ pub(super) fn check<'tcx>(
     } else if is_function_block(cx, expr_hir_id) {
         return false;
     }
-    span_lint_and_sugg(
+    let span = last.ident.span.with_hi(path.span.hi());
+    span_lint_and_then(
         cx,
         MISSING_TRANSMUTE_ANNOTATIONS,
-        last.ident.span.with_hi(path.span.hi()),
+        span,
         "transmute used without annotations",
-        "consider adding missing annotations",
-        format!("{}::<{from_ty}, {to_ty}>", last.ident),
-        Applicability::MaybeIncorrect,
+        |diag| {
+            let from_ty_no_name = ty_cannot_be_named(from_ty);
+            let to_ty_no_name = ty_cannot_be_named(to_ty);
+            if from_ty_no_name || to_ty_no_name {
+                let to_name = match (from_ty_no_name, to_ty_no_name) {
+                    (true, false) => maybe_name_by_expr(cx, arg.span, "the origin type"),
+                    (false, true) => "the destination type".into(),
+                    _ => "the source and destination types".into(),
+                };
+                diag.help(format!(
+                    "consider giving {to_name} a name, and adding missing type annotations"
+                ));
+            } else {
+                diag.span_suggestion(
+                    span,
+                    "consider adding missing annotations",
+                    format!("{}::<{from_ty}, {to_ty}>", last.ident),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        },
     );
     true
 }
+
+fn ty_cannot_be_named(ty: Ty<'_>) -> bool {
+    matches!(
+        ty.kind(),
+        ty::Alias(ty::AliasTyKind::Opaque | ty::AliasTyKind::Inherent, _)
+    )
+}
+
+fn maybe_name_by_expr<'a>(sess: &impl HasSession, span: Span, default: &'a str) -> Cow<'a, str> {
+    span.with_source_text(sess, |name| {
+        (name.len() + 9 < default.len()).then_some(format!("`{name}`'s type").into())
+    })
+    .flatten()
+    .unwrap_or(default.into())
+}
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 1c7bb4314dd..5fda388259a 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -520,7 +520,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 | transmuting_null::check(cx, e, arg, to_ty)
                 | transmute_null_to_fn::check(cx, e, arg, to_ty)
                 | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, self.msrv)
-                | missing_transmute_annotations::check(cx, path, from_ty, to_ty, e.hir_id)
+                | missing_transmute_annotations::check(cx, path, arg, from_ty, to_ty, e.hir_id)
                 | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
                 | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, self.msrv)
                 | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
index f27aaa2fa77..2257aa1b73c 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_INT_TO_NON_ZERO;
-use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::sugg;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
@@ -16,35 +16,24 @@ pub(super) fn check<'tcx>(
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
 ) -> bool {
-    let tcx = cx.tcx;
-
-    let (ty::Int(_) | ty::Uint(_), ty::Adt(adt, substs)) = (&from_ty.kind(), to_ty.kind()) else {
-        return false;
-    };
-
-    if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
-        return false;
+    if let ty::Int(_) | ty::Uint(_) = from_ty.kind()
+        && let ty::Adt(adt, substs) = to_ty.kind()
+        && cx.tcx.is_diagnostic_item(sym::NonZero, adt.did())
+        && let int_ty = substs.type_at(0)
+        && from_ty == int_ty
+    {
+        let arg = Sugg::hir(cx, arg, "..");
+        span_lint_and_sugg(
+            cx,
+            TRANSMUTE_INT_TO_NON_ZERO,
+            e.span,
+            format!("transmute from a `{from_ty}` to a `{}<{int_ty}>`", sym::NonZero),
+            "consider using",
+            format!("{}::{}({arg})", sym::NonZero, sym::new_unchecked),
+            Applicability::Unspecified,
+        );
+        true
+    } else {
+        false
     }
-
-    let int_ty = substs.type_at(0);
-    if from_ty != int_ty {
-        return false;
-    }
-
-    span_lint_and_then(
-        cx,
-        TRANSMUTE_INT_TO_NON_ZERO,
-        e.span,
-        format!("transmute from a `{from_ty}` to a `{}<{int_ty}>`", sym::NonZero),
-        |diag| {
-            let arg = sugg::Sugg::hir(cx, arg, "..");
-            diag.span_suggestion(
-                e.span,
-                "consider using",
-                format!("{}::{}({arg})", sym::NonZero, sym::new_unchecked),
-                Applicability::Unspecified,
-            );
-        },
-    );
-    true
 }
diff --git a/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs b/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
index d691f1878b1..c4fd0fbf87a 100644
--- a/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
+++ b/src/tools/clippy/clippy_lints/src/types/rc_buffer.rs
@@ -11,7 +11,8 @@ use super::RC_BUFFER;
 
 pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
     let app = Applicability::Unspecified;
-    if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
+    let name = cx.tcx.get_diagnostic_name(def_id);
+    if name == Some(sym::Rc) {
         if let Some(alternate) = match_buffer_type(cx, qpath) {
             #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
             span_lint_and_then(
@@ -56,7 +57,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
             );
             return true;
         }
-    } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) {
+    } else if name == Some(sym::Arc) {
         if let Some(alternate) = match_buffer_type(cx, qpath) {
             #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
index de3456a8ba5..0ba51daf027 100644
--- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
+++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
@@ -13,14 +13,11 @@ use super::{REDUNDANT_ALLOCATION, utils};
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath: &QPath<'tcx>, def_id: DefId) -> bool {
     let mut applicability = Applicability::MaybeIncorrect;
-    let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() {
-        "Box"
-    } else if cx.tcx.is_diagnostic_item(sym::Rc, def_id) {
-        "Rc"
-    } else if cx.tcx.is_diagnostic_item(sym::Arc, def_id) {
-        "Arc"
-    } else {
-        return false;
+    let outer_sym = match cx.tcx.get_diagnostic_name(def_id) {
+        _ if Some(def_id) == cx.tcx.lang_items().owned_box() => "Box",
+        Some(sym::Rc) => "Rc",
+        Some(sym::Arc) => "Arc",
+        _ => return false,
     };
 
     if let Some(span) = utils::match_borrows_parameter(cx, qpath) {
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs
index 48b532968cb..38716519e23 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node};
-use clippy_utils::sym;
+use clippy_utils::{is_unit_expr, sym};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 
@@ -16,10 +16,13 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
                 sym::assert_ne_macro | sym::debug_assert_ne_macro => "fail",
                 _ => return,
             };
-            let Some((left, _, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {
+            let Some((lhs, rhs, _)) = find_assert_eq_args(cx, expr, macro_call.expn) else {
                 return;
             };
-            if !cx.typeck_results().expr_ty(left).is_unit() {
+            if is_unit_expr(lhs) || is_unit_expr(rhs) {
+                return;
+            }
+            if !cx.typeck_results().expr_ty(lhs).is_unit() {
                 return;
             }
             span_lint(
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
index 7d996775a58..28f4884fa31 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
@@ -41,7 +41,8 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
             && let ty::Ref(_, inner_str, _) = cx.typeck_results().expr_ty_adjusted(expr).kind()
             && inner_str.is_str()
         {
-            if cx.tcx.is_diagnostic_item(sym::string_new, fun_def_id) {
+            let fun_name = cx.tcx.get_diagnostic_name(fun_def_id);
+            if fun_name == Some(sym::string_new) {
                 span_lint_and_sugg(
                     cx,
                     UNNECESSARY_OWNED_EMPTY_STRINGS,
@@ -51,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
                     "\"\"".to_owned(),
                     Applicability::MachineApplicable,
                 );
-            } else if cx.tcx.is_diagnostic_item(sym::from_fn, fun_def_id)
+            } else if fun_name == Some(sym::from_fn)
                 && let [arg] = args
                 && let ExprKind::Lit(spanned) = &arg.kind
                 && let LitKind::Str(symbol, _) = spanned.node
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index 54a7efc090a..849c0b438a5 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -107,12 +107,10 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
         // Get the wrapper and inner types, if can't, abort.
         let (return_type_label, lang_item, inner_type) =
             if let ty::Adt(adt_def, subst) = return_ty(cx, hir_id.expect_owner()).kind() {
-                if cx.tcx.is_diagnostic_item(sym::Option, adt_def.did()) {
-                    ("Option", OptionSome, subst.type_at(0))
-                } else if cx.tcx.is_diagnostic_item(sym::Result, adt_def.did()) {
-                    ("Result", ResultOk, subst.type_at(0))
-                } else {
-                    return;
+                match cx.tcx.get_diagnostic_name(adt_def.did()) {
+                    Some(sym::Option) => ("Option", OptionSome, subst.type_at(0)),
+                    Some(sym::Result) => ("Result", ResultOk, subst.type_at(0)),
+                    _ => return,
                 }
             } else {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 8b278d98a30..f3410c98973 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -326,7 +326,11 @@ fn extend_with_struct_pat(
                     if idx_1 == idx {
                         // In the case of `k`, we merely require identical field names
                         // so that we will transform into `ident_k: p1_k | p2_k`.
-                        let pos = fps2.iter().position(|fp2| eq_id(fp1.ident, fp2.ident));
+                        let pos = fps2.iter().position(|fp2| {
+                            // Avoid `Foo { bar } | Foo { bar }` => `Foo { bar | bar }`
+                            !(fp1.is_shorthand && fp2.is_shorthand)
+                                && eq_id(fp1.ident, fp2.ident)
+                        });
                         pos_in_2.set(pos);
                         pos.is_some()
                     } else {
diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
index f3cd3f1bb28..af3ad4566c4 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -89,7 +89,9 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
         {
             // We don't want to lint inside io::Read or io::Write implementations, as the author has more
             // information about their trait implementation than our lint, see https://github.com/rust-lang/rust-clippy/issues/4836
-            if cx.tcx.is_diagnostic_item(sym::IoRead, trait_id) || cx.tcx.is_diagnostic_item(sym::IoWrite, trait_id) {
+            if let Some(trait_name) = cx.tcx.get_diagnostic_name(trait_id)
+                && matches!(trait_name, sym::IoRead | sym::IoWrite)
+            {
                 return;
             }
 
diff --git a/src/tools/clippy/clippy_lints/src/unused_unit.rs b/src/tools/clippy/clippy_lints/src/unused_unit.rs
index 3811f0fe6b5..d503bd3379b 100644
--- a/src/tools/clippy/clippy_lints/src/unused_unit.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_unit.rs
@@ -6,13 +6,13 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    AssocItemConstraintKind, Body, Expr, ExprKind, FnDecl, FnRetTy, GenericArgsParentheses, Node, PolyTraitRef, Term,
-    Ty, TyKind,
+    AssocItemConstraintKind, Body, Expr, ExprKind, FnDecl, FnRetTy, GenericArgsParentheses, PolyTraitRef, Term, Ty,
+    TyKind,
 };
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::edition::Edition;
-use rustc_span::{BytePos, Span, sym};
+use rustc_span::{BytePos, Pos as _, Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -49,19 +49,22 @@ impl<'tcx> LateLintPass<'tcx> for UnusedUnit {
         decl: &'tcx FnDecl<'tcx>,
         body: &'tcx Body<'tcx>,
         span: Span,
-        def_id: LocalDefId,
+        _def_id: LocalDefId,
     ) {
         if let FnRetTy::Return(hir_ty) = decl.output
             && is_unit_ty(hir_ty)
             && !hir_ty.span.from_expansion()
             && get_def(span) == get_def(hir_ty.span)
         {
-            // implicit types in closure signatures are forbidden when `for<...>` is present
-            if let FnKind::Closure = kind
-                && let Node::Expr(expr) = cx.tcx.hir_node_by_def_id(def_id)
-                && let ExprKind::Closure(closure) = expr.kind
-                && !closure.bound_generic_params.is_empty()
-            {
+            // The explicit `-> ()` in the closure signature might be necessary for multiple reasons:
+            // - Implicit types in closure signatures are forbidden when `for<...>` is present
+            // - If the closure body ends with a function call, and that function's return type is generic, the
+            //   `-> ()` could be required for it to be inferred
+            //
+            // There could be more reasons to have it, and, in general, we shouldn't discourage the users from
+            // writing more type annotations than strictly necessary, because it can help readability and
+            // maintainability
+            if let FnKind::Closure = kind {
                 return;
             }
 
@@ -97,16 +100,13 @@ impl<'tcx> LateLintPass<'tcx> for UnusedUnit {
     }
 
     fn check_poly_trait_ref(&mut self, cx: &LateContext<'tcx>, poly: &'tcx PolyTraitRef<'tcx>) {
-        let segments = &poly.trait_ref.path.segments;
-
-        if segments.len() == 1
-            && matches!(segments[0].ident.name, sym::Fn | sym::FnMut | sym::FnOnce)
-            && let Some(args) = segments[0].args
+        if let [segment] = &poly.trait_ref.path.segments
+            && matches!(segment.ident.name, sym::Fn | sym::FnMut | sym::FnOnce)
+            && let Some(args) = segment.args
             && args.parenthesized == GenericArgsParentheses::ParenSugar
-            && let constraints = &args.constraints
-            && constraints.len() == 1
-            && constraints[0].ident.name == sym::Output
-            && let AssocItemConstraintKind::Equality { term: Term::Ty(hir_ty) } = constraints[0].kind
+            && let [constraint] = &args.constraints
+            && constraint.ident.name == sym::Output
+            && let AssocItemConstraintKind::Equality { term: Term::Ty(hir_ty) } = constraint.kind
             && args.span_ext.hi() != poly.span.hi()
             && !hir_ty.span.from_expansion()
             && args.span_ext.hi() != hir_ty.span.hi()
@@ -160,17 +160,15 @@ fn get_def(span: Span) -> Option<Span> {
 
 fn lint_unneeded_unit_return(cx: &LateContext<'_>, ty_span: Span, span: Span) {
     let (ret_span, appl) =
-        span.with_hi(ty_span.hi())
-            .get_source_text(cx)
-            .map_or((ty_span, Applicability::MaybeIncorrect), |src| {
-                position_before_rarrow(&src).map_or((ty_span, Applicability::MaybeIncorrect), |rpos| {
-                    (
-                        #[expect(clippy::cast_possible_truncation)]
-                        ty_span.with_lo(BytePos(span.lo().0 + rpos as u32)),
-                        Applicability::MachineApplicable,
-                    )
-                })
-            });
+        if let Some(Some(rpos)) = span.with_hi(ty_span.hi()).with_source_text(cx, position_before_rarrow) {
+            (
+                ty_span.with_lo(span.lo() + BytePos::from_usize(rpos)),
+                Applicability::MachineApplicable,
+            )
+        } else {
+            (ty_span, Applicability::MaybeIncorrect)
+        };
+
     span_lint_and_sugg(
         cx,
         UNUSED_UNIT,
diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
index 7bec212a23c..f26647fa348 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
@@ -1,13 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::visitors::for_each_expr;
-use clippy_utils::{method_chain_args, return_ty};
-use core::ops::ControlFlow;
-use rustc_hir as hir;
-use rustc_hir::ImplItemKind;
+use clippy_utils::{return_ty, sym};
+use rustc_hir::{
+    Body, BodyOwnerKind, Expr, ExprKind, FnSig, ImplItem, ImplItemKind, Item, ItemKind, OwnerId, PathSegment, QPath,
+};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::declare_lint_pass;
-use rustc_span::{Span, sym};
+use rustc_middle::ty::Ty;
+use rustc_session::impl_lint_pass;
+use rustc_span::{Ident, Span, Symbol};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -57,62 +56,165 @@ declare_clippy_lint! {
     "functions of type `Result<..>` or `Option`<...> that contain `expect()` or `unwrap()`"
 }
 
-declare_lint_pass!(UnwrapInResult=> [UNWRAP_IN_RESULT]);
+impl_lint_pass!(UnwrapInResult=> [UNWRAP_IN_RESULT]);
 
-impl<'tcx> LateLintPass<'tcx> for UnwrapInResult {
-    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
-        if let ImplItemKind::Fn(ref _signature, _) = impl_item.kind
-            // first check if it's a method or function
-            // checking if its return type is `result` or `option`
-            && (is_type_diagnostic_item(cx, return_ty(cx, impl_item.owner_id), sym::Result)
-                || is_type_diagnostic_item(cx, return_ty(cx, impl_item.owner_id), sym::Option))
-        {
-            lint_impl_body(cx, impl_item.span, impl_item);
+#[derive(Clone, Copy, Eq, PartialEq)]
+enum OptionOrResult {
+    Option,
+    Result,
+}
+
+impl OptionOrResult {
+    fn with_article(self) -> &'static str {
+        match self {
+            Self::Option => "an `Option`",
+            Self::Result => "a `Result`",
         }
     }
 }
 
-fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_item: &'tcx hir::ImplItem<'_>) {
-    if let ImplItemKind::Fn(_, body_id) = impl_item.kind {
-        let body = cx.tcx.hir_body(body_id);
-        let typeck = cx.tcx.typeck(impl_item.owner_id.def_id);
-        let mut result = Vec::new();
-        let _: Option<!> = for_each_expr(cx, body.value, |e| {
-            // check for `expect`
-            if let Some(arglists) = method_chain_args(e, &[sym::expect]) {
-                let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs();
-                if is_type_diagnostic_item(cx, receiver_ty, sym::Option)
-                    || is_type_diagnostic_item(cx, receiver_ty, sym::Result)
-                {
-                    result.push(e.span);
-                }
-            }
-
-            // check for `unwrap`
-            if let Some(arglists) = method_chain_args(e, &[sym::unwrap]) {
-                let receiver_ty = typeck.expr_ty(arglists[0].0).peel_refs();
-                if is_type_diagnostic_item(cx, receiver_ty, sym::Option)
-                    || is_type_diagnostic_item(cx, receiver_ty, sym::Result)
-                {
-                    result.push(e.span);
-                }
-            }
-
-            ControlFlow::Continue(())
+struct OptionOrResultFn {
+    kind: OptionOrResult,
+    return_ty_span: Option<Span>,
+}
+
+#[derive(Default)]
+pub struct UnwrapInResult {
+    fn_stack: Vec<Option<OptionOrResultFn>>,
+    current_fn: Option<OptionOrResultFn>,
+}
+
+impl UnwrapInResult {
+    fn enter_item(&mut self, cx: &LateContext<'_>, fn_def_id: OwnerId, sig: &FnSig<'_>) {
+        self.fn_stack.push(self.current_fn.take());
+        self.current_fn = is_option_or_result(cx, return_ty(cx, fn_def_id)).map(|kind| OptionOrResultFn {
+            kind,
+            return_ty_span: Some(sig.decl.output.span()),
         });
+    }
 
-        // if we've found one, lint
-        if !result.is_empty() {
+    fn leave_item(&mut self) {
+        self.current_fn = self.fn_stack.pop().unwrap();
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for UnwrapInResult {
+    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
+        if let ImplItemKind::Fn(sig, _) = &impl_item.kind {
+            self.enter_item(cx, impl_item.owner_id, sig);
+        }
+    }
+
+    fn check_impl_item_post(&mut self, _: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'tcx>) {
+        if let ImplItemKind::Fn(..) = impl_item.kind {
+            self.leave_item();
+        }
+    }
+
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        if let ItemKind::Fn {
+            has_body: true, sig, ..
+        } = &item.kind
+        {
+            self.enter_item(cx, item.owner_id, sig);
+        }
+    }
+
+    fn check_item_post(&mut self, _: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        if let ItemKind::Fn { has_body: true, .. } = item.kind {
+            self.leave_item();
+        }
+    }
+
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
+        if expr.span.from_expansion() {
+            return;
+        }
+
+        if let Some(OptionOrResultFn {
+            kind,
+            ref mut return_ty_span,
+        }) = self.current_fn
+            && let Some((oor, fn_name)) = is_unwrap_or_expect_call(cx, expr)
+            && oor == kind
+        {
             span_lint_and_then(
                 cx,
                 UNWRAP_IN_RESULT,
-                impl_span,
-                "used unwrap or expect in a function that returns result or option",
-                move |diag| {
-                    diag.help("unwrap and expect should not be used in a function that returns result or option");
-                    diag.span_note(result, "potential non-recoverable error(s)");
+                expr.span,
+                format!("`{fn_name}` used in a function that returns {}", kind.with_article()),
+                |diag| {
+                    // Issue the note and help only once per function
+                    if let Some(span) = return_ty_span.take() {
+                        diag.span_note(span, "in this function signature");
+                        let complement = if kind == OptionOrResult::Result {
+                            " or calling the `.map_err()` method"
+                        } else {
+                            ""
+                        };
+                        diag.help(format!("consider using the `?` operator{complement}"));
+                    }
                 },
             );
         }
     }
+
+    fn check_body(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
+        let body_def_id = cx.tcx.hir_body_owner_def_id(body.id());
+        if !matches!(cx.tcx.hir_body_owner_kind(body_def_id), BodyOwnerKind::Fn) {
+            // When entering a body which is not a function, mask the potential surrounding
+            // function to not apply the lint.
+            self.fn_stack.push(self.current_fn.take());
+        }
+    }
+
+    fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &Body<'tcx>) {
+        let body_def_id = cx.tcx.hir_body_owner_def_id(body.id());
+        if !matches!(cx.tcx.hir_body_owner_kind(body_def_id), BodyOwnerKind::Fn) {
+            // Unmask the potential surrounding function.
+            self.current_fn = self.fn_stack.pop().unwrap();
+        }
+    }
+}
+
+fn is_option_or_result(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<OptionOrResult> {
+    match ty.ty_adt_def().and_then(|def| cx.tcx.get_diagnostic_name(def.did())) {
+        Some(sym::Option) => Some(OptionOrResult::Option),
+        Some(sym::Result) => Some(OptionOrResult::Result),
+        _ => None,
+    }
+}
+
+fn is_unwrap_or_expect_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(OptionOrResult, Symbol)> {
+    if let ExprKind::Call(func, _) = expr.kind
+        && let ExprKind::Path(QPath::TypeRelative(
+            hir_ty,
+            PathSegment {
+                ident:
+                    Ident {
+                        name: name @ (sym::unwrap | sym::expect),
+                        ..
+                    },
+                ..
+            },
+        )) = func.kind
+    {
+        is_option_or_result(cx, cx.typeck_results().node_type(hir_ty.hir_id)).map(|oor| (oor, *name))
+    } else if let ExprKind::MethodCall(
+        PathSegment {
+            ident: Ident {
+                name: name @ (sym::unwrap | sym::expect),
+                ..
+            },
+            ..
+        },
+        recv,
+        _,
+        _,
+    ) = expr.kind
+    {
+        is_option_or_result(cx, cx.typeck_results().expr_ty_adjusted(recv)).map(|oor| (oor, *name))
+    } else {
+        None
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index e5b20c0e0a1..70ae982a445 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -386,12 +386,13 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
 
             ExprKind::Call(path, [arg]) => {
                 if let ExprKind::Path(ref qpath) = path.kind
-                    && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
                     && !is_ty_alias(qpath)
+                    && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+                    && let Some(name) = cx.tcx.get_diagnostic_name(def_id)
                 {
                     let a = cx.typeck_results().expr_ty(e);
                     let b = cx.typeck_results().expr_ty(arg);
-                    if cx.tcx.is_diagnostic_item(sym::try_from_fn, def_id)
+                    if name == sym::try_from_fn
                         && is_type_diagnostic_item(cx, a, sym::Result)
                         && let ty::Adt(_, args) = a.kind()
                         && let Some(a_type) = args.types().next()
@@ -406,9 +407,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                             None,
                             hint,
                         );
-                    }
-
-                    if cx.tcx.is_diagnostic_item(sym::from_fn, def_id) && same_type_and_consts(a, b) {
+                    } else if name == sym::from_fn && same_type_and_consts(a, b) {
                         let mut app = Applicability::MachineApplicable;
                         let sugg = Sugg::hir_with_context(cx, arg, e.span.ctxt(), "<expr>", &mut app).maybe_paren();
                         let sugg_msg = format!("consider removing `{}()`", snippet(cx, path.span, "From::from"));
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index 7b6a25123e8..52b30ddce12 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -1,4 +1,6 @@
 use std::collections::BTreeMap;
+use std::collections::btree_map::Entry;
+use std::mem;
 use std::ops::ControlFlow;
 
 use clippy_config::Conf;
@@ -20,15 +22,36 @@ use rustc_span::{DesugaringKind, Span};
 pub struct UselessVec {
     too_large_for_stack: u64,
     msrv: Msrv,
-    span_to_lint_map: BTreeMap<Span, Option<(HirId, SuggestedType, String, Applicability)>>,
+    /// Maps from a `vec![]` source callsite invocation span to the "state" (i.e., whether we can
+    /// emit a warning there or not).
+    ///
+    /// The purpose of this is to buffer lints up until `check_crate_post` so that we can cancel a
+    /// lint while visiting, because a `vec![]` invocation span can appear multiple times when
+    /// it is passed as a macro argument, once in a context that doesn't require a `Vec<_>` and
+    /// another time that does. Consider:
+    /// ```
+    /// macro_rules! m {
+    ///     ($v:expr) => {
+    ///         let a = $v;
+    ///         $v.push(3);
+    ///     }
+    /// }
+    /// m!(vec![1, 2]);
+    /// ```
+    /// The macro invocation expands to two `vec![1, 2]` invocations. If we eagerly suggest changing
+    /// the first `vec![1, 2]` (which is shared with the other expn) to an array which indeed would
+    /// work, we get a false positive warning on the `$v.push(3)` which really requires `$v` to
+    /// be a vector.
+    span_to_state: BTreeMap<Span, VecState>,
     allow_in_test: bool,
 }
+
 impl UselessVec {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
             too_large_for_stack: conf.too_large_for_stack,
             msrv: conf.msrv,
-            span_to_lint_map: BTreeMap::new(),
+            span_to_state: BTreeMap::new(),
             allow_in_test: conf.allow_useless_vec_in_tests,
         }
     }
@@ -62,17 +85,28 @@ declare_clippy_lint! {
 
 impl_lint_pass!(UselessVec => [USELESS_VEC]);
 
-impl<'tcx> LateLintPass<'tcx> for UselessVec {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) else {
-            return;
-        };
-        if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) {
-            return;
-        }
-        // the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!`
-        let callsite = expr.span.parent_callsite().unwrap_or(expr.span);
+/// The "state" of a `vec![]` invocation, indicating whether it can or cannot be changed.
+enum VecState {
+    Change {
+        suggest_ty: SuggestedType,
+        vec_snippet: String,
+        expr_hir_id: HirId,
+    },
+    NoChange,
+}
+
+enum VecToArray {
+    /// Expression does not need to be a `Vec<_>` and its type can be changed to an array (or
+    /// slice).
+    Possible,
+    /// Expression must be a `Vec<_>`. Type cannot change.
+    Impossible,
+}
 
+impl UselessVec {
+    /// Checks if the surrounding environment requires this expression to actually be of type
+    /// `Vec<_>`, or if it can be changed to `&[]`/`[]` without causing type errors.
+    fn expr_usage_requires_vec(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) -> VecToArray {
         match cx.tcx.parent_hir_node(expr.hir_id) {
             // search for `let foo = vec![_]` expressions where all uses of `foo`
             // adjust to slices or call a method that exist on slices (e.g. len)
@@ -100,110 +134,126 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
                 .is_continue();
 
                 if only_slice_uses {
-                    self.check_vec_macro(cx, &vec_args, callsite, expr.hir_id, SuggestedType::Array);
+                    VecToArray::Possible
                 } else {
-                    self.span_to_lint_map.insert(callsite, None);
+                    VecToArray::Impossible
                 }
             },
             // if the local pattern has a specified type, do not lint.
             Node::LetStmt(LetStmt { ty: Some(_), .. }) if higher::VecArgs::hir(cx, expr).is_some() => {
-                self.span_to_lint_map.insert(callsite, None);
+                VecToArray::Impossible
             },
             // search for `for _ in vec![...]`
             Node::Expr(Expr { span, .. })
                 if span.is_desugaring(DesugaringKind::ForLoop) && self.msrv.meets(cx, msrvs::ARRAY_INTO_ITERATOR) =>
             {
-                let suggest_slice = suggest_type(expr);
-                self.check_vec_macro(cx, &vec_args, callsite, expr.hir_id, suggest_slice);
+                VecToArray::Possible
             },
             // search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]`
             _ => {
-                let suggest_slice = suggest_type(expr);
-
                 if adjusts_to_slice(cx, expr) {
-                    self.check_vec_macro(cx, &vec_args, callsite, expr.hir_id, suggest_slice);
+                    VecToArray::Possible
                 } else {
-                    self.span_to_lint_map.insert(callsite, None);
+                    VecToArray::Impossible
                 }
             },
         }
     }
+}
+
+impl<'tcx> LateLintPass<'tcx> for UselessVec {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows())
+            // The `vec![]` or `&vec![]` invocation span.
+            && let vec_span = expr.span.parent_callsite().unwrap_or(expr.span)
+            && !vec_span.from_expansion()
+        {
+            if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) {
+                return;
+            }
+
+            match self.expr_usage_requires_vec(cx, expr) {
+                VecToArray::Possible => {
+                    let suggest_ty = suggest_type(expr);
+
+                    // Size and `Copy` checks don't depend on the enclosing usage of the expression
+                    // and don't need to be inserted into the state map.
+                    let vec_snippet = match vec_args {
+                        higher::VecArgs::Repeat(expr, len) => {
+                            if is_copy(cx, cx.typeck_results().expr_ty(expr))
+                                && let Some(Constant::Int(length)) = ConstEvalCtxt::new(cx).eval(len)
+                                && let Ok(length) = u64::try_from(length)
+                                && size_of(cx, expr)
+                                    .checked_mul(length)
+                                    .is_some_and(|size| size <= self.too_large_for_stack)
+                            {
+                                suggest_ty.snippet(
+                                    cx,
+                                    Some(expr.span.source_callsite()),
+                                    Some(len.span.source_callsite()),
+                                )
+                            } else {
+                                return;
+                            }
+                        },
+                        higher::VecArgs::Vec(args) => {
+                            if let Ok(length) = u64::try_from(args.len())
+                                && size_of(cx, expr)
+                                    .checked_mul(length)
+                                    .is_some_and(|size| size <= self.too_large_for_stack)
+                            {
+                                suggest_ty.snippet(
+                                    cx,
+                                    args.first().zip(args.last()).map(|(first, last)| {
+                                        first.span.source_callsite().to(last.span.source_callsite())
+                                    }),
+                                    None,
+                                )
+                            } else {
+                                return;
+                            }
+                        },
+                    };
+
+                    if let Entry::Vacant(entry) = self.span_to_state.entry(vec_span) {
+                        entry.insert(VecState::Change {
+                            suggest_ty,
+                            vec_snippet,
+                            expr_hir_id: expr.hir_id,
+                        });
+                    }
+                },
+                VecToArray::Impossible => {
+                    self.span_to_state.insert(vec_span, VecState::NoChange);
+                },
+            }
+        }
+    }
 
     fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
-        for (span, lint_opt) in &self.span_to_lint_map {
-            if let Some((hir_id, suggest_slice, snippet, applicability)) = lint_opt {
-                let help_msg = format!("you can use {} directly", suggest_slice.desc());
-                span_lint_hir_and_then(cx, USELESS_VEC, *hir_id, *span, "useless use of `vec!`", |diag| {
-                    // If the `vec!` macro contains comment, better not make the suggestion machine
-                    // applicable as it would remove them.
-                    let applicability = if *applicability != Applicability::Unspecified
-                        && let source_map = cx.tcx.sess.source_map()
-                        && span_contains_comment(source_map, *span)
-                    {
+        for (span, state) in mem::take(&mut self.span_to_state) {
+            if let VecState::Change {
+                suggest_ty,
+                vec_snippet,
+                expr_hir_id,
+            } = state
+            {
+                span_lint_hir_and_then(cx, USELESS_VEC, expr_hir_id, span, "useless use of `vec!`", |diag| {
+                    let help_msg = format!("you can use {} directly", suggest_ty.desc());
+                    // If the `vec!` macro contains comment, better not make the suggestion machine applicable as it
+                    // would remove them.
+                    let applicability = if span_contains_comment(cx.tcx.sess.source_map(), span) {
                         Applicability::Unspecified
                     } else {
-                        *applicability
+                        Applicability::MachineApplicable
                     };
-                    diag.span_suggestion(*span, help_msg, snippet, applicability);
+                    diag.span_suggestion(span, help_msg, vec_snippet, applicability);
                 });
             }
         }
     }
 }
 
-impl UselessVec {
-    fn check_vec_macro<'tcx>(
-        &mut self,
-        cx: &LateContext<'tcx>,
-        vec_args: &higher::VecArgs<'tcx>,
-        span: Span,
-        hir_id: HirId,
-        suggest_slice: SuggestedType,
-    ) {
-        if span.from_expansion() {
-            return;
-        }
-
-        let snippet = match *vec_args {
-            higher::VecArgs::Repeat(elem, len) => {
-                if let Some(Constant::Int(len_constant)) = ConstEvalCtxt::new(cx).eval(len) {
-                    // vec![ty; N] works when ty is Clone, [ty; N] requires it to be Copy also
-                    if !is_copy(cx, cx.typeck_results().expr_ty(elem)) {
-                        return;
-                    }
-
-                    #[expect(clippy::cast_possible_truncation)]
-                    if len_constant as u64 * size_of(cx, elem) > self.too_large_for_stack {
-                        return;
-                    }
-
-                    suggest_slice.snippet(cx, Some(elem.span), Some(len.span))
-                } else {
-                    return;
-                }
-            },
-            higher::VecArgs::Vec(args) => {
-                let args_span = if let Some(last) = args.iter().last() {
-                    if args.len() as u64 * size_of(cx, last) > self.too_large_for_stack {
-                        return;
-                    }
-                    Some(args[0].span.source_callsite().to(last.span.source_callsite()))
-                } else {
-                    None
-                };
-                suggest_slice.snippet(cx, args_span, None)
-            },
-        };
-
-        self.span_to_lint_map.entry(span).or_insert(Some((
-            hir_id,
-            suggest_slice,
-            snippet,
-            Applicability::MachineApplicable,
-        )));
-    }
-}
-
 #[derive(Copy, Clone)]
 pub(crate) enum SuggestedType {
     /// Suggest using a slice `&[..]` / `&mut [..]`
@@ -221,11 +271,17 @@ impl SuggestedType {
     }
 
     fn snippet(self, cx: &LateContext<'_>, args_span: Option<Span>, len_span: Option<Span>) -> String {
+        // Invariant of the lint as implemented: all spans are from the root context (and as a result,
+        // always trivially crate-local).
+        assert!(args_span.is_none_or(|s| !s.from_expansion()));
+        assert!(len_span.is_none_or(|s| !s.from_expansion()));
+
         let maybe_args = args_span
-            .and_then(|sp| sp.get_source_text(cx))
+            .map(|sp| sp.get_source_text(cx).expect("spans are always crate-local"))
             .map_or(String::new(), |x| x.to_owned());
         let maybe_len = len_span
-            .and_then(|sp| sp.get_source_text(cx).map(|s| format!("; {s}")))
+            .map(|sp| sp.get_source_text(cx).expect("spans are always crate-local"))
+            .map(|st| format!("; {st}"))
             .unwrap_or_default();
 
         match self {
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index a15e4e42e71..c55c5ec2f51 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -537,7 +537,7 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
 
             sug_span = Some(sug_span.unwrap_or(arg.expr.span).to(arg.expr.span));
 
-            if let Some((_, index)) = positional_arg_piece_span(piece) {
+            if let Some((_, index)) = format_arg_piece_span(piece) {
                 replaced_position.push(index);
             }
 
@@ -569,16 +569,11 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
     }
 }
 
-/// Extract Span and its index from the given `piece`, if it's positional argument.
-fn positional_arg_piece_span(piece: &FormatArgsPiece) -> Option<(Span, usize)> {
+/// Extract Span and its index from the given `piece`
+fn format_arg_piece_span(piece: &FormatArgsPiece) -> Option<(Span, usize)> {
     match piece {
         FormatArgsPiece::Placeholder(FormatPlaceholder {
-            argument:
-                FormatArgPosition {
-                    index: Ok(index),
-                    kind: FormatArgPositionKind::Number,
-                    ..
-                },
+            argument: FormatArgPosition { index: Ok(index), .. },
             span: Some(span),
             ..
         }) => Some((*span, *index)),
diff --git a/src/tools/clippy/clippy_lints/src/zombie_processes.rs b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
index 6ab94a52210..a934d2094e0 100644
--- a/src/tools/clippy/clippy_lints/src/zombie_processes.rs
+++ b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
@@ -1,5 +1,6 @@
 use ControlFlow::{Break, Continue};
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{fn_def_id, get_enclosing_block, path_to_local_id};
 use rustc_ast::Mutability;
 use rustc_ast::visit::visit_opt;
@@ -58,8 +59,8 @@ declare_lint_pass!(ZombieProcesses => [ZOMBIE_PROCESSES]);
 impl<'tcx> LateLintPass<'tcx> for ZombieProcesses {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if let ExprKind::Call(..) | ExprKind::MethodCall(..) = expr.kind
-            && let Some(child_adt) = cx.typeck_results().expr_ty(expr).ty_adt_def()
-            && cx.tcx.is_diagnostic_item(sym::Child, child_adt.did())
+            && let child_ty = cx.typeck_results().expr_ty(expr)
+            && is_type_diagnostic_item(cx, child_ty, sym::Child)
         {
             match cx.tcx.parent_hir_node(expr.hir_id) {
                 Node::LetStmt(local)
@@ -177,8 +178,8 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
                 Node::Expr(expr) if let ExprKind::AddrOf(_, Mutability::Not, _) = expr.kind => {},
                 Node::Expr(expr)
                     if let Some(fn_did) = fn_def_id(self.cx, expr)
-                        && (self.cx.tcx.is_diagnostic_item(sym::child_id, fn_did)
-                            || self.cx.tcx.is_diagnostic_item(sym::child_kill, fn_did)) => {},
+                        && let Some(fn_name) = self.cx.tcx.get_diagnostic_name(fn_did)
+                        && matches!(fn_name, sym::child_id | sym::child_kill) => {},
 
                 // Conservatively assume that all other kinds of nodes call `.wait()` somehow.
                 _ => return Break(MaybeWait(ex.span)),
@@ -351,9 +352,14 @@ fn check<'tcx>(cx: &LateContext<'tcx>, spawn_expr: &'tcx Expr<'tcx>, cause: Caus
 
 /// Checks if the given expression exits the process.
 fn is_exit_expression(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    fn_def_id(cx, expr).is_some_and(|fn_did| {
-        cx.tcx.is_diagnostic_item(sym::process_exit, fn_did) || cx.tcx.is_diagnostic_item(sym::process_abort, fn_did)
-    })
+    if let Some(fn_did) = fn_def_id(cx, expr)
+        && let Some(fn_name) = cx.tcx.get_diagnostic_name(fn_did)
+        && matches!(fn_name, sym::process_exit | sym::process_abort)
+    {
+        true
+    } else {
+        false
+    }
 }
 
 #[derive(Debug)]
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
index 2dfe28953d0..e01f563c49e 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-08-22
+nightly-2025-09-04
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 40c00568a3b..ad69e6eb184 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -21,7 +21,7 @@ pub fn is_useless_with_eq_exprs(kind: BinOpKind) -> bool {
 }
 
 /// Checks if each element in the first slice is contained within the latter as per `eq_fn`.
-pub fn unordered_over<X>(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
+pub fn unordered_over<X, Y>(left: &[X], right: &[Y], mut eq_fn: impl FnMut(&X, &Y) -> bool) -> bool {
     left.len() == right.len() && left.iter().all(|l| right.iter().any(|r| eq_fn(l, r)))
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index 4e0b00df950..bda28a663fb 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -287,23 +287,22 @@ impl<'a> VecArgs<'a> {
             && let ExprKind::Path(ref qpath) = fun.kind
             && is_expn_of(fun.span, sym::vec).is_some()
             && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
+            && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id)
         {
-            return if cx.tcx.is_diagnostic_item(sym::vec_from_elem, fun_def_id) && args.len() == 2 {
-                // `vec![elem; size]` case
-                Some(VecArgs::Repeat(&args[0], &args[1]))
-            } else if cx.tcx.is_diagnostic_item(sym::slice_into_vec, fun_def_id) && args.len() == 1 {
-                // `vec![a, b, c]` case
-                if let ExprKind::Call(_, [arg]) = &args[0].kind
-                    && let ExprKind::Array(args) = arg.kind
+            return match (name, args) {
+                (sym::vec_from_elem, [elem, size]) => {
+                    // `vec![elem; size]` case
+                    Some(VecArgs::Repeat(elem, size))
+                },
+                (sym::slice_into_vec, [slice])
+                    if let ExprKind::Call(_, [arg]) = slice.kind
+                        && let ExprKind::Array(args) = arg.kind =>
                 {
+                    // `vec![a, b, c]` case
                     Some(VecArgs::Vec(args))
-                } else {
-                    None
-                }
-            } else if cx.tcx.is_diagnostic_item(sym::vec_new, fun_def_id) && args.is_empty() {
-                Some(VecArgs::Vec(&[]))
-            } else {
-                None
+                },
+                (sym::vec_new, []) => Some(VecArgs::Vec(&[])),
+                _ => None,
             };
         }
 
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 8160443f413..b79e15cd717 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -757,7 +757,7 @@ pub fn both_some_and<X, Y>(l: Option<X>, r: Option<Y>, mut pred: impl FnMut(X, Y
 }
 
 /// Checks if two slices are equal as per `eq_fn`.
-pub fn over<X>(left: &[X], right: &[X], mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
+pub fn over<X, Y>(left: &[X], right: &[Y], mut eq_fn: impl FnMut(&X, &Y) -> bool) -> bool {
     left.len() == right.len() && left.iter().zip(right).all(|(x, y)| eq_fn(x, y))
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 011c9b2f931..14b64eb4d54 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -102,9 +102,9 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
 use rustc_hir::{
     self as hir, Arm, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, CoroutineDesugaring,
-    CoroutineKind, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg, GenericArgs, HirId, Impl,
-    ImplItem, ImplItemKind, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
-    Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem,
+    CoroutineKind, CoroutineSource, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg, GenericArgs,
+    HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId,
+    OwnerNode, Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem,
     TraitItemKind, TraitRef, TyKind, UnOp, def, find_attr,
 };
 use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
@@ -126,6 +126,7 @@ use rustc_span::{InnerSpan, Span};
 use source::{SpanRangeExt, walk_span_to_context};
 use visitors::{Visitable, for_each_unconsumed_temporary};
 
+use crate::ast_utils::unordered_over;
 use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
 use crate::higher::Range;
 use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};
@@ -308,6 +309,7 @@ pub fn is_lang_item_or_ctor(cx: &LateContext<'_>, did: DefId, item: LangItem) ->
     cx.tcx.lang_items().get(item) == Some(did)
 }
 
+/// Checks if `expr` is an empty block or an empty tuple.
 pub fn is_unit_expr(expr: &Expr<'_>) -> bool {
     matches!(
         expr.kind,
@@ -640,9 +642,8 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
         && let Some(impl_did) = cx.tcx.impl_of_assoc(def_id)
         && let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def()
     {
-        return std_types_symbols.iter().any(|&symbol| {
-            cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string()
-        });
+        return Some(adt.did()) == cx.tcx.lang_items().string()
+            || (cx.tcx.get_diagnostic_name(adt.did())).is_some_and(|adt_name| std_types_symbols.contains(&adt_name));
     }
     false
 }
@@ -1992,7 +1993,7 @@ pub fn is_expr_identity_of_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<
         (PatKind::Tuple(pats, dotdot), ExprKind::Tup(tup))
             if dotdot.as_opt_usize().is_none() && pats.len() == tup.len() =>
         {
-            zip(pats, tup).all(|(pat, expr)| is_expr_identity_of_pat(cx, pat, expr, by_hir))
+            over(pats, tup, |pat, expr| is_expr_identity_of_pat(cx, pat, expr, by_hir))
         },
         (PatKind::Slice(before, None, after), ExprKind::Array(arr)) if before.len() + after.len() == arr.len() => {
             zip(before.iter().chain(after), arr).all(|(pat, expr)| is_expr_identity_of_pat(cx, pat, expr, by_hir))
@@ -2004,7 +2005,7 @@ pub fn is_expr_identity_of_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<
             if let ExprKind::Path(ident) = &ident.kind
                 && qpath_res(&pat_ident, pat.hir_id) == qpath_res(ident, expr.hir_id)
                 // check fields
-                && zip(field_pats, fields).all(|(pat, expr)| is_expr_identity_of_pat(cx, pat, expr,by_hir))
+                && over(field_pats, fields, |pat, expr| is_expr_identity_of_pat(cx, pat, expr,by_hir))
             {
                 true
             } else {
@@ -2017,10 +2018,8 @@ pub fn is_expr_identity_of_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<
             // check ident
             qpath_res(&pat_ident, pat.hir_id) == qpath_res(ident, expr.hir_id)
                 // check fields
-                && field_pats.iter().all(|field_pat| {
-                    fields.iter().any(|field| {
-                        field_pat.ident == field.ident && is_expr_identity_of_pat(cx, field_pat.pat, field.expr, by_hir)
-                    })
+                && unordered_over(field_pats, fields, |field_pat, field| {
+                    field_pat.ident == field.ident && is_expr_identity_of_pat(cx, field_pat.pat, field.expr, by_hir)
                 })
         },
         _ => false,
@@ -2405,6 +2404,24 @@ pub fn peel_ref_operators<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>
     expr
 }
 
+/// Returns a `Vec` of `Expr`s containing `AddrOf` operators (`&`) or deref operators (`*`) of a
+/// given expression.
+pub fn get_ref_operators<'hir>(cx: &LateContext<'_>, expr: &'hir Expr<'hir>) -> Vec<&'hir Expr<'hir>> {
+    let mut operators = Vec::new();
+    peel_hir_expr_while(expr, |expr| match expr.kind {
+        ExprKind::AddrOf(_, _, e) => {
+            operators.push(expr);
+            Some(e)
+        },
+        ExprKind::Unary(UnOp::Deref, e) if cx.typeck_results().expr_ty(e).is_ref() => {
+            operators.push(expr);
+            Some(e)
+        },
+        _ => None,
+    });
+    operators
+}
+
 pub fn is_hir_ty_cfg_dependant(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
     if let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
         && let Res::Def(_, def_id) = path.res
@@ -3633,3 +3650,17 @@ pub fn expr_adjustment_requires_coercion(cx: &LateContext<'_>, expr: &Expr<'_>)
         )
     })
 }
+
+/// Checks if the expression is an async block (i.e., `async { ... }`).
+pub fn is_expr_async_block(expr: &Expr<'_>) -> bool {
+    matches!(
+        expr.kind,
+        ExprKind::Closure(Closure {
+            kind: hir::ClosureKind::Coroutine(CoroutineKind::Desugared(
+                CoroutineDesugaring::Async,
+                CoroutineSource::Block
+            )),
+            ..
+        })
+    )
+}
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index fafc1d07e51..8e302f9d2ad 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -387,10 +387,7 @@ pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
 /// Checks if the type is a reference equals to a diagnostic item
 pub fn is_type_ref_to_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symbol) -> bool {
     match ty.kind() {
-        ty::Ref(_, ref_ty, _) => match ref_ty.kind() {
-            ty::Adt(adt, _) => cx.tcx.is_diagnostic_item(diag_item, adt.did()),
-            _ => false,
-        },
+        ty::Ref(_, ref_ty, _) => is_type_diagnostic_item(cx, *ref_ty, diag_item),
         _ => false,
     }
 }
@@ -1378,9 +1375,7 @@ pub fn has_non_owning_mutable_access<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'
 
 /// Check if `ty` is slice-like, i.e., `&[T]`, `[T; N]`, or `Vec<T>`.
 pub fn is_slice_like<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
-    ty.is_slice()
-        || ty.is_array()
-        || matches!(ty.kind(), ty::Adt(adt_def, _) if cx.tcx.is_diagnostic_item(sym::Vec, adt_def.did()))
+    ty.is_slice() || ty.is_array() || is_type_diagnostic_item(cx, ty, sym::Vec)
 }
 
 pub fn get_field_idx_by_name(ty: Ty<'_>, name: Symbol) -> Option<usize> {
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index 76d43feee12..6eccbcdb122 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -144,11 +144,9 @@ impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> {
 
 /// Checks if the given expression is a macro call to `todo!()` or `unimplemented!()`.
 pub fn is_todo_unimplemented_macro(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    root_macro_call_first_node(cx, expr).is_some_and(|macro_call| {
-        [sym::todo_macro, sym::unimplemented_macro]
-            .iter()
-            .any(|&sym| cx.tcx.is_diagnostic_item(sym, macro_call.def_id))
-    })
+    root_macro_call_first_node(cx, expr)
+        .and_then(|macro_call| cx.tcx.get_diagnostic_name(macro_call.def_id))
+        .is_some_and(|macro_name| matches!(macro_name, sym::todo_macro | sym::unimplemented_macro))
 }
 
 /// Checks if the given expression is a stub, i.e., a `todo!()` or `unimplemented!()` expression,
diff --git a/src/tools/clippy/rust-toolchain.toml b/src/tools/clippy/rust-toolchain.toml
index 5497e77e8ad..ec2f24a0a6d 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-08-22"
+channel = "nightly-2025-09-04"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index c4076cbaa77..6bddcbfd94c 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -330,7 +330,8 @@ pub fn main() {
 
         // Do not run Clippy for Cargo's info queries so that invalid CLIPPY_ARGS are not cached
         // https://github.com/rust-lang/cargo/issues/14385
-        let info_query = has_arg(&orig_args, "-vV") || has_arg(&orig_args, "--print");
+        let info_query = has_arg(&orig_args, "-vV")
+            || arg_value(&orig_args, "--print", |val| val != "crate-root-lint-levels").is_some();
 
         let clippy_enabled = !cap_lints_allow && relevant_package && !info_query;
         if clippy_enabled {
diff --git a/src/tools/clippy/tests/config-consistency.rs b/src/tools/clippy/tests/config-consistency.rs
new file mode 100644
index 00000000000..9e7ca26c7d4
--- /dev/null
+++ b/src/tools/clippy/tests/config-consistency.rs
@@ -0,0 +1,30 @@
+#![feature(rustc_private)]
+
+// This test checks that all lints defined in `clippy_config::conf` in `#[lints]`
+// attributes exist as Clippy lints.
+//
+// This test is a no-op if run as part of the compiler test suite
+// and will always succeed.
+
+use std::collections::HashSet;
+
+#[test]
+fn config_consistency() {
+    if option_env!("RUSTC_TEST_SUITE").is_some() {
+        return;
+    }
+
+    let lint_names: HashSet<String> = clippy_lints::declared_lints::LINTS
+        .iter()
+        .map(|lint_info| lint_info.lint.name.strip_prefix("clippy::").unwrap().to_lowercase())
+        .collect();
+    for conf in clippy_config::get_configuration_metadata() {
+        for lint in conf.lints {
+            assert!(
+                lint_names.contains(*lint),
+                "Configuration option {} references lint `{lint}` which does not exist",
+                conf.name
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/no-profile-in-cargo-toml.rs b/src/tools/clippy/tests/no-profile-in-cargo-toml.rs
new file mode 100644
index 00000000000..2ad9bfb75de
--- /dev/null
+++ b/src/tools/clippy/tests/no-profile-in-cargo-toml.rs
@@ -0,0 +1,34 @@
+// Check that we do not have `profile.*` sections in our `Cargo.toml` files,
+// as this causes warnings when run from the compiler repository which includes
+// Clippy in a workspace.
+//
+// Those sections can be put into `.cargo/config.toml` which will be read
+// when commands are issued from the top-level Clippy directory, outside of
+// a workspace.
+
+use std::fs::File;
+use std::io::{self, BufRead as _};
+use walkdir::WalkDir;
+
+#[test]
+fn no_profile_in_cargo_toml() {
+    // This check could parse `Cargo.toml` using a TOML deserializer, but in practice
+    // profile sections would be added at the beginning of a line as `[profile.*]`, so
+    // keep it fast and simple.
+    for entry in WalkDir::new(".")
+        .into_iter()
+        .filter_map(Result::ok)
+        .filter(|e| e.file_name().to_str() == Some("Cargo.toml"))
+    {
+        for line in io::BufReader::new(File::open(entry.path()).unwrap())
+            .lines()
+            .map(Result::unwrap)
+        {
+            if line.starts_with("[profile.") {
+                eprintln!("Profile section `{line}` found in file `{}`.", entry.path().display());
+                eprintln!("Use `.cargo/config.toml` for profiles specific to the standalone Clippy repository.");
+                panic!("Profile section found in `Cargo.toml`");
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
index f03a745963e..e9d53c64dd9 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
@@ -4,7 +4,7 @@ error: use of a disallowed method `rustc_lint::context::LintContext::span_lint`
 LL |     cx.span_lint(lint, span, |lint| {
    |        ^^^^^^^^^
    |
-   = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint*` functions instead
+   = note: this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint*` functions instead
 note: the lint level is defined here
   --> tests/ui-internal/disallow_span_lint.rs:2:9
    |
@@ -17,7 +17,7 @@ error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_
 LL |     tcx.node_span_lint(lint, hir_id, span, |lint| {
    |         ^^^^^^^^^^^^^^
    |
-   = note: this function does not add a link to our documentation, please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead
+   = note: this function does not add a link to our documentation; please use the `clippy_utils::diagnostics::span_lint_hir*` functions instead
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/excessive_precision/clippy.toml b/src/tools/clippy/tests/ui-toml/excessive_precision/clippy.toml
new file mode 100644
index 00000000000..c7fc230dcb3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/excessive_precision/clippy.toml
@@ -0,0 +1 @@
+const-literal-digits-threshold = 20
diff --git a/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.fixed b/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.fixed
new file mode 100644
index 00000000000..577bbff2957
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.fixed
@@ -0,0 +1,38 @@
+#![warn(clippy::excessive_precision)]
+#![allow(
+    dead_code,
+    overflowing_literals,
+    unused_variables,
+    clippy::print_literal,
+    clippy::useless_vec
+)]
+
+fn main() {
+    // Overly specified constants
+    let _: f32 = 1.012_345_7;
+    //~^ excessive_precision
+    let _: f64 = 1.012_345_678_901_234_6;
+    //~^ excessive_precision
+    const _: f32 = 1.012345678901234567890;
+    const _: f64 = 1.012345678901234567890;
+
+    static STATIC1: f32 = 1.012345678901234567890;
+    static STATIC2: f64 = 1.012345678901234567890;
+
+    static mut STATIC_MUT1: f32 = 1.012345678901234567890;
+    static mut STATIC_MUT2: f64 = 1.012345678901234567890;
+}
+
+trait ExcessivelyPreciseTrait {
+    // Overly specified constants
+    const GOOD1: f32 = 1.012345678901234567890;
+    const GOOD2: f64 = 1.012345678901234567890;
+}
+
+struct ExcessivelyPreciseStruct;
+
+impl ExcessivelyPreciseStruct {
+    // Overly specified constants
+    const GOOD1: f32 = 1.012345678901234567890;
+    const GOOD2: f64 = 1.012345678901234567890;
+}
diff --git a/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.rs b/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.rs
new file mode 100644
index 00000000000..121448ed540
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.rs
@@ -0,0 +1,38 @@
+#![warn(clippy::excessive_precision)]
+#![allow(
+    dead_code,
+    overflowing_literals,
+    unused_variables,
+    clippy::print_literal,
+    clippy::useless_vec
+)]
+
+fn main() {
+    // Overly specified constants
+    let _: f32 = 1.012345678901234567890;
+    //~^ excessive_precision
+    let _: f64 = 1.012345678901234567890;
+    //~^ excessive_precision
+    const _: f32 = 1.012345678901234567890;
+    const _: f64 = 1.012345678901234567890;
+
+    static STATIC1: f32 = 1.012345678901234567890;
+    static STATIC2: f64 = 1.012345678901234567890;
+
+    static mut STATIC_MUT1: f32 = 1.012345678901234567890;
+    static mut STATIC_MUT2: f64 = 1.012345678901234567890;
+}
+
+trait ExcessivelyPreciseTrait {
+    // Overly specified constants
+    const GOOD1: f32 = 1.012345678901234567890;
+    const GOOD2: f64 = 1.012345678901234567890;
+}
+
+struct ExcessivelyPreciseStruct;
+
+impl ExcessivelyPreciseStruct {
+    // Overly specified constants
+    const GOOD1: f32 = 1.012345678901234567890;
+    const GOOD2: f64 = 1.012345678901234567890;
+}
diff --git a/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.stderr b/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.stderr
new file mode 100644
index 00000000000..65d33eddef1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/excessive_precision/excessive_precision.stderr
@@ -0,0 +1,38 @@
+error: float has excessive precision
+  --> tests/ui-toml/excessive_precision/excessive_precision.rs:12:18
+   |
+LL |     let _: f32 = 1.012345678901234567890;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: consider making it a `const` item
+  --> tests/ui-toml/excessive_precision/excessive_precision.rs:12:5
+   |
+LL |     let _: f32 = 1.012345678901234567890;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::excessive-precision` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::excessive_precision)]`
+help: consider changing the type or truncating it to
+   |
+LL -     let _: f32 = 1.012345678901234567890;
+LL +     let _: f32 = 1.012_345_7;
+   |
+
+error: float has excessive precision
+  --> tests/ui-toml/excessive_precision/excessive_precision.rs:14:18
+   |
+LL |     let _: f64 = 1.012345678901234567890;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: consider making it a `const` item
+  --> tests/ui-toml/excessive_precision/excessive_precision.rs:14:5
+   |
+LL |     let _: f64 = 1.012345678901234567890;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the type or truncating it to
+   |
+LL -     let _: f64 = 1.012345678901234567890;
+LL +     let _: f64 = 1.012_345_678_901_234_6;
+   |
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index 6ee77ebd8ec..20aeb4bb849 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -35,6 +35,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            check-inconsistent-struct-field-initializers
            check-private-items
            cognitive-complexity-threshold
+           const-literal-digits-threshold
            disallowed-macros
            disallowed-methods
            disallowed-names
@@ -129,6 +130,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            check-inconsistent-struct-field-initializers
            check-private-items
            cognitive-complexity-threshold
+           const-literal-digits-threshold
            disallowed-macros
            disallowed-methods
            disallowed-names
@@ -223,6 +225,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            check-inconsistent-struct-field-initializers
            check-private-items
            cognitive-complexity-threshold
+           const-literal-digits-threshold
            disallowed-macros
            disallowed-methods
            disallowed-names
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
index 09c1a8d0ed1..b2b7318c113 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.fixed
@@ -82,9 +82,18 @@ fn main() {
     assert!(r.is_err());
 }
 
-#[allow(dead_code)]
 fn issue9450() {
     let res: Result<i32, i32> = Ok(1);
     res.unwrap_err();
     //~^ assertions_on_result_states
 }
+
+fn issue9916(res: Result<u32, u32>) {
+    let a = 0;
+    match a {
+        0 => {},
+        1 => { res.unwrap(); },
+        //~^ assertions_on_result_states
+        _ => todo!(),
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.rs b/src/tools/clippy/tests/ui/assertions_on_result_states.rs
index c63c2502b53..33f1485326b 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.rs
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.rs
@@ -82,9 +82,18 @@ fn main() {
     assert!(r.is_err());
 }
 
-#[allow(dead_code)]
 fn issue9450() {
     let res: Result<i32, i32> = Ok(1);
     assert!(res.is_err())
     //~^ assertions_on_result_states
 }
+
+fn issue9916(res: Result<u32, u32>) {
+    let a = 0;
+    match a {
+        0 => {},
+        1 => assert!(res.is_ok()),
+        //~^ assertions_on_result_states
+        _ => todo!(),
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
index 3bf811588c6..826f049555c 100644
--- a/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
+++ b/src/tools/clippy/tests/ui/assertions_on_result_states.stderr
@@ -38,10 +38,16 @@ LL |     assert!(r.is_err());
    |     ^^^^^^^^^^^^^^^^^^^ help: replace with: `r.unwrap_err()`
 
 error: called `assert!` with `Result::is_err`
-  --> tests/ui/assertions_on_result_states.rs:88:5
+  --> tests/ui/assertions_on_result_states.rs:87:5
    |
 LL |     assert!(res.is_err())
    |     ^^^^^^^^^^^^^^^^^^^^^ help: replace with: `res.unwrap_err();`
 
-error: aborting due to 7 previous errors
+error: called `assert!` with `Result::is_ok`
+  --> tests/ui/assertions_on_result_states.rs:95:14
+   |
+LL |         1 => assert!(res.is_ok()),
+   |              ^^^^^^^^^^^^^^^^^^^^ help: replace with: `{ res.unwrap(); }`
+
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/assign_ops.fixed b/src/tools/clippy/tests/ui/assign_ops.fixed
index 3754b9dfe74..2046d089d6a 100644
--- a/src/tools/clippy/tests/ui/assign_ops.fixed
+++ b/src/tools/clippy/tests/ui/assign_ops.fixed
@@ -1,8 +1,9 @@
 #![allow(clippy::useless_vec)]
 #![warn(clippy::assign_op_pattern)]
-#![feature(const_trait_impl, const_ops)]
+#![feature(const_ops)]
+#![feature(const_trait_impl)]
 
-use core::num::Wrapping;
+use std::num::Wrapping;
 use std::ops::{Mul, MulAssign};
 
 fn main() {
@@ -82,6 +83,18 @@ mod issue14871 {
     pub trait Number: Copy + Add<Self, Output = Self> + AddAssign {
         const ZERO: Self;
         const ONE: Self;
+
+        fn non_constant(value: usize) -> Self {
+            let mut res = Self::ZERO;
+            let mut count = 0;
+            while count < value {
+                res += Self::ONE;
+                //~^ assign_op_pattern
+                count += 1;
+                //~^ assign_op_pattern
+            }
+            res
+        }
     }
 
     #[rustfmt::skip] // rustfmt doesn't understand the order of pub const on traits (yet)
@@ -91,7 +104,7 @@ mod issue14871 {
 
     impl<T> const NumberConstants for T
     where
-        T: Number + [const] core::ops::Add,
+        T: Number + [const] std::ops::Add,
     {
         fn constant(value: usize) -> Self {
             let mut res = Self::ZERO;
@@ -99,8 +112,28 @@ mod issue14871 {
             while count < value {
                 res = res + Self::ONE;
                 count += 1;
+                //~^ assign_op_pattern
             }
             res
         }
     }
+
+    pub struct S;
+
+    impl const std::ops::Add for S {
+        type Output = S;
+        fn add(self, _rhs: S) -> S {
+            S
+        }
+    }
+
+    impl const std::ops::AddAssign for S {
+        fn add_assign(&mut self, rhs: S) {}
+    }
+
+    const fn do_add() {
+        let mut s = S;
+        s += S;
+        //~^ assign_op_pattern
+    }
 }
diff --git a/src/tools/clippy/tests/ui/assign_ops.rs b/src/tools/clippy/tests/ui/assign_ops.rs
index 0b878d4f490..f83a40f5547 100644
--- a/src/tools/clippy/tests/ui/assign_ops.rs
+++ b/src/tools/clippy/tests/ui/assign_ops.rs
@@ -1,8 +1,9 @@
 #![allow(clippy::useless_vec)]
 #![warn(clippy::assign_op_pattern)]
-#![feature(const_trait_impl, const_ops)]
+#![feature(const_ops)]
+#![feature(const_trait_impl)]
 
-use core::num::Wrapping;
+use std::num::Wrapping;
 use std::ops::{Mul, MulAssign};
 
 fn main() {
@@ -82,6 +83,18 @@ mod issue14871 {
     pub trait Number: Copy + Add<Self, Output = Self> + AddAssign {
         const ZERO: Self;
         const ONE: Self;
+
+        fn non_constant(value: usize) -> Self {
+            let mut res = Self::ZERO;
+            let mut count = 0;
+            while count < value {
+                res = res + Self::ONE;
+                //~^ assign_op_pattern
+                count = count + 1;
+                //~^ assign_op_pattern
+            }
+            res
+        }
     }
 
     #[rustfmt::skip] // rustfmt doesn't understand the order of pub const on traits (yet)
@@ -91,16 +104,36 @@ mod issue14871 {
 
     impl<T> const NumberConstants for T
     where
-        T: Number + [const] core::ops::Add,
+        T: Number + [const] std::ops::Add,
     {
         fn constant(value: usize) -> Self {
             let mut res = Self::ZERO;
             let mut count = 0;
             while count < value {
                 res = res + Self::ONE;
-                count += 1;
+                count = count + 1;
+                //~^ assign_op_pattern
             }
             res
         }
     }
+
+    pub struct S;
+
+    impl const std::ops::Add for S {
+        type Output = S;
+        fn add(self, _rhs: S) -> S {
+            S
+        }
+    }
+
+    impl const std::ops::AddAssign for S {
+        fn add_assign(&mut self, rhs: S) {}
+    }
+
+    const fn do_add() {
+        let mut s = S;
+        s = s + S;
+        //~^ assign_op_pattern
+    }
 }
diff --git a/src/tools/clippy/tests/ui/assign_ops.stderr b/src/tools/clippy/tests/ui/assign_ops.stderr
index c5e698b3ee1..a4fca04893c 100644
--- a/src/tools/clippy/tests/ui/assign_ops.stderr
+++ b/src/tools/clippy/tests/ui/assign_ops.stderr
@@ -1,5 +1,5 @@
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:10:5
+  --> tests/ui/assign_ops.rs:11:5
    |
 LL |     a = a + 1;
    |     ^^^^^^^^^ help: replace it with: `a += 1`
@@ -8,70 +8,94 @@ LL |     a = a + 1;
    = help: to override `-D warnings` add `#[allow(clippy::assign_op_pattern)]`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:12:5
+  --> tests/ui/assign_ops.rs:13:5
    |
 LL |     a = 1 + a;
    |     ^^^^^^^^^ help: replace it with: `a += 1`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:14:5
+  --> tests/ui/assign_ops.rs:15:5
    |
 LL |     a = a - 1;
    |     ^^^^^^^^^ help: replace it with: `a -= 1`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:16:5
+  --> tests/ui/assign_ops.rs:17:5
    |
 LL |     a = a * 99;
    |     ^^^^^^^^^^ help: replace it with: `a *= 99`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:18:5
+  --> tests/ui/assign_ops.rs:19:5
    |
 LL |     a = 42 * a;
    |     ^^^^^^^^^^ help: replace it with: `a *= 42`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:20:5
+  --> tests/ui/assign_ops.rs:21:5
    |
 LL |     a = a / 2;
    |     ^^^^^^^^^ help: replace it with: `a /= 2`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:22:5
+  --> tests/ui/assign_ops.rs:23:5
    |
 LL |     a = a % 5;
    |     ^^^^^^^^^ help: replace it with: `a %= 5`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:24:5
+  --> tests/ui/assign_ops.rs:25:5
    |
 LL |     a = a & 1;
    |     ^^^^^^^^^ help: replace it with: `a &= 1`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:31:5
+  --> tests/ui/assign_ops.rs:32:5
    |
 LL |     s = s + "bla";
    |     ^^^^^^^^^^^^^ help: replace it with: `s += "bla"`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:36:5
+  --> tests/ui/assign_ops.rs:37:5
    |
 LL |     a = a + Wrapping(1u32);
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a += Wrapping(1u32)`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:39:5
+  --> tests/ui/assign_ops.rs:40:5
    |
 LL |     v[0] = v[0] + v[1];
    |     ^^^^^^^^^^^^^^^^^^ help: replace it with: `v[0] += v[1]`
 
 error: manual implementation of an assign operation
-  --> tests/ui/assign_ops.rs:52:5
+  --> tests/ui/assign_ops.rs:53:5
    |
 LL |     buf = buf + cows.clone();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `buf += cows.clone()`
 
-error: aborting due to 12 previous errors
+error: manual implementation of an assign operation
+  --> tests/ui/assign_ops.rs:91:17
+   |
+LL |                 res = res + Self::ONE;
+   |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `res += Self::ONE`
+
+error: manual implementation of an assign operation
+  --> tests/ui/assign_ops.rs:93:17
+   |
+LL |                 count = count + 1;
+   |                 ^^^^^^^^^^^^^^^^^ help: replace it with: `count += 1`
+
+error: manual implementation of an assign operation
+  --> tests/ui/assign_ops.rs:114:17
+   |
+LL |                 count = count + 1;
+   |                 ^^^^^^^^^^^^^^^^^ help: replace it with: `count += 1`
+
+error: manual implementation of an assign operation
+  --> tests/ui/assign_ops.rs:136:9
+   |
+LL |         s = s + S;
+   |         ^^^^^^^^^ help: replace it with: `s += S`
+
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/async_yields_async.fixed b/src/tools/clippy/tests/ui/async_yields_async.fixed
index 93c573d3086..bd1b31f74ee 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.fixed
+++ b/src/tools/clippy/tests/ui/async_yields_async.fixed
@@ -80,3 +80,42 @@ fn check_expect_suppression() {
         }
     };
 }
+
+#[allow(clippy::let_underscore_future)]
+fn issue15552() {
+    async fn bar(i: i32) {}
+
+    macro_rules! call_bar {
+        () => {
+            async { bar(5).await }
+        };
+        ($e:expr) => {
+            bar($e)
+        };
+    }
+    let x = async { call_bar!(5).await };
+    //~^ async_yields_async
+    let y = async { call_bar!().await };
+    //~^ async_yields_async
+    //~| async_yields_async
+
+    use std::future::{Future, Ready};
+    use std::ops::Add;
+    use std::pin::Pin;
+    use std::task::{Context, Poll};
+    struct CustomFutureType;
+    impl Add for CustomFutureType {
+        type Output = Self;
+        fn add(self, other: Self) -> Self {
+            self
+        }
+    }
+    impl Future for CustomFutureType {
+        type Output = ();
+        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+            Poll::Ready(())
+        }
+    }
+    let _ = async { (CustomFutureType + CustomFutureType).await };
+    //~^ async_yields_async
+}
diff --git a/src/tools/clippy/tests/ui/async_yields_async.rs b/src/tools/clippy/tests/ui/async_yields_async.rs
index 166d522e1c0..605d2734157 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.rs
+++ b/src/tools/clippy/tests/ui/async_yields_async.rs
@@ -80,3 +80,42 @@ fn check_expect_suppression() {
         }
     };
 }
+
+#[allow(clippy::let_underscore_future)]
+fn issue15552() {
+    async fn bar(i: i32) {}
+
+    macro_rules! call_bar {
+        () => {
+            async { bar(5) }
+        };
+        ($e:expr) => {
+            bar($e)
+        };
+    }
+    let x = async { call_bar!(5) };
+    //~^ async_yields_async
+    let y = async { call_bar!() };
+    //~^ async_yields_async
+    //~| async_yields_async
+
+    use std::future::{Future, Ready};
+    use std::ops::Add;
+    use std::pin::Pin;
+    use std::task::{Context, Poll};
+    struct CustomFutureType;
+    impl Add for CustomFutureType {
+        type Output = Self;
+        fn add(self, other: Self) -> Self {
+            self
+        }
+    }
+    impl Future for CustomFutureType {
+        type Output = ();
+        fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+            Poll::Ready(())
+        }
+    }
+    let _ = async { CustomFutureType + CustomFutureType };
+    //~^ async_yields_async
+}
diff --git a/src/tools/clippy/tests/ui/async_yields_async.stderr b/src/tools/clippy/tests/ui/async_yields_async.stderr
index 17a35076fa3..3041cf65789 100644
--- a/src/tools/clippy/tests/ui/async_yields_async.stderr
+++ b/src/tools/clippy/tests/ui/async_yields_async.stderr
@@ -89,5 +89,50 @@ LL | |         CustomFutureType
 LL | |     };
    | |_____- outer async construct
 
-error: aborting due to 6 previous errors
+error: an async construct yields a type which is itself awaitable
+  --> tests/ui/async_yields_async.rs:96:21
+   |
+LL |     let x = async { call_bar!(5) };
+   |                   --^^^^^^^^^^^^--
+   |                   | |
+   |                   | awaitable value not awaited
+   |                   | help: consider awaiting this value: `call_bar!(5).await`
+   |                   outer async construct
+
+error: an async construct yields a type which is itself awaitable
+  --> tests/ui/async_yields_async.rs:98:21
+   |
+LL |     let y = async { call_bar!() };
+   |                   --^^^^^^^^^^^--
+   |                   | |
+   |                   | awaitable value not awaited
+   |                   | help: consider awaiting this value: `call_bar!().await`
+   |                   outer async construct
+
+error: an async construct yields a type which is itself awaitable
+  --> tests/ui/async_yields_async.rs:90:21
+   |
+LL |             async { bar(5) }
+   |                   --^^^^^^--
+   |                   | |
+   |                   | awaitable value not awaited
+   |                   | help: consider awaiting this value: `bar(5).await`
+   |                   outer async construct
+...
+LL |     let y = async { call_bar!() };
+   |                     ----------- in this macro invocation
+   |
+   = note: this error originates in the macro `call_bar` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: an async construct yields a type which is itself awaitable
+  --> tests/ui/async_yields_async.rs:119:21
+   |
+LL |     let _ = async { CustomFutureType + CustomFutureType };
+   |                   --^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--
+   |                   | |
+   |                   | awaitable value not awaited
+   |                   | help: consider awaiting this value: `(CustomFutureType + CustomFutureType).await`
+   |                   outer async construct
+
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/bool_comparison.fixed b/src/tools/clippy/tests/ui/bool_comparison.fixed
index 166abbe549c..b0b60104c0b 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.fixed
+++ b/src/tools/clippy/tests/ui/bool_comparison.fixed
@@ -1,97 +1,41 @@
 #![allow(non_local_definitions, clippy::needless_if)]
 #![warn(clippy::bool_comparison)]
-#![allow(clippy::non_canonical_partial_ord_impl, clippy::nonminimal_bool)]
+#![allow(clippy::non_canonical_partial_ord_impl)]
 
 fn main() {
     let x = true;
-    if x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if !x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if !x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if !x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if !x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if !x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if !x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
+    let _ = if x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if !x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if !x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if !x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if !x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if !x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if !x { "yes" } else { "no" };
+    //~^ bool_comparison
+
     let y = true;
-    if !x & y {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x & !y {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
+    let _ = if !x & y { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x & !y { "yes" } else { "no" };
+    //~^ bool_comparison
 }
 
-#[allow(dead_code)]
 fn issue3703() {
     struct Foo;
     impl PartialEq<bool> for Foo {
@@ -127,26 +71,6 @@ fn issue3703() {
     if false < Foo {}
 }
 
-#[allow(dead_code)]
-fn issue4983() {
-    let a = true;
-    let b = false;
-
-    if a != b {};
-    //~^ bool_comparison
-    if a != b {};
-    //~^ bool_comparison
-    if a == b {};
-    if !a == !b {};
-
-    if b != a {};
-    //~^ bool_comparison
-    if b != a {};
-    //~^ bool_comparison
-    if b == a {};
-    if !b == !a {};
-}
-
 macro_rules! m {
     ($func:ident) => {
         $func()
@@ -157,7 +81,6 @@ fn func() -> bool {
     true
 }
 
-#[allow(dead_code)]
 fn issue3973() {
     // ok, don't lint on `cfg` invocation
     if false == cfg!(feature = "debugging") {}
@@ -196,6 +119,34 @@ fn issue9907() {
     //~^ bool_comparison
     // This is not part of the issue, but an unexpected found when fixing the issue,
     // the provided span was inside of macro rather than the macro callsite.
-    let _ = ((1 < 2) != m!(func)) as usize;
+    let _ = ((1 < 2) & !m!(func)) as usize;
     //~^ bool_comparison
 }
+
+#[allow(clippy::nonminimal_bool)]
+fn issue15367() {
+    let a = true;
+    let b = false;
+
+    // these cases are handled by `nonminimal_bool`, so don't double-lint
+    if a == !b {};
+    if !a == b {};
+    if b == !a {};
+    if !b == a {};
+}
+
+fn issue15497() {
+    fn func() -> bool {
+        true
+    }
+
+    fn foo(x: bool) -> bool {
+        x & !m!(func)
+        //~^ bool_comparison
+    }
+
+    fn bar(x: bool) -> bool {
+        !x & m!(func)
+        //~^ bool_comparison
+    }
+}
diff --git a/src/tools/clippy/tests/ui/bool_comparison.rs b/src/tools/clippy/tests/ui/bool_comparison.rs
index 7265c2b4c5a..1b1108d6ce5 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.rs
+++ b/src/tools/clippy/tests/ui/bool_comparison.rs
@@ -1,97 +1,41 @@
 #![allow(non_local_definitions, clippy::needless_if)]
 #![warn(clippy::bool_comparison)]
-#![allow(clippy::non_canonical_partial_ord_impl, clippy::nonminimal_bool)]
+#![allow(clippy::non_canonical_partial_ord_impl)]
 
 fn main() {
     let x = true;
-    if x == true {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x == false {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if true == x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if false == x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x != true {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x != false {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if true != x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if false != x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x < true {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if false < x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x > false {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if true > x {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
+    let _ = if x == true { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x == false { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if true == x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if false == x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x != true { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x != false { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if true != x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if false != x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x < true { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if false < x { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x > false { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if true > x { "yes" } else { "no" };
+    //~^ bool_comparison
+
     let y = true;
-    if x < y {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
-    if x > y {
-        //~^ bool_comparison
-        "yes"
-    } else {
-        "no"
-    };
+    let _ = if x < y { "yes" } else { "no" };
+    //~^ bool_comparison
+    let _ = if x > y { "yes" } else { "no" };
+    //~^ bool_comparison
 }
 
-#[allow(dead_code)]
 fn issue3703() {
     struct Foo;
     impl PartialEq<bool> for Foo {
@@ -127,26 +71,6 @@ fn issue3703() {
     if false < Foo {}
 }
 
-#[allow(dead_code)]
-fn issue4983() {
-    let a = true;
-    let b = false;
-
-    if a == !b {};
-    //~^ bool_comparison
-    if !a == b {};
-    //~^ bool_comparison
-    if a == b {};
-    if !a == !b {};
-
-    if b == !a {};
-    //~^ bool_comparison
-    if !b == a {};
-    //~^ bool_comparison
-    if b == a {};
-    if !b == !a {};
-}
-
 macro_rules! m {
     ($func:ident) => {
         $func()
@@ -157,7 +81,6 @@ fn func() -> bool {
     true
 }
 
-#[allow(dead_code)]
 fn issue3973() {
     // ok, don't lint on `cfg` invocation
     if false == cfg!(feature = "debugging") {}
@@ -196,6 +119,34 @@ fn issue9907() {
     //~^ bool_comparison
     // This is not part of the issue, but an unexpected found when fixing the issue,
     // the provided span was inside of macro rather than the macro callsite.
-    let _ = ((1 < 2) == !m!(func)) as usize;
+    let _ = ((1 < 2) > m!(func)) as usize;
     //~^ bool_comparison
 }
+
+#[allow(clippy::nonminimal_bool)]
+fn issue15367() {
+    let a = true;
+    let b = false;
+
+    // these cases are handled by `nonminimal_bool`, so don't double-lint
+    if a == !b {};
+    if !a == b {};
+    if b == !a {};
+    if !b == a {};
+}
+
+fn issue15497() {
+    fn func() -> bool {
+        true
+    }
+
+    fn foo(x: bool) -> bool {
+        x > m!(func)
+        //~^ bool_comparison
+    }
+
+    fn bar(x: bool) -> bool {
+        x < m!(func)
+        //~^ bool_comparison
+    }
+}
diff --git a/src/tools/clippy/tests/ui/bool_comparison.stderr b/src/tools/clippy/tests/ui/bool_comparison.stderr
index ddbb9ff78ed..98881a2d20f 100644
--- a/src/tools/clippy/tests/ui/bool_comparison.stderr
+++ b/src/tools/clippy/tests/ui/bool_comparison.stderr
@@ -1,155 +1,143 @@
 error: equality checks against true are unnecessary
-  --> tests/ui/bool_comparison.rs:7:8
+  --> tests/ui/bool_comparison.rs:7:16
    |
-LL |     if x == true {
-   |        ^^^^^^^^^ help: try simplifying it as shown: `x`
+LL |     let _ = if x == true { "yes" } else { "no" };
+   |                ^^^^^^^^^ help: try: `x`
    |
    = note: `-D clippy::bool-comparison` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
 
 error: equality checks against false can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:13:8
+  --> tests/ui/bool_comparison.rs:9:16
    |
-LL |     if x == false {
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
+LL |     let _ = if x == false { "yes" } else { "no" };
+   |                ^^^^^^^^^^ help: try: `!x`
 
 error: equality checks against true are unnecessary
-  --> tests/ui/bool_comparison.rs:19:8
+  --> tests/ui/bool_comparison.rs:11:16
    |
-LL |     if true == x {
-   |        ^^^^^^^^^ help: try simplifying it as shown: `x`
+LL |     let _ = if true == x { "yes" } else { "no" };
+   |                ^^^^^^^^^ help: try: `x`
 
 error: equality checks against false can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:25:8
+  --> tests/ui/bool_comparison.rs:13:16
    |
-LL |     if false == x {
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
+LL |     let _ = if false == x { "yes" } else { "no" };
+   |                ^^^^^^^^^^ help: try: `!x`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:31:8
+  --> tests/ui/bool_comparison.rs:15:16
    |
-LL |     if x != true {
-   |        ^^^^^^^^^ help: try simplifying it as shown: `!x`
+LL |     let _ = if x != true { "yes" } else { "no" };
+   |                ^^^^^^^^^ help: try: `!x`
 
 error: inequality checks against false are unnecessary
-  --> tests/ui/bool_comparison.rs:37:8
+  --> tests/ui/bool_comparison.rs:17:16
    |
-LL |     if x != false {
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `x`
+LL |     let _ = if x != false { "yes" } else { "no" };
+   |                ^^^^^^^^^^ help: try: `x`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:43:8
+  --> tests/ui/bool_comparison.rs:19:16
    |
-LL |     if true != x {
-   |        ^^^^^^^^^ help: try simplifying it as shown: `!x`
+LL |     let _ = if true != x { "yes" } else { "no" };
+   |                ^^^^^^^^^ help: try: `!x`
 
 error: inequality checks against false are unnecessary
-  --> tests/ui/bool_comparison.rs:49:8
+  --> tests/ui/bool_comparison.rs:21:16
    |
-LL |     if false != x {
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `x`
+LL |     let _ = if false != x { "yes" } else { "no" };
+   |                ^^^^^^^^^^ help: try: `x`
 
 error: less than comparison against true can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:55:8
+  --> tests/ui/bool_comparison.rs:23:16
    |
-LL |     if x < true {
-   |        ^^^^^^^^ help: try simplifying it as shown: `!x`
+LL |     let _ = if x < true { "yes" } else { "no" };
+   |                ^^^^^^^^ help: try: `!x`
 
 error: greater than checks against false are unnecessary
-  --> tests/ui/bool_comparison.rs:61:8
+  --> tests/ui/bool_comparison.rs:25:16
    |
-LL |     if false < x {
-   |        ^^^^^^^^^ help: try simplifying it as shown: `x`
+LL |     let _ = if false < x { "yes" } else { "no" };
+   |                ^^^^^^^^^ help: try: `x`
 
 error: greater than checks against false are unnecessary
-  --> tests/ui/bool_comparison.rs:67:8
+  --> tests/ui/bool_comparison.rs:27:16
    |
-LL |     if x > false {
-   |        ^^^^^^^^^ help: try simplifying it as shown: `x`
+LL |     let _ = if x > false { "yes" } else { "no" };
+   |                ^^^^^^^^^ help: try: `x`
 
 error: less than comparison against true can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:73:8
+  --> tests/ui/bool_comparison.rs:29:16
    |
-LL |     if true > x {
-   |        ^^^^^^^^ help: try simplifying it as shown: `!x`
+LL |     let _ = if true > x { "yes" } else { "no" };
+   |                ^^^^^^^^ help: try: `!x`
 
 error: order comparisons between booleans can be simplified
-  --> tests/ui/bool_comparison.rs:80:8
+  --> tests/ui/bool_comparison.rs:33:16
    |
-LL |     if x < y {
-   |        ^^^^^ help: try simplifying it as shown: `!x & y`
+LL |     let _ = if x < y { "yes" } else { "no" };
+   |                ^^^^^ help: try: `!x & y`
 
 error: order comparisons between booleans can be simplified
-  --> tests/ui/bool_comparison.rs:86:8
+  --> tests/ui/bool_comparison.rs:35:16
    |
-LL |     if x > y {
-   |        ^^^^^ help: try simplifying it as shown: `x & !y`
-
-error: this comparison might be written more concisely
-  --> tests/ui/bool_comparison.rs:135:8
-   |
-LL |     if a == !b {};
-   |        ^^^^^^^ help: try simplifying it as shown: `a != b`
-
-error: this comparison might be written more concisely
-  --> tests/ui/bool_comparison.rs:137:8
-   |
-LL |     if !a == b {};
-   |        ^^^^^^^ help: try simplifying it as shown: `a != b`
-
-error: this comparison might be written more concisely
-  --> tests/ui/bool_comparison.rs:142:8
-   |
-LL |     if b == !a {};
-   |        ^^^^^^^ help: try simplifying it as shown: `b != a`
-
-error: this comparison might be written more concisely
-  --> tests/ui/bool_comparison.rs:144:8
-   |
-LL |     if !b == a {};
-   |        ^^^^^^^ help: try simplifying it as shown: `b != a`
+LL |     let _ = if x > y { "yes" } else { "no" };
+   |                ^^^^^ help: try: `x & !y`
 
 error: equality checks against false can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:169:8
+  --> tests/ui/bool_comparison.rs:92:8
    |
 LL |     if false == m!(func) {}
-   |        ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)`
+   |        ^^^^^^^^^^^^^^^^^ help: try: `!m!(func)`
 
 error: equality checks against false can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:171:8
+  --> tests/ui/bool_comparison.rs:94:8
    |
 LL |     if m!(func) == false {}
-   |        ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)`
+   |        ^^^^^^^^^^^^^^^^^ help: try: `!m!(func)`
 
 error: equality checks against true are unnecessary
-  --> tests/ui/bool_comparison.rs:173:8
+  --> tests/ui/bool_comparison.rs:96:8
    |
 LL |     if true == m!(func) {}
-   |        ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)`
+   |        ^^^^^^^^^^^^^^^^ help: try: `m!(func)`
 
 error: equality checks against true are unnecessary
-  --> tests/ui/bool_comparison.rs:175:8
+  --> tests/ui/bool_comparison.rs:98:8
    |
 LL |     if m!(func) == true {}
-   |        ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `m!(func)`
+   |        ^^^^^^^^^^^^^^^^ help: try: `m!(func)`
 
 error: equality checks against false can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:193:14
+  --> tests/ui/bool_comparison.rs:116:14
    |
 LL |     let _ = ((1 < 2) == false) as usize;
-   |              ^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `1 >= 2`
+   |              ^^^^^^^^^^^^^^^^ help: try: `1 >= 2`
 
 error: equality checks against false can be replaced by a negation
-  --> tests/ui/bool_comparison.rs:195:14
+  --> tests/ui/bool_comparison.rs:118:14
    |
 LL |     let _ = (false == m!(func)) as usize;
-   |              ^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `!m!(func)`
+   |              ^^^^^^^^^^^^^^^^^ help: try: `!m!(func)`
 
-error: this comparison might be written more concisely
-  --> tests/ui/bool_comparison.rs:199:14
+error: order comparisons between booleans can be simplified
+  --> tests/ui/bool_comparison.rs:122:14
+   |
+LL |     let _ = ((1 < 2) > m!(func)) as usize;
+   |              ^^^^^^^^^^^^^^^^^^ help: try: `(1 < 2) & !m!(func)`
+
+error: order comparisons between booleans can be simplified
+  --> tests/ui/bool_comparison.rs:144:9
+   |
+LL |         x > m!(func)
+   |         ^^^^^^^^^^^^ help: try: `x & !m!(func)`
+
+error: order comparisons between booleans can be simplified
+  --> tests/ui/bool_comparison.rs:149:9
    |
-LL |     let _ = ((1 < 2) == !m!(func)) as usize;
-   |              ^^^^^^^^^^^^^^^^^^^^ help: try simplifying it as shown: `(1 < 2) != m!(func)`
+LL |         x < m!(func)
+   |         ^^^^^^^^^^^^ help: try: `!x & m!(func)`
 
-error: aborting due to 25 previous errors
+error: aborting due to 23 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
index bddcb0ebf64..3c1cf884595 100644
--- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.fixed
@@ -1,30 +1,53 @@
 #![warn(clippy::cast_slice_from_raw_parts)]
 
-#[allow(unused_imports, unused_unsafe)]
+const fn require_raw_slice_ptr<T>(_: *const [T]) {}
+
 fn main() {
     let mut vec = vec![0u8; 1];
     let ptr: *const u8 = vec.as_ptr();
     let mptr = vec.as_mut_ptr();
-    let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) };
+    let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts(ptr, 1) };
     //~^ cast_slice_from_raw_parts
-    let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) };
+    let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts_mut(mptr, 1) };
     //~^ cast_slice_from_raw_parts
-    let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+    let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);
     //~^ cast_slice_from_raw_parts
     {
         use core::slice;
-        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);
         //~^ cast_slice_from_raw_parts
         use slice as one;
-        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);
         //~^ cast_slice_from_raw_parts
     }
     {
         use std::slice;
-        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);
         //~^ cast_slice_from_raw_parts
         use slice as one;
-        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        let _: *const [u8] = std::ptr::slice_from_raw_parts(ptr, 1);
         //~^ cast_slice_from_raw_parts
     }
+
+    // implicit cast
+    {
+        let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts(ptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { std::ptr::slice_from_raw_parts_mut(mptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { std::ptr::slice_from_raw_parts(ptr, 1) });
+        //~^ cast_slice_from_raw_parts
+    }
+
+    // implicit cast in const context
+    const {
+        const PTR: *const u8 = std::ptr::null();
+        const MPTR: *mut u8 = std::ptr::null_mut();
+        let _: *const [u8] = unsafe { std::ptr::slice_from_raw_parts(PTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { std::ptr::slice_from_raw_parts_mut(MPTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { std::ptr::slice_from_raw_parts(PTR, 1) });
+        //~^ cast_slice_from_raw_parts
+    };
 }
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
index 0a1eb276d5e..8f57b1f9619 100644
--- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.rs
@@ -1,6 +1,7 @@
 #![warn(clippy::cast_slice_from_raw_parts)]
 
-#[allow(unused_imports, unused_unsafe)]
+const fn require_raw_slice_ptr<T>(_: *const [T]) {}
+
 fn main() {
     let mut vec = vec![0u8; 1];
     let ptr: *const u8 = vec.as_ptr();
@@ -27,4 +28,26 @@ fn main() {
         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
         //~^ cast_slice_from_raw_parts
     }
+
+    // implicit cast
+    {
+        let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(ptr, 1) });
+        //~^ cast_slice_from_raw_parts
+    }
+
+    // implicit cast in const context
+    const {
+        const PTR: *const u8 = std::ptr::null();
+        const MPTR: *mut u8 = std::ptr::null_mut();
+        let _: *const [u8] = unsafe { std::slice::from_raw_parts(PTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(MPTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(PTR, 1) });
+        //~^ cast_slice_from_raw_parts
+    };
 }
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
index 60794a988db..328dbafbafe 100644
--- a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast.stderr
@@ -1,47 +1,83 @@
 error: casting the result of `from_raw_parts` to *const [u8]
-  --> tests/ui/cast_raw_slice_pointer_cast.rs:8:35
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:9:35
    |
 LL |     let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) as *const [u8] };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`
    |
    = note: `-D clippy::cast-slice-from-raw-parts` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::cast_slice_from_raw_parts)]`
 
 error: casting the result of `from_raw_parts_mut` to *mut [u8]
-  --> tests/ui/cast_raw_slice_pointer_cast.rs:10:35
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:11:35
    |
 LL |     let _: *const [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts_mut(mptr, 1)`
 
 error: casting the result of `from_raw_parts` to *const [u8]
-  --> tests/ui/cast_raw_slice_pointer_cast.rs:12:26
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:13:26
    |
 LL |     let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) } as *const [u8];
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`
 
 error: casting the result of `from_raw_parts` to *const [u8]
-  --> tests/ui/cast_raw_slice_pointer_cast.rs:16:30
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:17:30
    |
 LL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`
 
 error: casting the result of `from_raw_parts` to *const [u8]
-  --> tests/ui/cast_raw_slice_pointer_cast.rs:19:30
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:20:30
    |
 LL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`
 
 error: casting the result of `from_raw_parts` to *const [u8]
-  --> tests/ui/cast_raw_slice_pointer_cast.rs:24:30
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:25:30
    |
 LL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`
 
 error: casting the result of `from_raw_parts` to *const [u8]
-  --> tests/ui/cast_raw_slice_pointer_cast.rs:27:30
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:28:30
    |
 LL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::ptr::slice_from_raw_parts(ptr, 1)`
 
-error: aborting due to 7 previous errors
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:34:39
+   |
+LL |         let _: *const [u8] = unsafe { std::slice::from_raw_parts(ptr, 1) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:36:37
+   |
+LL |         let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(mptr, 1) };
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts_mut(mptr, 1)`
+
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:38:40
+   |
+LL |         require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(ptr, 1) });
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:46:39
+   |
+LL |         let _: *const [u8] = unsafe { std::slice::from_raw_parts(PTR, 1) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(PTR, 1)`
+
+error: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:48:37
+   |
+LL |         let _: *mut [u8] = unsafe { std::slice::from_raw_parts_mut(MPTR, 1) };
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts_mut(MPTR, 1)`
+
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast.rs:50:40
+   |
+LL |         require_raw_slice_ptr(unsafe { std::slice::from_raw_parts(PTR, 1) });
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `std::ptr::slice_from_raw_parts(PTR, 1)`
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.fixed b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.fixed
new file mode 100644
index 00000000000..f71fb8d863c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.fixed
@@ -0,0 +1,55 @@
+#![warn(clippy::cast_slice_from_raw_parts)]
+#![no_std]
+#![crate_type = "lib"]
+
+const fn require_raw_slice_ptr<T>(_: *const [T]) {}
+
+fn main() {
+    let mut arr = [0u8; 1];
+    let ptr: *const u8 = arr.as_ptr();
+    let mptr = arr.as_mut_ptr();
+    let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) };
+    //~^ cast_slice_from_raw_parts
+    let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) };
+    //~^ cast_slice_from_raw_parts
+    let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+    //~^ cast_slice_from_raw_parts
+    {
+        use core::slice;
+        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        //~^ cast_slice_from_raw_parts
+        use slice as one;
+        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        //~^ cast_slice_from_raw_parts
+    }
+    {
+        use core::slice;
+        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        //~^ cast_slice_from_raw_parts
+        use slice as one;
+        let _: *const [u8] = core::ptr::slice_from_raw_parts(ptr, 1);
+        //~^ cast_slice_from_raw_parts
+    }
+
+    // implicit cast
+    {
+        let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(ptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(mptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { core::ptr::slice_from_raw_parts(ptr, 1) });
+        //~^ cast_slice_from_raw_parts
+    }
+
+    // implicit cast in const context
+    const {
+        const PTR: *const u8 = core::ptr::null();
+        const MPTR: *mut u8 = core::ptr::null_mut();
+        let _: *const [u8] = unsafe { core::ptr::slice_from_raw_parts(PTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { core::ptr::slice_from_raw_parts_mut(MPTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { core::ptr::slice_from_raw_parts(PTR, 1) });
+        //~^ cast_slice_from_raw_parts
+    };
+}
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.rs b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.rs
new file mode 100644
index 00000000000..743e44c97dc
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.rs
@@ -0,0 +1,55 @@
+#![warn(clippy::cast_slice_from_raw_parts)]
+#![no_std]
+#![crate_type = "lib"]
+
+const fn require_raw_slice_ptr<T>(_: *const [T]) {}
+
+fn main() {
+    let mut arr = [0u8; 1];
+    let ptr: *const u8 = arr.as_ptr();
+    let mptr = arr.as_mut_ptr();
+    let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) as *const [u8] };
+    //~^ cast_slice_from_raw_parts
+    let _: *const [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };
+    //~^ cast_slice_from_raw_parts
+    let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) } as *const [u8];
+    //~^ cast_slice_from_raw_parts
+    {
+        use core::slice;
+        let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+        //~^ cast_slice_from_raw_parts
+        use slice as one;
+        let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+        //~^ cast_slice_from_raw_parts
+    }
+    {
+        use core::slice;
+        let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+        //~^ cast_slice_from_raw_parts
+        use slice as one;
+        let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+        //~^ cast_slice_from_raw_parts
+    }
+
+    // implicit cast
+    {
+        let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(ptr, 1) });
+        //~^ cast_slice_from_raw_parts
+    }
+
+    // implicit cast in const context
+    const {
+        const PTR: *const u8 = core::ptr::null();
+        const MPTR: *mut u8 = core::ptr::null_mut();
+        let _: *const [u8] = unsafe { core::slice::from_raw_parts(PTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(MPTR, 1) };
+        //~^ cast_slice_from_raw_parts
+        require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(PTR, 1) });
+        //~^ cast_slice_from_raw_parts
+    };
+}
diff --git a/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.stderr b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.stderr
new file mode 100644
index 00000000000..5488fbcfa1c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_raw_slice_pointer_cast_no_std.stderr
@@ -0,0 +1,83 @@
+error: casting the result of `from_raw_parts` to *const [u8]
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:11:35
+   |
+LL |     let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) as *const [u8] };
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+   |
+   = note: `-D clippy::cast-slice-from-raw-parts` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::cast_slice_from_raw_parts)]`
+
+error: casting the result of `from_raw_parts_mut` to *mut [u8]
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:13:35
+   |
+LL |     let _: *const [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) as *mut [u8] };
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:15:26
+   |
+LL |     let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) } as *const [u8];
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:19:30
+   |
+LL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:22:30
+   |
+LL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:27:30
+   |
+LL |         let _: *const [u8] = unsafe { slice::from_raw_parts(ptr, 1) } as *const [u8];
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: casting the result of `from_raw_parts` to *const [u8]
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:30:30
+   |
+LL |         let _: *const [u8] = unsafe { one::from_raw_parts(ptr, 1) } as *const [u8];
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:36:39
+   |
+LL |         let _: *const [u8] = unsafe { core::slice::from_raw_parts(ptr, 1) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:38:37
+   |
+LL |         let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(mptr, 1) };
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts_mut(mptr, 1)`
+
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:40:40
+   |
+LL |         require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(ptr, 1) });
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(ptr, 1)`
+
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:48:39
+   |
+LL |         let _: *const [u8] = unsafe { core::slice::from_raw_parts(PTR, 1) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(PTR, 1)`
+
+error: implicitly casting the result of `from_raw_parts_mut` to `*mut [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:50:37
+   |
+LL |         let _: *mut [u8] = unsafe { core::slice::from_raw_parts_mut(MPTR, 1) };
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts_mut(MPTR, 1)`
+
+error: implicitly casting the result of `from_raw_parts` to `*const [u8]`
+  --> tests/ui/cast_raw_slice_pointer_cast_no_std.rs:52:40
+   |
+LL |         require_raw_slice_ptr(unsafe { core::slice::from_raw_parts(PTR, 1) });
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace_with: `core::ptr::slice_from_raw_parts(PTR, 1)`
+
+error: aborting due to 13 previous errors
+
diff --git a/src/tools/clippy/tests/ui/collapsible_match.rs b/src/tools/clippy/tests/ui/collapsible_match.rs
index 71b82040ff6..8931a3aa09c 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.rs
+++ b/src/tools/clippy/tests/ui/collapsible_match.rs
@@ -316,6 +316,47 @@ fn lint_emitted_at_right_node(opt: Option<Result<u64, String>>) {
     };
 }
 
+pub fn issue_14155() {
+    let mut arr = ["a", "b", "c"];
+    if let Some(last) = arr.last() {
+        match *last {
+            //~^ collapsible_match
+            "a" | "b" => {
+                unimplemented!()
+            },
+            _ => (),
+        }
+    }
+
+    if let Some(last) = arr.last() {
+        match &last {
+            //~^ collapsible_match
+            &&"a" | &&"b" => {
+                unimplemented!()
+            },
+            _ => (),
+        }
+    }
+
+    if let Some(mut last) = arr.last_mut() {
+        match &mut last {
+            //~^ collapsible_match
+            &mut &mut "a" | &mut &mut "b" => {
+                unimplemented!()
+            },
+            _ => (),
+        }
+    }
+
+    const NULL_PTR: *const &'static str = std::ptr::null();
+    if let Some(last) = arr.last() {
+        match &raw const *last {
+            NULL_PTR => unimplemented!(),
+            _ => (),
+        }
+    }
+}
+
 fn make<T>() -> T {
     unimplemented!()
 }
diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr
index c290d84ec29..14b1c1b187e 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match.stderr
@@ -250,5 +250,74 @@ LL |     if let Issue9647::A { a: Some(a), .. } = x {
 LL |         if let Some(u) = a {
    |                ^^^^^^^ with this pattern
 
-error: aborting due to 13 previous errors
+error: this `match` can be collapsed into the outer `if let`
+  --> tests/ui/collapsible_match.rs:322:9
+   |
+LL | /         match *last {
+LL | |
+LL | |             "a" | "b" => {
+LL | |                 unimplemented!()
+LL | |             },
+LL | |             _ => (),
+LL | |         }
+   | |_________^
+   |
+help: the outer pattern can be modified to include the inner pattern
+  --> tests/ui/collapsible_match.rs:321:17
+   |
+LL |     if let Some(last) = arr.last() {
+   |                 ^^^^    ---------- use: `arr.last().copied()`
+   |                 |
+   |                 replace this binding
+...
+LL |             "a" | "b" => {
+   |             ^^^^^^^^^ with this pattern
+
+error: this `match` can be collapsed into the outer `if let`
+  --> tests/ui/collapsible_match.rs:332:9
+   |
+LL | /         match &last {
+LL | |
+LL | |             &&"a" | &&"b" => {
+LL | |                 unimplemented!()
+LL | |             },
+LL | |             _ => (),
+LL | |         }
+   | |_________^
+   |
+help: the outer pattern can be modified to include the inner pattern
+  --> tests/ui/collapsible_match.rs:331:17
+   |
+LL |     if let Some(last) = arr.last() {
+   |                 ^^^^    ---------- use: `arr.last().as_ref()`
+   |                 |
+   |                 replace this binding
+...
+LL |             &&"a" | &&"b" => {
+   |             ^^^^^^^^^^^^^ with this pattern
+
+error: this `match` can be collapsed into the outer `if let`
+  --> tests/ui/collapsible_match.rs:342:9
+   |
+LL | /         match &mut last {
+LL | |
+LL | |             &mut &mut "a" | &mut &mut "b" => {
+LL | |                 unimplemented!()
+LL | |             },
+LL | |             _ => (),
+LL | |         }
+   | |_________^
+   |
+help: the outer pattern can be modified to include the inner pattern
+  --> tests/ui/collapsible_match.rs:341:17
+   |
+LL |     if let Some(mut last) = arr.last_mut() {
+   |                 ^^^^^^^^    -------------- use: `arr.last_mut().as_mut()`
+   |                 |
+   |                 replace this binding
+...
+LL |             &mut &mut "a" | &mut &mut "b" => {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ with this pattern
+
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/collapsible_match2.stderr b/src/tools/clippy/tests/ui/collapsible_match2.stderr
index 7b273063752..25970670999 100644
--- a/src/tools/clippy/tests/ui/collapsible_match2.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match2.stderr
@@ -77,6 +77,8 @@ LL | |         },
 help: the outer pattern can be modified to include the inner pattern
   --> tests/ui/collapsible_match2.rs:54:14
    |
+LL |     match Some(&[1]) {
+   |           ---------- use: `Some(&[1]).copied()`
 LL |         Some(s) => match *s {
    |              ^ replace this binding
 LL |
diff --git a/src/tools/clippy/tests/ui/derivable_impls.fixed b/src/tools/clippy/tests/ui/derivable_impls.fixed
index 65bfded3883..9f9e4e253c3 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.fixed
+++ b/src/tools/clippy/tests/ui/derivable_impls.fixed
@@ -1,4 +1,6 @@
 #![allow(dead_code)]
+#![feature(const_trait_impl)]
+#![feature(const_default)]
 
 use std::collections::HashMap;
 
@@ -326,4 +328,40 @@ mod issue11368 {
     }
 }
 
+mod issue15493 {
+    #[derive(Copy, Clone)]
+    #[repr(transparent)]
+    struct Foo(u64);
+
+    impl const Default for Foo {
+        fn default() -> Self {
+            Self(0)
+        }
+    }
+
+    #[derive(Copy, Clone)]
+    enum Bar {
+        A,
+        B,
+    }
+
+    impl const Default for Bar {
+        fn default() -> Self {
+            Bar::A
+        }
+    }
+}
+
+mod issue15536 {
+    #[derive(Copy, Clone)]
+    #[derive(Default)]
+    enum Bar {
+        #[default]
+        A,
+        B,
+    }
+
+    
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derivable_impls.rs b/src/tools/clippy/tests/ui/derivable_impls.rs
index 4826c5497b4..74a793b9a70 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.rs
+++ b/src/tools/clippy/tests/ui/derivable_impls.rs
@@ -1,4 +1,6 @@
 #![allow(dead_code)]
+#![feature(const_trait_impl)]
+#![feature(const_default)]
 
 use std::collections::HashMap;
 
@@ -396,4 +398,43 @@ mod issue11368 {
     }
 }
 
+mod issue15493 {
+    #[derive(Copy, Clone)]
+    #[repr(transparent)]
+    struct Foo(u64);
+
+    impl const Default for Foo {
+        fn default() -> Self {
+            Self(0)
+        }
+    }
+
+    #[derive(Copy, Clone)]
+    enum Bar {
+        A,
+        B,
+    }
+
+    impl const Default for Bar {
+        fn default() -> Self {
+            Bar::A
+        }
+    }
+}
+
+mod issue15536 {
+    #[derive(Copy, Clone)]
+    enum Bar {
+        A,
+        B,
+    }
+
+    impl Default for Bar {
+        //~^ derivable_impls
+        fn default() -> Self {
+            Self::A
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derivable_impls.stderr b/src/tools/clippy/tests/ui/derivable_impls.stderr
index 0f73ad55a85..cd46414cb4a 100644
--- a/src/tools/clippy/tests/ui/derivable_impls.stderr
+++ b/src/tools/clippy/tests/ui/derivable_impls.stderr
@@ -1,5 +1,5 @@
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:20:1
+  --> tests/ui/derivable_impls.rs:22:1
    |
 LL | / impl std::default::Default for FooDefault<'_> {
 LL | |
@@ -18,7 +18,7 @@ LL ~ struct FooDefault<'a> {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:42:1
+  --> tests/ui/derivable_impls.rs:44:1
    |
 LL | / impl std::default::Default for TupleDefault {
 LL | |
@@ -35,7 +35,7 @@ LL ~ struct TupleDefault(bool, i32, u64);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:95:1
+  --> tests/ui/derivable_impls.rs:97:1
    |
 LL | / impl Default for StrDefault<'_> {
 LL | |
@@ -52,7 +52,7 @@ LL ~ struct StrDefault<'a>(&'a str);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:122:1
+  --> tests/ui/derivable_impls.rs:124:1
    |
 LL | / impl Default for Y {
 LL | |
@@ -69,7 +69,7 @@ LL ~ struct Y(u32);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:162:1
+  --> tests/ui/derivable_impls.rs:164:1
    |
 LL | / impl Default for WithoutSelfCurly {
 LL | |
@@ -86,7 +86,7 @@ LL ~ struct WithoutSelfCurly {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:171:1
+  --> tests/ui/derivable_impls.rs:173:1
    |
 LL | / impl Default for WithoutSelfParan {
 LL | |
@@ -103,7 +103,7 @@ LL ~ struct WithoutSelfParan(bool);
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:194:1
+  --> tests/ui/derivable_impls.rs:196:1
    |
 LL | / impl Default for DirectDefaultDefaultCall {
 LL | |
@@ -119,7 +119,7 @@ LL ~ pub struct DirectDefaultDefaultCall {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:206:1
+  --> tests/ui/derivable_impls.rs:208:1
    |
 LL | / impl Default for EquivalentToDefaultDefaultCallVec {
 LL | |
@@ -135,7 +135,7 @@ LL ~ pub struct EquivalentToDefaultDefaultCallVec {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:234:1
+  --> tests/ui/derivable_impls.rs:236:1
    |
 LL | / impl Default for EquivalentToDefaultDefaultCallLocal {
 LL | |
@@ -151,7 +151,7 @@ LL ~ pub struct EquivalentToDefaultDefaultCallLocal {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:274:1
+  --> tests/ui/derivable_impls.rs:276:1
    |
 LL | / impl Default for RepeatDefault1 {
 LL | |
@@ -168,7 +168,7 @@ LL ~ pub struct RepeatDefault1 {
    |
 
 error: this `impl` can be derived
-  --> tests/ui/derivable_impls.rs:309:1
+  --> tests/ui/derivable_impls.rs:311:1
    |
 LL | / impl Default for SimpleEnum {
 LL | |
@@ -187,5 +187,28 @@ LL ~     #[default]
 LL ~     Bar,
    |
 
-error: aborting due to 11 previous errors
+error: this `impl` can be derived
+  --> tests/ui/derivable_impls.rs:432:5
+   |
+LL | /     impl Default for Bar {
+LL | |
+LL | |         fn default() -> Self {
+LL | |             Self::A
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+help: replace the manual implementation with a derive attribute and mark the default variant
+   |
+LL ~     #[derive(Default)]
+LL ~     enum Bar {
+LL ~         #[default]
+LL ~         A,
+LL |         B,
+LL |     }
+LL |
+LL ~     
+   |
+
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/derivable_impls_derive_const.fixed b/src/tools/clippy/tests/ui/derivable_impls_derive_const.fixed
new file mode 100644
index 00000000000..f0d8d2d2409
--- /dev/null
+++ b/src/tools/clippy/tests/ui/derivable_impls_derive_const.fixed
@@ -0,0 +1,25 @@
+#![allow(dead_code)]
+#![feature(const_trait_impl)]
+#![feature(const_default)]
+#![feature(derive_const)]
+
+mod issue15493 {
+    #[derive(Copy, Clone)]
+    #[repr(transparent)]
+    #[derive_const(Default)]
+    struct Foo(u64);
+
+    
+
+    #[derive(Copy, Clone)]
+    #[derive_const(Default)]
+    enum Bar {
+        #[default]
+        A,
+        B,
+    }
+
+    
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/derivable_impls_derive_const.rs b/src/tools/clippy/tests/ui/derivable_impls_derive_const.rs
new file mode 100644
index 00000000000..7d70db1c097
--- /dev/null
+++ b/src/tools/clippy/tests/ui/derivable_impls_derive_const.rs
@@ -0,0 +1,32 @@
+#![allow(dead_code)]
+#![feature(const_trait_impl)]
+#![feature(const_default)]
+#![feature(derive_const)]
+
+mod issue15493 {
+    #[derive(Copy, Clone)]
+    #[repr(transparent)]
+    struct Foo(u64);
+
+    impl const Default for Foo {
+        //~^ derivable_impls
+        fn default() -> Self {
+            Self(0)
+        }
+    }
+
+    #[derive(Copy, Clone)]
+    enum Bar {
+        A,
+        B,
+    }
+
+    impl const Default for Bar {
+        //~^ derivable_impls
+        fn default() -> Self {
+            Bar::A
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/derivable_impls_derive_const.stderr b/src/tools/clippy/tests/ui/derivable_impls_derive_const.stderr
new file mode 100644
index 00000000000..196bac185dd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/derivable_impls_derive_const.stderr
@@ -0,0 +1,46 @@
+error: this `impl` can be derived
+  --> tests/ui/derivable_impls_derive_const.rs:11:5
+   |
+LL | /     impl const Default for Foo {
+LL | |
+LL | |         fn default() -> Self {
+LL | |             Self(0)
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = note: `-D clippy::derivable-impls` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::derivable_impls)]`
+help: replace the manual implementation with a derive attribute
+   |
+LL ~     #[derive_const(Default)]
+LL ~     struct Foo(u64);
+LL |
+LL ~     
+   |
+
+error: this `impl` can be derived
+  --> tests/ui/derivable_impls_derive_const.rs:24:5
+   |
+LL | /     impl const Default for Bar {
+LL | |
+LL | |         fn default() -> Self {
+LL | |             Bar::A
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+help: replace the manual implementation with a derive attribute and mark the default variant
+   |
+LL ~     #[derive_const(Default)]
+LL ~     enum Bar {
+LL ~         #[default]
+LL ~         A,
+LL |         B,
+LL |     }
+LL |
+LL ~     
+   |
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index 423a73734da..46695dc929a 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -73,6 +73,7 @@ fn test_units() {
 /// GPLv2 GPLv3
 /// GitHub GitLab
 /// IPv4 IPv6
+/// InfiniBand RoCE
 /// ClojureScript CoffeeScript JavaScript PostScript PureScript TypeScript
 /// PowerPC WebAssembly
 /// NaN NaNs
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 8deffb4210e..4082fa5b56f 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -73,6 +73,7 @@ fn test_units() {
 /// GPLv2 GPLv3
 /// GitHub GitLab
 /// IPv4 IPv6
+/// InfiniBand RoCE
 /// ClojureScript CoffeeScript JavaScript PostScript PureScript TypeScript
 /// PowerPC WebAssembly
 /// NaN NaNs
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
index 98c26e6bec2..2a94a8f3165 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
@@ -145,7 +145,7 @@ LL + /// `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:90:5
+  --> tests/ui/doc/doc-fixable.rs:91:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL + /// `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:108:5
+  --> tests/ui/doc/doc-fixable.rs:109:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -169,7 +169,7 @@ LL + /// `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:117:8
+  --> tests/ui/doc/doc-fixable.rs:118:8
    |
 LL | /// ## CamelCaseThing
    |        ^^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ LL + /// ## `CamelCaseThing`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:121:7
+  --> tests/ui/doc/doc-fixable.rs:122:7
    |
 LL | /// # CamelCaseThing
    |       ^^^^^^^^^^^^^^
@@ -193,7 +193,7 @@ LL + /// # `CamelCaseThing`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:124:22
+  --> tests/ui/doc/doc-fixable.rs:125:22
    |
 LL | /// Not a title #897 CamelCaseThing
    |                      ^^^^^^^^^^^^^^
@@ -205,7 +205,7 @@ LL + /// Not a title #897 `CamelCaseThing`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:126:5
+  --> tests/ui/doc/doc-fixable.rs:127:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL + /// `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:134:5
+  --> tests/ui/doc/doc-fixable.rs:135:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -229,7 +229,7 @@ LL + /// `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:148:5
+  --> tests/ui/doc/doc-fixable.rs:149:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,7 +241,7 @@ LL + /// `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:160:43
+  --> tests/ui/doc/doc-fixable.rs:161:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
@@ -253,7 +253,7 @@ LL + /** E.g., serialization of an empty list: `FooBar`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:165:5
+  --> tests/ui/doc/doc-fixable.rs:166:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
@@ -265,7 +265,7 @@ LL + And `BarQuz` too.
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:166:1
+  --> tests/ui/doc/doc-fixable.rs:167:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -277,7 +277,7 @@ LL + `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:174:43
+  --> tests/ui/doc/doc-fixable.rs:175:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
@@ -289,7 +289,7 @@ LL + /** E.g., serialization of an empty list: `FooBar`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:179:5
+  --> tests/ui/doc/doc-fixable.rs:180:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
@@ -301,7 +301,7 @@ LL + And `BarQuz` too.
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:180:1
+  --> tests/ui/doc/doc-fixable.rs:181:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -313,7 +313,7 @@ LL + `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:194:5
+  --> tests/ui/doc/doc-fixable.rs:195:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -325,7 +325,7 @@ LL + /// `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:214:22
+  --> tests/ui/doc/doc-fixable.rs:215:22
    |
 LL | /// An iterator over mycrate::Collection's values.
    |                      ^^^^^^^^^^^^^^^^^^^
@@ -337,7 +337,7 @@ LL + /// An iterator over `mycrate::Collection`'s values.
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:239:34
+  --> tests/ui/doc/doc-fixable.rs:240:34
    |
 LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint
    |                                  ^^^^^^^^^^^^^^^
@@ -349,7 +349,7 @@ LL + /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:263:22
+  --> tests/ui/doc/doc-fixable.rs:264:22
    |
 LL | /// There is no try (do() or do_not()).
    |                      ^^^^
@@ -361,7 +361,7 @@ LL + /// There is no try (`do()` or do_not()).
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:263:30
+  --> tests/ui/doc/doc-fixable.rs:264:30
    |
 LL | /// There is no try (do() or do_not()).
    |                              ^^^^^^^^
@@ -373,7 +373,7 @@ LL + /// There is no try (do() or `do_not()`).
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:268:5
+  --> tests/ui/doc/doc-fixable.rs:269:5
    |
 LL | /// ABes
    |     ^^^^
@@ -385,7 +385,7 @@ LL + /// `ABes`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:275:9
+  --> tests/ui/doc/doc-fixable.rs:276:9
    |
 LL |     /// foo()
    |         ^^^^^
@@ -397,7 +397,7 @@ LL +     /// `foo()`
    |
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> tests/ui/doc/doc-fixable.rs:280:5
+  --> tests/ui/doc/doc-fixable.rs:281:5
    |
 LL | /// https://github.com/rust-lang/rust-clippy/pull/12836
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<https://github.com/rust-lang/rust-clippy/pull/12836>`
diff --git a/src/tools/clippy/tests/ui/entry_unfixable.stderr b/src/tools/clippy/tests/ui/entry_unfixable.stderr
index 0197d2ab4cf..f92f472512f 100644
--- a/src/tools/clippy/tests/ui/entry_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/entry_unfixable.stderr
@@ -10,6 +10,7 @@ LL | |                 false
 LL | |             }
    | |_____________^
    |
+   = help: consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.HashMap.html#entry-api
    = note: `-D clippy::map-entry` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`
 
@@ -24,6 +25,8 @@ LL | |     } else {
 LL | |         hm.insert(key, true);
 LL | |     }
    | |_____^
+   |
+   = help: consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.HashMap.html#entry-api
 
 error: usage of `contains_key` followed by `insert` on a `HashMap`
   --> tests/ui/entry_unfixable.rs:80:13
@@ -36,6 +39,8 @@ LL | |                 let interner = INTERNER.lock().unwrap();
 LL | |                 return Err(interner.resolve(name).unwrap().to_owned());
 LL | |             }
    | |_____________^
+   |
+   = help: consider using the `Entry` API: https://doc.rust-lang.org/std/collections/struct.HashMap.html#entry-api
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index 3d2b41b8fb8..6944a979c05 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -565,6 +565,51 @@ fn issue_14789() {
     );
 }
 
+fn issue_15072() {
+    use std::ops::Deref;
+
+    struct Foo;
+    impl Deref for Foo {
+        type Target = fn() -> &'static str;
+
+        fn deref(&self) -> &Self::Target {
+            fn hello() -> &'static str {
+                "Hello, world!"
+            }
+            &(hello as fn() -> &'static str)
+        }
+    }
+
+    fn accepts_fn(f: impl Fn() -> &'static str) {
+        println!("{}", f());
+    }
+
+    fn some_fn() -> &'static str {
+        todo!()
+    }
+
+    let f = &Foo;
+    accepts_fn(**f);
+    //~^ redundant_closure
+
+    let g = &some_fn;
+    accepts_fn(g);
+    //~^ redundant_closure
+
+    struct Bar(Foo);
+    impl Deref for Bar {
+        type Target = Foo;
+
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+
+    let b = &Bar(Foo);
+    accepts_fn(***b);
+    //~^ redundant_closure
+}
+
 fn issue8817() {
     fn f(_: u32) -> u32 {
         todo!()
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index 79d1103410d..5bcc1cb26fd 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -565,6 +565,51 @@ fn issue_14789() {
     );
 }
 
+fn issue_15072() {
+    use std::ops::Deref;
+
+    struct Foo;
+    impl Deref for Foo {
+        type Target = fn() -> &'static str;
+
+        fn deref(&self) -> &Self::Target {
+            fn hello() -> &'static str {
+                "Hello, world!"
+            }
+            &(hello as fn() -> &'static str)
+        }
+    }
+
+    fn accepts_fn(f: impl Fn() -> &'static str) {
+        println!("{}", f());
+    }
+
+    fn some_fn() -> &'static str {
+        todo!()
+    }
+
+    let f = &Foo;
+    accepts_fn(|| f());
+    //~^ redundant_closure
+
+    let g = &some_fn;
+    accepts_fn(|| g());
+    //~^ redundant_closure
+
+    struct Bar(Foo);
+    impl Deref for Bar {
+        type Target = Foo;
+
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+
+    let b = &Bar(Foo);
+    accepts_fn(|| b());
+    //~^ redundant_closure
+}
+
 fn issue8817() {
     fn f(_: u32) -> u32 {
         todo!()
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index aa32ed1a38e..0b401cdea98 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -215,28 +215,46 @@ LL |         let _field = bind.or_else(|| get_default()).unwrap();
    |                                   ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default`
 
 error: redundant closure
-  --> tests/ui/eta.rs:588:14
+  --> tests/ui/eta.rs:592:16
+   |
+LL |     accepts_fn(|| f());
+   |                ^^^^^^ help: replace the closure with the function itself: `**f`
+
+error: redundant closure
+  --> tests/ui/eta.rs:596:16
+   |
+LL |     accepts_fn(|| g());
+   |                ^^^^^^ help: replace the closure with the function itself: `g`
+
+error: redundant closure
+  --> tests/ui/eta.rs:609:16
+   |
+LL |     accepts_fn(|| b());
+   |                ^^^^^^ help: replace the closure with the function itself: `***b`
+
+error: redundant closure
+  --> tests/ui/eta.rs:633:14
    |
 LL |         .map(|n| MyError::A(n))
    |              ^^^^^^^^^^^^^^^^^ help: replace the closure with the tuple variant itself: `MyError::A`
 
 error: redundant closure
-  --> tests/ui/eta.rs:585:14
+  --> tests/ui/eta.rs:630:14
    |
 LL |         .map(|n| S(n))
    |              ^^^^^^^^ help: replace the closure with the tuple struct itself: `S`
 
 error: redundant closure
-  --> tests/ui/eta.rs:582:14
+  --> tests/ui/eta.rs:627:14
    |
 LL |         .map(|n| g(n))
    |              ^^^^^^^^ help: replace the closure with the function itself: `g`
 
 error: redundant closure
-  --> tests/ui/eta.rs:579:14
+  --> tests/ui/eta.rs:624:14
    |
 LL |         .map(|n| f(n))
    |              ^^^^^^^^ help: replace the closure with the function itself: `f`
 
-error: aborting due to 39 previous errors
+error: aborting due to 42 previous errors
 
diff --git a/src/tools/clippy/tests/ui/excessive_precision.fixed b/src/tools/clippy/tests/ui/excessive_precision.fixed
index 8a8c2e1939c..8158d4b332a 100644
--- a/src/tools/clippy/tests/ui/excessive_precision.fixed
+++ b/src/tools/clippy/tests/ui/excessive_precision.fixed
@@ -4,9 +4,16 @@
     overflowing_literals,
     unused_variables,
     clippy::print_literal,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::approx_constant
 )]
 
+macro_rules! make_pi {
+    ($i:ident : $t:ty) => {
+        const $i: $t = 3.14159265358979323846264338327950288419716939937510582097494459230781640628;
+    };
+}
+
 fn main() {
     // Consts
     const GOOD32: f32 = 0.123_456;
@@ -101,4 +108,40 @@ fn main() {
     const _: f64 = 3.0;
     //~^ excessive_precision
     const _: f64 = 3.0000000000000000;
+
+    // Overly specified constants
+    let _: f32 = 1.012_345_7;
+    //~^ excessive_precision
+    let _: f64 = 1.012_345_678_901_234_6;
+    //~^ excessive_precision
+    const _: f32 = 1.01234567890123456789012345678901234567890;
+    const _: f64 = 1.01234567890123456789012345678901234567890;
+
+    static STATIC1: f32 = 1.01234567890123456789012345678901234567890;
+    static STATIC2: f64 = 1.01234567890123456789012345678901234567890;
+
+    static mut STATIC_MUT1: f32 = 1.01234567890123456789012345678901234567890;
+    static mut STATIC_MUT2: f64 = 1.01234567890123456789012345678901234567890;
+
+    // From issue #13855
+    let gamma = 0.577_215_664_901_532_9;
+    //~^ excessive_precision
+    const GAMMA: f64 = 0.5772156649015328606065120900824024310421;
+
+    make_pi!(P32: f32);
+    make_pi!(P64: f64);
+}
+
+trait ExcessivelyPreciseTrait {
+    // Overly specified constants
+    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;
+    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;
+}
+
+struct ExcessivelyPreciseStruct;
+
+impl ExcessivelyPreciseStruct {
+    // Overly specified constants
+    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;
+    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;
 }
diff --git a/src/tools/clippy/tests/ui/excessive_precision.rs b/src/tools/clippy/tests/ui/excessive_precision.rs
index 5dcf55cb927..7ee6247ee5a 100644
--- a/src/tools/clippy/tests/ui/excessive_precision.rs
+++ b/src/tools/clippy/tests/ui/excessive_precision.rs
@@ -4,9 +4,16 @@
     overflowing_literals,
     unused_variables,
     clippy::print_literal,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::approx_constant
 )]
 
+macro_rules! make_pi {
+    ($i:ident : $t:ty) => {
+        const $i: $t = 3.14159265358979323846264338327950288419716939937510582097494459230781640628;
+    };
+}
+
 fn main() {
     // Consts
     const GOOD32: f32 = 0.123_456;
@@ -101,4 +108,40 @@ fn main() {
     const _: f64 = 3.0000000000000000e+00;
     //~^ excessive_precision
     const _: f64 = 3.0000000000000000;
+
+    // Overly specified constants
+    let _: f32 = 1.01234567890123456789012345678901234567890;
+    //~^ excessive_precision
+    let _: f64 = 1.01234567890123456789012345678901234567890;
+    //~^ excessive_precision
+    const _: f32 = 1.01234567890123456789012345678901234567890;
+    const _: f64 = 1.01234567890123456789012345678901234567890;
+
+    static STATIC1: f32 = 1.01234567890123456789012345678901234567890;
+    static STATIC2: f64 = 1.01234567890123456789012345678901234567890;
+
+    static mut STATIC_MUT1: f32 = 1.01234567890123456789012345678901234567890;
+    static mut STATIC_MUT2: f64 = 1.01234567890123456789012345678901234567890;
+
+    // From issue #13855
+    let gamma = 0.5772156649015328606065120900824024310421;
+    //~^ excessive_precision
+    const GAMMA: f64 = 0.5772156649015328606065120900824024310421;
+
+    make_pi!(P32: f32);
+    make_pi!(P64: f64);
+}
+
+trait ExcessivelyPreciseTrait {
+    // Overly specified constants
+    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;
+    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;
+}
+
+struct ExcessivelyPreciseStruct;
+
+impl ExcessivelyPreciseStruct {
+    // Overly specified constants
+    const GOOD1: f32 = 1.01234567890123456789012345678901234567890;
+    const GOOD2: f64 = 1.01234567890123456789012345678901234567890;
 }
diff --git a/src/tools/clippy/tests/ui/excessive_precision.stderr b/src/tools/clippy/tests/ui/excessive_precision.stderr
index f5eeadf0c8c..40806d67487 100644
--- a/src/tools/clippy/tests/ui/excessive_precision.stderr
+++ b/src/tools/clippy/tests/ui/excessive_precision.stderr
@@ -1,5 +1,5 @@
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:20:26
+  --> tests/ui/excessive_precision.rs:27:26
    |
 LL |     const BAD32_1: f32 = 0.123_456_789_f32;
    |                          ^^^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     const BAD32_1: f32 = 0.123_456_79_f32;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:22:26
+  --> tests/ui/excessive_precision.rs:29:26
    |
 LL |     const BAD32_2: f32 = 0.123_456_789;
    |                          ^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL +     const BAD32_2: f32 = 0.123_456_79;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:24:26
+  --> tests/ui/excessive_precision.rs:31:26
    |
 LL |     const BAD32_3: f32 = 0.100_000_000_000_1;
    |                          ^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL +     const BAD32_3: f32 = 0.1;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:26:29
+  --> tests/ui/excessive_precision.rs:33:29
    |
 LL |     const BAD32_EDGE: f32 = 1.000_000_9;
    |                             ^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL +     const BAD32_EDGE: f32 = 1.000_001;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:31:26
+  --> tests/ui/excessive_precision.rs:38:26
    |
 LL |     const BAD64_3: f64 = 0.100_000_000_000_000_000_1;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL +     const BAD64_3: f64 = 0.1;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:35:22
+  --> tests/ui/excessive_precision.rs:42:22
    |
 LL |     println!("{:?}", 8.888_888_888_888_888_888_888);
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL +     println!("{:?}", 8.888_888_888_888_89);
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:47:22
+  --> tests/ui/excessive_precision.rs:54:22
    |
 LL |     let bad32: f32 = 1.123_456_789;
    |                      ^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL +     let bad32: f32 = 1.123_456_8;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:49:26
+  --> tests/ui/excessive_precision.rs:56:26
    |
 LL |     let bad32_suf: f32 = 1.123_456_789_f32;
    |                          ^^^^^^^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL +     let bad32_suf: f32 = 1.123_456_8_f32;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:51:21
+  --> tests/ui/excessive_precision.rs:58:21
    |
 LL |     let bad32_inf = 1.123_456_789_f32;
    |                     ^^^^^^^^^^^^^^^^^
@@ -109,7 +109,7 @@ LL +     let bad32_inf = 1.123_456_8_f32;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:62:36
+  --> tests/ui/excessive_precision.rs:69:36
    |
 LL |     let bad_vec32: Vec<f32> = vec![0.123_456_789];
    |                                    ^^^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL +     let bad_vec32: Vec<f32> = vec![0.123_456_79];
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:64:36
+  --> tests/ui/excessive_precision.rs:71:36
    |
 LL |     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL +     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_78];
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:69:24
+  --> tests/ui/excessive_precision.rs:76:24
    |
 LL |     let bad_e32: f32 = 1.123_456_788_888e-10;
    |                        ^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ LL +     let bad_e32: f32 = 1.123_456_8e-10;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:73:27
+  --> tests/ui/excessive_precision.rs:80:27
    |
 LL |     let bad_bige32: f32 = 1.123_456_788_888E-10;
    |                           ^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL +     let bad_bige32: f32 = 1.123_456_8E-10;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:86:13
+  --> tests/ui/excessive_precision.rs:93:13
    |
 LL |     let _ = 2.225_073_858_507_201_1e-308_f64;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -169,7 +169,7 @@ LL +     let _ = 2.225_073_858_507_201e-308_f64;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:90:13
+  --> tests/ui/excessive_precision.rs:97:13
    |
 LL |     let _ = 1.000_000_000_000_001e-324_f64;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ LL +     let _ = 0_f64;
    |
 
 error: float has excessive precision
-  --> tests/ui/excessive_precision.rs:101:20
+  --> tests/ui/excessive_precision.rs:108:20
    |
 LL |     const _: f64 = 3.0000000000000000e+00;
    |                    ^^^^^^^^^^^^^^^^^^^^^^
@@ -192,5 +192,56 @@ LL -     const _: f64 = 3.0000000000000000e+00;
 LL +     const _: f64 = 3.0;
    |
 
-error: aborting due to 16 previous errors
+error: float has excessive precision
+  --> tests/ui/excessive_precision.rs:113:18
+   |
+LL |     let _: f32 = 1.01234567890123456789012345678901234567890;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: consider making it a `const` item
+  --> tests/ui/excessive_precision.rs:113:5
+   |
+LL |     let _: f32 = 1.01234567890123456789012345678901234567890;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the type or truncating it to
+   |
+LL -     let _: f32 = 1.01234567890123456789012345678901234567890;
+LL +     let _: f32 = 1.012_345_7;
+   |
+
+error: float has excessive precision
+  --> tests/ui/excessive_precision.rs:115:18
+   |
+LL |     let _: f64 = 1.01234567890123456789012345678901234567890;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: consider making it a `const` item
+  --> tests/ui/excessive_precision.rs:115:5
+   |
+LL |     let _: f64 = 1.01234567890123456789012345678901234567890;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the type or truncating it to
+   |
+LL -     let _: f64 = 1.01234567890123456789012345678901234567890;
+LL +     let _: f64 = 1.012_345_678_901_234_6;
+   |
+
+error: float has excessive precision
+  --> tests/ui/excessive_precision.rs:127:17
+   |
+LL |     let gamma = 0.5772156649015328606065120900824024310421;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: consider making it a `const` item
+  --> tests/ui/excessive_precision.rs:127:5
+   |
+LL |     let gamma = 0.5772156649015328606065120900824024310421;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider changing the type or truncating it to
+   |
+LL -     let gamma = 0.5772156649015328606065120900824024310421;
+LL +     let gamma = 0.577_215_664_901_532_9;
+   |
+
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/float_equality_without_abs.rs b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
index a1548db6710..e1dd7902683 100644
--- a/src/tools/clippy/tests/ui/float_equality_without_abs.rs
+++ b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
@@ -1,8 +1,8 @@
+#![feature(f128)]
+#![feature(f16)]
 #![warn(clippy::float_equality_without_abs)]
 //@no-rustfix: suggestions cause type ambiguity
 
-// FIXME(f16_f128): add tests for these types when abs is available
-
 pub fn is_roughly_equal(a: f32, b: f32) -> bool {
     (a - b) < f32::EPSILON
     //~^ float_equality_without_abs
@@ -44,10 +44,20 @@ pub fn main() {
     let _ = f32::EPSILON > 1.0 - 2.0;
     //~^ float_equality_without_abs
 
+    let _ = (a as f16 - b as f16) < f16::EPSILON;
+    //~^ float_equality_without_abs
+
+    let _ = (a as f128 - b as f128) < f128::EPSILON;
+    //~^ float_equality_without_abs
+
     // those are correct
+    let _ = (a as f16 - b as f16).abs() < f16::EPSILON;
     let _ = (a - b).abs() < f32::EPSILON;
     let _ = (a as f64 - b as f64).abs() < f64::EPSILON;
+    let _ = (a as f128 - b as f128).abs() < f128::EPSILON;
 
+    let _ = f16::EPSILON > (a as f16 - b as f16).abs();
     let _ = f32::EPSILON > (a - b).abs();
     let _ = f64::EPSILON > (a as f64 - b as f64).abs();
+    let _ = f128::EPSILON > (a as f128 - b as f128).abs();
 }
diff --git a/src/tools/clippy/tests/ui/float_equality_without_abs.stderr b/src/tools/clippy/tests/ui/float_equality_without_abs.stderr
index d4c89ce72ba..55a150dead5 100644
--- a/src/tools/clippy/tests/ui/float_equality_without_abs.stderr
+++ b/src/tools/clippy/tests/ui/float_equality_without_abs.stderr
@@ -89,5 +89,21 @@ LL |     let _ = f32::EPSILON > 1.0 - 2.0;
    |                            |
    |                            help: add `.abs()`: `(1.0 - 2.0).abs()`
 
-error: aborting due to 11 previous errors
+error: float equality check without `.abs()`
+  --> tests/ui/float_equality_without_abs.rs:47:13
+   |
+LL |     let _ = (a as f16 - b as f16) < f16::EPSILON;
+   |             ---------------------^^^^^^^^^^^^^^^
+   |             |
+   |             help: add `.abs()`: `(a as f16 - b as f16).abs()`
+
+error: float equality check without `.abs()`
+  --> tests/ui/float_equality_without_abs.rs:50:13
+   |
+LL |     let _ = (a as f128 - b as f128) < f128::EPSILON;
+   |             -----------------------^^^^^^^^^^^^^^^^
+   |             |
+   |             help: add `.abs()`: `(a as f128 - b as f128).abs()`
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.fixed b/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
index d14a805b666..0fd130609ae 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
@@ -165,3 +165,44 @@ mod issue15257 {
         do_something((i % 2 == 0).then_some(closure_fn));
     }
 }
+
+fn issue15005() {
+    struct Counter {
+        count: u32,
+    }
+
+    impl Counter {
+        fn new() -> Counter {
+            Counter { count: 0 }
+        }
+    }
+
+    impl Iterator for Counter {
+        type Item = u32;
+
+        fn next(&mut self) -> Option<Self::Item> {
+            //~v if_then_some_else_none
+            (self.count < 5).then(||  { self.count += 1; self.count })
+        }
+    }
+}
+
+fn statements_from_macro() {
+    macro_rules! mac {
+        () => {
+            println!("foo");
+            println!("bar");
+        };
+    }
+    //~v if_then_some_else_none
+    let _ = true.then(||  { mac!(); 42 });
+}
+
+fn dont_lint_inside_macros() {
+    macro_rules! mac {
+        ($cond:expr, $res:expr) => {
+            if $cond { Some($res) } else { None }
+        };
+    }
+    let _: Option<u32> = mac!(true, 42);
+}
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.rs b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
index bb0072f3157..640828aa9bf 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.rs
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
@@ -211,3 +211,54 @@ mod issue15257 {
         });
     }
 }
+
+fn issue15005() {
+    struct Counter {
+        count: u32,
+    }
+
+    impl Counter {
+        fn new() -> Counter {
+            Counter { count: 0 }
+        }
+    }
+
+    impl Iterator for Counter {
+        type Item = u32;
+
+        fn next(&mut self) -> Option<Self::Item> {
+            //~v if_then_some_else_none
+            if self.count < 5 {
+                self.count += 1;
+                Some(self.count)
+            } else {
+                None
+            }
+        }
+    }
+}
+
+fn statements_from_macro() {
+    macro_rules! mac {
+        () => {
+            println!("foo");
+            println!("bar");
+        };
+    }
+    //~v if_then_some_else_none
+    let _ = if true {
+        mac!();
+        Some(42)
+    } else {
+        None
+    };
+}
+
+fn dont_lint_inside_macros() {
+    macro_rules! mac {
+        ($cond:expr, $res:expr) => {
+            if $cond { Some($res) } else { None }
+        };
+    }
+    let _: Option<u32> = mac!(true, 42);
+}
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
index c2e624a0a73..58651a05594 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
@@ -116,5 +116,28 @@ LL | |             None
 LL | |         });
    | |_________^ help: try: `(i % 2 == 0).then_some(closure_fn)`
 
-error: aborting due to 11 previous errors
+error: this could be simplified with `bool::then`
+  --> tests/ui/if_then_some_else_none.rs:231:13
+   |
+LL | /             if self.count < 5 {
+LL | |                 self.count += 1;
+LL | |                 Some(self.count)
+LL | |             } else {
+LL | |                 None
+LL | |             }
+   | |_____________^ help: try: `(self.count < 5).then(||  { self.count += 1; self.count })`
+
+error: this could be simplified with `bool::then`
+  --> tests/ui/if_then_some_else_none.rs:249:13
+   |
+LL |       let _ = if true {
+   |  _____________^
+LL | |         mac!();
+LL | |         Some(42)
+LL | |     } else {
+LL | |         None
+LL | |     };
+   | |_____^ help: try: `true.then(||  { mac!(); 42 })`
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/infinite_loops.rs b/src/tools/clippy/tests/ui/infinite_loops.rs
index 9b8c3933197..7d01a7fb61f 100644
--- a/src/tools/clippy/tests/ui/infinite_loops.rs
+++ b/src/tools/clippy/tests/ui/infinite_loops.rs
@@ -521,4 +521,19 @@ mod tokio_spawn_test {
     }
 }
 
+mod issue15541 {
+    async fn good() -> ! {
+        loop {
+            std::future::pending().await
+        }
+    }
+
+    async fn bad() {
+        //~v infinite_loop
+        loop {
+            std::future::pending().await
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/infinite_loops.stderr b/src/tools/clippy/tests/ui/infinite_loops.stderr
index 4c6b6f725f1..319f1e5012b 100644
--- a/src/tools/clippy/tests/ui/infinite_loops.stderr
+++ b/src/tools/clippy/tests/ui/infinite_loops.stderr
@@ -333,5 +333,15 @@ LL | |             }
    |
    = help: if this is not intended, try adding a `break` or `return` condition in the loop
 
-error: aborting due to 23 previous errors
+error: infinite loop detected
+  --> tests/ui/infinite_loops.rs:533:9
+   |
+LL | /         loop {
+LL | |             std::future::pending().await
+LL | |         }
+   | |_________^
+   |
+   = help: if this is not intended, try adding a `break` or `return` condition in the loop
+
+error: aborting due to 24 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
index 7b0d1906834..406336dbd09 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.fixed
@@ -108,6 +108,8 @@ fn generics() {
     //~^ manual_is_ascii_check
     take_while(|c: char| c.is_ascii_uppercase());
     //~^ manual_is_ascii_check
+    take_while(|c: char| c.is_ascii_uppercase());
+    //~^ manual_is_ascii_check
 }
 
 fn adds_type_reference() {
@@ -115,4 +117,6 @@ fn adds_type_reference() {
     //~^ manual_is_ascii_check
     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
     //~^ manual_is_ascii_check
+    let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
+    //~^ manual_is_ascii_check
 }
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
index e4f7fe9f583..a624497e75e 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.rs
@@ -108,6 +108,8 @@ fn generics() {
     //~^ manual_is_ascii_check
     take_while(|c: char| ('A'..='Z').contains(&c));
     //~^ manual_is_ascii_check
+    take_while(|c| matches!(c, 'A'..='Z'));
+    //~^ manual_is_ascii_check
 }
 
 fn adds_type_reference() {
@@ -115,4 +117,6 @@ fn adds_type_reference() {
     //~^ manual_is_ascii_check
     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();
     //~^ manual_is_ascii_check
+    let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();
+    //~^ manual_is_ascii_check
 }
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
index 9fd7f457b42..cb2548ea731 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
@@ -176,7 +176,19 @@ LL |     take_while(|c: char| ('A'..='Z').contains(&c));
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_uppercase()`
 
 error: manual check for common ascii range
-  --> tests/ui/manual_is_ascii_check.rs:114:63
+  --> tests/ui/manual_is_ascii_check.rs:111:20
+   |
+LL |     take_while(|c| matches!(c, 'A'..='Z'));
+   |                    ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -     take_while(|c| matches!(c, 'A'..='Z'));
+LL +     take_while(|c: char| c.is_ascii_uppercase());
+   |
+
+error: manual check for common ascii range
+  --> tests/ui/manual_is_ascii_check.rs:116:63
    |
 LL |     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect();
    |                                                               ^^^^^^^^^^^^^^^^^^^^^^^
@@ -188,7 +200,7 @@ LL +     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_
    |
 
 error: manual check for common ascii range
-  --> tests/ui/manual_is_ascii_check.rs:116:71
+  --> tests/ui/manual_is_ascii_check.rs:118:71
    |
 LL |     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();
    |                                                                       ^^^^^^^^^^^^^^^^^^^^^^^
@@ -199,5 +211,17 @@ LL -     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'.
 LL +     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
    |
 
-error: aborting due to 29 previous errors
+error: manual check for common ascii range
+  --> tests/ui/manual_is_ascii_check.rs:120:71
+   |
+LL |     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();
+   |                                                                       ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| matches!(c, '0'..='9')).collect();
+LL +     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
+   |
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed
index 6c971ba6338..a10aae8cc12 100644
--- a/src/tools/clippy/tests/ui/map_identity.fixed
+++ b/src/tools/clippy/tests/ui/map_identity.fixed
@@ -1,3 +1,4 @@
+//@require-annotations-for-level: ERROR
 #![warn(clippy::map_identity)]
 #![allow(clippy::needless_return, clippy::disallowed_names)]
 
@@ -72,20 +73,33 @@ fn issue11764() {
 }
 
 fn issue13904() {
-    // don't lint: `it.next()` would not be legal as `it` is immutable
-    let it = [1, 2, 3].into_iter();
-    let _ = it.map(|x| x).next();
+    // lint, but there's a catch:
+    // when we remove the `.map()`, `it.next()` would require `it` to be mutable
+    // therefore, include that in the suggestion as well
+    let mut it = [1, 2, 3].into_iter();
+    let _ = it.next();
+    //~^ map_identity
+    //~| HELP: remove the call to `map`, and make `it` mutable
+
+    // lint
+    let mut index = [1, 2, 3].into_iter();
+    let mut subindex = (index.by_ref().take(3), 42);
+    let _ = subindex.0.next();
+    //~^ map_identity
+    //~| HELP: remove the call to `map`, and make `subindex` mutable
 
     // lint
     #[allow(unused_mut)]
     let mut it = [1, 2, 3].into_iter();
     let _ = it.next();
     //~^ map_identity
+    //~| HELP: remove the call to `map`
 
     // lint
     let it = [1, 2, 3].into_iter();
     let _ = { it }.next();
     //~^ map_identity
+    //~| HELP: remove the call to `map`
 }
 
 // same as `issue11764`, but for arrays
diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs
index 59dcfcda3b6..fc6e018f924 100644
--- a/src/tools/clippy/tests/ui/map_identity.rs
+++ b/src/tools/clippy/tests/ui/map_identity.rs
@@ -1,3 +1,4 @@
+//@require-annotations-for-level: ERROR
 #![warn(clippy::map_identity)]
 #![allow(clippy::needless_return, clippy::disallowed_names)]
 
@@ -78,20 +79,33 @@ fn issue11764() {
 }
 
 fn issue13904() {
-    // don't lint: `it.next()` would not be legal as `it` is immutable
+    // lint, but there's a catch:
+    // when we remove the `.map()`, `it.next()` would require `it` to be mutable
+    // therefore, include that in the suggestion as well
     let it = [1, 2, 3].into_iter();
     let _ = it.map(|x| x).next();
+    //~^ map_identity
+    //~| HELP: remove the call to `map`, and make `it` mutable
+
+    // lint
+    let mut index = [1, 2, 3].into_iter();
+    let subindex = (index.by_ref().take(3), 42);
+    let _ = subindex.0.map(|n| n).next();
+    //~^ map_identity
+    //~| HELP: remove the call to `map`, and make `subindex` mutable
 
     // lint
     #[allow(unused_mut)]
     let mut it = [1, 2, 3].into_iter();
     let _ = it.map(|x| x).next();
     //~^ map_identity
+    //~| HELP: remove the call to `map`
 
     // lint
     let it = [1, 2, 3].into_iter();
     let _ = { it }.map(|x| x).next();
     //~^ map_identity
+    //~| HELP: remove the call to `map`
 }
 
 // same as `issue11764`, but for arrays
diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr
index a50c0d6b87b..8d19d62cdc6 100644
--- a/src/tools/clippy/tests/ui/map_identity.stderr
+++ b/src/tools/clippy/tests/ui/map_identity.stderr
@@ -1,5 +1,5 @@
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:7:47
+  --> tests/ui/map_identity.rs:8:47
    |
 LL |     let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect();
    |                                               ^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
@@ -8,25 +8,25 @@ LL |     let _: Vec<_> = x.iter().map(not_identity).map(|x| return x).collect();
    = help: to override `-D warnings` add `#[allow(clippy::map_identity)]`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:9:57
+  --> tests/ui/map_identity.rs:10:57
    |
 LL |     let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect();
    |                                                         ^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:9:29
+  --> tests/ui/map_identity.rs:10:29
    |
 LL |     let _: Vec<_> = x.iter().map(std::convert::identity).map(|y| y).collect();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:12:32
+  --> tests/ui/map_identity.rs:13:32
    |
 LL |     let _: Option<u8> = Some(3).map(|x| x);
    |                                ^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:14:36
+  --> tests/ui/map_identity.rs:15:36
    |
 LL |       let _: Result<i8, f32> = Ok(-3).map(|x| {
    |  ____________________________________^
@@ -36,19 +36,19 @@ LL | |     });
    | |______^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:25:36
+  --> tests/ui/map_identity.rs:26:36
    |
 LL |     let _: Result<u32, u32> = Ok(1).map_err(|a| a);
    |                                    ^^^^^^^^^^^^^^^ help: remove the call to `map_err`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:36:22
+  --> tests/ui/map_identity.rs:37:22
    |
 LL |     let _ = x.clone().map(|(x, y)| (x, y));
    |                      ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:38:22
+  --> tests/ui/map_identity.rs:39:22
    |
 LL |       let _ = x.clone().map(|(x, y)| {
    |  ______________________^
@@ -58,76 +58,100 @@ LL | |     });
    | |______^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:42:22
+  --> tests/ui/map_identity.rs:43:22
    |
 LL |     let _ = x.clone().map(|(x, y)| return (x, y));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:46:22
+  --> tests/ui/map_identity.rs:47:22
    |
 LL |     let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:76:30
+  --> tests/ui/map_identity.rs:77:30
    |
 LL |     let _ = x.iter().copied().map(|(x, y)| (x, y));
    |                              ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:88:15
+  --> tests/ui/map_identity.rs:86:15
+   |
+LL |     let _ = it.map(|x| x).next();
+   |               ^^^^^^^^^^^
+   |
+help: remove the call to `map`, and make `it` mutable
+   |
+LL ~     let mut it = [1, 2, 3].into_iter();
+LL ~     let _ = it.next();
+   |
+
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:93:23
+   |
+LL |     let _ = subindex.0.map(|n| n).next();
+   |                       ^^^^^^^^^^^
+   |
+help: remove the call to `map`, and make `subindex` mutable
+   |
+LL ~     let mut subindex = (index.by_ref().take(3), 42);
+LL ~     let _ = subindex.0.next();
+   |
+
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:100:15
    |
 LL |     let _ = it.map(|x| x).next();
    |               ^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:93:19
+  --> tests/ui/map_identity.rs:106:19
    |
 LL |     let _ = { it }.map(|x| x).next();
    |                   ^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:105:30
+  --> tests/ui/map_identity.rs:119:30
    |
 LL |     let _ = x.iter().copied().map(|[x, y]| [x, y]);
    |                              ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:131:26
+  --> tests/ui/map_identity.rs:145:26
    |
 LL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo, bar });
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:135:26
+  --> tests/ui/map_identity.rs:149:26
    |
 LL |     let _ = x.into_iter().map(|Foo { foo, bar }| foo::Foo { foo, bar });
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:143:26
+  --> tests/ui/map_identity.rs:157:26
    |
 LL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: foo, bar: bar });
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:147:26
+  --> tests/ui/map_identity.rs:161:26
    |
 LL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { bar, foo });
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:157:26
+  --> tests/ui/map_identity.rs:171:26
    |
 LL |     let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(foo, bar));
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
 error: unnecessary map of the identity function
-  --> tests/ui/map_identity.rs:161:26
+  --> tests/ui/map_identity.rs:175:26
    |
 LL |     let _ = x.into_iter().map(|Foo2(foo, bar)| foo::Foo2(foo, bar));
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
-error: aborting due to 20 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/missing_inline.rs b/src/tools/clippy/tests/ui/missing_inline.rs
index 223c7447975..8e937d60951 100644
--- a/src/tools/clippy/tests/ui/missing_inline.rs
+++ b/src/tools/clippy/tests/ui/missing_inline.rs
@@ -97,3 +97,10 @@ pub mod issue15301 {
         println!("Just called a Rust function from Rust!");
     }
 }
+
+pub mod issue15491 {
+    pub trait Foo {
+        #[allow(clippy::missing_inline_in_public_items)]
+        fn foo(&self) {}
+    }
+}
diff --git a/src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.rs b/src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.rs
new file mode 100644
index 00000000000..08ba3b791ee
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.rs
@@ -0,0 +1,29 @@
+//@no-rustfix
+
+fn issue14984() {
+    async fn e() {}
+    async fn x() -> u32 {
+        0
+    }
+    async fn y() -> f32 {
+        0.0
+    };
+    let mut yy = unsafe { std::ptr::read(&y()) };
+    yy = unsafe { std::mem::transmute(std::ptr::read(&x())) };
+    //~^ missing_transmute_annotations
+
+    let mut zz = 0u8;
+    zz = unsafe { std::mem::transmute(std::ptr::read(&x())) };
+    //~^ missing_transmute_annotations
+
+    yy = unsafe { std::mem::transmute(zz) };
+    //~^ missing_transmute_annotations
+
+    fn a() -> impl Sized {
+        0u32
+    }
+
+    let mut b: f32 = 0.0;
+    b = unsafe { std::mem::transmute(a()) };
+    //~^ missing_transmute_annotations
+}
diff --git a/src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.stderr b/src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.stderr
new file mode 100644
index 00000000000..83efdce13f7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_transmute_annotations_unfixable.stderr
@@ -0,0 +1,36 @@
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations_unfixable.rs:12:29
+   |
+LL |     yy = unsafe { std::mem::transmute(std::ptr::read(&x())) };
+   |                             ^^^^^^^^^
+   |
+   = help: consider giving the source and destination types a name, and adding missing type annotations
+   = note: `-D clippy::missing-transmute-annotations` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations_unfixable.rs:16:29
+   |
+LL |     zz = unsafe { std::mem::transmute(std::ptr::read(&x())) };
+   |                             ^^^^^^^^^
+   |
+   = help: consider giving the origin type a name, and adding missing type annotations
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations_unfixable.rs:19:29
+   |
+LL |     yy = unsafe { std::mem::transmute(zz) };
+   |                             ^^^^^^^^^
+   |
+   = help: consider giving the destination type a name, and adding missing type annotations
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations_unfixable.rs:27:28
+   |
+LL |     b = unsafe { std::mem::transmute(a()) };
+   |                            ^^^^^^^^^
+   |
+   = help: consider giving `a()`'s type a name, and adding missing type annotations
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/mut_reference.fixed b/src/tools/clippy/tests/ui/mut_reference.fixed
new file mode 100644
index 00000000000..03d854099e6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mut_reference.fixed
@@ -0,0 +1,170 @@
+#![allow(clippy::mut_mut)]
+
+fn takes_ref(a: &i32) {}
+fn takes_refmut(a: &mut i32) {}
+fn takes_ref_ref(a: &&i32) {}
+fn takes_refmut_ref(a: &mut &i32) {}
+fn takes_ref_refmut(a: &&mut i32) {}
+fn takes_refmut_refmut(a: &mut &mut i32) {}
+fn takes_raw_const(a: *const i32) {}
+fn takes_raw_mut(a: *mut i32) {}
+
+mod issue11268 {
+    macro_rules! x {
+        (1 $f:expr) => {
+            $f(&mut 1);
+        };
+        (2 $f:expr) => {
+            $f(&mut &1)
+        };
+        (3 $f:expr) => {
+            $f(&mut &mut 1)
+        };
+        (4 $f:expr) => {
+            let mut a = 1;
+            $f(&raw mut a)
+        };
+    }
+
+    fn f() {
+        x!(1 super::takes_ref);
+        x!(1 super::takes_refmut);
+        x!(2 super::takes_refmut_ref);
+        x!(3 super::takes_ref_refmut);
+        x!(3 super::takes_refmut_refmut);
+        x!(4 super::takes_raw_const);
+        x!(4 super::takes_raw_mut);
+    }
+}
+
+struct MyStruct;
+
+impl MyStruct {
+    fn takes_ref(&self, a: &i32) {}
+    fn takes_refmut(&self, a: &mut i32) {}
+    fn takes_ref_ref(&self, a: &&i32) {}
+    fn takes_refmut_ref(&self, a: &mut &i32) {}
+    fn takes_ref_refmut(&self, a: &&mut i32) {}
+    fn takes_refmut_refmut(&self, a: &mut &mut i32) {}
+    fn takes_raw_const(&self, a: *const i32) {}
+    fn takes_raw_mut(&self, a: *mut i32) {}
+}
+
+#[warn(clippy::unnecessary_mut_passed)]
+fn main() {
+    // Functions
+    takes_ref(&42);
+    //~^ unnecessary_mut_passed
+    takes_ref_ref(&&42);
+    //~^ unnecessary_mut_passed
+    takes_ref_refmut(&&mut 42);
+    //~^ unnecessary_mut_passed
+    takes_raw_const(&42);
+    //~^ unnecessary_mut_passed
+
+    let as_ptr: fn(&i32) = takes_ref;
+    as_ptr(&42);
+    //~^ unnecessary_mut_passed
+    let as_ptr: fn(&&i32) = takes_ref_ref;
+    as_ptr(&&42);
+    //~^ unnecessary_mut_passed
+    let as_ptr: fn(&&mut i32) = takes_ref_refmut;
+    as_ptr(&&mut 42);
+    //~^ unnecessary_mut_passed
+    let as_ptr: fn(*const i32) = takes_raw_const;
+    as_ptr(&42);
+    //~^ unnecessary_mut_passed
+
+    // Methods
+    let my_struct = MyStruct;
+    my_struct.takes_ref(&42);
+    //~^ unnecessary_mut_passed
+    my_struct.takes_ref_ref(&&42);
+    //~^ unnecessary_mut_passed
+    my_struct.takes_ref_refmut(&&mut 42);
+    //~^ unnecessary_mut_passed
+    my_struct.takes_raw_const(&42);
+    //~^ unnecessary_mut_passed
+
+    // No error
+
+    // Functions
+    takes_ref(&42);
+    let as_ptr: fn(&i32) = takes_ref;
+    as_ptr(&42);
+
+    takes_refmut(&mut 42);
+    let as_ptr: fn(&mut i32) = takes_refmut;
+    as_ptr(&mut 42);
+
+    takes_ref_ref(&&42);
+    let as_ptr: fn(&&i32) = takes_ref_ref;
+    as_ptr(&&42);
+
+    takes_refmut_ref(&mut &42);
+    let as_ptr: fn(&mut &i32) = takes_refmut_ref;
+    as_ptr(&mut &42);
+
+    takes_ref_refmut(&&mut 42);
+    let as_ptr: fn(&&mut i32) = takes_ref_refmut;
+    as_ptr(&&mut 42);
+
+    takes_refmut_refmut(&mut &mut 42);
+    let as_ptr: fn(&mut &mut i32) = takes_refmut_refmut;
+    as_ptr(&mut &mut 42);
+
+    takes_raw_const(&42);
+    let as_ptr: fn(*const i32) = takes_raw_const;
+    as_ptr(&42);
+
+    takes_raw_mut(&mut 42);
+    let as_ptr: fn(*mut i32) = takes_raw_mut;
+    as_ptr(&mut 42);
+
+    let a = &mut 42;
+    let b = &mut &42;
+    let c = &mut &mut 42;
+    takes_ref(a);
+    takes_ref_ref(b);
+    takes_ref_refmut(c);
+    takes_raw_const(a);
+
+    // Methods
+    my_struct.takes_ref(&42);
+    my_struct.takes_refmut(&mut 42);
+    my_struct.takes_ref_ref(&&42);
+    my_struct.takes_refmut_ref(&mut &42);
+    my_struct.takes_ref_refmut(&&mut 42);
+    my_struct.takes_refmut_refmut(&mut &mut 42);
+    my_struct.takes_raw_const(&42);
+    my_struct.takes_raw_mut(&mut 42);
+    my_struct.takes_ref(a);
+    my_struct.takes_ref_ref(b);
+    my_struct.takes_ref_refmut(c);
+    my_struct.takes_raw_const(a);
+    my_struct.takes_raw_mut(a);
+}
+
+// not supported currently
+fn raw_ptrs(my_struct: MyStruct) {
+    let mut n = 42;
+
+    takes_raw_const(&raw mut n);
+
+    let as_ptr: fn(*const i32) = takes_raw_const;
+    as_ptr(&raw mut n);
+
+    my_struct.takes_raw_const(&raw mut n);
+
+    // No error
+
+    takes_raw_const(&raw const n);
+    takes_raw_mut(&raw mut n);
+
+    let a = &raw mut n;
+    takes_raw_const(a);
+
+    my_struct.takes_raw_const(&raw const n);
+    my_struct.takes_raw_mut(&raw mut n);
+    my_struct.takes_raw_const(a);
+}
diff --git a/src/tools/clippy/tests/ui/mut_reference.rs b/src/tools/clippy/tests/ui/mut_reference.rs
index f664c373cdc..80e3f506927 100644
--- a/src/tools/clippy/tests/ui/mut_reference.rs
+++ b/src/tools/clippy/tests/ui/mut_reference.rs
@@ -1,60 +1,170 @@
-#![allow(unused_variables, dead_code)]
-//@no-rustfix
-fn takes_an_immutable_reference(a: &i32) {}
-fn takes_a_mutable_reference(a: &mut i32) {}
+#![allow(clippy::mut_mut)]
+
+fn takes_ref(a: &i32) {}
+fn takes_refmut(a: &mut i32) {}
+fn takes_ref_ref(a: &&i32) {}
+fn takes_refmut_ref(a: &mut &i32) {}
+fn takes_ref_refmut(a: &&mut i32) {}
+fn takes_refmut_refmut(a: &mut &mut i32) {}
+fn takes_raw_const(a: *const i32) {}
+fn takes_raw_mut(a: *mut i32) {}
 
 mod issue11268 {
     macro_rules! x {
-        ($f:expr) => {
+        (1 $f:expr) => {
             $f(&mut 1);
         };
+        (2 $f:expr) => {
+            $f(&mut &1)
+        };
+        (3 $f:expr) => {
+            $f(&mut &mut 1)
+        };
+        (4 $f:expr) => {
+            let mut a = 1;
+            $f(&raw mut a)
+        };
     }
 
     fn f() {
-        x!(super::takes_an_immutable_reference);
-        x!(super::takes_a_mutable_reference);
+        x!(1 super::takes_ref);
+        x!(1 super::takes_refmut);
+        x!(2 super::takes_refmut_ref);
+        x!(3 super::takes_ref_refmut);
+        x!(3 super::takes_refmut_refmut);
+        x!(4 super::takes_raw_const);
+        x!(4 super::takes_raw_mut);
     }
 }
 
 struct MyStruct;
 
 impl MyStruct {
-    fn takes_an_immutable_reference(&self, a: &i32) {}
-
-    fn takes_a_mutable_reference(&self, a: &mut i32) {}
+    fn takes_ref(&self, a: &i32) {}
+    fn takes_refmut(&self, a: &mut i32) {}
+    fn takes_ref_ref(&self, a: &&i32) {}
+    fn takes_refmut_ref(&self, a: &mut &i32) {}
+    fn takes_ref_refmut(&self, a: &&mut i32) {}
+    fn takes_refmut_refmut(&self, a: &mut &mut i32) {}
+    fn takes_raw_const(&self, a: *const i32) {}
+    fn takes_raw_mut(&self, a: *mut i32) {}
 }
 
 #[warn(clippy::unnecessary_mut_passed)]
 fn main() {
     // Functions
-    takes_an_immutable_reference(&mut 42);
+    takes_ref(&mut 42);
+    //~^ unnecessary_mut_passed
+    takes_ref_ref(&mut &42);
+    //~^ unnecessary_mut_passed
+    takes_ref_refmut(&mut &mut 42);
+    //~^ unnecessary_mut_passed
+    takes_raw_const(&mut 42);
     //~^ unnecessary_mut_passed
 
-    let as_ptr: fn(&i32) = takes_an_immutable_reference;
+    let as_ptr: fn(&i32) = takes_ref;
+    as_ptr(&mut 42);
+    //~^ unnecessary_mut_passed
+    let as_ptr: fn(&&i32) = takes_ref_ref;
+    as_ptr(&mut &42);
+    //~^ unnecessary_mut_passed
+    let as_ptr: fn(&&mut i32) = takes_ref_refmut;
+    as_ptr(&mut &mut 42);
+    //~^ unnecessary_mut_passed
+    let as_ptr: fn(*const i32) = takes_raw_const;
     as_ptr(&mut 42);
     //~^ unnecessary_mut_passed
 
     // Methods
     let my_struct = MyStruct;
-    my_struct.takes_an_immutable_reference(&mut 42);
+    my_struct.takes_ref(&mut 42);
+    //~^ unnecessary_mut_passed
+    my_struct.takes_ref_ref(&mut &42);
+    //~^ unnecessary_mut_passed
+    my_struct.takes_ref_refmut(&mut &mut 42);
+    //~^ unnecessary_mut_passed
+    my_struct.takes_raw_const(&mut 42);
     //~^ unnecessary_mut_passed
 
     // No error
 
     // Functions
-    takes_an_immutable_reference(&42);
-    let as_ptr: fn(&i32) = takes_an_immutable_reference;
+    takes_ref(&42);
+    let as_ptr: fn(&i32) = takes_ref;
     as_ptr(&42);
 
-    takes_a_mutable_reference(&mut 42);
-    let as_ptr: fn(&mut i32) = takes_a_mutable_reference;
+    takes_refmut(&mut 42);
+    let as_ptr: fn(&mut i32) = takes_refmut;
+    as_ptr(&mut 42);
+
+    takes_ref_ref(&&42);
+    let as_ptr: fn(&&i32) = takes_ref_ref;
+    as_ptr(&&42);
+
+    takes_refmut_ref(&mut &42);
+    let as_ptr: fn(&mut &i32) = takes_refmut_ref;
+    as_ptr(&mut &42);
+
+    takes_ref_refmut(&&mut 42);
+    let as_ptr: fn(&&mut i32) = takes_ref_refmut;
+    as_ptr(&&mut 42);
+
+    takes_refmut_refmut(&mut &mut 42);
+    let as_ptr: fn(&mut &mut i32) = takes_refmut_refmut;
+    as_ptr(&mut &mut 42);
+
+    takes_raw_const(&42);
+    let as_ptr: fn(*const i32) = takes_raw_const;
+    as_ptr(&42);
+
+    takes_raw_mut(&mut 42);
+    let as_ptr: fn(*mut i32) = takes_raw_mut;
     as_ptr(&mut 42);
 
     let a = &mut 42;
-    takes_an_immutable_reference(a);
+    let b = &mut &42;
+    let c = &mut &mut 42;
+    takes_ref(a);
+    takes_ref_ref(b);
+    takes_ref_refmut(c);
+    takes_raw_const(a);
 
     // Methods
-    my_struct.takes_an_immutable_reference(&42);
-    my_struct.takes_a_mutable_reference(&mut 42);
-    my_struct.takes_an_immutable_reference(a);
+    my_struct.takes_ref(&42);
+    my_struct.takes_refmut(&mut 42);
+    my_struct.takes_ref_ref(&&42);
+    my_struct.takes_refmut_ref(&mut &42);
+    my_struct.takes_ref_refmut(&&mut 42);
+    my_struct.takes_refmut_refmut(&mut &mut 42);
+    my_struct.takes_raw_const(&42);
+    my_struct.takes_raw_mut(&mut 42);
+    my_struct.takes_ref(a);
+    my_struct.takes_ref_ref(b);
+    my_struct.takes_ref_refmut(c);
+    my_struct.takes_raw_const(a);
+    my_struct.takes_raw_mut(a);
+}
+
+// not supported currently
+fn raw_ptrs(my_struct: MyStruct) {
+    let mut n = 42;
+
+    takes_raw_const(&raw mut n);
+
+    let as_ptr: fn(*const i32) = takes_raw_const;
+    as_ptr(&raw mut n);
+
+    my_struct.takes_raw_const(&raw mut n);
+
+    // No error
+
+    takes_raw_const(&raw const n);
+    takes_raw_mut(&raw mut n);
+
+    let a = &raw mut n;
+    takes_raw_const(a);
+
+    my_struct.takes_raw_const(&raw const n);
+    my_struct.takes_raw_mut(&raw mut n);
+    my_struct.takes_raw_const(a);
 }
diff --git a/src/tools/clippy/tests/ui/mut_reference.stderr b/src/tools/clippy/tests/ui/mut_reference.stderr
index 474221329c2..5ecfaa37416 100644
--- a/src/tools/clippy/tests/ui/mut_reference.stderr
+++ b/src/tools/clippy/tests/ui/mut_reference.stderr
@@ -1,23 +1,77 @@
-error: the function `takes_an_immutable_reference` doesn't need a mutable reference
-  --> tests/ui/mut_reference.rs:30:34
+error: the function `takes_ref` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:56:15
    |
-LL |     takes_an_immutable_reference(&mut 42);
-   |                                  ^^^^^^^
+LL |     takes_ref(&mut 42);
+   |               ^^^^^^^ help: remove this `mut`: `&42`
    |
    = note: `-D clippy::unnecessary-mut-passed` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_mut_passed)]`
 
+error: the function `takes_ref_ref` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:58:19
+   |
+LL |     takes_ref_ref(&mut &42);
+   |                   ^^^^^^^^ help: remove this `mut`: `&&42`
+
+error: the function `takes_ref_refmut` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:60:22
+   |
+LL |     takes_ref_refmut(&mut &mut 42);
+   |                      ^^^^^^^^^^^^ help: remove this `mut`: `&&mut 42`
+
+error: the function `takes_raw_const` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:62:21
+   |
+LL |     takes_raw_const(&mut 42);
+   |                     ^^^^^^^ help: remove this `mut`: `&42`
+
+error: the function `as_ptr` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:66:12
+   |
+LL |     as_ptr(&mut 42);
+   |            ^^^^^^^ help: remove this `mut`: `&42`
+
+error: the function `as_ptr` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:69:12
+   |
+LL |     as_ptr(&mut &42);
+   |            ^^^^^^^^ help: remove this `mut`: `&&42`
+
+error: the function `as_ptr` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:72:12
+   |
+LL |     as_ptr(&mut &mut 42);
+   |            ^^^^^^^^^^^^ help: remove this `mut`: `&&mut 42`
+
 error: the function `as_ptr` doesn't need a mutable reference
-  --> tests/ui/mut_reference.rs:34:12
+  --> tests/ui/mut_reference.rs:75:12
    |
 LL |     as_ptr(&mut 42);
-   |            ^^^^^^^
+   |            ^^^^^^^ help: remove this `mut`: `&42`
+
+error: the method `takes_ref` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:80:25
+   |
+LL |     my_struct.takes_ref(&mut 42);
+   |                         ^^^^^^^ help: remove this `mut`: `&42`
+
+error: the method `takes_ref_ref` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:82:29
+   |
+LL |     my_struct.takes_ref_ref(&mut &42);
+   |                             ^^^^^^^^ help: remove this `mut`: `&&42`
+
+error: the method `takes_ref_refmut` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:84:32
+   |
+LL |     my_struct.takes_ref_refmut(&mut &mut 42);
+   |                                ^^^^^^^^^^^^ help: remove this `mut`: `&&mut 42`
 
-error: the method `takes_an_immutable_reference` doesn't need a mutable reference
-  --> tests/ui/mut_reference.rs:39:44
+error: the method `takes_raw_const` doesn't need a mutable reference
+  --> tests/ui/mut_reference.rs:86:31
    |
-LL |     my_struct.takes_an_immutable_reference(&mut 42);
-   |                                            ^^^^^^^
+LL |     my_struct.takes_raw_const(&mut 42);
+   |                               ^^^^^^^ help: remove this `mut`: `&42`
 
-error: aborting due to 3 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_bool/fixable.stderr b/src/tools/clippy/tests/ui/needless_bool/fixable.stderr
index 3f117ee5a50..9404d07ba0e 100644
--- a/src/tools/clippy/tests/ui/needless_bool/fixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_bool/fixable.stderr
@@ -135,7 +135,7 @@ error: equality checks against true are unnecessary
   --> tests/ui/needless_bool/fixable.rs:157:8
    |
 LL |     if x == true {};
-   |        ^^^^^^^^^ help: try simplifying it as shown: `x`
+   |        ^^^^^^^^^ help: try: `x`
    |
    = note: `-D clippy::bool-comparison` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
@@ -144,19 +144,19 @@ error: equality checks against false can be replaced by a negation
   --> tests/ui/needless_bool/fixable.rs:162:8
    |
 LL |     if x == false {};
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
+   |        ^^^^^^^^^^ help: try: `!x`
 
 error: equality checks against true are unnecessary
   --> tests/ui/needless_bool/fixable.rs:173:8
    |
 LL |     if x == true {};
-   |        ^^^^^^^^^ help: try simplifying it as shown: `x`
+   |        ^^^^^^^^^ help: try: `x`
 
 error: equality checks against false can be replaced by a negation
   --> tests/ui/needless_bool/fixable.rs:175:8
    |
 LL |     if x == false {};
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
+   |        ^^^^^^^^^^ help: try: `!x`
 
 error: this if-then-else expression returns a bool literal
   --> tests/ui/needless_bool/fixable.rs:185:12
diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs b/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs
index 159cbe49828..24ce5786b91 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs
+++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.rs
@@ -1,6 +1,6 @@
 //@no-rustfix: overlapping suggestions
 #![warn(clippy::needless_for_each)]
-#![allow(clippy::needless_return, clippy::uninlined_format_args)]
+#![allow(clippy::needless_return)]
 
 fn main() {
     let v: Vec<i32> = Vec::new();
@@ -11,7 +11,22 @@ fn main() {
         if *v == 10 {
             return;
         } else {
-            println!("{}", v);
+            println!("{v}");
         }
     });
 }
+
+fn issue9912() {
+    let mut i = 0;
+    // Changing this to a `for` loop would break type inference
+    [].iter().for_each(move |_: &i32| {
+        //~^ needless_for_each
+        i += 1;
+    });
+
+    // Changing this would actually be okay, but we still suggest `MaybeIncorrect`ly
+    [1i32].iter().for_each(move |_: &i32| {
+        //~^ needless_for_each
+        i += 1;
+    });
+}
diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
index 3a3a240c5a3..6bc56db68a0 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
@@ -19,7 +19,7 @@ LL +
 LL +         if *v == 10 {
 LL +             return;
 LL +         } else {
-LL +             println!("{}", v);
+LL +             println!("{v}");
 LL +         }
 LL +     }
    |
@@ -29,5 +29,39 @@ LL -             return;
 LL +             continue;
    |
 
-error: aborting due to 1 previous error
+error: needless use of `for_each`
+  --> tests/ui/needless_for_each_unfixable.rs:22:5
+   |
+LL | /     [].iter().for_each(move |_: &i32| {
+LL | |
+LL | |         i += 1;
+LL | |     });
+   | |_______^
+   |
+help: try
+   |
+LL ~     for _ in [].iter() {
+LL +
+LL +         i += 1;
+LL +     }
+   |
+
+error: needless use of `for_each`
+  --> tests/ui/needless_for_each_unfixable.rs:28:5
+   |
+LL | /     [1i32].iter().for_each(move |_: &i32| {
+LL | |
+LL | |         i += 1;
+LL | |     });
+   | |_______^
+   |
+help: try
+   |
+LL ~     for _ in [1i32].iter() {
+LL +
+LL +         i += 1;
+LL +     }
+   |
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_range_loop.rs b/src/tools/clippy/tests/ui/needless_range_loop.rs
index 70cf9fa7369..ea4591d8b71 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop.rs
+++ b/src/tools/clippy/tests/ui/needless_range_loop.rs
@@ -210,3 +210,35 @@ fn needless_loop() {
         black_box([1, 2, 3, 4, 5, 6, 7, 8][i]);
     }
 }
+
+fn issue_15068() {
+    let a = vec![vec![0u8; MAX_LEN]; MAX_LEN];
+    let b = vec![0u8; MAX_LEN];
+
+    for i in 0..MAX_LEN {
+        // no error
+        let _ = a[0][i];
+        let _ = b[i];
+    }
+
+    for i in 0..MAX_LEN {
+        // no error
+        let _ = a[i][0];
+        let _ = b[i];
+    }
+
+    for i in 0..MAX_LEN {
+        // no error
+        let _ = a[i][b[i] as usize];
+    }
+
+    for i in 0..MAX_LEN {
+        //~^ needless_range_loop
+        let _ = a[i][i];
+    }
+
+    for i in 0..MAX_LEN {
+        //~^ needless_range_loop
+        let _ = a[0][i];
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_range_loop.stderr b/src/tools/clippy/tests/ui/needless_range_loop.stderr
index 23c085f9d3b..33a519d8a80 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop.stderr
+++ b/src/tools/clippy/tests/ui/needless_range_loop.stderr
@@ -168,5 +168,29 @@ LL -     for i in 0..vec.len() {
 LL +     for (i, <item>) in vec.iter_mut().enumerate() {
    |
 
-error: aborting due to 14 previous errors
+error: the loop variable `i` is used to index `a`
+  --> tests/ui/needless_range_loop.rs:235:14
+   |
+LL |     for i in 0..MAX_LEN {
+   |              ^^^^^^^^^^
+   |
+help: consider using an iterator and enumerate()
+   |
+LL -     for i in 0..MAX_LEN {
+LL +     for (i, <item>) in a.iter().enumerate().take(MAX_LEN) {
+   |
+
+error: the loop variable `i` is only used to index `a`
+  --> tests/ui/needless_range_loop.rs:240:14
+   |
+LL |     for i in 0..MAX_LEN {
+   |              ^^^^^^^^^^
+   |
+help: consider using an iterator
+   |
+LL -     for i in 0..MAX_LEN {
+LL +     for <item> in a.iter().take(MAX_LEN) {
+   |
+
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs
index cacce9a7d1c..f03f74dfafe 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs
@@ -182,14 +182,12 @@ fn issue_5794() {
     if !b == true {}
     //~^ nonminimal_bool
     //~| bool_comparison
-    //~| bool_comparison
     if !b != true {}
     //~^ nonminimal_bool
     //~| bool_comparison
     if true == !b {}
     //~^ nonminimal_bool
     //~| bool_comparison
-    //~| bool_comparison
     if true != !b {}
     //~^ nonminimal_bool
     //~| bool_comparison
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
index c20412974b2..6a20b9216da 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
@@ -154,98 +154,86 @@ error: this boolean expression can be simplified
 LL |     if !b == true {}
    |        ^^^^^^^^^^ help: try: `b != true`
 
-error: this comparison might be written more concisely
+error: equality checks against true are unnecessary
   --> tests/ui/nonminimal_bool.rs:182:8
    |
 LL |     if !b == true {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `b != true`
+   |        ^^^^^^^^^^ help: try: `!b`
    |
    = note: `-D clippy::bool-comparison` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
 
-error: equality checks against true are unnecessary
-  --> tests/ui/nonminimal_bool.rs:182:8
-   |
-LL |     if !b == true {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!b`
-
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:186:8
+  --> tests/ui/nonminimal_bool.rs:185:8
    |
 LL |     if !b != true {}
    |        ^^^^^^^^^^ help: try: `b == true`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/nonminimal_bool.rs:186:8
+  --> tests/ui/nonminimal_bool.rs:185:8
    |
 LL |     if !b != true {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `b`
+   |        ^^^^^^^^^^ help: try: `b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:189:8
+  --> tests/ui/nonminimal_bool.rs:188:8
    |
 LL |     if true == !b {}
    |        ^^^^^^^^^^ help: try: `true != b`
 
-error: this comparison might be written more concisely
-  --> tests/ui/nonminimal_bool.rs:189:8
-   |
-LL |     if true == !b {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `true != b`
-
 error: equality checks against true are unnecessary
-  --> tests/ui/nonminimal_bool.rs:189:8
+  --> tests/ui/nonminimal_bool.rs:188:8
    |
 LL |     if true == !b {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!b`
+   |        ^^^^^^^^^^ help: try: `!b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:193:8
+  --> tests/ui/nonminimal_bool.rs:191:8
    |
 LL |     if true != !b {}
    |        ^^^^^^^^^^ help: try: `true == b`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/nonminimal_bool.rs:193:8
+  --> tests/ui/nonminimal_bool.rs:191:8
    |
 LL |     if true != !b {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `b`
+   |        ^^^^^^^^^^ help: try: `b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:196:8
+  --> tests/ui/nonminimal_bool.rs:194:8
    |
 LL |     if !b == !c {}
    |        ^^^^^^^^ help: try: `b == c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:198:8
+  --> tests/ui/nonminimal_bool.rs:196:8
    |
 LL |     if !b != !c {}
    |        ^^^^^^^^ help: try: `b != c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:214:8
+  --> tests/ui/nonminimal_bool.rs:212:8
    |
 LL |     if !(a < 2.0 && !b) {
    |        ^^^^^^^^^^^^^^^^ help: try: `a >= 2.0 || b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:233:12
+  --> tests/ui/nonminimal_bool.rs:231:12
    |
 LL |         if !(matches!(ty, TyKind::Ref(_, _, _)) && !is_mutable(&expr)) {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!matches!(ty, TyKind::Ref(_, _, _)) || is_mutable(&expr)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:253:8
+  --> tests/ui/nonminimal_bool.rs:251:8
    |
 LL |     if !S != true {}
    |        ^^^^^^^^^^ help: try: `S == true`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/nonminimal_bool.rs:253:8
+  --> tests/ui/nonminimal_bool.rs:251:8
    |
 LL |     if !S != true {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!!S`
+   |        ^^^^^^^^^^ help: try: `!!S`
 
-error: aborting due to 33 previous errors
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
index 55c1b8f110c..340be7c7e93 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
@@ -102,4 +102,13 @@ fn option_map_unit_fn() {
     //~^ option_map_unit_fn
 }
 
+fn issue15568() {
+    unsafe fn f(_: u32) {}
+    let x = Some(3);
+    if let Some(x) = x { unsafe { f(x) } }
+    //~^ option_map_unit_fn
+    if let Some(x) = x { unsafe { f(x) } }
+    //~^ option_map_unit_fn
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
index 5ed47e4c60b..d902c87379b 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
@@ -102,4 +102,13 @@ fn option_map_unit_fn() {
     //~^ option_map_unit_fn
 }
 
+fn issue15568() {
+    unsafe fn f(_: u32) {}
+    let x = Some(3);
+    x.map(|x| unsafe { f(x) });
+    //~^ option_map_unit_fn
+    x.map(|x| unsafe { { f(x) } });
+    //~^ option_map_unit_fn
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
index 3f7abae34ee..2405aa9a7cc 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
@@ -153,5 +153,21 @@ LL |     option().map(|value| println!("{:?}", value));
    |     |
    |     help: try: `if let Some(value) = option() { println!("{:?}", value) }`
 
-error: aborting due to 19 previous errors
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
+  --> tests/ui/option_map_unit_fn_fixable.rs:108:5
+   |
+LL |     x.map(|x| unsafe { f(x) });
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |     |
+   |     help: try: `if let Some(x) = x { unsafe { f(x) } }`
+
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
+  --> tests/ui/option_map_unit_fn_fixable.rs:110:5
+   |
+LL |     x.map(|x| unsafe { { f(x) } });
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |     |
+   |     help: try: `if let Some(x) = x { unsafe { f(x) } }`
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.fixed b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
index ba9beef57af..9660b82fe7d 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
@@ -28,6 +28,12 @@ fn main() {
     //
     //~^^ or_then_unwrap
 
+    // Call with macro should preserve the macro call rather than expand it
+    let option: Option<Vec<&str>> = None;
+    let _ = option.unwrap_or(vec!["fallback"]); // should trigger lint
+    //
+    //~^^ or_then_unwrap
+
     // as part of a method chain
     let option: Option<&str> = None;
     let _ = option.map(|v| v).unwrap_or("fallback").to_string().chars(); // should trigger lint
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.rs b/src/tools/clippy/tests/ui/or_then_unwrap.rs
index fac90249a24..c3873352116 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.rs
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.rs
@@ -28,6 +28,12 @@ fn main() {
     //
     //~^^ or_then_unwrap
 
+    // Call with macro should preserve the macro call rather than expand it
+    let option: Option<Vec<&str>> = None;
+    let _ = option.or(Some(vec!["fallback"])).unwrap(); // should trigger lint
+    //
+    //~^^ or_then_unwrap
+
     // as part of a method chain
     let option: Option<&str> = None;
     let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.stderr b/src/tools/clippy/tests/ui/or_then_unwrap.stderr
index 1160498c605..3e66b15edbd 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.stderr
@@ -14,10 +14,16 @@ LL |     let _ = result.or::<&str>(Ok("fallback")).unwrap(); // should trigger l
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")`
 
 error: found `.or(Some(…)).unwrap()`
-  --> tests/ui/or_then_unwrap.rs:33:31
+  --> tests/ui/or_then_unwrap.rs:33:20
+   |
+LL |     let _ = option.or(Some(vec!["fallback"])).unwrap(); // should trigger lint
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or(vec!["fallback"])`
+
+error: found `.or(Some(…)).unwrap()`
+  --> tests/ui/or_then_unwrap.rs:39:31
    |
 LL |     let _ = option.map(|v| v).or(Some("fallback")).unwrap().to_string().chars(); // should trigger lint
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or("fallback")`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/panicking_macros.rs b/src/tools/clippy/tests/ui/panicking_macros.rs
index 65854d7eb4b..b044be7d54a 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.rs
+++ b/src/tools/clippy/tests/ui/panicking_macros.rs
@@ -31,6 +31,20 @@ fn panic() {
     let b = a + 2;
 }
 
+const fn panic_const() {
+    let a = 2;
+    panic!();
+    //~^ panic
+
+    panic!("message");
+    //~^ panic
+
+    panic!("{} {}", "panic with", "multiple arguments");
+    //~^ panic
+
+    let b = a + 2;
+}
+
 fn todo() {
     let a = 2;
     todo!();
@@ -114,6 +128,7 @@ fn debug_assert_msg() {
 
 fn main() {
     panic();
+    panic_const();
     todo();
     unimplemented();
     unreachable();
diff --git a/src/tools/clippy/tests/ui/panicking_macros.stderr b/src/tools/clippy/tests/ui/panicking_macros.stderr
index 03e459e4ec6..7b767ae0f65 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.stderr
+++ b/src/tools/clippy/tests/ui/panicking_macros.stderr
@@ -19,9 +19,27 @@ error: `panic` should not be present in production code
 LL |     panic!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: `todo` should not be present in production code
+error: `panic` should not be present in production code
   --> tests/ui/panicking_macros.rs:36:5
    |
+LL |     panic!();
+   |     ^^^^^^^^
+
+error: `panic` should not be present in production code
+  --> tests/ui/panicking_macros.rs:39:5
+   |
+LL |     panic!("message");
+   |     ^^^^^^^^^^^^^^^^^
+
+error: `panic` should not be present in production code
+  --> tests/ui/panicking_macros.rs:42:5
+   |
+LL |     panic!("{} {}", "panic with", "multiple arguments");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `todo` should not be present in production code
+  --> tests/ui/panicking_macros.rs:50:5
+   |
 LL |     todo!();
    |     ^^^^^^^
    |
@@ -29,19 +47,19 @@ LL |     todo!();
    = help: to override `-D warnings` add `#[allow(clippy::todo)]`
 
 error: `todo` should not be present in production code
-  --> tests/ui/panicking_macros.rs:39:5
+  --> tests/ui/panicking_macros.rs:53:5
    |
 LL |     todo!("message");
    |     ^^^^^^^^^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> tests/ui/panicking_macros.rs:42:5
+  --> tests/ui/panicking_macros.rs:56:5
    |
 LL |     todo!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> tests/ui/panicking_macros.rs:50:5
+  --> tests/ui/panicking_macros.rs:64:5
    |
 LL |     unimplemented!();
    |     ^^^^^^^^^^^^^^^^
@@ -50,19 +68,19 @@ LL |     unimplemented!();
    = help: to override `-D warnings` add `#[allow(clippy::unimplemented)]`
 
 error: `unimplemented` should not be present in production code
-  --> tests/ui/panicking_macros.rs:53:5
+  --> tests/ui/panicking_macros.rs:67:5
    |
 LL |     unimplemented!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> tests/ui/panicking_macros.rs:56:5
+  --> tests/ui/panicking_macros.rs:70:5
    |
 LL |     unimplemented!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> tests/ui/panicking_macros.rs:64:5
+  --> tests/ui/panicking_macros.rs:78:5
    |
 LL |     unreachable!();
    |     ^^^^^^^^^^^^^^
@@ -71,40 +89,40 @@ LL |     unreachable!();
    = help: to override `-D warnings` add `#[allow(clippy::unreachable)]`
 
 error: usage of the `unreachable!` macro
-  --> tests/ui/panicking_macros.rs:67:5
+  --> tests/ui/panicking_macros.rs:81:5
    |
 LL |     unreachable!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> tests/ui/panicking_macros.rs:70:5
+  --> tests/ui/panicking_macros.rs:84:5
    |
 LL |     unreachable!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `panic` should not be present in production code
-  --> tests/ui/panicking_macros.rs:78:5
+  --> tests/ui/panicking_macros.rs:92:5
    |
 LL |     panic!();
    |     ^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> tests/ui/panicking_macros.rs:81:5
+  --> tests/ui/panicking_macros.rs:95:5
    |
 LL |     todo!();
    |     ^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> tests/ui/panicking_macros.rs:84:5
+  --> tests/ui/panicking_macros.rs:98:5
    |
 LL |     unimplemented!();
    |     ^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> tests/ui/panicking_macros.rs:87:5
+  --> tests/ui/panicking_macros.rs:101:5
    |
 LL |     unreachable!();
    |     ^^^^^^^^^^^^^^
 
-error: aborting due to 16 previous errors
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/print_literal.fixed b/src/tools/clippy/tests/ui/print_literal.fixed
index ebfe19c700e..26139f9b671 100644
--- a/src/tools/clippy/tests/ui/print_literal.fixed
+++ b/src/tools/clippy/tests/ui/print_literal.fixed
@@ -105,3 +105,16 @@ fn issue_14930() {
     println!("Hello x is {0:2$.1$}", 0.01, 2, 3);
     //~^ print_literal
 }
+
+fn issue_15576() {
+    println!("Hello x is {1:.*}", 5, 0.01);
+    //~^ print_literal
+
+    println!("Hello x is {:.p$}", 0.01, p = 5);
+    //~^ print_literal
+
+    println!(
+        "Hello name: x is {1:.*} (which {1} with {0} places)", 5, 0.01
+    );
+    //~^^ print_literal
+}
diff --git a/src/tools/clippy/tests/ui/print_literal.rs b/src/tools/clippy/tests/ui/print_literal.rs
index 8f3d9be0698..7c4cf028e84 100644
--- a/src/tools/clippy/tests/ui/print_literal.rs
+++ b/src/tools/clippy/tests/ui/print_literal.rs
@@ -106,3 +106,17 @@ fn issue_14930() {
     println!("Hello {0} is {1:3$.2$}", "x", 0.01, 2, 3);
     //~^ print_literal
 }
+
+fn issue_15576() {
+    println!("Hello {} is {2:.*}", "x", 5, 0.01);
+    //~^ print_literal
+
+    println!("Hello {} is {:.p$}", "x", 0.01, p = 5);
+    //~^ print_literal
+
+    println!(
+        "Hello {}: {2} is {3:.*} (which {3} with {1} places)",
+        "name", 5, "x", 0.01
+    );
+    //~^^ print_literal
+}
diff --git a/src/tools/clippy/tests/ui/print_literal.stderr b/src/tools/clippy/tests/ui/print_literal.stderr
index 1c378017d15..c136f52800f 100644
--- a/src/tools/clippy/tests/ui/print_literal.stderr
+++ b/src/tools/clippy/tests/ui/print_literal.stderr
@@ -277,5 +277,41 @@ LL -     println!("Hello {0} is {1:3$.2$}", "x", 0.01, 2, 3);
 LL +     println!("Hello x is {0:2$.1$}", 0.01, 2, 3);
    |
 
-error: aborting due to 22 previous errors
+error: literal with an empty format string
+  --> tests/ui/print_literal.rs:111:36
+   |
+LL |     println!("Hello {} is {2:.*}", "x", 5, 0.01);
+   |                                    ^^^
+   |
+help: try
+   |
+LL -     println!("Hello {} is {2:.*}", "x", 5, 0.01);
+LL +     println!("Hello x is {1:.*}", 5, 0.01);
+   |
+
+error: literal with an empty format string
+  --> tests/ui/print_literal.rs:114:36
+   |
+LL |     println!("Hello {} is {:.p$}", "x", 0.01, p = 5);
+   |                                    ^^^
+   |
+help: try
+   |
+LL -     println!("Hello {} is {:.p$}", "x", 0.01, p = 5);
+LL +     println!("Hello x is {:.p$}", 0.01, p = 5);
+   |
+
+error: literal with an empty format string
+  --> tests/ui/print_literal.rs:119:9
+   |
+LL |         "name", 5, "x", 0.01
+   |         ^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -         "Hello {}: {2} is {3:.*} (which {3} with {1} places)",
+LL +         "Hello name: x is {1:.*} (which {1} with {0} places)", 5, 0.01
+   |
+
+error: aborting due to 25 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
index 78e1ceb480a..4457878b6fa 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
@@ -229,3 +229,9 @@ fn issue15283() {
         //~^ ptr_as_ptr
     }
 }
+
+fn issue15232() {
+    let mut b = Box::new(0i32);
+    let _ptr = std::ptr::addr_of_mut!(*b).cast::<()>();
+    //~^ ptr_as_ptr
+}
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
index 70732cf0a6c..9124fc912d2 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
@@ -229,3 +229,9 @@ fn issue15283() {
         //~^ ptr_as_ptr
     }
 }
+
+fn issue15232() {
+    let mut b = Box::new(0i32);
+    let _ptr = std::ptr::addr_of_mut!(*b) as *mut ();
+    //~^ ptr_as_ptr
+}
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
index c0a2a4b6d20..af21c1e35f5 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
@@ -199,5 +199,11 @@ error: `as` casting between raw pointers without changing their constness
 LL |         let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u8>()`
 
-error: aborting due to 33 previous errors
+error: `as` casting between raw pointers without changing their constness
+  --> tests/ui/ptr_as_ptr.rs:235:16
+   |
+LL |     let _ptr = std::ptr::addr_of_mut!(*b) as *mut ();
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `std::ptr::addr_of_mut!(*b).cast::<()>()`
+
+error: aborting due to 34 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
index 79bfae1f7eb..cf57de53d9f 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
@@ -106,3 +106,9 @@ fn issue14621() {
     let _ = std::ptr::addr_of_mut!(local).cast_const();
     //~^ ptr_cast_constness
 }
+
+fn issue11317() {
+    let r = &0_u32;
+    let _ptr: *mut u32 = (r as *const u32).cast_mut();
+    //~^ ptr_cast_constness
+}
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.rs b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
index f6590dabd5b..ea53a0fa8c5 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.rs
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
@@ -106,3 +106,9 @@ fn issue14621() {
     let _ = std::ptr::addr_of_mut!(local) as *const _;
     //~^ ptr_cast_constness
 }
+
+fn issue11317() {
+    let r = &0_u32;
+    let _ptr: *mut u32 = r as *const _ as *mut _;
+    //~^ ptr_cast_constness
+}
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
index 0b1644168ff..4adb5cc5ad7 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
@@ -89,5 +89,11 @@ error: `as` casting between raw pointers while changing only its constness
 LL |     let _ = std::ptr::addr_of_mut!(local) as *const _;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `std::ptr::addr_of_mut!(local).cast_const()`
 
-error: aborting due to 14 previous errors
+error: `as` casting between raw pointers while changing only its constness
+  --> tests/ui/ptr_cast_constness.rs:112:26
+   |
+LL |     let _ptr: *mut u32 = r as *const _ as *mut _;
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(r as *const u32).cast_mut()`
+
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block.fixed b/src/tools/clippy/tests/ui/semicolon_inside_block.fixed
index 7eb53e733ad..7308e78aae2 100644
--- a/src/tools/clippy/tests/ui/semicolon_inside_block.fixed
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block.fixed
@@ -86,3 +86,8 @@ fn main() {
 
     unit_fn_block()
 }
+
+pub fn issue15388() {
+    #[rustfmt::skip]
+    {0; 0};
+}
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block.rs b/src/tools/clippy/tests/ui/semicolon_inside_block.rs
index 9fa5b117194..467bf4d779f 100644
--- a/src/tools/clippy/tests/ui/semicolon_inside_block.rs
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block.rs
@@ -86,3 +86,8 @@ fn main() {
 
     unit_fn_block()
 }
+
+pub fn issue15388() {
+    #[rustfmt::skip]
+    {0; 0};
+}
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.fixed b/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.fixed
new file mode 100644
index 00000000000..5b93a91da00
--- /dev/null
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.fixed
@@ -0,0 +1,11 @@
+// Test when the feature `stmt_expr_attributes` is enabled
+
+#![feature(stmt_expr_attributes)]
+#![allow(clippy::no_effect)]
+#![warn(clippy::semicolon_inside_block)]
+
+pub fn issue15388() {
+    #[rustfmt::skip]
+    {0; 0;}
+    //~^ semicolon_inside_block
+}
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.rs b/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.rs
new file mode 100644
index 00000000000..aa2c0cb5029
--- /dev/null
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.rs
@@ -0,0 +1,11 @@
+// Test when the feature `stmt_expr_attributes` is enabled
+
+#![feature(stmt_expr_attributes)]
+#![allow(clippy::no_effect)]
+#![warn(clippy::semicolon_inside_block)]
+
+pub fn issue15388() {
+    #[rustfmt::skip]
+    {0; 0};
+    //~^ semicolon_inside_block
+}
diff --git a/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.stderr b/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.stderr
new file mode 100644
index 00000000000..5bb91915a5f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/semicolon_inside_block_stmt_expr_attrs.stderr
@@ -0,0 +1,16 @@
+error: consider moving the `;` inside the block for consistent formatting
+  --> tests/ui/semicolon_inside_block_stmt_expr_attrs.rs:9:5
+   |
+LL |     {0; 0};
+   |     ^^^^^^^
+   |
+   = note: `-D clippy::semicolon-inside-block` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::semicolon_inside_block)]`
+help: put the `;` here
+   |
+LL -     {0; 0};
+LL +     {0; 0;}
+   |
+
+error: aborting due to 1 previous error
+
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 603ab0accb0..c27cec55824 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.fixed
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
@@ -89,3 +89,10 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: core::net::IpAddr) {}
 //~^ std_instead_of_core
+
+#[warn(clippy::alloc_instead_of_core)]
+fn issue15579() {
+    use std::alloc;
+
+    let layout = alloc::Layout::new::<u8>();
+}
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 b6d4abad9f8..7d53f7fc307 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.rs
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs
@@ -89,3 +89,10 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: std::net::IpAddr) {}
 //~^ std_instead_of_core
+
+#[warn(clippy::alloc_instead_of_core)]
+fn issue15579() {
+    use std::alloc;
+
+    let layout = alloc::Layout::new::<u8>();
+}
diff --git a/src/tools/clippy/tests/ui/unit_cmp.rs b/src/tools/clippy/tests/ui/unit_cmp.rs
index 93f5b87c3d2..0a0fe3a1990 100644
--- a/src/tools/clippy/tests/ui/unit_cmp.rs
+++ b/src/tools/clippy/tests/ui/unit_cmp.rs
@@ -68,3 +68,20 @@ fn main() {
         }
     );
 }
+
+fn issue15559() {
+    fn foo() {}
+    assert_eq!(
+        //~^ unit_cmp
+        {
+            1;
+        },
+        foo()
+    );
+    assert_eq!(foo(), foo());
+    //~^ unit_cmp
+
+    // don't lint on explicitly written unit expr
+    assert_eq!(foo(), ());
+    assert_ne!((), ContainsUnit(()).0);
+}
diff --git a/src/tools/clippy/tests/ui/unit_cmp.stderr b/src/tools/clippy/tests/ui/unit_cmp.stderr
index 8f26749fd86..21aa9dce151 100644
--- a/src/tools/clippy/tests/ui/unit_cmp.stderr
+++ b/src/tools/clippy/tests/ui/unit_cmp.stderr
@@ -71,5 +71,23 @@ LL | |             true;
 LL | |     );
    | |_____^
 
-error: aborting due to 6 previous errors
+error: `assert_eq` of unit values detected. This will always succeed
+  --> tests/ui/unit_cmp.rs:74:5
+   |
+LL | /     assert_eq!(
+LL | |
+LL | |         {
+LL | |             1;
+LL | |         },
+LL | |         foo()
+LL | |     );
+   | |_____^
+
+error: `assert_eq` of unit values detected. This will always succeed
+  --> tests/ui/unit_cmp.rs:81:5
+   |
+LL |     assert_eq!(foo(), foo());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_clone.stderr b/src/tools/clippy/tests/ui/unnecessary_clone.stderr
index a4fdf09cd5d..17518e123d1 100644
--- a/src/tools/clippy/tests/ui/unnecessary_clone.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_clone.stderr
@@ -2,7 +2,7 @@ error: using `.clone()` on a ref-counted pointer
   --> tests/ui/unnecessary_clone.rs:23:5
    |
 LL |     rc.clone();
-   |     ^^^^^^^^^^ help: try: `Rc::<bool>::clone(&rc)`
+   |     ^^^^^^^^^^ help: try: `std::rc::Rc::<bool>::clone(&rc)`
    |
    = note: `-D clippy::clone-on-ref-ptr` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::clone_on_ref_ptr)]`
@@ -11,25 +11,25 @@ error: using `.clone()` on a ref-counted pointer
   --> tests/ui/unnecessary_clone.rs:28:5
    |
 LL |     arc.clone();
-   |     ^^^^^^^^^^^ help: try: `Arc::<bool>::clone(&arc)`
+   |     ^^^^^^^^^^^ help: try: `std::sync::Arc::<bool>::clone(&arc)`
 
 error: using `.clone()` on a ref-counted pointer
   --> tests/ui/unnecessary_clone.rs:33:5
    |
 LL |     rcweak.clone();
-   |     ^^^^^^^^^^^^^^ help: try: `Weak::<bool>::clone(&rcweak)`
+   |     ^^^^^^^^^^^^^^ help: try: `std::rc::Weak::<bool>::clone(&rcweak)`
 
 error: using `.clone()` on a ref-counted pointer
   --> tests/ui/unnecessary_clone.rs:38:5
    |
 LL |     arc_weak.clone();
-   |     ^^^^^^^^^^^^^^^^ help: try: `Weak::<bool>::clone(&arc_weak)`
+   |     ^^^^^^^^^^^^^^^^ help: try: `std::sync::Weak::<bool>::clone(&arc_weak)`
 
 error: using `.clone()` on a ref-counted pointer
   --> tests/ui/unnecessary_clone.rs:44:33
    |
 LL |     let _: Arc<dyn SomeTrait> = x.clone();
-   |                                 ^^^^^^^^^ help: try: `Arc::<SomeImpl>::clone(&x)`
+   |                                 ^^^^^^^^^ help: try: `std::sync::Arc::<SomeImpl>::clone(&x)`
 
 error: using `clone` on type `T` which implements the `Copy` trait
   --> tests/ui/unnecessary_clone.rs:49:5
@@ -56,7 +56,7 @@ error: using `.clone()` on a ref-counted pointer
   --> tests/ui/unnecessary_clone.rs:108:14
    |
 LL |         Some(try_opt!(Some(rc)).clone())
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Rc::<u8>::clone(&try_opt!(Some(rc)))`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::rc::Rc::<u8>::clone(&try_opt!(Some(rc)))`
 
 error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
index 2081772d06b..339d4a95084 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
@@ -9,6 +9,11 @@
 )]
 #![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
 
+struct S {
+    x: u8,
+    y: u8,
+}
+
 fn main() {
     // Should be ignored by this lint, as nesting requires more characters.
     if let &0 | &2 = &0 {}
@@ -45,10 +50,6 @@ fn main() {
     //~^ unnested_or_patterns
     if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
     //~^ unnested_or_patterns
-    struct S {
-        x: u8,
-        y: u8,
-    }
     if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
     //~^ unnested_or_patterns
     if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
@@ -77,3 +78,19 @@ mod issue9952 {
     fn or_in_param((x | x | x): i32) {}
     //~^ unnested_or_patterns
 }
+
+fn issue15219() {
+    struct Foo {
+        x: u8,
+    }
+
+    // the original repro
+    if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}
+
+    // also works with more fields
+    if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}
+
+    // `y` not triggering the lint doesn't stop the `x` from getting flagged
+    if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}
+    //~^ unnested_or_patterns
+}
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.rs b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
index 6bf8fce3661..f5c99183b0c 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.rs
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
@@ -9,6 +9,11 @@
 )]
 #![allow(unreachable_patterns, irrefutable_let_patterns, unused)]
 
+struct S {
+    x: u8,
+    y: u8,
+}
+
 fn main() {
     // Should be ignored by this lint, as nesting requires more characters.
     if let &0 | &2 = &0 {}
@@ -45,10 +50,6 @@ fn main() {
     //~^ unnested_or_patterns
     if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
     //~^ unnested_or_patterns
-    struct S {
-        x: u8,
-        y: u8,
-    }
     if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
     //~^ unnested_or_patterns
     if let S { x: 0, y, .. } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
@@ -77,3 +78,19 @@ mod issue9952 {
     fn or_in_param((x | (x | x)): i32) {}
     //~^ unnested_or_patterns
 }
+
+fn issue15219() {
+    struct Foo {
+        x: u8,
+    }
+
+    // the original repro
+    if let Foo { x } | Foo { x } = (Foo { x: 0 }) {}
+
+    // also works with more fields
+    if let S { x, y } | S { x, y } = (S { x: 0, y: 0 }) {}
+
+    // `y` not triggering the lint doesn't stop the `x` from getting flagged
+    if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
+    //~^ unnested_or_patterns
+}
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
index c805dc992b1..d2b617c322c 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
@@ -1,5 +1,5 @@
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:16:12
+  --> tests/ui/unnested_or_patterns.rs:21:12
    |
 LL |     if let box 0 | box 2 = Box::new(0) {}
    |            ^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     if let box (0 | 2) = Box::new(0) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:18:12
+  --> tests/ui/unnested_or_patterns.rs:23:12
    |
 LL |     if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL +     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:21:12
+  --> tests/ui/unnested_or_patterns.rs:26:12
    |
 LL |     if let Some(1) | C0 | Some(2) = None {}
    |            ^^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL +     if let Some(1 | 2) | C0 = None {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:23:12
+  --> tests/ui/unnested_or_patterns.rs:28:12
    |
 LL |     if let &mut 0 | &mut 2 = &mut 0 {}
    |            ^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL +     if let &mut (0 | 2) = &mut 0 {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:25:12
+  --> tests/ui/unnested_or_patterns.rs:30:12
    |
 LL |     if let x @ 0 | x @ 2 = 0 {}
    |            ^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL +     if let x @ (0 | 2) = 0 {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:27:12
+  --> tests/ui/unnested_or_patterns.rs:32:12
    |
 LL |     if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL +     if let (0, 1 | 2 | 3) = (0, 0) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:29:12
+  --> tests/ui/unnested_or_patterns.rs:34:12
    |
 LL |     if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL +     if let (1 | 2 | 3, 0) = (0, 0) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:31:12
+  --> tests/ui/unnested_or_patterns.rs:36:12
    |
 LL |     if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL +     if let (x, ..) | (x, 1 | 2) = (0, 1) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:33:12
+  --> tests/ui/unnested_or_patterns.rs:38:12
    |
 LL |     if let [0] | [1] = [0] {}
    |            ^^^^^^^^^
@@ -109,7 +109,7 @@ LL +     if let [0 | 1] = [0] {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:35:12
+  --> tests/ui/unnested_or_patterns.rs:40:12
    |
 LL |     if let [x, 0] | [x, 1] = [0, 1] {}
    |            ^^^^^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL +     if let [x, 0 | 1] = [0, 1] {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:37:12
+  --> tests/ui/unnested_or_patterns.rs:42:12
    |
 LL |     if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL +     if let [x, 0 | 1 | 2] = [0, 1] {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:39:12
+  --> tests/ui/unnested_or_patterns.rs:44:12
    |
 LL |     if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ LL +     if let [x, ..] | [x, 1 | 2] = [0, 1] {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:42:12
+  --> tests/ui/unnested_or_patterns.rs:47:12
    |
 LL |     if let TS(0, x) | TS(1, x) = TS(0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL +     if let TS(0 | 1, x) = TS(0, 0) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:44:12
+  --> tests/ui/unnested_or_patterns.rs:49:12
    |
 LL |     if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -169,7 +169,7 @@ LL +     if let TS(1 | 2 | 3, 0) = TS(0, 0) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:46:12
+  --> tests/ui/unnested_or_patterns.rs:51:12
    |
 LL |     if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -181,7 +181,7 @@ LL +     if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:52:12
+  --> tests/ui/unnested_or_patterns.rs:53:12
    |
 LL |     if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -193,7 +193,7 @@ LL +     if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:64:12
+  --> tests/ui/unnested_or_patterns.rs:65:12
    |
 LL |     if let [1] | [53] = [0] {}
    |            ^^^^^^^^^^
@@ -205,7 +205,7 @@ LL +     if let [1 | 53] = [0] {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:70:13
+  --> tests/ui/unnested_or_patterns.rs:71:13
    |
 LL |         let (0 | (1 | _)) = 0;
    |             ^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL +         let (0 | 1 | _) = 0;
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:73:16
+  --> tests/ui/unnested_or_patterns.rs:74:16
    |
 LL |         if let (0 | (1 | _)) = 0 {}
    |                ^^^^^^^^^^^^^
@@ -229,7 +229,7 @@ LL +         if let (0 | 1 | _) = 0 {}
    |
 
 error: unnested or-patterns
-  --> tests/ui/unnested_or_patterns.rs:77:20
+  --> tests/ui/unnested_or_patterns.rs:78:20
    |
 LL |     fn or_in_param((x | (x | x)): i32) {}
    |                    ^^^^^^^^^^^^^
@@ -240,5 +240,17 @@ LL -     fn or_in_param((x | (x | x)): i32) {}
 LL +     fn or_in_param((x | x | x): i32) {}
    |
 
-error: aborting due to 20 previous errors
+error: unnested or-patterns
+  --> tests/ui/unnested_or_patterns.rs:94:12
+   |
+LL |     if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: nest the patterns
+   |
+LL -     if let S { y, x: 0 } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
+LL +     if let S { y, x: 0 | 1 } = (S { x: 0, y: 1 }) {}
+   |
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unused_unit.edition2021.fixed b/src/tools/clippy/tests/ui/unused_unit.edition2021.fixed
index def8ef86e3c..8e12bd2c8c7 100644
--- a/src/tools/clippy/tests/ui/unused_unit.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/unused_unit.edition2021.fixed
@@ -127,14 +127,10 @@ mod issue14577 {
     trait Unit {}
     impl Unit for () {}
 
-    fn run<R: Unit>(f: impl FnOnce() -> R) {
-        f();
-    }
-
     #[allow(dependency_on_unit_never_type_fallback)]
     fn bar() {
-        run(|| { todo!() }); 
         //~[edition2021]^ unused_unit
+        panic!()
     }
 
     struct UnitStruct;
@@ -150,3 +146,24 @@ mod pr14962 {
     type UnusedParensButNoUnit = Box<dyn (Fn())>;
 }
 
+
+mod issue15035 {
+
+    trait Convert<T> {
+        fn from(value: T) -> Self;
+    }
+
+    impl Convert<u64> for () {
+        fn from(_value: u64) -> Self {}
+    }
+
+    fn handle<T: Convert<u64>>(value: u64) -> T {
+        Convert::from(value)
+    }
+
+    pub fn f() -> Option<bool> {
+        let result: Result<bool, u64> = Err(42);
+        // the `-> ()` is required for the inference of `handle`'s return type
+        result.map_err(|err| -> () { handle(err) }).ok()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unused_unit.edition2021.stderr b/src/tools/clippy/tests/ui/unused_unit.edition2021.stderr
index 13cc20d4d7a..9ad3c2df915 100644
--- a/src/tools/clippy/tests/ui/unused_unit.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/unused_unit.edition2021.stderr
@@ -119,10 +119,10 @@ LL | fn test3()-> (){}
    |           ^^^^^ help: remove the `-> ()`
 
 error: unneeded unit return type
-  --> tests/ui/unused_unit.rs:136:15
+  --> tests/ui/unused_unit.rs:131:13
    |
-LL |         run(|| -> () { todo!() }); 
-   |               ^^^^^^ help: remove the `-> ()`
+LL |     fn bar() -> () {
+   |             ^^^^^^ help: remove the `-> ()`
 
 error: aborting due to 20 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unused_unit.edition2024.fixed b/src/tools/clippy/tests/ui/unused_unit.edition2024.fixed
index f908b958b19..688d2fe9afa 100644
--- a/src/tools/clippy/tests/ui/unused_unit.edition2024.fixed
+++ b/src/tools/clippy/tests/ui/unused_unit.edition2024.fixed
@@ -127,14 +127,10 @@ mod issue14577 {
     trait Unit {}
     impl Unit for () {}
 
-    fn run<R: Unit>(f: impl FnOnce() -> R) {
-        f();
-    }
-
     #[allow(dependency_on_unit_never_type_fallback)]
-    fn bar() {
-        run(|| -> () { todo!() }); 
+    fn bar() -> () {
         //~[edition2021]^ unused_unit
+        panic!()
     }
 
     struct UnitStruct;
@@ -150,3 +146,24 @@ mod pr14962 {
     type UnusedParensButNoUnit = Box<dyn (Fn())>;
 }
 
+
+mod issue15035 {
+
+    trait Convert<T> {
+        fn from(value: T) -> Self;
+    }
+
+    impl Convert<u64> for () {
+        fn from(_value: u64) -> Self {}
+    }
+
+    fn handle<T: Convert<u64>>(value: u64) -> T {
+        Convert::from(value)
+    }
+
+    pub fn f() -> Option<bool> {
+        let result: Result<bool, u64> = Err(42);
+        // the `-> ()` is required for the inference of `handle`'s return type
+        result.map_err(|err| -> () { handle(err) }).ok()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unused_unit.rs b/src/tools/clippy/tests/ui/unused_unit.rs
index 7298ec40cc2..31e980f2655 100644
--- a/src/tools/clippy/tests/ui/unused_unit.rs
+++ b/src/tools/clippy/tests/ui/unused_unit.rs
@@ -127,14 +127,10 @@ mod issue14577 {
     trait Unit {}
     impl Unit for () {}
 
-    fn run<R: Unit>(f: impl FnOnce() -> R) {
-        f();
-    }
-
     #[allow(dependency_on_unit_never_type_fallback)]
-    fn bar() {
-        run(|| -> () { todo!() }); 
+    fn bar() -> () {
         //~[edition2021]^ unused_unit
+        panic!()
     }
 
     struct UnitStruct;
@@ -150,3 +146,24 @@ mod pr14962 {
     type UnusedParensButNoUnit = Box<dyn (Fn())>;
 }
 
+
+mod issue15035 {
+
+    trait Convert<T> {
+        fn from(value: T) -> Self;
+    }
+
+    impl Convert<u64> for () {
+        fn from(_value: u64) -> Self {}
+    }
+
+    fn handle<T: Convert<u64>>(value: u64) -> T {
+        Convert::from(value)
+    }
+
+    pub fn f() -> Option<bool> {
+        let result: Result<bool, u64> = Err(42);
+        // the `-> ()` is required for the inference of `handle`'s return type
+        result.map_err(|err| -> () { handle(err) }).ok()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unwrap_in_result.rs b/src/tools/clippy/tests/ui/unwrap_in_result.rs
index 4e872c67b42..70c28fe54f3 100644
--- a/src/tools/clippy/tests/ui/unwrap_in_result.rs
+++ b/src/tools/clippy/tests/ui/unwrap_in_result.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::unwrap_in_result)]
+#![allow(clippy::ok_expect)]
 
 struct A;
 
@@ -20,10 +21,9 @@ impl A {
 
     // should be detected
     fn bad_divisible_by_3(i_str: String) -> Result<bool, String> {
-        //~^ unwrap_in_result
-
         // checks whether a string represents a number divisible by 3
         let i = i_str.parse::<i32>().unwrap();
+        //~^ unwrap_in_result
         if i % 3 == 0 {
             Ok(true)
         } else {
@@ -32,9 +32,8 @@ impl A {
     }
 
     fn example_option_expect(i_str: String) -> Option<bool> {
+        let i = i_str.parse::<i32>().ok().expect("not a number");
         //~^ unwrap_in_result
-
-        let i = i_str.parse::<i32>().expect("not a number");
         if i % 3 == 0 {
             return Some(true);
         }
@@ -42,13 +41,66 @@ impl A {
     }
 
     fn in_closure(a: Option<bool>) -> Option<bool> {
-        //~^ unwrap_in_result
+        // No lint inside a closure
         let c = || a.unwrap();
-        Some(c())
+
+        // But lint outside
+        let a = c().then_some(true);
+        let _ = a.unwrap();
+        //~^ unwrap_in_result
+
+        None
     }
+
+    const fn in_const_inside_fn() -> bool {
+        const A: bool = {
+            const fn inner(b: Option<bool>) -> Option<bool> {
+                Some(b.unwrap())
+                //~^ unwrap_in_result
+            }
+
+            // No lint inside `const`
+            inner(Some(true)).unwrap()
+        };
+        A
+    }
+
+    fn in_static_inside_fn() -> bool {
+        static A: bool = {
+            const fn inner(b: Option<bool>) -> Option<bool> {
+                Some(b.unwrap())
+                //~^ unwrap_in_result
+            }
+
+            // No lint inside `static`
+            inner(Some(true)).unwrap()
+        };
+        A
+    }
+}
+
+macro_rules! mac {
+    () => {
+        Option::unwrap(Some(3))
+    };
+}
+
+fn type_relative_unwrap() -> Option<()> {
+    _ = Option::unwrap(Some(3));
+    //~^ unwrap_in_result
+
+    // Do not lint macro output
+    _ = mac!();
+
+    None
 }
 
-fn main() {
-    A::bad_divisible_by_3("3".to_string());
-    A::good_divisible_by_3("3".to_string());
+fn main() -> Result<(), ()> {
+    A::bad_divisible_by_3("3".to_string()).unwrap();
+    //~^ unwrap_in_result
+    A::good_divisible_by_3("3".to_string()).unwrap();
+    //~^ unwrap_in_result
+    Result::unwrap(A::good_divisible_by_3("3".to_string()));
+    //~^ unwrap_in_result
+    Ok(())
 }
diff --git a/src/tools/clippy/tests/ui/unwrap_in_result.stderr b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
index 5e3eab813e0..804b44246dc 100644
--- a/src/tools/clippy/tests/ui/unwrap_in_result.stderr
+++ b/src/tools/clippy/tests/ui/unwrap_in_result.stderr
@@ -1,55 +1,107 @@
-error: used unwrap or expect in a function that returns result or option
-  --> tests/ui/unwrap_in_result.rs:22:5
-   |
-LL | /     fn bad_divisible_by_3(i_str: String) -> Result<bool, String> {
-...  |
-LL | |     }
-   | |_____^
-   |
-   = help: unwrap and expect should not be used in a function that returns result or option
-note: potential non-recoverable error(s)
-  --> tests/ui/unwrap_in_result.rs:26:17
+error: `unwrap` used in a function that returns a `Result`
+  --> tests/ui/unwrap_in_result.rs:25:17
    |
 LL |         let i = i_str.parse::<i32>().unwrap();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: in this function signature
+  --> tests/ui/unwrap_in_result.rs:23:45
+   |
+LL |     fn bad_divisible_by_3(i_str: String) -> Result<bool, String> {
+   |                                             ^^^^^^^^^^^^^^^^^^^^
+   = help: consider using the `?` operator or calling the `.map_err()` method
    = note: `-D clippy::unwrap-in-result` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unwrap_in_result)]`
 
-error: used unwrap or expect in a function that returns result or option
-  --> tests/ui/unwrap_in_result.rs:34:5
+error: `expect` used in a function that returns an `Option`
+  --> tests/ui/unwrap_in_result.rs:35:17
+   |
+LL |         let i = i_str.parse::<i32>().ok().expect("not a number");
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: in this function signature
+  --> tests/ui/unwrap_in_result.rs:34:48
+   |
+LL |     fn example_option_expect(i_str: String) -> Option<bool> {
+   |                                                ^^^^^^^^^^^^
+   = help: consider using the `?` operator
+
+error: `unwrap` used in a function that returns an `Option`
+  --> tests/ui/unwrap_in_result.rs:49:17
+   |
+LL |         let _ = a.unwrap();
+   |                 ^^^^^^^^^^
+   |
+note: in this function signature
+  --> tests/ui/unwrap_in_result.rs:43:39
+   |
+LL |     fn in_closure(a: Option<bool>) -> Option<bool> {
+   |                                       ^^^^^^^^^^^^
+   = help: consider using the `?` operator
+
+error: `unwrap` used in a function that returns an `Option`
+  --> tests/ui/unwrap_in_result.rs:58:22
    |
-LL | /     fn example_option_expect(i_str: String) -> Option<bool> {
-LL | |
-LL | |
-LL | |         let i = i_str.parse::<i32>().expect("not a number");
-...  |
-LL | |         None
-LL | |     }
-   | |_____^
+LL |                 Some(b.unwrap())
+   |                      ^^^^^^^^^^
    |
-   = help: unwrap and expect should not be used in a function that returns result or option
-note: potential non-recoverable error(s)
-  --> tests/ui/unwrap_in_result.rs:37:17
+note: in this function signature
+  --> tests/ui/unwrap_in_result.rs:57:48
    |
-LL |         let i = i_str.parse::<i32>().expect("not a number");
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |             const fn inner(b: Option<bool>) -> Option<bool> {
+   |                                                ^^^^^^^^^^^^
+   = help: consider using the `?` operator
 
-error: used unwrap or expect in a function that returns result or option
-  --> tests/ui/unwrap_in_result.rs:44:5
+error: `unwrap` used in a function that returns an `Option`
+  --> tests/ui/unwrap_in_result.rs:71:22
    |
-LL | /     fn in_closure(a: Option<bool>) -> Option<bool> {
-LL | |
-LL | |         let c = || a.unwrap();
-LL | |         Some(c())
-LL | |     }
-   | |_____^
+LL |                 Some(b.unwrap())
+   |                      ^^^^^^^^^^
    |
-   = help: unwrap and expect should not be used in a function that returns result or option
-note: potential non-recoverable error(s)
-  --> tests/ui/unwrap_in_result.rs:46:20
+note: in this function signature
+  --> tests/ui/unwrap_in_result.rs:70:48
+   |
+LL |             const fn inner(b: Option<bool>) -> Option<bool> {
+   |                                                ^^^^^^^^^^^^
+   = help: consider using the `?` operator
+
+error: `unwrap` used in a function that returns an `Option`
+  --> tests/ui/unwrap_in_result.rs:89:9
+   |
+LL |     _ = Option::unwrap(Some(3));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: in this function signature
+  --> tests/ui/unwrap_in_result.rs:88:30
+   |
+LL | fn type_relative_unwrap() -> Option<()> {
+   |                              ^^^^^^^^^^
+   = help: consider using the `?` operator
+
+error: `unwrap` used in a function that returns a `Result`
+  --> tests/ui/unwrap_in_result.rs:99:5
+   |
+LL |     A::bad_divisible_by_3("3".to_string()).unwrap();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: in this function signature
+  --> tests/ui/unwrap_in_result.rs:98:14
+   |
+LL | fn main() -> Result<(), ()> {
+   |              ^^^^^^^^^^^^^^
+   = help: consider using the `?` operator or calling the `.map_err()` method
+
+error: `unwrap` used in a function that returns a `Result`
+  --> tests/ui/unwrap_in_result.rs:101:5
+   |
+LL |     A::good_divisible_by_3("3".to_string()).unwrap();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `unwrap` used in a function that returns a `Result`
+  --> tests/ui/unwrap_in_result.rs:103:5
    |
-LL |         let c = || a.unwrap();
-   |                    ^^^^^^^^^^
+LL |     Result::unwrap(A::good_divisible_by_3("3".to_string()));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/vec.fixed b/src/tools/clippy/tests/ui/vec.fixed
index f360a8afadf..55742459c92 100644
--- a/src/tools/clippy/tests/ui/vec.fixed
+++ b/src/tools/clippy/tests/ui/vec.fixed
@@ -242,3 +242,12 @@ fn issue_12101() {
     for a in &[1, 2] {}
     //~^ useless_vec
 }
+
+fn issue_14531() {
+    // The lint used to suggest using an array rather than a reference to a slice.
+
+    fn requires_ref_slice(v: &[()]) {}
+    let v = &[];
+    //~^ useless_vec
+    requires_ref_slice(v);
+}
diff --git a/src/tools/clippy/tests/ui/vec.rs b/src/tools/clippy/tests/ui/vec.rs
index a779d33557c..fbf7131323c 100644
--- a/src/tools/clippy/tests/ui/vec.rs
+++ b/src/tools/clippy/tests/ui/vec.rs
@@ -242,3 +242,12 @@ fn issue_12101() {
     for a in &(vec![1, 2]) {}
     //~^ useless_vec
 }
+
+fn issue_14531() {
+    // The lint used to suggest using an array rather than a reference to a slice.
+
+    fn requires_ref_slice(v: &[()]) {}
+    let v = &vec![];
+    //~^ useless_vec
+    requires_ref_slice(v);
+}
diff --git a/src/tools/clippy/tests/ui/vec.stderr b/src/tools/clippy/tests/ui/vec.stderr
index 806d6617200..d16c8a8944a 100644
--- a/src/tools/clippy/tests/ui/vec.stderr
+++ b/src/tools/clippy/tests/ui/vec.stderr
@@ -127,5 +127,11 @@ error: useless use of `vec!`
 LL |     for a in &(vec![1, 2]) {}
    |              ^^^^^^^^^^^^^ help: you can use a slice directly: `&[1, 2]`
 
-error: aborting due to 21 previous errors
+error: useless use of `vec!`
+  --> tests/ui/vec.rs:250:13
+   |
+LL |     let v = &vec![];
+   |             ^^^^^^^ help: you can use a slice directly: `&[]`
+
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 805baf2af6d..7b19f8658c0 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -49,11 +49,18 @@ new_pr = true
 # These labels are set when there are unresolved concerns, removed otherwise
 labels = ["S-waiting-on-concerns"]
 
+# Show differences when a PR is rebased
+[range-diff]
+
+# Amend a review to include a link to what was changed since the review
+[review-changes-since]
+
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
     "matthiaskrgr",
     "Manishearth",
+    "flip1995",
 ]
 
 [assign.owners]
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 89b1b4f84b6..62fdee98735 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -667,6 +667,10 @@ pub struct Config {
     /// to avoid `!nocapture` double-negatives.
     pub nocapture: bool,
 
+    /// True if the experimental new output-capture implementation should be
+    /// used, avoiding the need for `#![feature(internal_output_capture)]`.
+    pub new_output_capture: bool,
+
     /// Needed both to construct [`build_helper::git::GitConfig`].
     pub nightly_branch: String,
     pub git_merge_commit_email: String,
@@ -784,6 +788,7 @@ impl Config {
             builtin_cfg_names: Default::default(),
             supported_crate_types: Default::default(),
             nocapture: Default::default(),
+            new_output_capture: Default::default(),
             nightly_branch: Default::default(),
             git_merge_commit_email: Default::default(),
             profiler_runtime: Default::default(),
diff --git a/src/tools/compiletest/src/executor.rs b/src/tools/compiletest/src/executor.rs
index 5519ef1af1f..b0dc24798b6 100644
--- a/src/tools/compiletest/src/executor.rs
+++ b/src/tools/compiletest/src/executor.rs
@@ -13,6 +13,7 @@ use std::sync::{Arc, Mutex, mpsc};
 use std::{env, hint, io, mem, panic, thread};
 
 use crate::common::{Config, TestPaths};
+use crate::output_capture::{self, ConsoleOut};
 use crate::panic_hook;
 
 mod deadline;
@@ -120,28 +121,28 @@ fn run_test_inner(
     runnable_test: RunnableTest,
     completion_sender: mpsc::Sender<TestCompletion>,
 ) {
-    let is_capture = !runnable_test.config.nocapture;
+    let capture = CaptureKind::for_config(&runnable_test.config);
 
     // Install a panic-capture buffer for use by the custom panic hook.
-    if is_capture {
+    if capture.should_set_panic_hook() {
         panic_hook::set_capture_buf(Default::default());
     }
-    let capture_buf = is_capture.then(|| Arc::new(Mutex::new(vec![])));
 
-    if let Some(capture_buf) = &capture_buf {
-        io::set_output_capture(Some(Arc::clone(capture_buf)));
+    if let CaptureKind::Old { ref buf } = capture {
+        io::set_output_capture(Some(Arc::clone(buf)));
     }
 
-    let panic_payload = panic::catch_unwind(move || runnable_test.run()).err();
+    let stdout = capture.stdout();
+    let stderr = capture.stderr();
+
+    let panic_payload = panic::catch_unwind(move || runnable_test.run(stdout, stderr)).err();
 
     if let Some(panic_buf) = panic_hook::take_capture_buf() {
         let panic_buf = panic_buf.lock().unwrap_or_else(|e| e.into_inner());
-        // For now, forward any captured panic message to (captured) stderr.
-        // FIXME(Zalathar): Once we have our own output-capture buffer for
-        // non-panic output, append the panic message to that buffer instead.
-        eprint!("{panic_buf}");
+        // Forward any captured panic message to (captured) stderr.
+        write!(stderr, "{panic_buf}");
     }
-    if is_capture {
+    if matches!(capture, CaptureKind::Old { .. }) {
         io::set_output_capture(None);
     }
 
@@ -152,11 +153,70 @@ fn run_test_inner(
             TestOutcome::Failed { message: Some("test did not panic as expected") }
         }
     };
-    let stdout = capture_buf.map(|mutex| mutex.lock().unwrap_or_else(|e| e.into_inner()).to_vec());
 
+    let stdout = capture.into_inner();
     completion_sender.send(TestCompletion { id, outcome, stdout }).unwrap();
 }
 
+enum CaptureKind {
+    /// Do not capture test-runner output, for `--no-capture`.
+    ///
+    /// (This does not affect `rustc` and other subprocesses spawned by test
+    /// runners, whose output is always captured.)
+    None,
+
+    /// Use the old output-capture implementation, which relies on the unstable
+    /// library feature `#![feature(internal_output_capture)]`.
+    Old { buf: Arc<Mutex<Vec<u8>>> },
+
+    /// Use the new output-capture implementation, which only uses stable Rust.
+    New { buf: output_capture::CaptureBuf },
+}
+
+impl CaptureKind {
+    fn for_config(config: &Config) -> Self {
+        if config.nocapture {
+            Self::None
+        } else if config.new_output_capture {
+            Self::New { buf: output_capture::CaptureBuf::new() }
+        } else {
+            // Create a capure buffer for `io::set_output_capture`.
+            Self::Old { buf: Default::default() }
+        }
+    }
+
+    fn should_set_panic_hook(&self) -> bool {
+        match self {
+            Self::None => false,
+            Self::Old { .. } => true,
+            Self::New { .. } => true,
+        }
+    }
+
+    fn stdout(&self) -> &dyn ConsoleOut {
+        self.capture_buf_or(&output_capture::Stdout)
+    }
+
+    fn stderr(&self) -> &dyn ConsoleOut {
+        self.capture_buf_or(&output_capture::Stderr)
+    }
+
+    fn capture_buf_or<'a>(&'a self, fallback: &'a dyn ConsoleOut) -> &'a dyn ConsoleOut {
+        match self {
+            Self::None | Self::Old { .. } => fallback,
+            Self::New { buf } => buf,
+        }
+    }
+
+    fn into_inner(self) -> Option<Vec<u8>> {
+        match self {
+            Self::None => None,
+            Self::Old { buf } => Some(buf.lock().unwrap_or_else(|e| e.into_inner()).to_vec()),
+            Self::New { buf } => Some(buf.into_inner().into()),
+        }
+    }
+}
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 struct TestId(usize);
 
@@ -174,10 +234,12 @@ impl RunnableTest {
         Self { config, testpaths, revision }
     }
 
-    fn run(&self) {
+    fn run(&self, stdout: &dyn ConsoleOut, stderr: &dyn ConsoleOut) {
         __rust_begin_short_backtrace(|| {
             crate::runtest::run(
                 Arc::clone(&self.config),
+                stdout,
+                stderr,
                 &self.testpaths,
                 self.revision.as_deref(),
             );
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index fa84691a46f..f647f96a9bf 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -15,6 +15,7 @@ pub mod directives;
 pub mod errors;
 mod executor;
 mod json;
+mod output_capture;
 mod panic_hook;
 mod raise_fd_limit;
 mod read2;
@@ -177,6 +178,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
         // FIXME: Temporarily retained so we can point users to `--no-capture`
         .optflag("", "nocapture", "")
         .optflag("", "no-capture", "don't capture stdout/stderr of tests")
+        .optopt(
+            "N",
+            "new-output-capture",
+            "enables or disables the new output-capture implementation",
+            "off|on",
+        )
         .optflag("", "profiler-runtime", "is the profiler runtime enabled for this target")
         .optflag("h", "help", "show this message")
         .reqopt("", "channel", "current Rust channel", "CHANNEL")
@@ -461,6 +468,14 @@ pub fn parse_config(args: Vec<String>) -> Config {
         supported_crate_types: OnceLock::new(),
 
         nocapture: matches.opt_present("no-capture"),
+        new_output_capture: {
+            let value = matches
+                .opt_str("new-output-capture")
+                .or_else(|| env::var("COMPILETEST_NEW_OUTPUT_CAPTURE").ok())
+                .unwrap_or_else(|| "off".to_owned());
+            parse_bool_option(&value)
+                .unwrap_or_else(|| panic!("unknown `--new-output-capture` value `{value}` given"))
+        },
 
         nightly_branch: matches.opt_str("nightly-branch").unwrap(),
         git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),
@@ -476,6 +491,19 @@ pub fn parse_config(args: Vec<String>) -> Config {
     }
 }
 
+/// Parses the same set of boolean values accepted by rustc command-line arguments.
+///
+/// Accepting all of these values is more complicated than just picking one
+/// pair, but has the advantage that contributors who are used to rustc
+/// shouldn't have to think about which values are legal.
+fn parse_bool_option(value: &str) -> Option<bool> {
+    match value {
+        "off" | "no" | "n" | "false" => Some(false),
+        "on" | "yes" | "y" | "true" => Some(true),
+        _ => None,
+    }
+}
+
 pub fn opt_str(maybestr: &Option<String>) -> &str {
     match *maybestr {
         None => "(none)",
diff --git a/src/tools/compiletest/src/output_capture.rs b/src/tools/compiletest/src/output_capture.rs
new file mode 100644
index 00000000000..de1aea11ade
--- /dev/null
+++ b/src/tools/compiletest/src/output_capture.rs
@@ -0,0 +1,52 @@
+use std::fmt;
+use std::panic::RefUnwindSafe;
+use std::sync::Mutex;
+
+pub trait ConsoleOut: fmt::Debug + RefUnwindSafe {
+    fn write_fmt(&self, args: fmt::Arguments<'_>);
+}
+
+#[derive(Debug)]
+pub(crate) struct Stdout;
+
+impl ConsoleOut for Stdout {
+    fn write_fmt(&self, args: fmt::Arguments<'_>) {
+        print!("{args}");
+    }
+}
+
+#[derive(Debug)]
+pub(crate) struct Stderr;
+
+impl ConsoleOut for Stderr {
+    fn write_fmt(&self, args: fmt::Arguments<'_>) {
+        eprint!("{args}");
+    }
+}
+
+pub(crate) struct CaptureBuf {
+    inner: Mutex<String>,
+}
+
+impl CaptureBuf {
+    pub(crate) fn new() -> Self {
+        Self { inner: Mutex::new(String::new()) }
+    }
+
+    pub(crate) fn into_inner(self) -> String {
+        self.inner.into_inner().unwrap_or_else(|e| e.into_inner())
+    }
+}
+
+impl fmt::Debug for CaptureBuf {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("CaptureBuf").finish_non_exhaustive()
+    }
+}
+
+impl ConsoleOut for CaptureBuf {
+    fn write_fmt(&self, args: fmt::Arguments<'_>) {
+        let mut s = self.inner.lock().unwrap_or_else(|e| e.into_inner());
+        <String as fmt::Write>::write_fmt(&mut s, args).unwrap();
+    }
+}
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 867624cc8fa..89fb8eb4357 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -23,6 +23,7 @@ use crate::common::{
 };
 use crate::directives::TestProps;
 use crate::errors::{Error, ErrorKind, load_errors};
+use crate::output_capture::ConsoleOut;
 use crate::read2::{Truncated, read2_abbreviated};
 use crate::runtest::compute_diff::{DiffLine, make_diff, write_diff, write_filtered_diff};
 use crate::util::{Utf8PathBufExt, add_dylib_path, static_regex};
@@ -108,7 +109,13 @@ fn dylib_name(name: &str) -> String {
     format!("{}{name}.{}", std::env::consts::DLL_PREFIX, std::env::consts::DLL_EXTENSION)
 }
 
-pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
+pub fn run(
+    config: Arc<Config>,
+    stdout: &dyn ConsoleOut,
+    stderr: &dyn ConsoleOut,
+    testpaths: &TestPaths,
+    revision: Option<&str>,
+) {
     match &*config.target {
         "arm-linux-androideabi"
         | "armv7-linux-androideabi"
@@ -131,7 +138,7 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
 
     if config.verbose {
         // We're going to be dumping a lot of info. Start on a new line.
-        print!("\n\n");
+        write!(stdout, "\n\n");
     }
     debug!("running {}", testpaths.file);
     let mut props = TestProps::from_file(&testpaths.file, revision, &config);
@@ -143,7 +150,7 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
         props.incremental_dir = Some(incremental_dir(&config, testpaths, revision));
     }
 
-    let cx = TestCx { config: &config, props: &props, testpaths, revision };
+    let cx = TestCx { config: &config, stdout, stderr, props: &props, testpaths, revision };
 
     if let Err(e) = create_dir_all(&cx.output_base_dir()) {
         panic!("failed to create output base directory {}: {e}", cx.output_base_dir());
@@ -162,6 +169,8 @@ pub fn run(config: Arc<Config>, testpaths: &TestPaths, revision: Option<&str>) {
             revision_props.incremental_dir = props.incremental_dir.clone();
             let rev_cx = TestCx {
                 config: &config,
+                stdout,
+                stderr,
                 props: &revision_props,
                 testpaths,
                 revision: Some(revision),
@@ -212,6 +221,8 @@ pub fn compute_stamp_hash(config: &Config) -> String {
 #[derive(Copy, Clone, Debug)]
 struct TestCx<'test> {
     config: &'test Config,
+    stdout: &'test dyn ConsoleOut,
+    stderr: &'test dyn ConsoleOut,
     props: &'test TestProps,
     testpaths: &'test TestPaths,
     revision: Option<&'test str>,
@@ -603,7 +614,8 @@ impl<'test> TestCx<'test> {
             );
         } else {
             for pattern in missing_patterns {
-                println!(
+                writeln!(
+                    self.stdout,
                     "\n{prefix}: error pattern '{pattern}' not found!",
                     prefix = self.error_prefix()
                 );
@@ -783,7 +795,8 @@ impl<'test> TestCx<'test> {
                 };
                 format!("{file_name}:{line_num}{opt_col_num}")
             };
-            let print_error = |e| println!("{}: {}: {}", line_str(e), e.kind, e.msg.cyan());
+            let print_error =
+                |e| writeln!(self.stdout, "{}: {}: {}", line_str(e), e.kind, e.msg.cyan());
             let push_suggestion =
                 |suggestions: &mut Vec<_>, e: &Error, kind, line, msg, color, rank| {
                     let mut ret = String::new();
@@ -811,7 +824,7 @@ impl<'test> TestCx<'test> {
                 if let Some(&(_, top_rank)) = suggestions.first() {
                     for (suggestion, rank) in suggestions {
                         if rank == top_rank {
-                            println!("  {} {suggestion}", prefix.color(color));
+                            writeln!(self.stdout, "  {} {suggestion}", prefix.color(color));
                         }
                     }
                 }
@@ -824,7 +837,8 @@ impl<'test> TestCx<'test> {
             // - only known line - meh, but suggested
             // - others are not worth suggesting
             if !unexpected.is_empty() {
-                println!(
+                writeln!(
+                    self.stdout,
                     "\n{prefix}: {n} diagnostics reported in JSON output but not expected in test file",
                     prefix = self.error_prefix(),
                     n = unexpected.len(),
@@ -858,7 +872,8 @@ impl<'test> TestCx<'test> {
                 }
             }
             if !not_found.is_empty() {
-                println!(
+                writeln!(
+                    self.stdout,
                     "\n{prefix}: {n} diagnostics expected in test file but not reported in JSON output",
                     prefix = self.error_prefix(),
                     n = not_found.len(),
@@ -978,6 +993,8 @@ impl<'test> TestCx<'test> {
                     self.props.from_aux_file(&aux_testpaths.file, self.revision, self.config);
                 let aux_cx = TestCx {
                     config: self.config,
+                    stdout: self.stdout,
+                    stderr: self.stderr,
                     props: &props_for_aux,
                     testpaths: &aux_testpaths,
                     revision: self.revision,
@@ -1343,6 +1360,8 @@ impl<'test> TestCx<'test> {
         let aux_output = TargetLocation::ThisDirectory(aux_dir.clone());
         let aux_cx = TestCx {
             config: self.config,
+            stdout: self.stdout,
+            stderr: self.stderr,
             props: &aux_props,
             testpaths: &aux_testpaths,
             revision: self.revision,
@@ -1948,11 +1967,11 @@ impl<'test> TestCx<'test> {
         } else {
             path.file_name().unwrap().into()
         };
-        println!("------{proc_name} stdout------------------------------");
-        println!("{}", out);
-        println!("------{proc_name} stderr------------------------------");
-        println!("{}", err);
-        println!("------------------------------------------");
+        writeln!(self.stdout, "------{proc_name} stdout------------------------------");
+        writeln!(self.stdout, "{}", out);
+        writeln!(self.stdout, "------{proc_name} stderr------------------------------");
+        writeln!(self.stdout, "{}", err);
+        writeln!(self.stdout, "------------------------------------------");
     }
 
     fn dump_output_file(&self, out: &str, extension: &str) {
@@ -2014,7 +2033,7 @@ impl<'test> TestCx<'test> {
         debug!("{message}");
         if self.config.verbose {
             // Note: `./x test ... --verbose --no-capture` is needed to see this print.
-            println!("{message}");
+            writeln!(self.stdout, "{message}");
         }
     }
 
@@ -2030,7 +2049,7 @@ impl<'test> TestCx<'test> {
 
     #[track_caller]
     fn fatal(&self, err: &str) -> ! {
-        println!("\n{prefix}: {err}", prefix = self.error_prefix());
+        writeln!(self.stdout, "\n{prefix}: {err}", prefix = self.error_prefix());
         error!("fatal error, panic: {:?}", err);
         panic!("fatal error");
     }
@@ -2048,15 +2067,15 @@ impl<'test> TestCx<'test> {
         proc_res: &ProcRes,
         callback_before_unwind: impl FnOnce(),
     ) -> ! {
-        println!("\n{prefix}: {err}", prefix = self.error_prefix());
+        writeln!(self.stdout, "\n{prefix}: {err}", prefix = self.error_prefix());
 
         // Some callers want to print additional notes after the main error message.
         if let Some(note) = extra_note {
-            println!("{note}");
+            writeln!(self.stdout, "{note}");
         }
 
         // Print the details and output of the subprocess that caused this test to fail.
-        println!("{}", proc_res.format_info());
+        writeln!(self.stdout, "{}", proc_res.format_info());
 
         // Some callers want print more context or show a custom diff before the unwind occurs.
         callback_before_unwind();
@@ -2126,7 +2145,7 @@ impl<'test> TestCx<'test> {
         if !self.config.has_html_tidy {
             return;
         }
-        println!("info: generating a diff against nightly rustdoc");
+        writeln!(self.stdout, "info: generating a diff against nightly rustdoc");
 
         let suffix =
             self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly");
@@ -2162,7 +2181,7 @@ impl<'test> TestCx<'test> {
 
         let proc_res = new_rustdoc.document(&compare_dir, &new_rustdoc.testpaths);
         if !proc_res.status.success() {
-            eprintln!("failed to run nightly rustdoc");
+            writeln!(self.stderr, "failed to run nightly rustdoc");
             return;
         }
 
@@ -2207,6 +2226,7 @@ impl<'test> TestCx<'test> {
         let diff_filename = format!("build/tmp/rustdoc-compare-{}.diff", std::process::id());
 
         if !write_filtered_diff(
+            self,
             &diff_filename,
             out_dir,
             &compare_dir,
@@ -2227,7 +2247,7 @@ impl<'test> TestCx<'test> {
         if let Some(pager) = pager {
             let pager = pager.trim();
             if self.config.verbose {
-                eprintln!("using pager {}", pager);
+                writeln!(self.stderr, "using pager {}", pager);
             }
             let output = Command::new(pager)
                 // disable paging; we want this to be non-interactive
@@ -2238,8 +2258,8 @@ impl<'test> TestCx<'test> {
                 .output()
                 .unwrap();
             assert!(output.status.success());
-            println!("{}", String::from_utf8_lossy(&output.stdout));
-            eprintln!("{}", String::from_utf8_lossy(&output.stderr));
+            writeln!(self.stdout, "{}", String::from_utf8_lossy(&output.stdout));
+            writeln!(self.stderr, "{}", String::from_utf8_lossy(&output.stderr));
         } else {
             warning!("no pager configured, falling back to unified diff");
             help!(
@@ -2254,7 +2274,7 @@ impl<'test> TestCx<'test> {
                 match diff.read_until(b'\n', &mut line) {
                     Ok(0) => break,
                     Ok(_) => {}
-                    Err(e) => eprintln!("ERROR: {:?}", e),
+                    Err(e) => writeln!(self.stderr, "ERROR: {:?}", e),
                 }
                 match String::from_utf8(line.clone()) {
                     Ok(line) => {
@@ -2802,11 +2822,11 @@ impl<'test> TestCx<'test> {
         if let Err(err) = fs::write(&actual_path, &actual) {
             self.fatal(&format!("failed to write {stream} to `{actual_path}`: {err}",));
         }
-        println!("Saved the actual {stream} to `{actual_path}`");
+        writeln!(self.stdout, "Saved the actual {stream} to `{actual_path}`");
 
         if !self.config.bless {
             if expected.is_empty() {
-                println!("normalized {}:\n{}\n", stream, actual);
+                writeln!(self.stdout, "normalized {}:\n{}\n", stream, actual);
             } else {
                 self.show_diff(
                     stream,
@@ -2830,14 +2850,15 @@ impl<'test> TestCx<'test> {
                 if let Err(err) = fs::write(&expected_path, &actual) {
                     self.fatal(&format!("failed to write {stream} to `{expected_path}`: {err}"));
                 }
-                println!(
+                writeln!(
+                    self.stdout,
                     "Blessing the {stream} of `{test_name}` as `{expected_path}`",
                     test_name = self.testpaths.file
                 );
             }
         }
 
-        println!("\nThe actual {stream} differed from the expected {stream}");
+        writeln!(self.stdout, "\nThe actual {stream} differed from the expected {stream}");
 
         if self.config.bless { CompareOutcome::Blessed } else { CompareOutcome::Differed }
     }
@@ -2852,7 +2873,7 @@ impl<'test> TestCx<'test> {
         actual: &str,
         actual_unnormalized: &str,
     ) {
-        eprintln!("diff of {stream}:\n");
+        writeln!(self.stderr, "diff of {stream}:\n");
         if let Some(diff_command) = self.config.diff_command.as_deref() {
             let mut args = diff_command.split_whitespace();
             let name = args.next().unwrap();
@@ -2864,11 +2885,11 @@ impl<'test> TestCx<'test> {
                 }
                 Ok(output) => {
                     let output = String::from_utf8_lossy(&output.stdout);
-                    eprint!("{output}");
+                    write!(self.stderr, "{output}");
                 }
             }
         } else {
-            eprint!("{}", write_diff(expected, actual, 3));
+            write!(self.stderr, "{}", write_diff(expected, actual, 3));
         }
 
         // NOTE: argument order is important, we need `actual` to be on the left so the line number match up when we compare it to `actual_unnormalized` below.
@@ -2906,9 +2927,16 @@ impl<'test> TestCx<'test> {
             && !mismatches_unnormalized.is_empty()
             && !mismatches_normalized.is_empty()
         {
-            eprintln!("Note: some mismatched output was normalized before being compared");
+            writeln!(
+                self.stderr,
+                "Note: some mismatched output was normalized before being compared"
+            );
             // FIXME: respect diff_command
-            eprint!("{}", write_diff(&mismatches_unnormalized, &mismatches_normalized, 0));
+            write!(
+                self.stderr,
+                "{}",
+                write_diff(&mismatches_unnormalized, &mismatches_normalized, 0)
+            );
         }
     }
 
@@ -2986,7 +3014,7 @@ impl<'test> TestCx<'test> {
         fs::create_dir_all(&incremental_dir).unwrap();
 
         if self.config.verbose {
-            println!("init_incremental_test: incremental_dir={incremental_dir}");
+            writeln!(self.stdout, "init_incremental_test: incremental_dir={incremental_dir}");
         }
     }
 }
diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs
index 44ddcb1d288..16c251c3c9e 100644
--- a/src/tools/compiletest/src/runtest/codegen_units.rs
+++ b/src/tools/compiletest/src/runtest/codegen_units.rs
@@ -62,13 +62,13 @@ impl TestCx<'_> {
         if !missing.is_empty() {
             missing.sort();
 
-            println!("\nThese items should have been contained but were not:\n");
+            writeln!(self.stdout, "\nThese items should have been contained but were not:\n");
 
             for item in &missing {
-                println!("{}", item);
+                writeln!(self.stdout, "{}", item);
             }
 
-            println!("\n");
+            writeln!(self.stdout, "\n");
         }
 
         if !unexpected.is_empty() {
@@ -78,24 +78,32 @@ impl TestCx<'_> {
                 sorted
             };
 
-            println!("\nThese items were contained but should not have been:\n");
+            writeln!(self.stdout, "\nThese items were contained but should not have been:\n");
 
             for item in sorted {
-                println!("{}", item);
+                writeln!(self.stdout, "{}", item);
             }
 
-            println!("\n");
+            writeln!(self.stdout, "\n");
         }
 
         if !wrong_cgus.is_empty() {
             wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
-            println!("\nThe following items were assigned to wrong codegen units:\n");
+            writeln!(self.stdout, "\nThe following items were assigned to wrong codegen units:\n");
 
             for &(ref expected_item, ref actual_item) in &wrong_cgus {
-                println!("{}", expected_item.name);
-                println!("  expected: {}", codegen_units_to_str(&expected_item.codegen_units));
-                println!("  actual:   {}", codegen_units_to_str(&actual_item.codegen_units));
-                println!();
+                writeln!(self.stdout, "{}", expected_item.name);
+                writeln!(
+                    self.stdout,
+                    "  expected: {}",
+                    codegen_units_to_str(&expected_item.codegen_units)
+                );
+                writeln!(
+                    self.stdout,
+                    "  actual:   {}",
+                    codegen_units_to_str(&actual_item.codegen_units)
+                );
+                writeln!(self.stdout);
             }
         }
 
diff --git a/src/tools/compiletest/src/runtest/compute_diff.rs b/src/tools/compiletest/src/runtest/compute_diff.rs
index 509e7e11703..3363127b3ea 100644
--- a/src/tools/compiletest/src/runtest/compute_diff.rs
+++ b/src/tools/compiletest/src/runtest/compute_diff.rs
@@ -3,6 +3,8 @@ use std::fs::{File, FileType};
 
 use camino::Utf8Path;
 
+use crate::runtest::TestCx;
+
 #[derive(Debug, PartialEq)]
 pub enum DiffLine {
     Context(String),
@@ -112,6 +114,7 @@ pub(crate) fn write_diff(expected: &str, actual: &str, context_size: usize) -> S
 ///
 /// Returns whether any data was actually written.
 pub(crate) fn write_filtered_diff<Filter>(
+    cx: &TestCx<'_>,
     diff_filename: &str,
     out_dir: &Utf8Path,
     compare_dir: &Utf8Path,
@@ -147,11 +150,11 @@ where
     }
 
     if !wrote_data {
-        println!("note: diff is identical to nightly rustdoc");
+        writeln!(cx.stdout, "note: diff is identical to nightly rustdoc");
         assert!(diff_output.metadata().unwrap().len() == 0);
         return false;
     } else if verbose {
-        eprintln!("printing diff:");
+        writeln!(cx.stderr, "printing diff:");
         let mut buf = Vec::new();
         diff_output.read_to_end(&mut buf).unwrap();
         std::io::stderr().lock().write_all(&mut buf).unwrap();
diff --git a/src/tools/compiletest/src/runtest/crashes.rs b/src/tools/compiletest/src/runtest/crashes.rs
index da1e74b4a56..0aae7eaa39c 100644
--- a/src/tools/compiletest/src/runtest/crashes.rs
+++ b/src/tools/compiletest/src/runtest/crashes.rs
@@ -6,10 +6,10 @@ impl TestCx<'_> {
         let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
 
         if std::env::var("COMPILETEST_VERBOSE_CRASHES").is_ok() {
-            eprintln!("{}", proc_res.status);
-            eprintln!("{}", proc_res.stdout);
-            eprintln!("{}", proc_res.stderr);
-            eprintln!("{}", proc_res.cmdline);
+            writeln!(self.stderr, "{}", proc_res.status);
+            writeln!(self.stderr, "{}", proc_res.stdout);
+            writeln!(self.stderr, "{}", proc_res.stderr);
+            writeln!(self.stderr, "{}", proc_res.cmdline);
         }
 
         // if a test does not crash, consider it an error
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
index 88d022b8bba..071c0863b7e 100644
--- a/src/tools/compiletest/src/runtest/debuginfo.rs
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -245,7 +245,7 @@ impl TestCx<'_> {
                 cmdline,
             };
             if adb.kill().is_err() {
-                println!("Adb process is already finished.");
+                writeln!(self.stdout, "Adb process is already finished.");
             }
         } else {
             let rust_pp_module_abs_path = self.config.src_root.join("src").join("etc");
@@ -256,7 +256,11 @@ impl TestCx<'_> {
 
             match self.config.gdb_version {
                 Some(version) => {
-                    println!("NOTE: compiletest thinks it is using GDB version {}", version);
+                    writeln!(
+                        self.stdout,
+                        "NOTE: compiletest thinks it is using GDB version {}",
+                        version
+                    );
 
                     if !self.props.disable_gdb_pretty_printers
                         && version > extract_gdb_version("7.4").unwrap()
@@ -278,7 +282,8 @@ impl TestCx<'_> {
                     }
                 }
                 _ => {
-                    println!(
+                    writeln!(
+                        self.stdout,
                         "NOTE: compiletest does not know which version of \
                          GDB it is using"
                     );
@@ -376,10 +381,15 @@ impl TestCx<'_> {
 
         match self.config.lldb_version {
             Some(ref version) => {
-                println!("NOTE: compiletest thinks it is using LLDB version {}", version);
+                writeln!(
+                    self.stdout,
+                    "NOTE: compiletest thinks it is using LLDB version {}",
+                    version
+                );
             }
             _ => {
-                println!(
+                writeln!(
+                    self.stdout,
                     "NOTE: compiletest does not know which version of \
                      LLDB it is using"
                 );
diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs
index 90cff6bab4d..44eb80300c3 100644
--- a/src/tools/compiletest/src/runtest/incremental.rs
+++ b/src/tools/compiletest/src/runtest/incremental.rs
@@ -30,7 +30,7 @@ impl TestCx<'_> {
         assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
 
         if self.config.verbose {
-            print!("revision={:?} props={:#?}", revision, self.props);
+            write!(self.stdout, "revision={:?} props={:#?}", revision, self.props);
         }
 
         if revision.starts_with("cpass") {
diff --git a/src/tools/compiletest/src/runtest/mir_opt.rs b/src/tools/compiletest/src/runtest/mir_opt.rs
index 55043bf4bc2..94487926383 100644
--- a/src/tools/compiletest/src/runtest/mir_opt.rs
+++ b/src/tools/compiletest/src/runtest/mir_opt.rs
@@ -80,7 +80,7 @@ impl TestCx<'_> {
                 }
                 let expected_string = fs::read_to_string(&expected_file).unwrap();
                 if dumped_string != expected_string {
-                    print!("{}", write_diff(&expected_string, &dumped_string, 3));
+                    write!(self.stdout, "{}", write_diff(&expected_string, &dumped_string, 3));
                     panic!(
                         "Actual MIR output differs from expected MIR output {}",
                         expected_file.display()
diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs
index 083398f9274..b8da6e2ac52 100644
--- a/src/tools/compiletest/src/runtest/rustdoc_json.rs
+++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs
@@ -30,8 +30,8 @@ impl TestCx<'_> {
 
         if !res.status.success() {
             self.fatal_proc_rec_general("jsondocck failed!", None, &res, || {
-                println!("Rustdoc Output:");
-                println!("{}", proc_res.format_info());
+                writeln!(self.stdout, "Rustdoc Output:");
+                writeln!(self.stdout, "{}", proc_res.format_info());
             })
         }
 
diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs
index 40b0ee0a399..d683a325c86 100644
--- a/src/tools/compiletest/src/runtest/ui.rs
+++ b/src/tools/compiletest/src/runtest/ui.rs
@@ -115,10 +115,14 @@ impl TestCx<'_> {
         }
 
         if errors > 0 {
-            println!("To update references, rerun the tests and pass the `--bless` flag");
+            writeln!(
+                self.stdout,
+                "To update references, rerun the tests and pass the `--bless` flag"
+            );
             let relative_path_to_file =
                 self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
-            println!(
+            writeln!(
+                self.stdout,
                 "To only update this specific test, also pass `--test-args {}`",
                 relative_path_to_file,
             );
diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs
index 1f16a672a98..558e9a58697 100644
--- a/src/tools/compiletest/src/util.rs
+++ b/src/tools/compiletest/src/util.rs
@@ -45,7 +45,7 @@ impl Utf8PathBufExt for Utf8PathBuf {
 
 /// The name of the environment variable that holds dynamic library locations.
 pub fn dylib_env_var() -> &'static str {
-    if cfg!(windows) {
+    if cfg!(any(windows, target_os = "cygwin")) {
         "PATH"
     } else if cfg!(target_vendor = "apple") {
         "DYLD_LIBRARY_PATH"
diff --git a/src/tools/miri/tests/fail/intrinsics/funnel_shl.rs b/src/tools/miri/tests/fail/intrinsics/funnel_shl.rs
new file mode 100644
index 00000000000..40b61f65ebe
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/funnel_shl.rs
@@ -0,0 +1,7 @@
+#![feature(core_intrinsics, funnel_shifts)]
+
+fn main() {
+    unsafe {
+        std::intrinsics::unchecked_funnel_shl(1_u32, 2, 32); //~ ERROR: Undefined Behavior
+    }
+}
diff --git a/src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr b/src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr
new file mode 100644
index 00000000000..fc828021b13
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/funnel_shl.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: `assume` called with `false`
+  --> tests/fail/intrinsics/funnel_shl.rs:LL:CC
+   |
+LL |         std::intrinsics::unchecked_funnel_shl(1_u32, 2, 32);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/intrinsics/funnel_shl.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/fail/intrinsics/funnel_shr.rs b/src/tools/miri/tests/fail/intrinsics/funnel_shr.rs
new file mode 100644
index 00000000000..95822656397
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/funnel_shr.rs
@@ -0,0 +1,7 @@
+#![feature(core_intrinsics, funnel_shifts)]
+
+fn main() {
+    unsafe {
+        std::intrinsics::unchecked_funnel_shr(1_u32, 2, 32); //~ ERROR: Undefined Behavior
+    }
+}
diff --git a/src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr b/src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr
new file mode 100644
index 00000000000..7361df1b4c7
--- /dev/null
+++ b/src/tools/miri/tests/fail/intrinsics/funnel_shr.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: `assume` called with `false`
+  --> tests/fail/intrinsics/funnel_shr.rs:LL:CC
+   |
+LL |         std::intrinsics::unchecked_funnel_shr(1_u32, 2, 32);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/intrinsics/funnel_shr.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass/intrinsics/integer.rs b/src/tools/miri/tests/pass/intrinsics/integer.rs
index 13e7bd8e1b9..8727b6d3c87 100644
--- a/src/tools/miri/tests/pass/intrinsics/integer.rs
+++ b/src/tools/miri/tests/pass/intrinsics/integer.rs
@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: MIT OR Apache-2.0
 // SPDX-FileCopyrightText: The Rust Project Developers (see https://thanks.rust-lang.org)
 
-#![feature(core_intrinsics)]
+#![feature(core_intrinsics, funnel_shifts)]
 use std::intrinsics::*;
 
 pub fn main() {
@@ -143,5 +143,11 @@ pub fn main() {
 
         assert_eq!(unchecked_mul(6u8, 7), 42);
         assert_eq!(unchecked_mul(13, -5), -65);
+
+        assert_eq!(unchecked_funnel_shl(1_u32, 2, 5), 32);
+        assert_eq!(unchecked_funnel_shl(1_u32, 2, 31), 0x80000001);
+
+        assert_eq!(unchecked_funnel_shr(1_u32, 2, 5), 0x08000000);
+        assert_eq!(unchecked_funnel_shr(1_u32, 2, 31), 2);
     }
 }
diff --git a/src/tools/tidy/src/extra_checks/mod.rs b/src/tools/tidy/src/extra_checks/mod.rs
index 31169ec5967..34d9ea92629 100644
--- a/src/tools/tidy/src/extra_checks/mod.rs
+++ b/src/tools/tidy/src/extra_checks/mod.rs
@@ -720,21 +720,19 @@ impl ExtraCheckArg {
         if !self.auto {
             return true;
         }
-        let ext = match self.lang {
-            ExtraCheckLang::Py => ".py",
-            ExtraCheckLang::Cpp => ".cpp",
-            ExtraCheckLang::Shell => ".sh",
-            ExtraCheckLang::Js => ".js",
+        let exts: &[&str] = match self.lang {
+            ExtraCheckLang::Py => &[".py"],
+            ExtraCheckLang::Cpp => &[".cpp"],
+            ExtraCheckLang::Shell => &[".sh"],
+            ExtraCheckLang::Js => &[".js", ".ts"],
             ExtraCheckLang::Spellcheck => {
-                for dir in SPELLCHECK_DIRS {
-                    if Path::new(filepath).starts_with(dir) {
-                        return true;
-                    }
+                if SPELLCHECK_DIRS.iter().any(|dir| Path::new(filepath).starts_with(dir)) {
+                    return true;
                 }
-                return false;
+                &[]
             }
         };
-        filepath.ends_with(ext)
+        exts.iter().any(|ext| filepath.ends_with(ext))
     }
 
     fn has_supported_kind(&self) -> bool {
diff --git a/src/tools/tidy/src/triagebot.rs b/src/tools/tidy/src/triagebot.rs
index 305a0b4d264..6f25ed616fa 100644
--- a/src/tools/tidy/src/triagebot.rs
+++ b/src/tools/tidy/src/triagebot.rs
@@ -19,7 +19,12 @@ pub fn check(path: &Path, bad: &mut bool) {
 
     // Check [mentions."*"] sections, i.e. [mentions."compiler/rustc_const_eval/src/"]
     if let Some(Value::Table(mentions)) = config.get("mentions") {
-        for path_str in mentions.keys() {
+        for (entry_key, entry_val) in mentions.iter() {
+            // If the type is set to something other than "filename", then this is not a path.
+            if entry_val.get("type").is_some_and(|t| t.as_str().unwrap_or_default() != "filename") {
+                continue;
+            }
+            let path_str = entry_key;
             // Remove quotes from the path
             let clean_path = path_str.trim_matches('"');
             let full_path = path.join(clean_path);
diff --git a/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs
index 642bf5e7576..ada525b6c80 100644
--- a/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs
+++ b/tests/codegen-llvm/sanitizer/address-sanitizer-globals-tracking.rs
@@ -19,7 +19,7 @@
 //@ only-linux
 //
 //@ revisions:ASAN ASAN-FAT-LTO
-//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static
+//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 // [ASAN] no extra compile-flags
 //@[ASAN-FAT-LTO] compile-flags: -Cprefer-dynamic=false -Clto=fat
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/add-canonical-jump-tables-flag.rs b/tests/codegen-llvm/sanitizer/cfi/add-canonical-jump-tables-flag.rs
index 22577e2a3c4..77857ca4ccb 100644
--- a/tests/codegen-llvm/sanitizer/cfi/add-canonical-jump-tables-flag.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/add-canonical-jump-tables-flag.rs
@@ -1,7 +1,7 @@
 // Verifies that "CFI Canonical Jump Tables" module flag is added.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/add-cfi-normalize-integers-flag.rs b/tests/codegen-llvm/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
index a54a6d84a80..6cf9a72b748 100644
--- a/tests/codegen-llvm/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/add-cfi-normalize-integers-flag.rs
@@ -1,7 +1,7 @@
 // Verifies that "cfi-normalize-integers" module flag is added.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
+//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/add-enable-split-lto-unit-flag.rs b/tests/codegen-llvm/sanitizer/cfi/add-enable-split-lto-unit-flag.rs
index 283b8f26102..0bfdbfba5d2 100644
--- a/tests/codegen-llvm/sanitizer/cfi/add-enable-split-lto-unit-flag.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/add-enable-split-lto-unit-flag.rs
@@ -1,7 +1,7 @@
 // Verifies that "EnableSplitLTOUnit" module flag is added.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/dbg-location-on-cfi-blocks.rs b/tests/codegen-llvm/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
index df65960dfe0..2a18e30e2b0 100644
--- a/tests/codegen-llvm/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/dbg-location-on-cfi-blocks.rs
@@ -1,7 +1,7 @@
 // Verifies that the parent block's debug information are assigned to the inserted cfi block.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -Cdebuginfo=1
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -Cdebuginfo=1 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-attr-sanitize-off.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-attr-sanitize-off.rs
index 651afb33228..c49438f4318 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-attr-sanitize-off.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks-attr-sanitize-off.rs
@@ -1,7 +1,7 @@
 // Verifies that pointer type membership tests for indirect calls are omitted.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(sanitize)]
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks.rs
index ebc66a015df..9cad88f6518 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-checks.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-checks.rs
@@ -1,7 +1,7 @@
 // Verifies that pointer type membership tests for indirect calls are emitted.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs
index 9bc2e42db0f..cd9088f58af 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-attr-cfi-encoding.rs
@@ -1,7 +1,7 @@
 // Verifies that user-defined CFI encoding for types are emitted.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(cfi_encoding, extern_types)]
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
index 9048c6a1f18..cf26c17af1e 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-const-generics.rs
@@ -2,7 +2,7 @@
 // for const generics.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs
index 8fec275fd06..279350d20c5 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-drop-in-place.rs
@@ -5,7 +5,7 @@
 // future.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
index 7e60aafff68..047b532e994 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
@@ -2,7 +2,7 @@
 // for function types.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
index 36d2e8c9f25..92b2ab32ea0 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-lifetimes.rs
@@ -2,7 +2,7 @@
 // for lifetimes/regions.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs
index 9d611777ff0..5de39dc85c1 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-method-secondary-typeid.rs
@@ -2,7 +2,7 @@
 // self so they can be used as function pointers.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
index a8ba8db1be3..f5846713bd5 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-paths.rs
@@ -2,7 +2,7 @@
 // for paths.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(type_alias_impl_trait)]
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs
index d37bb740f55..ad4fe11d087 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-pointer-types.rs
@@ -2,7 +2,7 @@
 // for pointer types.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs
index 7d9e4d05872..93845d05195 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-primitive-types.rs
@@ -2,7 +2,7 @@
 // for primitive types.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
index 0f97c70f3f9..025aa902658 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-repr-transparent-types.rs
@@ -2,7 +2,7 @@
 // for repr transparent types.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs
index bdee3f47a83..76c8150b778 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-sequence-types.rs
@@ -2,7 +2,7 @@
 // for sequence types.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
index 55e816178f8..4fafdd2f040 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
@@ -2,7 +2,7 @@
 // for trait types.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs
index c1f3ca61afe..91351096ca2 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-user-defined-types.rs
@@ -2,7 +2,7 @@
 // for user-defined types.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(extern_types)]
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs
index 32637b64b3e..22d518cca74 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-generalized.rs
@@ -1,7 +1,7 @@
 // Verifies that generalized type metadata for functions are emitted.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs
index 51121b0aef1..7639ce7b104 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized-generalized.rs
@@ -1,7 +1,7 @@
 // Verifies that normalized and generalized type metadata for functions are emitted.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Zsanitizer-cfi-generalize-pointers -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs
index 1cfdd23006e..acd72b0ca3c 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi-normalized.rs
@@ -1,7 +1,7 @@
 // Verifies that normalized type metadata for functions are emitted.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs
index 56ab1ce4b35..fa5cd471466 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-itanium-cxx-abi.rs
@@ -1,7 +1,7 @@
 // Verifies that type metadata for functions are emitted.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-trait-objects.rs b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-trait-objects.rs
index 0e57ce322d1..82873e935b2 100644
--- a/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-trait-objects.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/emit-type-metadata-trait-objects.rs
@@ -1,7 +1,7 @@
 // Verifies that type metadata identifiers for trait objects are emitted correctly.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Copt-level=0 -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/external_weak_symbols.rs b/tests/codegen-llvm/sanitizer/cfi/external_weak_symbols.rs
index b3cb6dfdd37..893b0167693 100644
--- a/tests/codegen-llvm/sanitizer/cfi/external_weak_symbols.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/external_weak_symbols.rs
@@ -2,7 +2,7 @@
 // emitted correctly.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clinker-plugin-lto -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Clinker-plugin-lto -Copt-level=0 -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 #![crate_type = "bin"]
 #![feature(linkage)]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/generalize-pointers.rs b/tests/codegen-llvm/sanitizer/cfi/generalize-pointers.rs
index 57004da6f8e..caa2f258f8f 100644
--- a/tests/codegen-llvm/sanitizer/cfi/generalize-pointers.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/generalize-pointers.rs
@@ -1,7 +1,7 @@
 // Verifies that pointer types are generalized.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers -Copt-level=0
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/cfi/normalize-integers.rs b/tests/codegen-llvm/sanitizer/cfi/normalize-integers.rs
index 770ee4e64e0..16f76adafb8 100644
--- a/tests/codegen-llvm/sanitizer/cfi/normalize-integers.rs
+++ b/tests/codegen-llvm/sanitizer/cfi/normalize-integers.rs
@@ -1,7 +1,7 @@
 // Verifies that integer types are normalized.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Copt-level=0
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/dataflow-instrument-functions.rs b/tests/codegen-llvm/sanitizer/dataflow-instrument-functions.rs
index a2d0d63cc17..cd8c2c48ea4 100644
--- a/tests/codegen-llvm/sanitizer/dataflow-instrument-functions.rs
+++ b/tests/codegen-llvm/sanitizer/dataflow-instrument-functions.rs
@@ -1,7 +1,7 @@
 // Verifies that functions are instrumented.
 //
 //@ needs-sanitizer-dataflow
-//@ compile-flags: -Copt-level=0 -Zsanitizer=dataflow
+//@ compile-flags: -Copt-level=0 -Zsanitizer=dataflow -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/memory-track-origins.rs b/tests/codegen-llvm/sanitizer/memory-track-origins.rs
index 5eb5b356b05..a72e523c4e1 100644
--- a/tests/codegen-llvm/sanitizer/memory-track-origins.rs
+++ b/tests/codegen-llvm/sanitizer/memory-track-origins.rs
@@ -4,7 +4,7 @@
 //@ needs-sanitizer-memory
 //@ revisions:MSAN-0 MSAN-1 MSAN-2 MSAN-1-LTO MSAN-2-LTO
 //
-//@ compile-flags: -Zsanitizer=memory -Ctarget-feature=-crt-static
+//@ compile-flags: -Zsanitizer=memory -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 // [MSAN-0] no extra compile-flags
 //@[MSAN-1] compile-flags: -Zsanitizer-memory-track-origins=1
 //@[MSAN-2] compile-flags: -Zsanitizer-memory-track-origins
diff --git a/tests/codegen-llvm/sanitizer/memtag-attr-check.rs b/tests/codegen-llvm/sanitizer/memtag-attr-check.rs
index ffe3a2322a2..fc430f3a570 100644
--- a/tests/codegen-llvm/sanitizer/memtag-attr-check.rs
+++ b/tests/codegen-llvm/sanitizer/memtag-attr-check.rs
@@ -2,7 +2,7 @@
 // applied when enabling the memtag sanitizer.
 //
 //@ needs-sanitizer-memtag
-//@ compile-flags: -Zsanitizer=memtag -Ctarget-feature=+mte -Copt-level=0
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer -Zsanitizer=memtag -Ctarget-feature=+mte -Copt-level=0
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/safestack-attr-check.rs b/tests/codegen-llvm/sanitizer/safestack-attr-check.rs
index 050a60333af..414dd89a580 100644
--- a/tests/codegen-llvm/sanitizer/safestack-attr-check.rs
+++ b/tests/codegen-llvm/sanitizer/safestack-attr-check.rs
@@ -1,7 +1,7 @@
 // This tests that the safestack attribute is applied when enabling the safe-stack sanitizer.
 //
 //@ needs-sanitizer-safestack
-//@ compile-flags: -Zsanitizer=safestack -Copt-level=0
+//@ compile-flags: -Zsanitizer=safestack -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen-llvm/sanitizer/sanitize-off-inlining.rs b/tests/codegen-llvm/sanitizer/sanitize-off-inlining.rs
index 69771827c3a..0f43e6b8393 100644
--- a/tests/codegen-llvm/sanitizer/sanitize-off-inlining.rs
+++ b/tests/codegen-llvm/sanitizer/sanitize-off-inlining.rs
@@ -1,9 +1,9 @@
 // Verifies that sanitize(xyz = "off") attribute prevents inlining when
 // given sanitizer is enabled, but has no effect on inlining otherwise.
-//
 //@ needs-sanitizer-address
 //@ needs-sanitizer-leak
 //@ revisions: ASAN LSAN
+//@       compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@       compile-flags: -Copt-level=3 -Zmir-opt-level=4 -Ctarget-feature=-crt-static
 //@[ASAN] compile-flags: -Zsanitizer=address
 //@[LSAN] compile-flags: -Zsanitizer=leak
diff --git a/tests/codegen-llvm/sanitizer/sanitize-off-kasan-asan.rs b/tests/codegen-llvm/sanitizer/sanitize-off-kasan-asan.rs
index 94945f2b2e6..61ad0ba7d90 100644
--- a/tests/codegen-llvm/sanitizer/sanitize-off-kasan-asan.rs
+++ b/tests/codegen-llvm/sanitizer/sanitize-off-kasan-asan.rs
@@ -2,7 +2,7 @@
 // the address sanitizer.
 //
 //@ needs-sanitizer-address
-//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -Copt-level=0
+//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static -Copt-level=0 -C unsafe-allow-abi-mismatch=sanitizer
 
 #![crate_type = "lib"]
 #![feature(sanitize)]
diff --git a/tests/codegen-llvm/sanitizer/sanitizer-recover.rs b/tests/codegen-llvm/sanitizer/sanitizer-recover.rs
index 6b659320481..b8a24e31c30 100644
--- a/tests/codegen-llvm/sanitizer/sanitizer-recover.rs
+++ b/tests/codegen-llvm/sanitizer/sanitizer-recover.rs
@@ -5,7 +5,7 @@
 //@ needs-sanitizer-memory
 //@ revisions:ASAN ASAN-RECOVER MSAN MSAN-RECOVER MSAN-RECOVER-LTO
 //@ no-prefer-dynamic
-//
+//@                   compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@                   compile-flags: -Ctarget-feature=-crt-static
 //@[ASAN]             compile-flags: -Zsanitizer=address -Copt-level=0
 //@[ASAN-RECOVER]     compile-flags: -Zsanitizer=address -Zsanitizer-recover=address -Copt-level=0
diff --git a/tests/run-make/multiline-args-value/cfg.stderr b/tests/run-make/multiline-args-value/cfg.stderr
new file mode 100644
index 00000000000..9b06f84be48
--- /dev/null
+++ b/tests/run-make/multiline-args-value/cfg.stderr
@@ -0,0 +1,4 @@
+error: invalid `--cfg` argument: `---
+       ---
+       key` (expected `key` or `key="value"`)
+
diff --git a/tests/run-make/multiline-args-value/check-cfg.stderr b/tests/run-make/multiline-args-value/check-cfg.stderr
new file mode 100644
index 00000000000..4a499cc0a1e
--- /dev/null
+++ b/tests/run-make/multiline-args-value/check-cfg.stderr
@@ -0,0 +1,7 @@
+error: invalid `--check-cfg` argument: `---
+       ---
+       cfg(key)`
+  |
+  = note: expected `cfg(name, values("value1", "value2", ... "valueN"))`
+  = note: visit <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more details
+
diff --git a/tests/run-make/multiline-args-value/rmake.rs b/tests/run-make/multiline-args-value/rmake.rs
new file mode 100644
index 00000000000..825cbd158c0
--- /dev/null
+++ b/tests/run-make/multiline-args-value/rmake.rs
@@ -0,0 +1,34 @@
+use run_make_support::{cwd, diff, rustc};
+
+fn test_and_compare(flag: &str, val: &str) {
+    let mut cmd = rustc();
+
+    let output =
+        cmd.input("").arg("--crate-type=lib").arg(&format!("--{flag}")).arg(val).run_fail();
+
+    assert_eq!(output.stdout_utf8(), "");
+    diff()
+        .expected_file(format!("{flag}.stderr"))
+        .actual_text("output", output.stderr_utf8())
+        .run();
+}
+
+fn main() {
+    // Verify that frontmatter isn't allowed in `--cfg` arguments.
+    // https://github.com/rust-lang/rust/issues/146130
+    test_and_compare(
+        "cfg",
+        r#"---
+---
+key"#,
+    );
+
+    // Verify that frontmatter isn't allowed in `--check-cfg` arguments.
+    // https://github.com/rust-lang/rust/issues/146130
+    test_and_compare(
+        "check-cfg",
+        r#"---
+---
+cfg(key)"#,
+    );
+}
diff --git a/tests/run-make/rustdoc-dep-info/rmake.rs b/tests/run-make/rustdoc-dep-info/rmake.rs
index 625f81fd428..166e8d5702f 100644
--- a/tests/run-make/rustdoc-dep-info/rmake.rs
+++ b/tests/run-make/rustdoc-dep-info/rmake.rs
@@ -33,4 +33,16 @@ fn main() {
     // Now we check that we can provide a file name to the `dep-info` argument.
     rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run();
     assert!(path("bla.d").exists());
+
+    // The last emit-type wins. The same behavior as rustc.
+    rustdoc()
+        .input("lib.rs")
+        .arg("-Zunstable-options")
+        .emit("dep-info=precedence1.d")
+        .emit("dep-info=precedence2.d")
+        .emit("dep-info=precedence3.d")
+        .run();
+    assert!(!path("precedence1.d").exists());
+    assert!(!path("precedence2.d").exists());
+    assert!(path("precedence3.d").exists());
 }
diff --git a/tests/run-make/rustdoc-search-load-itemtype/bar.rs b/tests/run-make/rustdoc-search-load-itemtype/bar.rs
new file mode 100644
index 00000000000..0416b1b75b5
--- /dev/null
+++ b/tests/run-make/rustdoc-search-load-itemtype/bar.rs
@@ -0,0 +1,27 @@
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+use proc_macro::*;
+
+//@ has bar/macro.a_procmacro.html
+//@ hasraw search.index/name/*.js a_procmacro
+#[proc_macro]
+pub fn a_procmacro(_: TokenStream) -> TokenStream {
+    unimplemented!()
+}
+
+//@ has bar/attr.a_procattribute.html
+//@ hasraw search.index/name/*.js a_procattribute
+#[proc_macro_attribute]
+pub fn a_procattribute(_: TokenStream, _: TokenStream) -> TokenStream {
+    unimplemented!()
+}
+
+//@ has bar/derive.AProcDerive.html
+//@ !has bar/derive.a_procderive.html
+//@ hasraw search.index/name/*.js AProcDerive
+//@ !hasraw search.index/name/*.js a_procderive
+#[proc_macro_derive(AProcDerive)]
+pub fn a_procderive(_: TokenStream) -> TokenStream {
+    unimplemented!()
+}
diff --git a/tests/run-make/rustdoc-search-load-itemtype/baz.rs b/tests/run-make/rustdoc-search-load-itemtype/baz.rs
new file mode 100644
index 00000000000..4d1f5430fc6
--- /dev/null
+++ b/tests/run-make/rustdoc-search-load-itemtype/baz.rs
@@ -0,0 +1,3 @@
+//@ has baz/struct.Baz.html
+//@ hasraw search.index/name/*.js Baz
+pub struct Baz;
diff --git a/tests/run-make/rustdoc-search-load-itemtype/foo.rs b/tests/run-make/rustdoc-search-load-itemtype/foo.rs
new file mode 100644
index 00000000000..93b372d10cb
--- /dev/null
+++ b/tests/run-make/rustdoc-search-load-itemtype/foo.rs
@@ -0,0 +1,119 @@
+#![feature(extern_types, rustc_attrs, rustdoc_internals, trait_alias)]
+#![allow(internal_features)]
+#![no_std]
+
+//@ has foo/keyword.while.html
+//@ hasraw search.index/name/*.js while
+//@ !hasraw search.index/name/*.js w_keyword
+#[doc(keyword = "while")]
+mod w_keyword {}
+
+//@ has foo/primitive.u32.html
+//@ hasraw search.index/name/*.js u32
+//@ !hasraw search.index/name/*.js u_primitive
+#[rustc_doc_primitive = "u32"]
+mod u_primitive {}
+
+//@ has foo/x_mod/index.html
+//@ hasraw search.index/name/*.js x_mod
+pub mod x_mod {}
+
+//@ hasraw foo/index.html y_crate
+//@ hasraw search.index/name/*.js y_crate
+#[doc(no_inline)]
+pub extern crate core as y_crate;
+
+//@ hasraw foo/index.html z_import
+//@ hasraw search.index/name/*.js z_import
+#[doc(no_inline)]
+pub use core::option as z_import;
+
+//@ has foo/struct.AStruct.html
+//@ hasraw search.index/name/*.js AStruct
+pub struct AStruct {
+    //@ hasraw foo/struct.AStruct.html a_structfield
+    //@ hasraw search.index/name/*.js a_structfield
+    pub a_structfield: i32,
+}
+
+//@ has foo/enum.AEnum.html
+//@ hasraw search.index/name/*.js AEnum
+pub enum AEnum {
+    //@ hasraw foo/enum.AEnum.html AVariant
+    //@ hasraw search.index/name/*.js AVariant
+    AVariant,
+}
+
+//@ has foo/fn.a_fn.html
+//@ hasraw search.index/name/*.js a_fn
+pub fn a_fn() {}
+
+//@ has foo/type.AType.html
+//@ hasraw search.index/name/*.js AType
+pub type AType = AStruct;
+
+//@ has foo/static.a_static.html
+//@ hasraw search.index/name/*.js a_static
+pub static a_static: i32 = 1;
+
+//@ has foo/trait.ATrait.html
+//@ hasraw search.index/name/*.js ATrait
+pub trait ATrait {
+    //@ hasraw foo/trait.ATrait.html a_tymethod
+    //@ hasraw search.index/name/*.js a_tymethod
+    fn a_tymethod();
+    //@ hasraw foo/trait.ATrait.html AAssocType
+    //@ hasraw search.index/name/*.js AAssocType
+    type AAssocType;
+    //@ hasraw foo/trait.ATrait.html AAssocConst
+    //@ hasraw search.index/name/*.js AAssocConst
+    const AAssocConst: bool;
+}
+
+// skip ItemType::Impl, since impls are anonymous
+// and have no search entry
+
+impl AStruct {
+    //@ hasraw foo/struct.AStruct.html a_method
+    //@ hasraw search.index/name/*.js a_method
+    pub fn a_method() {}
+}
+
+//@ has foo/macro.a_macro.html
+//@ hasraw search.index/name/*.js a_macro
+#[macro_export]
+macro_rules! a_macro {
+    () => {};
+}
+
+//@ has foo/constant.A_CONSTANT.html
+//@ hasraw search.index/name/*.js A_CONSTANT
+pub const A_CONSTANT: i32 = 1;
+
+//@ has foo/union.AUnion.html
+//@ hasraw search.index/name/*.js AUnion
+pub union AUnion {
+    //@ hasraw foo/union.AUnion.html a_unionfield
+    //@ hasraw search.index/name/*.js a_unionfield
+    pub a_unionfield: i32,
+}
+
+extern "C" {
+    //@ has foo/foreigntype.AForeignType.html
+    //@ hasraw search.index/name/*.js AForeignType
+    pub type AForeignType;
+}
+
+// procattribute and procderive are defined in
+// bar.rs, because they only work with proc_macro
+// crate type.
+
+//@ has foo/traitalias.ATraitAlias.html
+//@ hasraw search.index/name/*.js ATraitAlias
+pub trait ATraitAlias = ATrait;
+
+//@ has foo/attribute.doc.html
+//@ hasraw search.index/name/*.js doc
+//@ !hasraw search.index/name/*.js aa_mod
+#[doc(attribute = "doc")]
+mod aa_mod {}
diff --git a/tests/run-make/rustdoc-search-load-itemtype/rmake.rs b/tests/run-make/rustdoc-search-load-itemtype/rmake.rs
new file mode 100644
index 00000000000..803eb8a61da
--- /dev/null
+++ b/tests/run-make/rustdoc-search-load-itemtype/rmake.rs
@@ -0,0 +1,21 @@
+//@ ignore-cross-compile
+//@ needs-crate-type: proc-macro
+
+// Test that rustdoc can deserialize a search index with every itemtype.
+// https://github.com/rust-lang/rust/pull/146117
+
+use std::path::Path;
+
+use run_make_support::{htmldocck, rfs, rustdoc, source_root};
+
+fn main() {
+    let out_dir = Path::new("rustdoc-search-load-itemtype");
+
+    rfs::create_dir_all(&out_dir);
+    rustdoc().out_dir(&out_dir).input("foo.rs").run();
+    rustdoc().out_dir(&out_dir).input("bar.rs").arg("--crate-type=proc-macro").run();
+    rustdoc().out_dir(&out_dir).input("baz.rs").run();
+    htmldocck().arg(out_dir).arg("foo.rs").run();
+    htmldocck().arg(out_dir).arg("bar.rs").run();
+    htmldocck().arg(out_dir).arg("baz.rs").run();
+}
diff --git a/tests/run-make/sanitizer-cdylib-link/rmake.rs b/tests/run-make/sanitizer-cdylib-link/rmake.rs
index f9d7fd98789..8ff58594d10 100644
--- a/tests/run-make/sanitizer-cdylib-link/rmake.rs
+++ b/tests/run-make/sanitizer-cdylib-link/rmake.rs
@@ -8,6 +8,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 use run_make_support::{run_fail, rustc};
 
 fn main() {
diff --git a/tests/run-make/sanitizer-dylib-link/rmake.rs b/tests/run-make/sanitizer-dylib-link/rmake.rs
index b43420adc72..bae3240a236 100644
--- a/tests/run-make/sanitizer-dylib-link/rmake.rs
+++ b/tests/run-make/sanitizer-dylib-link/rmake.rs
@@ -7,6 +7,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 use run_make_support::{run_fail, rustc};
 
 fn main() {
diff --git a/tests/run-make/sanitizer-staticlib-link/rmake.rs b/tests/run-make/sanitizer-staticlib-link/rmake.rs
index e38d15a8a3c..dda92626189 100644
--- a/tests/run-make/sanitizer-staticlib-link/rmake.rs
+++ b/tests/run-make/sanitizer-staticlib-link/rmake.rs
@@ -11,6 +11,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run_fail, rustc, static_lib_name};
 
 fn main() {
diff --git a/tests/run-make/separate-link-fail/rmake.rs b/tests/run-make/separate-link-fail/rmake.rs
index b5d5300de68..ba24f777395 100644
--- a/tests/run-make/separate-link-fail/rmake.rs
+++ b/tests/run-make/separate-link-fail/rmake.rs
@@ -11,5 +11,5 @@ fn main() {
         .arg("-Zlink-only")
         .input("foo.rs")
         .run_fail()
-        .assert_stderr_contains("The input does not look like a .rlink file");
+        .assert_stderr_contains("the input does not look like a .rlink file");
 }
diff --git a/tests/rustdoc-gui/scrape-examples-ice-links.goml b/tests/rustdoc-gui/scrape-examples-ice-links.goml
index 1db220e1a32..0a159621935 100644
--- a/tests/rustdoc-gui/scrape-examples-ice-links.goml
+++ b/tests/rustdoc-gui/scrape-examples-ice-links.goml
@@ -4,3 +4,5 @@ wait-for: ".scraped-example-title"
 assert-attribute: (".scraped-example-title a", {"href": "../src/bar/bar.rs.html#2"})
 click: ".scraped-example-title a"
 wait-for-property: ("h1", {"innerText": "bar/\nbar.rs"})
+// Ensure that the `--html-after-content` option was correctly handled.
+assert: "#outer-html"
diff --git a/tests/rustdoc-gui/src/scrape_examples_ice/empty.html b/tests/rustdoc-gui/src/scrape_examples_ice/empty.html
deleted file mode 100644
index 8b137891791..00000000000
--- a/tests/rustdoc-gui/src/scrape_examples_ice/empty.html
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tests/rustdoc-gui/src/scrape_examples_ice/extra.html b/tests/rustdoc-gui/src/scrape_examples_ice/extra.html
new file mode 100644
index 00000000000..e7a420154a6
--- /dev/null
+++ b/tests/rustdoc-gui/src/scrape_examples_ice/extra.html
@@ -0,0 +1 @@
+<span id="outer-html"></span>
diff --git a/tests/rustdoc-gui/src/scrape_examples_ice/src/lib.rs b/tests/rustdoc-gui/src/scrape_examples_ice/src/lib.rs
index b854c7722c9..7d910c6de7d 100644
--- a/tests/rustdoc-gui/src/scrape_examples_ice/src/lib.rs
+++ b/tests/rustdoc-gui/src/scrape_examples_ice/src/lib.rs
@@ -1,5 +1,5 @@
 //@ run-flags:-Zrustdoc-scrape-examples
-//@ compile-flags: --html-after-content empty.html
+//@ compile-flags: --html-after-content extra.html
 pub struct ObscurelyNamedType1;
 
 impl ObscurelyNamedType1 {
diff --git a/tests/rustdoc/sanitizer-option.rs b/tests/rustdoc/sanitizer-option.rs
index 2adf1be51fd..7b0038138f0 100644
--- a/tests/rustdoc/sanitizer-option.rs
+++ b/tests/rustdoc/sanitizer-option.rs
@@ -1,6 +1,6 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-address
-//@ compile-flags: --test -Z sanitizer=address
+//@ compile-flags: --test -Z sanitizer=address -C unsafe-allow-abi-mismatch=sanitizer
 //
 // #43031: Verify that rustdoc passes `-Z` options to rustc. Use an extern
 // function that is provided by the sanitizer runtime, if flag is not passed
diff --git a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs
index b7636d116ec..aef25d057d4 100644
--- a/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs
+++ b/tests/ui/asm/global-asm-isnt-really-a-mir-body.rs
@@ -1,5 +1,7 @@
 //@ revisions: emit_mir instrument cfi
 
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+
 // Make sure we don't try to emit MIR for it.
 //@[emit_mir] compile-flags: --emit=mir
 
diff --git a/tests/ui/codegen/empty-static-libs-issue-108825.rs b/tests/ui/codegen/empty-static-libs-issue-108825.rs
index 4c644be0954..4f8e4420f72 100644
--- a/tests/ui/codegen/empty-static-libs-issue-108825.rs
+++ b/tests/ui/codegen/empty-static-libs-issue-108825.rs
@@ -15,4 +15,4 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
 }
 
 //~? NOTE native-static-libs:
-//~? NOTE Link against the following native artifacts when linking against this static library
+//~? NOTE link against the following native artifacts when linking against this static library
diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
index 0c57eddbe93..cc6a813b747 100644
--- a/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
+++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.32bit.stderr
@@ -14,7 +14,7 @@ error[E0080]: constructing invalid value: encountered 0x42, but expected a boole
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                42                                              │ B
            }
@@ -25,7 +25,7 @@ error[E0080]: constructing invalid value: encountered 0x42, but expected a boole
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                42                                              │ B
            }
diff --git a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
index 0c57eddbe93..cc6a813b747 100644
--- a/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
+++ b/tests/ui/const-generics/min_const_generics/invalid-patterns.64bit.stderr
@@ -14,7 +14,7 @@ error[E0080]: constructing invalid value: encountered 0x42, but expected a boole
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, 'z'>();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                42                                              │ B
            }
@@ -25,7 +25,7 @@ error[E0080]: constructing invalid value: encountered 0x42, but expected a boole
 LL |   get_flag::<{ unsafe { bool_raw.boolean } }, { unsafe { char_raw.character } }>();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                42                                              │ B
            }
diff --git a/tests/ui/const-ptr/forbidden_slices.stderr b/tests/ui/const-ptr/forbidden_slices.stderr
index 25d6f0461a9..70ae00af23f 100644
--- a/tests/ui/const-ptr/forbidden_slices.stderr
+++ b/tests/ui/const-ptr/forbidden_slices.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered a null reference
 LL | pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) };
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value: encountered a null reference
 LL | pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) };
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitializ
 LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -50,7 +50,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -61,7 +61,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but e
 LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -72,7 +72,7 @@ error[E0080]: constructing invalid value at .<deref>[1]: encountered uninitializ
 LL | pub static S7: &[u16] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -83,7 +83,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | pub static S8: &[u64] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -94,7 +94,7 @@ error[E0080]: constructing invalid value: encountered a null reference
 LL | pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -117,7 +117,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitializ
 LL | pub static R4: &[u8] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -130,7 +130,7 @@ LL | pub static R5: &[u8] = unsafe {
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -141,7 +141,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but e
 LL | pub static R6: &[bool] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -152,7 +152,7 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (re
 LL | pub static R7: &[u16] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
index a8c7ee93971..239bca51fc9 100644
--- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered uninitialized
 LL | const BAR: &i32 = unsafe {
    | ^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC0<imm>╼                                     │ ╾──╼
            }
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
index 47e1c22cc2c..3c6d66ac5b6 100644
--- a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered uninitialized
 LL | const BAR: &i32 = unsafe {
    | ^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC0<imm>╼                         │ ╾──────╼
            }
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
index d4039e1952c..152eeababc5 100644
--- a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (use-
 LL | const _X: &'static u8 = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr
index 36183e28921..2861f82ec53 100644
--- a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr
+++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x00000001,
 LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                01 00 00 00                                     │ ....
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x00000000,
 LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                00 00 00 00                                     │ ....
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabi
 LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                01                                              │ .
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabi
 LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                03                                              │ .
            }
@@ -48,7 +48,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0.1: encounter
 LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                78 00 00 00 ff ff ff ff                         │ x.......
            }
@@ -59,7 +59,7 @@ error[E0080]: constructing invalid value: encountered 0, but expected something
 LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                00 00 00 00                                     │ ....
            }
@@ -70,7 +70,7 @@ error[E0080]: constructing invalid value at .0: encountered 0, but expected some
 LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                00                                              │ .
            }
@@ -81,7 +81,7 @@ error[E0080]: constructing invalid value at .0: encountered 0, but expected some
 LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                00 00 00 00                                     │ ....
            }
@@ -92,7 +92,7 @@ error[E0080]: constructing invalid value: encountered 42, but expected something
 LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                2a 00 00 00                                     │ *...
            }
@@ -103,7 +103,7 @@ error[E0080]: constructing invalid value: encountered 20, but expected something
 LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                14 00 00 00                                     │ ....
            }
@@ -114,7 +114,7 @@ error[E0080]: constructing invalid value: encountered 0, but expected something
 LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                00 00 00 00 ╾ALLOC_ID╼                         │ ....╾──╼
            }
@@ -125,7 +125,7 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (re
 LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC_ID╼                                     │ ╾──╼
            }
@@ -136,7 +136,7 @@ error[E0080]: constructing invalid value: encountered an unaligned box (required
 LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC_ID╼                                     │ ╾──╼
            }
@@ -147,7 +147,7 @@ error[E0080]: constructing invalid value: encountered a null reference
 LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                00 00 00 00                                     │ ....
            }
@@ -158,7 +158,7 @@ error[E0080]: constructing invalid value: encountered a null box
 LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                00 00 00 00                                     │ ....
            }
@@ -169,7 +169,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (0x53
 LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                39 05 00 00                                     │ 9...
            }
@@ -180,7 +180,7 @@ error[E0080]: constructing invalid value: encountered a dangling box (0x539[noal
 LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                39 05 00 00                                     │ 9...
            }
@@ -191,7 +191,7 @@ error[E0080]: constructing invalid value: encountered null pointer, but expected
 LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                00 00 00 00                                     │ ....
            }
@@ -202,7 +202,7 @@ error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected
 LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                0d 00 00 00                                     │ ....
            }
@@ -213,7 +213,7 @@ error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected
 LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC_ID╼                                     │ ╾──╼
            }
@@ -224,7 +224,7 @@ error[E0080]: constructing invalid value: encountered a reference pointing to un
 LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                01 00 00 00                                     │ ....
            }
@@ -235,7 +235,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ e7 03 00 00                         │ ╾──╼....
            }
@@ -246,7 +246,7 @@ error[E0080]: constructing invalid value at .0: encountered invalid reference me
 LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ff ff ff ff                         │ ╾──╼....
            }
@@ -257,7 +257,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ff ff ff ff                         │ ╾──╼....
            }
@@ -268,7 +268,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered uninitialized
 LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 01 00 00 00                         │ ╾──╼....
            }
@@ -279,7 +279,7 @@ error[E0080]: constructing invalid value at .<deref>.0: encountered uninitialize
 LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 01 00 00 00                         │ ╾──╼....
            }
@@ -292,7 +292,7 @@ LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 01 00 00 00                         │ ╾──╼....
            }
@@ -303,7 +303,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ e7 03 00 00                         │ ╾──╼....
            }
@@ -314,7 +314,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ff ff ff 7f                         │ ╾──╼....
            }
@@ -325,7 +325,7 @@ error[E0080]: constructing invalid value: encountered a dangling box (going beyo
 LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ e7 03 00 00                         │ ╾──╼....
            }
@@ -336,7 +336,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x03, but e
 LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC_ID╼                                     │ ╾──╼
            }
@@ -353,7 +353,7 @@ error[E0080]: constructing invalid value at .<deref>.0: encountered 0x03, but ex
 LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC_ID╼                                     │ ╾──╼
            }
@@ -370,7 +370,7 @@ error[E0080]: constructing invalid value at .<deref>.1[0]: encountered 0x03, but
 LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC_ID╼                                     │ ╾──╼
            }
@@ -387,7 +387,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC17<imm>, but ex
 LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼                         │ ╾──╼╾──╼
            }
@@ -398,7 +398,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC19<imm>, but ex
 LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼                         │ ╾──╼╾──╼
            }
@@ -409,7 +409,7 @@ error[E0080]: constructing invalid value at .0: encountered 0x4[noalloc], but ex
 LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 04 00 00 00                         │ ╾──╼....
            }
@@ -420,7 +420,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC22<imm>, but ex
 LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼                         │ ╾──╼╾──╼
            }
@@ -431,7 +431,7 @@ error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>: encountered
 LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼                         │ ╾──╼╾──╼
            }
@@ -442,7 +442,7 @@ error[E0080]: constructing invalid value: encountered null pointer, but expected
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 00 00 00 00                         │ ╾──╼....
            }
@@ -453,7 +453,7 @@ error[E0080]: constructing invalid value: encountered ALLOC27<imm>, but expected
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼                         │ ╾──╼╾──╼
            }
@@ -464,7 +464,7 @@ error[E0080]: constructing invalid value: encountered a reference pointing to un
 LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
    | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                01 00 00 00                                     │ ....
            }
@@ -475,7 +475,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of
 LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                01 00 00 00 01 00 00 00                         │ ........
            }
@@ -486,7 +486,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of
 LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                01 00 00 00 2a 00 00 00                         │ ....*...
            }
@@ -497,7 +497,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitializ
 LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 01 00 00 00                         │ ╾──╼....
            }
@@ -510,7 +510,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem:
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 04 00 00 00                         │ ╾──╼....
            }
@@ -521,7 +521,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but e
 LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 04 00 00 00                         │ ╾──╼....
            }
@@ -532,7 +532,7 @@ error[E0080]: constructing invalid value at .<deref>[1]: encountered uninitializ
 LL | pub static S7: &[u16] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID+0x2╼ 04 00 00 00                         │ ╾──╼....
            }
@@ -543,7 +543,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitializ
 LL | pub static R4: &[u8] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 01 00 00 00                         │ ╾──╼....
            }
@@ -556,7 +556,7 @@ LL | pub static R5: &[u8] = unsafe {
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 04 00 00 00                         │ ╾──╼....
            }
@@ -567,7 +567,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but e
 LL | pub static R6: &[bool] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC_ID╼ 04 00 00 00                         │ ╾──╼....
            }
diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr
index c53326534fd..8e6dc66a40e 100644
--- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr
+++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x000000000
 LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                01 00 00 00 00 00 00 00                         │ ........
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x000000000
 LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                00 00 00 00 00 00 00 00                         │ ........
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabi
 LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                01                                              │ .
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabi
 LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                03                                              │ .
            }
@@ -48,7 +48,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0.1: encounter
 LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                78 00 00 00 ff ff ff ff                         │ x.......
            }
@@ -59,7 +59,7 @@ error[E0080]: constructing invalid value: encountered 0, but expected something
 LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                00 00 00 00 00 00 00 00                         │ ........
            }
@@ -70,7 +70,7 @@ error[E0080]: constructing invalid value at .0: encountered 0, but expected some
 LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                00                                              │ .
            }
@@ -81,7 +81,7 @@ error[E0080]: constructing invalid value at .0: encountered 0, but expected some
 LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                00 00 00 00 00 00 00 00                         │ ........
            }
@@ -92,7 +92,7 @@ error[E0080]: constructing invalid value: encountered 42, but expected something
 LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                2a 00 00 00                                     │ *...
            }
@@ -103,7 +103,7 @@ error[E0080]: constructing invalid value: encountered 20, but expected something
 LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                14 00 00 00                                     │ ....
            }
@@ -114,7 +114,7 @@ error[E0080]: constructing invalid value: encountered 0, but expected something
 LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                00 00 00 00 00 00 00 00 ╾ALLOC_ID╼ │ ........╾──────╼
            }
@@ -125,7 +125,7 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (re
 LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC_ID╼                         │ ╾──────╼
            }
@@ -136,7 +136,7 @@ error[E0080]: constructing invalid value: encountered an unaligned box (required
 LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC_ID╼                         │ ╾──────╼
            }
@@ -147,7 +147,7 @@ error[E0080]: constructing invalid value: encountered a null reference
 LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                00 00 00 00 00 00 00 00                         │ ........
            }
@@ -158,7 +158,7 @@ error[E0080]: constructing invalid value: encountered a null box
 LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                00 00 00 00 00 00 00 00                         │ ........
            }
@@ -169,7 +169,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (0x53
 LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                39 05 00 00 00 00 00 00                         │ 9.......
            }
@@ -180,7 +180,7 @@ error[E0080]: constructing invalid value: encountered a dangling box (0x539[noal
 LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                39 05 00 00 00 00 00 00                         │ 9.......
            }
@@ -191,7 +191,7 @@ error[E0080]: constructing invalid value: encountered null pointer, but expected
 LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                00 00 00 00 00 00 00 00                         │ ........
            }
@@ -202,7 +202,7 @@ error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected
 LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                0d 00 00 00 00 00 00 00                         │ ........
            }
@@ -213,7 +213,7 @@ error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected
 LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC_ID╼                         │ ╾──────╼
            }
@@ -224,7 +224,7 @@ error[E0080]: constructing invalid value: encountered a reference pointing to un
 LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                01 00 00 00 00 00 00 00                         │ ........
            }
@@ -235,7 +235,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -246,7 +246,7 @@ error[E0080]: constructing invalid value at .0: encountered invalid reference me
 LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........
            }
@@ -257,7 +257,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........
            }
@@ -268,7 +268,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered uninitialized
 LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -279,7 +279,7 @@ error[E0080]: constructing invalid value at .<deref>.0: encountered uninitialize
 LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -292,7 +292,7 @@ LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -303,7 +303,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -314,7 +314,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ff ff ff ff ff ff ff 7f │ ╾──────╼........
            }
@@ -325,7 +325,7 @@ error[E0080]: constructing invalid value: encountered a dangling box (going beyo
 LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -336,7 +336,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x03, but e
 LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC_ID╼                         │ ╾──────╼
            }
@@ -353,7 +353,7 @@ error[E0080]: constructing invalid value at .<deref>.0: encountered 0x03, but ex
 LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC_ID╼                         │ ╾──────╼
            }
@@ -370,7 +370,7 @@ error[E0080]: constructing invalid value at .<deref>.1[0]: encountered 0x03, but
 LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC_ID╼                         │ ╾──────╼
            }
@@ -387,7 +387,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC17<imm>, but ex
 LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
            }
@@ -398,7 +398,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC19<imm>, but ex
 LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
            }
@@ -409,7 +409,7 @@ error[E0080]: constructing invalid value at .0: encountered 0x4[noalloc], but ex
 LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -420,7 +420,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC22<imm>, but ex
 LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
            }
@@ -431,7 +431,7 @@ error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>: encountered
 LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
            }
@@ -442,7 +442,7 @@ error[E0080]: constructing invalid value: encountered null pointer, but expected
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -453,7 +453,7 @@ error[E0080]: constructing invalid value: encountered ALLOC27<imm>, but expected
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
            }
@@ -464,7 +464,7 @@ error[E0080]: constructing invalid value: encountered a reference pointing to un
 LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
    | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                01 00 00 00 00 00 00 00                         │ ........
            }
@@ -475,7 +475,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of
 LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ ................
            }
@@ -486,7 +486,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of
 LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                01 00 00 00 00 00 00 00 2a 00 00 00 00 00 00 00 │ ........*.......
            }
@@ -497,7 +497,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitializ
 LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -510,7 +510,7 @@ LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem:
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -521,7 +521,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but e
 LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -532,7 +532,7 @@ error[E0080]: constructing invalid value at .<deref>[1]: encountered uninitializ
 LL | pub static S7: &[u16] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID+0x2╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -543,7 +543,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered uninitializ
 LL | pub static R4: &[u8] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -556,7 +556,7 @@ LL | pub static R5: &[u8] = unsafe {
    |
    = 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
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........
            }
@@ -567,7 +567,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x11, but e
 LL | pub static R6: &[bool] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
            }
diff --git a/tests/ui/consts/const-eval/transmute-const.stderr b/tests/ui/consts/const-eval/transmute-const.stderr
index ed3b3df70dd..53665c176a7 100644
--- a/tests/ui/consts/const-eval/transmute-const.stderr
+++ b/tests/ui/consts/const-eval/transmute-const.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered 0x03, but expected a boole
 LL | static FOO: bool = unsafe { mem::transmute(3u8) };
    | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                03                                              │ .
            }
diff --git a/tests/ui/consts/const-eval/ub-enum.stderr b/tests/ui/consts/const-eval/ub-enum.stderr
index 5cbd6176c92..1efd9383229 100644
--- a/tests/ui/consts/const-eval/ub-enum.stderr
+++ b/tests/ui/consts/const-eval/ub-enum.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x01, but e
 LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -33,7 +33,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered 0x0, but ex
 LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -81,7 +81,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabi
 LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -92,7 +92,7 @@ error[E0080]: constructing invalid value at .<enum-tag>: encountered an uninhabi
 LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -103,7 +103,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0.1: encounter
 LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr b/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
index 86d6f8c52bc..1e4d425d78e 100644
--- a/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
+++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered ALLOC1<imm>, but expected
 LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC0<imm>╼ ╾ALLOC1<imm>╼                         │ ╾──╼╾──╼
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected
 LL | const INVALID_VTABLE_SIZE: &dyn Trait =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC2<imm>╼ ╾ALLOC3<imm>╼                         │ ╾──╼╾──╼
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC5<imm>, but exp
 LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼                         │ ╾──╼╾──╼
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC7<imm>, but exp
 LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC6<imm>╼ ╾ALLOC7<imm>╼                         │ ╾──╼╾──╼
            }
@@ -48,7 +48,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC9<imm>, but exp
 LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC8<imm>╼ ╾ALLOC9<imm>╼                         │ ╾──╼╾──╼
            }
@@ -59,7 +59,7 @@ error[E0080]: constructing invalid value at .1: encountered a dangling reference
 LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC10<imm>╼ ╾ALLOC11╼                         │ ╾──╼╾──╼
            }
diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr b/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
index a9518216dbd..a068991f324 100644
--- a/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
+++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered ALLOC1<imm>, but expected
 LL | const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC0<imm>╼ ╾ALLOC1<imm>╼ │ ╾──────╼╾──────╼
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value: encountered ALLOC3<imm>, but expected
 LL | const INVALID_VTABLE_SIZE: &dyn Trait =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC2<imm>╼ ╾ALLOC3<imm>╼ │ ╾──────╼╾──────╼
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC5<imm>, but exp
 LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC4<imm>╼ ╾ALLOC5<imm>╼ │ ╾──────╼╾──────╼
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC7<imm>, but exp
 LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC6<imm>╼ ╾ALLOC7<imm>╼ │ ╾──────╼╾──────╼
            }
@@ -48,7 +48,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC9<imm>, but exp
 LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC8<imm>╼ ╾ALLOC9<imm>╼ │ ╾──────╼╾──────╼
            }
@@ -59,7 +59,7 @@ error[E0080]: constructing invalid value at .1: encountered a dangling reference
 LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC10<imm>╼ ╾ALLOC11╼ │ ╾──────╼╾──────╼
            }
diff --git a/tests/ui/consts/const-eval/ub-int-array.stderr b/tests/ui/consts/const-eval/ub-int-array.stderr
index 10eb7c46c92..065bfd2c304 100644
--- a/tests/ui/consts/const-eval/ub-int-array.stderr
+++ b/tests/ui/consts/const-eval/ub-int-array.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at [0]: encountered uninitialized memor
 LL | const UNINIT_INT_0: [u32; 3] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 12, align: 4) {
                __ __ __ __ 11 11 11 11 22 22 22 22             │ ░░░░....""""
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value at [1]: encountered uninitialized memor
 LL | const UNINIT_INT_1: [u32; 3] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 12, align: 4) {
                00 00 00 00 01 __ 01 01 02 02 __ 02             │ .....░....░.
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at [2]: encountered uninitialized memor
 LL | const UNINIT_INT_2: [u32; 3] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 12, align: 4) {
                00 00 00 00 01 01 01 01 02 02 02 __             │ ...........░
            }
diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr
index 19ae66cf3c6..91c82efbc5e 100644
--- a/tests/ui/consts/const-eval/ub-nonnull.stderr
+++ b/tests/ui/consts/const-eval/ub-nonnull.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered 0, but expected something
 LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -21,7 +21,7 @@ error[E0080]: constructing invalid value at .0: encountered 0, but expected some
 LL | const NULL_U8: NonZero<u8> = unsafe { mem::transmute(0u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -32,7 +32,7 @@ error[E0080]: constructing invalid value at .0: encountered 0, but expected some
 LL | const NULL_USIZE: NonZero<usize> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -53,7 +53,7 @@ error[E0080]: constructing invalid value: encountered 42, but expected something
 LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -64,7 +64,7 @@ error[E0080]: constructing invalid value: encountered 20, but expected something
 LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -75,7 +75,7 @@ error[E0080]: constructing invalid value: encountered 0, but expected something
 LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
index 451ebb6eba1..c45f66c2925 100644
--- a/tests/ui/consts/const-eval/ub-ref-ptr.stderr
+++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered an unaligned reference (re
 LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value: encountered an unaligned box (required
 LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value: encountered a null reference
 LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value: encountered a null box
 LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -87,7 +87,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (0x53
 LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -98,7 +98,7 @@ error[E0080]: constructing invalid value: encountered a dangling box (0x539[noal
 LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -119,7 +119,7 @@ error[E0080]: constructing invalid value: encountered null pointer, but expected
 LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -140,7 +140,7 @@ error[E0080]: constructing invalid value: encountered 0xd[noalloc], but expected
 LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -151,7 +151,7 @@ error[E0080]: constructing invalid value: encountered ALLOC2<imm>, but expected
 LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-eval/ub-uninhabit.stderr b/tests/ui/consts/const-eval/ub-uninhabit.stderr
index b0f475fe938..aca0b13bb90 100644
--- a/tests/ui/consts/const-eval/ub-uninhabit.stderr
+++ b/tests/ui/consts/const-eval/ub-uninhabit.stderr
@@ -10,7 +10,7 @@ error[E0080]: constructing invalid value: encountered a reference pointing to un
 LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-eval/ub-upvars.32bit.stderr b/tests/ui/consts/const-eval/ub-upvars.32bit.stderr
index ecd1c768c28..b434970b677 100644
--- a/tests/ui/consts/const-eval/ub-upvars.32bit.stderr
+++ b/tests/ui/consts/const-eval/ub-upvars.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>.<captured-va
 LL | const BAD_UPVAR: &dyn FnOnce() = &{
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC0<imm>╼ ╾ALLOC1╼                         │ ╾──╼╾──╼
            }
diff --git a/tests/ui/consts/const-eval/ub-upvars.64bit.stderr b/tests/ui/consts/const-eval/ub-upvars.64bit.stderr
index 108dfe6b27b..de1e1f8a2be 100644
--- a/tests/ui/consts/const-eval/ub-upvars.64bit.stderr
+++ b/tests/ui/consts/const-eval/ub-upvars.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>.<captured-va
 LL | const BAD_UPVAR: &dyn FnOnce() = &{
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC0<imm>╼ ╾ALLOC1╼ │ ╾──────╼╾──────╼
            }
diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr
index ab15ba826a5..c505e5cc8a2 100644
--- a/tests/ui/consts/const-eval/ub-wide-ptr.stderr
+++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value at .0: encountered invalid reference me
 LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -44,7 +44,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -55,7 +55,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered uninitialized
 LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -66,7 +66,7 @@ error[E0080]: constructing invalid value at .<deref>.0: encountered uninitialize
 LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -87,7 +87,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (goin
 LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -98,7 +98,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -118,7 +118,7 @@ error[E0080]: constructing invalid value: encountered a dangling box (going beyo
 LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -138,7 +138,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered 0x03, but e
 LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -155,7 +155,7 @@ error[E0080]: constructing invalid value at .<deref>.0: encountered 0x03, but ex
 LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -172,7 +172,7 @@ error[E0080]: constructing invalid value at .<deref>.1[0]: encountered 0x03, but
 LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -199,7 +199,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC12<imm>, but ex
 LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -210,7 +210,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC14<imm>, but ex
 LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -221,7 +221,7 @@ error[E0080]: constructing invalid value at .0: encountered 0x4[noalloc], but ex
 LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -232,7 +232,7 @@ error[E0080]: constructing invalid value: encountered ALLOC17<imm>, but expected
 LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -243,7 +243,7 @@ error[E0080]: constructing invalid value: encountered ALLOC19<imm>, but expected
 LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -254,7 +254,7 @@ error[E0080]: constructing invalid value: encountered ALLOC21<imm>, but expected
 LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -265,7 +265,7 @@ error[E0080]: constructing invalid value at .0: encountered ALLOC23<imm>, but ex
 LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -276,7 +276,7 @@ error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>: encountered
 LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -287,7 +287,7 @@ error[E0080]: constructing invalid value: encountered null pointer, but expected
 LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -298,7 +298,7 @@ error[E0080]: constructing invalid value: encountered ALLOC28<imm>, but expected
 LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -309,7 +309,7 @@ error[E0080]: constructing invalid value: encountered null pointer, but expected
 LL | static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -320,7 +320,7 @@ error[E0080]: constructing invalid value: encountered ALLOC31<imm>, but expected
 LL | static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-eval/union-ub.32bit.stderr b/tests/ui/consts/const-eval/union-ub.32bit.stderr
index 757bcea91c3..fb2311b9921 100644
--- a/tests/ui/consts/const-eval/union-ub.32bit.stderr
+++ b/tests/ui/consts/const-eval/union-ub.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered 0x2a, but expected a boole
 LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                2a                                              │ *
            }
diff --git a/tests/ui/consts/const-eval/union-ub.64bit.stderr b/tests/ui/consts/const-eval/union-ub.64bit.stderr
index 757bcea91c3..fb2311b9921 100644
--- a/tests/ui/consts/const-eval/union-ub.64bit.stderr
+++ b/tests/ui/consts/const-eval/union-ub.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered 0x2a, but expected a boole
 LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool };
    | ^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 1, align: 1) {
                2a                                              │ *
            }
diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr
index 16dee44d800..08656776468 100644
--- a/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr
+++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final.stderr
@@ -34,7 +34,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | const IMMUT_MUT_REF: &mut u16 = unsafe { mem::transmute(&13) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -45,7 +45,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | static IMMUT_MUT_REF_STATIC: &mut u16 = unsafe { mem::transmute(&13) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
index 302e342bce6..96263998ad4 100644
--- a/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
+++ b/tests/ui/consts/const-mut-refs/mut_ref_in_final_dynamic_check.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered
 LL | const MUT: Option<&mut i32> = helper();
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered
 LL | const INT2PTR: Option<&mut i32> = helper_int2ptr();
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered
 LL | static INT2PTR_STATIC: Option<&mut i32> = helper_int2ptr();
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered
 LL | const DANGLING: Option<&mut i32> = helper_dangling();
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -48,7 +48,7 @@ error[E0080]: constructing invalid value at .<enum-variant(Some)>.0: encountered
 LL | static DANGLING_STATIC: Option<&mut i32> = helper_dangling();
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr
index 8be8b4bc50f..f9088c318a6 100644
--- a/tests/ui/consts/const_refs_to_static_fail_invalid.stderr
+++ b/tests/ui/consts/const_refs_to_static_fail_invalid.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered 0x0a, but expe
 LL |     const C: &bool = unsafe { std::mem::transmute(&S) };
    |     ^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/dangling-alloc-id-ice.stderr b/tests/ui/consts/dangling-alloc-id-ice.stderr
index 65a46b62dae..4b034c81a61 100644
--- a/tests/ui/consts/dangling-alloc-id-ice.stderr
+++ b/tests/ui/consts/dangling-alloc-id-ice.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (use-
 LL | const FOO: &() = {
    | ^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/dangling-zst-ice-issue-126393.stderr b/tests/ui/consts/dangling-zst-ice-issue-126393.stderr
index 2f600e494c4..248db694d52 100644
--- a/tests/ui/consts/dangling-zst-ice-issue-126393.stderr
+++ b/tests/ui/consts/dangling-zst-ice-issue-126393.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered a dangling reference (use-
 LL | pub static MAGIC_FFI_REF: &'static Wrapper = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/interior-mut-const-via-union.32bit.stderr b/tests/ui/consts/interior-mut-const-via-union.32bit.stderr
index 47bb2e5e879..17b32383912 100644
--- a/tests/ui/consts/interior-mut-const-via-union.32bit.stderr
+++ b/tests/ui/consts/interior-mut-const-via-union.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>.y.<enum-variant(B)>.0: enco
 LL | fn main() {
    | ^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC0╼                                     │ ╾──╼
            }
diff --git a/tests/ui/consts/interior-mut-const-via-union.64bit.stderr b/tests/ui/consts/interior-mut-const-via-union.64bit.stderr
index b4c9a4bd47e..c4f78e7bf9e 100644
--- a/tests/ui/consts/interior-mut-const-via-union.64bit.stderr
+++ b/tests/ui/consts/interior-mut-const-via-union.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>.y.<enum-variant(B)>.0: enco
 LL | fn main() {
    | ^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC0╼                         │ ╾──────╼
            }
diff --git a/tests/ui/consts/issue-17718-const-bad-values.stderr b/tests/ui/consts/issue-17718-const-bad-values.stderr
index 68d1a72b71e..2c54200c8a2 100644
--- a/tests/ui/consts/issue-17718-const-bad-values.stderr
+++ b/tests/ui/consts/issue-17718-const-bad-values.stderr
@@ -14,7 +14,7 @@ error[E0080]: constructing invalid value: encountered mutable reference in `cons
 LL | const C2: &'static mut i32 = unsafe { &mut S };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $PTR, align: $PTR) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/issue-63952.32bit.stderr b/tests/ui/consts/issue-63952.32bit.stderr
index e5340788167..cf97ed6e487 100644
--- a/tests/ui/consts/issue-63952.32bit.stderr
+++ b/tests/ui/consts/issue-63952.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const SLICE_WAY_TOO_LONG: &[u8] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                ╾ALLOC0<imm>╼ ff ff ff ff                         │ ╾──╼....
            }
diff --git a/tests/ui/consts/issue-63952.64bit.stderr b/tests/ui/consts/issue-63952.64bit.stderr
index 27e74833fc5..4cea967314c 100644
--- a/tests/ui/consts/issue-63952.64bit.stderr
+++ b/tests/ui/consts/issue-63952.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered invalid reference metadata
 LL | const SLICE_WAY_TOO_LONG: &[u8] = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC0<imm>╼ ff ff ff ff ff ff ff ff │ ╾──────╼........
            }
diff --git a/tests/ui/consts/issue-79690.64bit.stderr b/tests/ui/consts/issue-79690.64bit.stderr
index 7488f7b7752..2653ff22f12 100644
--- a/tests/ui/consts/issue-79690.64bit.stderr
+++ b/tests/ui/consts/issue-79690.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .1: encountered a dangling reference
 LL | const G: Fat = unsafe { Transmute { t: FOO }.u };
    | ^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 16, align: 8) {
                ╾ALLOC0<imm>╼ ╾ALLOC1╼ │ ╾──────╼╾──────╼
            }
diff --git a/tests/ui/consts/miri_unleashed/mutable_references.stderr b/tests/ui/consts/miri_unleashed/mutable_references.stderr
index 137efde44b3..b35076b669e 100644
--- a/tests/ui/consts/miri_unleashed/mutable_references.stderr
+++ b/tests/ui/consts/miri_unleashed/mutable_references.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>: encountered mutable refere
 LL | static FOO: &&mut u32 = &&mut 42;
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | static OH_YES: &mut i32 = &mut 42;
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -38,7 +38,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | const BLUNT: &mut i32 = &mut 42;
    | ^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -49,7 +49,7 @@ error[E0080]: constructing invalid value: encountered mutable reference in `cons
 LL | const SUBTLE: &mut i32 = unsafe {
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -60,7 +60,7 @@ error[E0080]: constructing invalid value at .x.<deref>: encountered `UnsafeCell`
 LL | static MEH: Meh = Meh { x: &UnsafeCell::new(42) };
    | ^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -71,7 +71,7 @@ error[E0080]: constructing invalid value at .x.<deref>: encountered `UnsafeCell`
 LL | const MUH: Meh = Meh {
    | ^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -82,7 +82,7 @@ error[E0080]: constructing invalid value at .<deref>.<dyn-downcast>.x: encounter
 LL | const SNEAKY: &dyn Sync = &Synced { x: UnsafeCell::new(42) };
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -93,7 +93,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | static mut MUT_TO_READONLY: &mut i32 = unsafe { &mut *(&READONLY as *const _ as *mut _) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr b/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr
index 1ef20689985..d7c668a9812 100644
--- a/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr
+++ b/tests/ui/consts/miri_unleashed/static-no-inner-mut.32bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell`
 LL | static REF: &AtomicI32 = &AtomicI32::new(42);
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC0╼                                     │ ╾──╼
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | static REFMUT: &mut i32 = &mut 0;
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC1╼                                     │ ╾──╼
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell`
 LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC2╼                                     │ ╾──╼
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                ╾ALLOC3╼                                     │ ╾──╼
            }
diff --git a/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr b/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr
index 06f78e679b1..f3bb49900b5 100644
--- a/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr
+++ b/tests/ui/consts/miri_unleashed/static-no-inner-mut.64bit.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell`
 LL | static REF: &AtomicI32 = &AtomicI32::new(42);
    | ^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC0╼                         │ ╾──────╼
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | static REFMUT: &mut i32 = &mut 0;
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC1╼                         │ ╾──────╼
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .<deref>.v: encountered `UnsafeCell`
 LL | static REF2: &AtomicI32 = {let x = AtomicI32::new(42); &{x}};
    | ^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC2╼                         │ ╾──────╼
            }
@@ -37,7 +37,7 @@ error[E0080]: constructing invalid value: encountered mutable reference or box p
 LL | static REFMUT2: &mut i32 = {let mut x = 0; &mut {x}};
    | ^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 8) {
                ╾ALLOC3╼                         │ ╾──────╼
            }
diff --git a/tests/ui/consts/validate_never_arrays.stderr b/tests/ui/consts/validate_never_arrays.stderr
index 0f503df4060..3c405e8d3cd 100644
--- a/tests/ui/consts/validate_never_arrays.stderr
+++ b/tests/ui/consts/validate_never_arrays.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered a reference pointing to un
 LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
    | ^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -15,7 +15,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of
 LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
@@ -26,7 +26,7 @@ error[E0080]: constructing invalid value at .<deref>[0]: encountered a value of
 LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
    | ^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/drop/if-let-super-let.rs b/tests/ui/drop/if-let-super-let.rs
new file mode 100644
index 00000000000..c6543e6d3dc
--- /dev/null
+++ b/tests/ui/drop/if-let-super-let.rs
@@ -0,0 +1,112 @@
+//! Test for #145328: ensure the lifetime of a `super let` binding within an `if let` scrutinee is
+//! at most the scope of the `if` condition's temporaries. Additionally, test `pin!` since it's
+//! implemented in terms of `super let` and exposes this behavior.
+//@ run-pass
+//@ revisions: e2021 e2024
+//@ [e2021] edition: 2021
+//@ [e2024] edition: 2024
+
+#![feature(if_let_guard)]
+#![feature(super_let)]
+#![expect(irrefutable_let_patterns)]
+
+use std::cell::RefCell;
+use std::pin::pin;
+
+fn main() {
+    // The `super let` bindings here should have the same scope as `if let` temporaries.
+    // In Rust 2021, this means it lives past the end of the `if` expression.
+    // In Rust 2024, this means it lives to the end of the `if`'s success block.
+    assert_drop_order(0..=2, |o| {
+        #[cfg(e2021)]
+        (
+            if let _ = { super let _x = o.log(2); } { o.push(0) },
+            o.push(1),
+        );
+        #[cfg(e2024)]
+        (
+            if let _ = { super let _x = o.log(1); } { o.push(0) },
+            o.push(2),
+        );
+    });
+    assert_drop_order(0..=2, |o| {
+        #[cfg(e2021)]
+        (
+            if let true = { super let _x = o.log(2); false } {} else { o.push(0) },
+            o.push(1),
+        );
+        #[cfg(e2024)]
+        (
+            if let true = { super let _x = o.log(0); false } {} else { o.push(1) },
+            o.push(2),
+        );
+    });
+
+    // `pin!` should behave likewise.
+    assert_drop_order(0..=2, |o| {
+        #[cfg(e2021)] (if let _ = pin!(o.log(2)) { o.push(0) }, o.push(1));
+        #[cfg(e2024)] (if let _ = pin!(o.log(1)) { o.push(0) }, o.push(2));
+    });
+    assert_drop_order(0..=2, |o| {
+        #[cfg(e2021)]
+        (
+            if let None = Some(pin!(o.log(2))) {} else { o.push(0) },
+            o.push(1),
+        );
+        #[cfg(e2024)]
+        (
+            if let None = Some(pin!(o.log(0))) {} else { o.push(1) },
+            o.push(2),
+        );
+    });
+
+    // `super let` bindings' scope should also be consistent with `if let` temporaries in guards.
+    // Here, that means the `super let` binding in the second guard condition operand should be
+    // dropped before the first operand's temporary. This is consistent across Editions.
+    assert_drop_order(0..=1, |o| {
+        match () {
+            _ if let _ = o.log(1)
+                && let _ = { super let _x = o.log(0); } => {}
+            _ => unreachable!(),
+        }
+    });
+    assert_drop_order(0..=1, |o| {
+        match () {
+            _ if let _ = o.log(1)
+                && let _ = pin!(o.log(0)) => {}
+            _ => unreachable!(),
+        }
+    });
+}
+
+// # Test scaffolding...
+
+struct DropOrder(RefCell<Vec<u64>>);
+struct LogDrop<'o>(&'o DropOrder, u64);
+
+impl DropOrder {
+    fn log(&self, n: u64) -> LogDrop<'_> {
+        LogDrop(self, n)
+    }
+    fn push(&self, n: u64) {
+        self.0.borrow_mut().push(n);
+    }
+}
+
+impl<'o> Drop for LogDrop<'o> {
+    fn drop(&mut self) {
+        self.0.push(self.1);
+    }
+}
+
+#[track_caller]
+fn assert_drop_order(
+    ex: impl IntoIterator<Item = u64>,
+    f: impl Fn(&DropOrder),
+) {
+    let order = DropOrder(RefCell::new(Vec::new()));
+    f(&order);
+    let order = order.0.into_inner();
+    let expected: Vec<u64> = ex.into_iter().collect();
+    assert_eq!(order, expected);
+}
diff --git a/tests/ui/feature-gates/feature-gate-target-feature-inline-always.rs b/tests/ui/feature-gates/feature-gate-target-feature-inline-always.rs
new file mode 100644
index 00000000000..181f9a21000
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-target-feature-inline-always.rs
@@ -0,0 +1,9 @@
+//@ only-aarch64
+#[inline(always)]
+//~^ ERROR cannot use `#[inline(always)]` with `#[target_feature]`
+#[target_feature(enable="fp16")]
+fn test() {
+
+}
+
+fn main() { }
diff --git a/tests/ui/feature-gates/feature-gate-target-feature-inline-always.stderr b/tests/ui/feature-gates/feature-gate-target-feature-inline-always.stderr
new file mode 100644
index 00000000000..de54844bc29
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-target-feature-inline-always.stderr
@@ -0,0 +1,13 @@
+error[E0658]: cannot use `#[inline(always)]` with `#[target_feature]`
+  --> $DIR/feature-gate-target-feature-inline-always.rs:2:1
+   |
+LL | #[inline(always)]
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #145574 <https://github.com/rust-lang/rust/issues/145574> for more information
+   = help: add `#![feature(target_feature_inline_always)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed
index b58c3a6720d..14d5de0261d 100644
--- a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed
+++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.fixed
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![deny(unused_assignments, unused_variables)]
+#![deny(unused_assignments)]
 #![allow(unused_mut)]
 struct Object;
 
@@ -8,15 +8,15 @@ fn change_object(object: &mut Object) { //~ HELP you might have meant to mutate
    *object = object2; //~ ERROR mismatched types
 }
 
-fn change_object2(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
-   //~^ HELP you might have meant to mutate
+fn change_object2(object: &mut Object) {
+    //~^ HELP you might have meant to mutate
    let object2 = Object;
    *object = object2;
    //~^ ERROR `object2` does not live long enough
    //~| ERROR value assigned to `object` is never read
 }
 
-fn change_object3(object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
+fn change_object3(object: &mut Object) {
     //~^ HELP you might have meant to mutate
     let mut object2 = Object; //~ HELP consider changing this to be mutable
     *object = object2;
diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs
index 1fd222e0db1..5805afb3369 100644
--- a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs
+++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs
@@ -1,5 +1,5 @@
 //@ run-rustfix
-#![deny(unused_assignments, unused_variables)]
+#![deny(unused_assignments)]
 #![allow(unused_mut)]
 struct Object;
 
@@ -8,15 +8,15 @@ fn change_object(mut object: &Object) { //~ HELP you might have meant to mutate
    object = object2; //~ ERROR mismatched types
 }
 
-fn change_object2(mut object: &Object) { //~ ERROR variable `object` is assigned to, but never used
-   //~^ HELP you might have meant to mutate
+fn change_object2(mut object: &Object) {
+    //~^ HELP you might have meant to mutate
    let object2 = Object;
    object = &object2;
    //~^ ERROR `object2` does not live long enough
    //~| ERROR value assigned to `object` is never read
 }
 
-fn change_object3(mut object: &mut Object) { //~ ERROR variable `object` is assigned to, but never used
+fn change_object3(mut object: &mut Object) {
     //~^ HELP you might have meant to mutate
     let object2 = Object; //~ HELP consider changing this to be mutable
     object = &mut object2;
diff --git a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr
index 0330853d922..c2c7378f07a 100644
--- a/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr
+++ b/tests/ui/fn/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.stderr
@@ -23,7 +23,7 @@ LL |    object = &object2;
 note: the lint level is defined here
   --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:9
    |
-LL | #![deny(unused_assignments, unused_variables)]
+LL | #![deny(unused_assignments)]
    |         ^^^^^^^^^^^^^^^^^^
 help: you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
    |
@@ -33,19 +33,6 @@ LL |    let object2 = Object;
 LL ~    *object = object2;
    |
 
-error: variable `object` is assigned to, but never used
-  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:11:23
-   |
-LL | fn change_object2(mut object: &Object) {
-   |                       ^^^^^^
-   |
-   = note: consider using `_object` instead
-note: the lint level is defined here
-  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:2:29
-   |
-LL | #![deny(unused_assignments, unused_variables)]
-   |                             ^^^^^^^^^^^^^^^^
-
 error[E0597]: `object2` does not live long enough
   --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:14:13
    |
@@ -77,14 +64,6 @@ LL |     let object2 = Object;
 LL ~     *object = object2;
    |
 
-error: variable `object` is assigned to, but never used
-  --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:19:23
-   |
-LL | fn change_object3(mut object: &mut Object) {
-   |                       ^^^^^^
-   |
-   = note: consider using `_object` instead
-
 error[E0596]: cannot borrow `object2` as mutable, as it is not declared as mutable
   --> $DIR/mut-arg-of-borrowed-type-meant-to-be-arg-of-mut-borrow.rs:22:14
    |
@@ -96,7 +75,7 @@ help: consider changing this to be mutable
 LL |     let mut object2 = Object;
    |         +++
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0308, E0596, E0597.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs
index 0c78d799bad..f5f92db3b50 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs
@@ -11,4 +11,4 @@ pub fn lib_main() {
     unsafe { f(42); }
 }
 
-//~? ERROR Error calling dlltool 'does_not_exist.exe': program not found
+//~? ERROR error calling dlltool 'does_not_exist.exe': program not found
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr
index 4bbad9b30a7..311d8c61589 100644
--- a/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr
@@ -1,4 +1,4 @@
-error: Error calling dlltool 'does_not_exist.exe': program not found
+error: error calling dlltool 'does_not_exist.exe': program not found
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/linking/mixed-allocator-shim.rs b/tests/ui/linking/mixed-allocator-shim.rs
new file mode 100644
index 00000000000..e4f20a11ebb
--- /dev/null
+++ b/tests/ui/linking/mixed-allocator-shim.rs
@@ -0,0 +1,16 @@
+//@ build-pass
+//@ compile-flags: --crate-type staticlib,dylib -Zstaticlib-prefer-dynamic
+//@ no-prefer-dynamic
+//@ needs-crate-type: dylib
+
+// Test that compiling for multiple crate types in a single compilation with
+// mismatching allocator shim requirements doesn't result in the allocator shim
+// missing entirely.
+// In this particular test the dylib crate type will statically link libstd and
+// thus need an allocator shim, while the staticlib crate type will dynamically
+// link libstd and thus not need an allocator shim.
+// The -Zstaticlib-prefer-dynamic flag could be avoided by doing it the other
+// way around, but testing that the staticlib correctly has the allocator shim
+// in that case would require a run-make test instead.
+
+pub fn foo() {}
diff --git a/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr b/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr
index b0c56003957..e5f2e65fd91 100644
--- a/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr
+++ b/tests/ui/lint/non-snake-case/lint-uppercase-variables.stderr
@@ -16,7 +16,7 @@ warning: unused variable: `Foo`
   --> $DIR/lint-uppercase-variables.rs:22:9
    |
 LL |         Foo => {}
-   |         ^^^ help: if this is intentional, prefix it with an underscore: `_Foo`
+   |         ^^^
    |
 note: the lint level is defined here
   --> $DIR/lint-uppercase-variables.rs:1:9
@@ -24,12 +24,29 @@ note: the lint level is defined here
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unused_variables)]` implied by `#[warn(unused)]`
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         _Foo => {}
+   |         +
+help: you might have meant to pattern match on the similarly named variant `Foo`
+   |
+LL |         foo::Foo::Foo => {}
+   |         ++++++++++
 
 warning: unused variable: `Foo`
   --> $DIR/lint-uppercase-variables.rs:28:9
    |
 LL |     let Foo = foo::Foo::Foo;
-   |         ^^^ help: if this is intentional, prefix it with an underscore: `_Foo`
+   |         ^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |     let _Foo = foo::Foo::Foo;
+   |         +
+help: you might have meant to pattern match on the similarly named variant `Foo`
+   |
+LL |     let foo::Foo::Foo = foo::Foo::Foo;
+   |         ++++++++++
 
 error[E0170]: pattern binding `Foo` is named the same as one of the variants of the type `foo::Foo`
   --> $DIR/lint-uppercase-variables.rs:33:17
@@ -41,7 +58,16 @@ warning: unused variable: `Foo`
   --> $DIR/lint-uppercase-variables.rs:33:17
    |
 LL |     fn in_param(Foo: foo::Foo) {}
-   |                 ^^^ help: if this is intentional, prefix it with an underscore: `_Foo`
+   |                 ^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |     fn in_param(_Foo: foo::Foo) {}
+   |                 +
+help: you might have meant to pattern match on the similarly named variant `Foo`
+   |
+LL |     fn in_param(foo::Foo::Foo: foo::Foo) {}
+   |                 ++++++++++
 
 error: structure field `X` should have a snake case name
   --> $DIR/lint-uppercase-variables.rs:10:5
diff --git a/tests/ui/lto/issue-100772.rs b/tests/ui/lto/issue-100772.rs
index 29ec5b9bf96..9468e20894a 100644
--- a/tests/ui/lto/issue-100772.rs
+++ b/tests/ui/lto/issue-100772.rs
@@ -1,6 +1,6 @@
 //@ build-pass
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
 
diff --git a/tests/ui/or-patterns/binding-typo-2.rs b/tests/ui/or-patterns/binding-typo-2.rs
new file mode 100644
index 00000000000..275b68a22e2
--- /dev/null
+++ b/tests/ui/or-patterns/binding-typo-2.rs
@@ -0,0 +1,122 @@
+// Issue #51976
+#![deny(unused_variables)] //~ NOTE: the lint level is defined here
+enum Lol {
+    Foo,
+    Bar,
+}
+const Bat: () = ();
+const Battery: () = ();
+struct Bay;
+
+fn foo(x: (Lol, Lol)) {
+    use Lol::*;
+    match &x {
+        (Foo, Bar) | (Ban, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named previously used binding `Bar`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        //~| ERROR: variable `Ban` is assigned to, but never used
+        //~| NOTE: consider using `_Ban` instead
+        //~| HELP: you might have meant to pattern match on the similarly named
+        _ => {}
+    }
+    match &x {
+        (Foo, _) | (Ban, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named unit variant `Bar`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        //~| ERROR: variable `Ban` is assigned to, but never used
+        //~| NOTE: consider using `_Ban` instead
+        //~| HELP: you might have meant to pattern match on the similarly named
+        _ => {}
+    }
+    match Some(42) {
+        Some(_) => {}
+        Non => {}
+        //~^ ERROR: unused variable: `Non`
+        //~| HELP: if this is intentional, prefix it with an underscore
+        //~| HELP: you might have meant to pattern match on the similarly named
+    }
+    match Some(42) {
+        Some(_) => {}
+        Non | None => {}
+        //~^ ERROR: unused variable: `Non`
+        //~| HELP: if this is intentional, prefix it with an underscore
+        //~| ERROR: variable `Non` is not bound in all patterns [E0408]
+        //~| NOTE: pattern doesn't bind `Non`
+        //~| NOTE: variable not in all patterns
+        //~| HELP: you might have meant to use the similarly named unit variant `None`
+        //~| HELP: you might have meant to pattern match on the similarly named
+    }
+    match Some(42) {
+        Non | Some(_) => {}
+        //~^ ERROR: unused variable: `Non`
+        //~| HELP: if this is intentional, prefix it with an underscore
+        //~| ERROR: variable `Non` is not bound in all patterns [E0408]
+        //~| NOTE: pattern doesn't bind `Non`
+        //~| NOTE: variable not in all patterns
+        //~| HELP: you might have meant to use the similarly named unit variant `None`
+        //~| HELP: you might have meant to pattern match on the similarly named
+    }
+}
+fn bar(x: (Lol, Lol)) {
+    use Lol::*;
+    use ::Bat;
+    use ::Bay;
+    match &x {
+        (Foo, _) | (Ban, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named unit variant `Bar`
+        //~| HELP: you might have meant to use the similarly named unit struct `Bay`
+        //~| HELP: you might have meant to use the similarly named constant `Bat`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        //~| ERROR: variable `Ban` is assigned to, but never used
+        //~| NOTE: consider using `_Ban` instead
+        //~| HELP: you might have meant to pattern match on the similarly named
+        _ => {}
+    }
+}
+fn baz(x: (Lol, Lol)) {
+    use Lol::*;
+    use Bat;
+    match &x {
+        (Foo, _) | (Ban, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named unit variant `Bar`
+        //~| HELP: you might have meant to use the similarly named constant `Bat`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        //~| ERROR: variable `Ban` is assigned to, but never used
+        //~| NOTE: consider using `_Ban` instead
+        //~| HELP: you might have meant to pattern match on the similarly named
+        _ => {}
+    }
+    match &x {
+        (Ban, _) => {}
+        //~^ ERROR: unused variable: `Ban`
+        //~| HELP: if this is intentional, prefix it with an underscore
+        //~| HELP: you might have meant to pattern match on the similarly named
+    }
+    match Bay {
+        Ban => {}
+        //~^ ERROR: unused variable: `Ban`
+        //~| HELP: if this is intentional, prefix it with an underscore
+        //~| HELP: you might have meant to pattern match on the similarly named
+    }
+    match () {
+        Batery => {}
+        //~^ ERROR: unused variable: `Batery`
+        //~| HELP: if this is intentional, prefix it with an underscore
+        //~| HELP: you might have meant to pattern match on the similarly named constant
+    }
+}
+
+fn main() {
+    use Lol::*;
+    foo((Foo, Bar));
+    bar((Foo, Bar));
+    baz((Foo, Bar));
+}
diff --git a/tests/ui/or-patterns/binding-typo-2.stderr b/tests/ui/or-patterns/binding-typo-2.stderr
new file mode 100644
index 00000000000..81ea6e6b1bc
--- /dev/null
+++ b/tests/ui/or-patterns/binding-typo-2.stderr
@@ -0,0 +1,254 @@
+error[E0408]: variable `Ban` is not bound in all patterns
+  --> $DIR/binding-typo-2.rs:14:9
+   |
+LL |         (Foo, Bar) | (Ban, Foo) => {}
+   |         ^^^^^^^^^^    --- variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Ban`
+   |
+help: you might have meant to use the similarly named previously used binding `Bar`
+   |
+LL -         (Foo, Bar) | (Ban, Foo) => {}
+LL +         (Foo, Bar) | (Bar, Foo) => {}
+   |
+
+error[E0408]: variable `Ban` is not bound in all patterns
+  --> $DIR/binding-typo-2.rs:25:9
+   |
+LL |         (Foo, _) | (Ban, Foo) => {}
+   |         ^^^^^^^^    --- variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Ban`
+   |
+help: you might have meant to use the similarly named unit variant `Bar`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Bar, Foo) => {}
+   |
+
+error[E0408]: variable `Non` is not bound in all patterns
+  --> $DIR/binding-typo-2.rs:44:15
+   |
+LL |         Non | None => {}
+   |         ---   ^^^^ pattern doesn't bind `Non`
+   |         |
+   |         variable not in all patterns
+   |
+help: you might have meant to use the similarly named unit variant `None`
+   |
+LL -         Non | None => {}
+LL +         core::option::Option::None | None => {}
+   |
+
+error[E0408]: variable `Non` is not bound in all patterns
+  --> $DIR/binding-typo-2.rs:54:15
+   |
+LL |         Non | Some(_) => {}
+   |         ---   ^^^^^^^ pattern doesn't bind `Non`
+   |         |
+   |         variable not in all patterns
+   |
+help: you might have meant to use the similarly named unit variant `None`
+   |
+LL -         Non | Some(_) => {}
+LL +         core::option::Option::None | Some(_) => {}
+   |
+
+error[E0408]: variable `Ban` is not bound in all patterns
+  --> $DIR/binding-typo-2.rs:69:9
+   |
+LL |         (Foo, _) | (Ban, Foo) => {}
+   |         ^^^^^^^^    --- variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Ban`
+   |
+help: you might have meant to use the similarly named unit variant `Bar`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Bar, Foo) => {}
+   |
+help: you might have meant to use the similarly named unit struct `Bay`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Bay, Foo) => {}
+   |
+help: you might have meant to use the similarly named constant `Bat`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Bat, Foo) => {}
+   |
+
+error[E0408]: variable `Ban` is not bound in all patterns
+  --> $DIR/binding-typo-2.rs:86:9
+   |
+LL |         (Foo, _) | (Ban, Foo) => {}
+   |         ^^^^^^^^    --- variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Ban`
+   |
+help: you might have meant to use the similarly named unit variant `Bar`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Bar, Foo) => {}
+   |
+help: you might have meant to use the similarly named constant `Bat`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Bat, Foo) => {}
+   |
+
+error: variable `Ban` is assigned to, but never used
+  --> $DIR/binding-typo-2.rs:14:23
+   |
+LL |         (Foo, Bar) | (Ban, Foo) => {}
+   |                       ^^^
+   |
+   = note: consider using `_Ban` instead
+note: the lint level is defined here
+  --> $DIR/binding-typo-2.rs:2:9
+   |
+LL | #![deny(unused_variables)]
+   |         ^^^^^^^^^^^^^^^^
+help: you might have meant to pattern match on the similarly named variant `Bar`
+   |
+LL -         (Foo, Bar) | (Ban, Foo) => {}
+LL +         (Foo, Bar) | (Lol::Bar, Foo) => {}
+   |
+
+error: variable `Ban` is assigned to, but never used
+  --> $DIR/binding-typo-2.rs:25:21
+   |
+LL |         (Foo, _) | (Ban, Foo) => {}
+   |                     ^^^
+   |
+   = note: consider using `_Ban` instead
+help: you might have meant to pattern match on the similarly named variant `Bar`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Lol::Bar, Foo) => {}
+   |
+
+error: unused variable: `Non`
+  --> $DIR/binding-typo-2.rs:37:9
+   |
+LL |         Non => {}
+   |         ^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         _Non => {}
+   |         +
+help: you might have meant to pattern match on the similarly named variant `None`
+   |
+LL -         Non => {}
+LL +         std::prelude::v1::None => {}
+   |
+
+error: unused variable: `Non`
+  --> $DIR/binding-typo-2.rs:44:9
+   |
+LL |         Non | None => {}
+   |         ^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         _Non | None => {}
+   |         +
+help: you might have meant to pattern match on the similarly named variant `None`
+   |
+LL -         Non | None => {}
+LL +         std::prelude::v1::None | None => {}
+   |
+
+error: unused variable: `Non`
+  --> $DIR/binding-typo-2.rs:54:9
+   |
+LL |         Non | Some(_) => {}
+   |         ^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         _Non | Some(_) => {}
+   |         +
+help: you might have meant to pattern match on the similarly named variant `None`
+   |
+LL -         Non | Some(_) => {}
+LL +         std::prelude::v1::None | Some(_) => {}
+   |
+
+error: variable `Ban` is assigned to, but never used
+  --> $DIR/binding-typo-2.rs:69:21
+   |
+LL |         (Foo, _) | (Ban, Foo) => {}
+   |                     ^^^
+   |
+   = note: consider using `_Ban` instead
+help: you might have meant to pattern match on the similarly named variant `Bar`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Lol::Bar, Foo) => {}
+   |
+
+error: variable `Ban` is assigned to, but never used
+  --> $DIR/binding-typo-2.rs:86:21
+   |
+LL |         (Foo, _) | (Ban, Foo) => {}
+   |                     ^^^
+   |
+   = note: consider using `_Ban` instead
+help: you might have meant to pattern match on the similarly named variant `Bar`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Lol::Bar, Foo) => {}
+   |
+
+error: unused variable: `Ban`
+  --> $DIR/binding-typo-2.rs:98:10
+   |
+LL |         (Ban, _) => {}
+   |          ^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         (_Ban, _) => {}
+   |          +
+help: you might have meant to pattern match on the similarly named variant `Bar`
+   |
+LL -         (Ban, _) => {}
+LL +         (Lol::Bar, _) => {}
+   |
+
+error: unused variable: `Ban`
+  --> $DIR/binding-typo-2.rs:104:9
+   |
+LL |         Ban => {}
+   |         ^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         _Ban => {}
+   |         +
+help: you might have meant to pattern match on the similarly named struct `Bay`
+   |
+LL -         Ban => {}
+LL +         Bay => {}
+   |
+
+error: unused variable: `Batery`
+  --> $DIR/binding-typo-2.rs:110:9
+   |
+LL |         Batery => {}
+   |         ^^^^^^
+   |
+help: if this is intentional, prefix it with an underscore
+   |
+LL |         _Batery => {}
+   |         +
+help: you might have meant to pattern match on the similarly named constant `Battery`
+   |
+LL |         Battery => {}
+   |            +
+
+error: aborting due to 16 previous errors
+
+For more information about this error, try `rustc --explain E0408`.
diff --git a/tests/ui/or-patterns/binding-typo.fixed b/tests/ui/or-patterns/binding-typo.fixed
new file mode 100644
index 00000000000..f209ad644db
--- /dev/null
+++ b/tests/ui/or-patterns/binding-typo.fixed
@@ -0,0 +1,32 @@
+// Issue #51976
+//@ run-rustfix
+#![allow(unused_variables)] // allowed so we don't get overlapping suggestions
+enum Lol {
+    Foo,
+    Bar,
+}
+
+fn foo(x: (Lol, Lol)) {
+    use Lol::*;
+    match &x {
+        (Foo, Bar) | (Bar, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named previously used binding `Bar`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        _ => {}
+    }
+    match &x {
+        (Foo, _) | (Bar, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named unit variant `Bar`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        _ => {}
+    }
+}
+
+fn main() {
+    use Lol::*;
+    foo((Foo, Bar));
+}
diff --git a/tests/ui/or-patterns/binding-typo.rs b/tests/ui/or-patterns/binding-typo.rs
new file mode 100644
index 00000000000..6be9b801a0d
--- /dev/null
+++ b/tests/ui/or-patterns/binding-typo.rs
@@ -0,0 +1,32 @@
+// Issue #51976
+//@ run-rustfix
+#![allow(unused_variables)] // allowed so we don't get overlapping suggestions
+enum Lol {
+    Foo,
+    Bar,
+}
+
+fn foo(x: (Lol, Lol)) {
+    use Lol::*;
+    match &x {
+        (Foo, Bar) | (Ban, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named previously used binding `Bar`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        _ => {}
+    }
+    match &x {
+        (Foo, _) | (Ban, Foo) => {}
+        //~^ ERROR: variable `Ban` is not bound in all patterns
+        //~| HELP: you might have meant to use the similarly named unit variant `Bar`
+        //~| NOTE: pattern doesn't bind `Ban`
+        //~| NOTE: variable not in all patterns
+        _ => {}
+    }
+}
+
+fn main() {
+    use Lol::*;
+    foo((Foo, Bar));
+}
diff --git a/tests/ui/or-patterns/binding-typo.stderr b/tests/ui/or-patterns/binding-typo.stderr
new file mode 100644
index 00000000000..fb6d5f71209
--- /dev/null
+++ b/tests/ui/or-patterns/binding-typo.stderr
@@ -0,0 +1,31 @@
+error[E0408]: variable `Ban` is not bound in all patterns
+  --> $DIR/binding-typo.rs:12:9
+   |
+LL |         (Foo, Bar) | (Ban, Foo) => {}
+   |         ^^^^^^^^^^    --- variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Ban`
+   |
+help: you might have meant to use the similarly named previously used binding `Bar`
+   |
+LL -         (Foo, Bar) | (Ban, Foo) => {}
+LL +         (Foo, Bar) | (Bar, Foo) => {}
+   |
+
+error[E0408]: variable `Ban` is not bound in all patterns
+  --> $DIR/binding-typo.rs:20:9
+   |
+LL |         (Foo, _) | (Ban, Foo) => {}
+   |         ^^^^^^^^    --- variable not in all patterns
+   |         |
+   |         pattern doesn't bind `Ban`
+   |
+help: you might have meant to use the similarly named unit variant `Bar`
+   |
+LL -         (Foo, _) | (Ban, Foo) => {}
+LL +         (Foo, _) | (Bar, Foo) => {}
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0408`.
diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr
index 6288cc58913..636f7016647 100644
--- a/tests/ui/or-patterns/missing-bindings.stderr
+++ b/tests/ui/or-patterns/missing-bindings.stderr
@@ -86,6 +86,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |            ^^^^^^^     - variable not in all patterns
    |            |
    |            pattern doesn't bind `c`
+   |
+help: you might have meant to use the similarly named previously used binding `a`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(a, b) | B(a), d) | B(e)) = Y;
+   |
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:47:22
@@ -94,6 +100,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |              -       ^^^^ pattern doesn't bind `a`
    |              |
    |              variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(c, b) | B(c), d) | B(e)) = Y;
+   |
 
 error[E0408]: variable `b` is not bound in all patterns
   --> $DIR/missing-bindings.rs:47:22
@@ -102,6 +114,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 -    ^^^^ pattern doesn't bind `b`
    |                 |
    |                 variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(a, c) | B(c), d) | B(e)) = Y;
+   |
 
 error[E0408]: variable `e` is not bound in all patterns
   --> $DIR/missing-bindings.rs:47:10
@@ -110,6 +128,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |          ^^^^^^^^^^^^^^^^^^^^     - variable not in all patterns
    |          |
    |          pattern doesn't bind `e`
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(a, b) | B(c), d) | B(c)) = Y;
+   |
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:47:33
@@ -118,6 +142,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |              -                  ^^^^ pattern doesn't bind `a`
    |              |
    |              variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `e`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(e, b) | B(c), d) | B(e)) = Y;
+   |
 
 error[E0408]: variable `b` is not bound in all patterns
   --> $DIR/missing-bindings.rs:47:33
@@ -126,6 +156,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 -               ^^^^ pattern doesn't bind `b`
    |                 |
    |                 variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `e`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(a, e) | B(c), d) | B(e)) = Y;
+   |
 
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/missing-bindings.rs:47:33
@@ -134,6 +170,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                        -        ^^^^ pattern doesn't bind `c`
    |                        |
    |                        variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `e`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(a, b) | B(e), d) | B(e)) = Y;
+   |
 
 error[E0408]: variable `d` is not bound in all patterns
   --> $DIR/missing-bindings.rs:47:33
@@ -142,6 +184,12 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                            -    ^^^^ pattern doesn't bind `d`
    |                            |
    |                            variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `e`
+   |
+LL -     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+LL +     let (A(A(a, b) | B(c), e) | B(e)) = Y;
+   |
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:63:29
@@ -158,6 +206,12 @@ LL |                     A(_, a) |
    |                     ^^^^^^^ pattern doesn't bind `b`
 LL |                     B(b),
    |                       - variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `a`
+   |
+LL -                     B(b),
+LL +                     B(a),
+   |
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:71:21
@@ -166,6 +220,12 @@ LL |                     A(_, a) |
    |                          - variable not in all patterns
 LL |                     B(b),
    |                     ^^^^ pattern doesn't bind `a`
+   |
+help: you might have meant to use the similarly named previously used binding `b`
+   |
+LL -                     A(_, a) |
+LL +                     A(_, b) |
+   |
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:74:17
@@ -202,6 +262,12 @@ LL |                       B(b),
 ...
 LL |               V3(c),
    |               ^^^^^ pattern doesn't bind `b`
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL -                     B(b),
+LL +                     B(c),
+   |
 
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/missing-bindings.rs:59:13
@@ -223,6 +289,12 @@ LL | |             ) |
    | |_____________^ pattern doesn't bind `c`
 LL |               V3(c),
    |                  - variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `a`
+   |
+LL -             V3(c),
+LL +             V3(a),
+   |
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:78:13
@@ -235,6 +307,15 @@ LL |                     A(_, a) |
 ...
 LL |             V3(c),
    |             ^^^^^ pattern doesn't bind `a`
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL ~                 B(Ok(a) | Err(c))
+LL |             ) |
+LL |             V2(
+LL |                 A(
+LL ~                     A(_, c) |
+   |
 
 error[E0170]: pattern binding `beta` is named the same as one of the variants of the type `check_handling_of_paths::bar::foo`
   --> $DIR/missing-bindings.rs:19:18
diff --git a/tests/ui/pattern/at-in-struct-patterns.rs b/tests/ui/pattern/at-in-struct-patterns.rs
index e8fad61f317..b0557220d05 100644
--- a/tests/ui/pattern/at-in-struct-patterns.rs
+++ b/tests/ui/pattern/at-in-struct-patterns.rs
@@ -5,7 +5,7 @@ struct Foo {
 
 fn main() {
     let foo = Foo { field1: 1, field2: 2 };
-    let Foo { var @ field1, .. } = foo; //~ ERROR Unexpected `@` in struct pattern
+    let Foo { var @ field1, .. } = foo; //~ ERROR unexpected `@` in struct pattern
     dbg!(var); //~ ERROR cannot find value `var` in this scope
     let Foo { field1: _, bar @ .. } = foo; //~ ERROR `@ ..` is not supported in struct patterns
     let Foo { bar @ .. } = foo; //~ ERROR `@ ..` is not supported in struct patterns
diff --git a/tests/ui/pattern/at-in-struct-patterns.stderr b/tests/ui/pattern/at-in-struct-patterns.stderr
index ff75edfe681..20832897ca5 100644
--- a/tests/ui/pattern/at-in-struct-patterns.stderr
+++ b/tests/ui/pattern/at-in-struct-patterns.stderr
@@ -1,4 +1,4 @@
-error: Unexpected `@` in struct pattern
+error: unexpected `@` in struct pattern
   --> $DIR/at-in-struct-patterns.rs:8:15
    |
 LL |     let Foo { var @ field1, .. } = foo;
diff --git a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr
index d76e60478a1..a5d9fd2b1a6 100644
--- a/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr
+++ b/tests/ui/pattern/rfc-3637-guard-patterns/name-resolution.stderr
@@ -5,6 +5,12 @@ LL |         ((Ok(x) if y) | (Err(y) if x),) => x && y,
    |          ^^^^^^^^^^^^        - variable not in all patterns
    |          |
    |          pattern doesn't bind `y`
+   |
+help: you might have meant to use the similarly named previously used binding `x`
+   |
+LL -         ((Ok(x) if y) | (Err(y) if x),) => x && y,
+LL +         ((Ok(x) if y) | (Err(x) if x),) => x && y,
+   |
 
 error[E0408]: variable `x` is not bound in all patterns
   --> $DIR/name-resolution.rs:37:25
@@ -13,6 +19,12 @@ LL |         ((Ok(x) if y) | (Err(y) if x),) => x && y,
    |              -          ^^^^^^^^^^^^^ pattern doesn't bind `x`
    |              |
    |              variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `y`
+   |
+LL -         ((Ok(x) if y) | (Err(y) if x),) => x && y,
+LL +         ((Ok(y) if y) | (Err(y) if x),) => x && y,
+   |
 
 error[E0408]: variable `x` is not bound in all patterns
   --> $DIR/name-resolution.rs:63:28
diff --git a/tests/ui/resolve/resolve-inconsistent-names.rs b/tests/ui/resolve/resolve-inconsistent-names.rs
index 9a40b20346c..96504720e83 100644
--- a/tests/ui/resolve/resolve-inconsistent-names.rs
+++ b/tests/ui/resolve/resolve-inconsistent-names.rs
@@ -10,8 +10,8 @@ pub mod m {
 fn main() {
     let y = 1;
     match y {
-       a | b => {} //~  ERROR variable `a` is not bound in all patterns
-                   //~| ERROR variable `b` is not bound in all patterns
+        a | b => {} //~  ERROR variable `a` is not bound in all patterns
+        //~| ERROR variable `b` is not bound in all patterns
     }
 
     let x = (E::A, E::B);
diff --git a/tests/ui/resolve/resolve-inconsistent-names.stderr b/tests/ui/resolve/resolve-inconsistent-names.stderr
index 5fac622eef2..d2333150961 100644
--- a/tests/ui/resolve/resolve-inconsistent-names.stderr
+++ b/tests/ui/resolve/resolve-inconsistent-names.stderr
@@ -1,18 +1,18 @@
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/resolve-inconsistent-names.rs:13:8
+  --> $DIR/resolve-inconsistent-names.rs:13:9
    |
-LL |        a | b => {}
-   |        ^   - variable not in all patterns
-   |        |
-   |        pattern doesn't bind `b`
+LL |         a | b => {}
+   |         ^   - variable not in all patterns
+   |         |
+   |         pattern doesn't bind `b`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/resolve-inconsistent-names.rs:13:12
+  --> $DIR/resolve-inconsistent-names.rs:13:13
    |
-LL |        a | b => {}
-   |        -   ^ pattern doesn't bind `a`
-   |        |
-   |        variable not in all patterns
+LL |         a | b => {}
+   |         -   ^ pattern doesn't bind `a`
+   |         |
+   |         variable not in all patterns
 
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/resolve-inconsistent-names.rs:19:9
diff --git a/tests/ui/sanitizer/address.rs b/tests/ui/sanitizer/address.rs
index 704d84764c1..1688f46c2d5 100644
--- a/tests/ui/sanitizer/address.rs
+++ b/tests/ui/sanitizer/address.rs
@@ -2,7 +2,7 @@
 //@ needs-sanitizer-address
 //@ ignore-cross-compile
 //
-//@ compile-flags: -Z sanitizer=address -O -g
+//@ compile-flags: -Z sanitizer=address -O -g -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail-or-crash
 //@ error-pattern: AddressSanitizer: stack-buffer-overflow
diff --git a/tests/ui/sanitizer/asan_odr_windows.rs b/tests/ui/sanitizer/asan_odr_windows.rs
index 28c24716761..b638d6eb969 100644
--- a/tests/ui/sanitizer/asan_odr_windows.rs
+++ b/tests/ui/sanitizer/asan_odr_windows.rs
@@ -2,7 +2,7 @@
 //! See <https://github.com/rust-lang/rust/issues/124390>.
 
 //@ run-pass
-//@ compile-flags:-Zsanitizer=address
+//@ compile-flags:-Zsanitizer=address -C unsafe-allow-abi-mismatch=sanitizer
 //@ aux-build: asan_odr_win-2.rs
 //@ only-windows-msvc
 //@ needs-sanitizer-support
diff --git a/tests/ui/sanitizer/badfree.rs b/tests/ui/sanitizer/badfree.rs
index 6b3aea7239c..b1b02649dcc 100644
--- a/tests/ui/sanitizer/badfree.rs
+++ b/tests/ui/sanitizer/badfree.rs
@@ -2,7 +2,7 @@
 //@ needs-sanitizer-address
 //@ ignore-cross-compile
 //
-//@ compile-flags: -Z sanitizer=address -O
+//@ compile-flags: -Z sanitizer=address -O -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail-or-crash
 //@ regex-error-pattern: AddressSanitizer: (SEGV|attempting free on address which was not malloc)
diff --git a/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs b/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
index fad57198dfb..5de5e99f6d0 100644
--- a/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
+++ b/tests/ui/sanitizer/cfi/assoc-ty-lifetime-issue-123053.rs
@@ -2,7 +2,7 @@
 // trait object type to fail, causing an ICE.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 //@ edition: 2021
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
diff --git a/tests/ui/sanitizer/cfi/async-closures.rs b/tests/ui/sanitizer/cfi/async-closures.rs
index 9b099263000..621a0882c91 100644
--- a/tests/ui/sanitizer/cfi/async-closures.rs
+++ b/tests/ui/sanitizer/cfi/async-closures.rs
@@ -7,7 +7,7 @@
 //@ ignore-backends: gcc
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C target-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
index a881c6b92b2..310ce04c552 100644
--- a/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
+++ b/tests/ui/sanitizer/cfi/can-reveal-opaques.rs
@@ -1,5 +1,5 @@
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
 //@ ignore-backends: gcc
diff --git a/tests/ui/sanitizer/cfi/closures.rs b/tests/ui/sanitizer/cfi/closures.rs
index fc9718faa28..7493dba4928 100644
--- a/tests/ui/sanitizer/cfi/closures.rs
+++ b/tests/ui/sanitizer/cfi/closures.rs
@@ -6,7 +6,7 @@
 //@ ignore-backends: gcc
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C target-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/complex-receiver.rs b/tests/ui/sanitizer/cfi/complex-receiver.rs
index aac44c33227..adacc0d6c5d 100644
--- a/tests/ui/sanitizer/cfi/complex-receiver.rs
+++ b/tests/ui/sanitizer/cfi/complex-receiver.rs
@@ -8,7 +8,7 @@
 //@ ignore-backends: gcc
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C target-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/coroutine.rs b/tests/ui/sanitizer/cfi/coroutine.rs
index 084a521f597..d85615b597d 100644
--- a/tests/ui/sanitizer/cfi/coroutine.rs
+++ b/tests/ui/sanitizer/cfi/coroutine.rs
@@ -8,6 +8,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/drop-in-place.rs b/tests/ui/sanitizer/cfi/drop-in-place.rs
index 160338a5b54..fe59d546312 100644
--- a/tests/ui/sanitizer/cfi/drop-in-place.rs
+++ b/tests/ui/sanitizer/cfi/drop-in-place.rs
@@ -5,6 +5,7 @@
 //@ ignore-backends: gcc
 //@ needs-sanitizer-cfi
 //@ compile-flags: -Clto -Copt-level=0 -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ run-pass
 
 struct EmptyDrop;
diff --git a/tests/ui/sanitizer/cfi/drop-no-principal.rs b/tests/ui/sanitizer/cfi/drop-no-principal.rs
index e3a46fe9d75..4fb905eb51d 100644
--- a/tests/ui/sanitizer/cfi/drop-no-principal.rs
+++ b/tests/ui/sanitizer/cfi/drop-no-principal.rs
@@ -4,7 +4,7 @@
 // FIXME(#122848) Remove only-linux once OSX CFI binaries works
 //@ only-linux
 //@ ignore-backends: gcc
-//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi
+//@ compile-flags: --crate-type=bin -Cprefer-dynamic=off -Clto -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 //@ compile-flags: -C target-feature=-crt-static -C codegen-units=1 -C opt-level=0
 // FIXME(#118761) Should be run-pass once the labels on drop are compatible.
 // This test is being landed ahead of that to test that the compiler doesn't ICE while labeling the
diff --git a/tests/ui/sanitizer/cfi/fn-ptr.rs b/tests/ui/sanitizer/cfi/fn-ptr.rs
index d3209c62ddf..bdb8c7ceb32 100644
--- a/tests/ui/sanitizer/cfi/fn-ptr.rs
+++ b/tests/ui/sanitizer/cfi/fn-ptr.rs
@@ -7,6 +7,7 @@
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
 //@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C opt-level=0 -C codegen-units=1 -C lto
 //@ [cfi] compile-flags: -C prefer-dynamic=off
 //@ [cfi] compile-flags: -Z sanitizer=cfi
diff --git a/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs b/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs
index d46002c69fd..44cdcb250e7 100644
--- a/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs
+++ b/tests/ui/sanitizer/cfi/generalize-pointers-attr-cfg.rs
@@ -4,6 +4,7 @@
 //@ needs-sanitizer-cfi
 //@ check-pass
 //@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-generalize-pointers
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
 
 #![feature(cfg_sanitizer_cfi)]
 
diff --git a/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs b/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs
index 24c2c2c13da..ce4e31eb69b 100644
--- a/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs
+++ b/tests/ui/sanitizer/cfi/normalize-integers-attr-cfg.rs
@@ -3,7 +3,7 @@
 //
 //@ needs-sanitizer-cfi
 //@ check-pass
-//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers
+//@ compile-flags: -Clto -Cno-prepopulate-passes -Ctarget-feature=-crt-static -Zsanitizer=cfi -Zsanitizer-cfi-normalize-integers -C unsafe-allow-abi-mismatch=sanitizer,sanitizer-cfi-normalize-integers
 
 #![feature(cfg_sanitizer_cfi)]
 
diff --git a/tests/ui/sanitizer/cfi/self-ref.rs b/tests/ui/sanitizer/cfi/self-ref.rs
index b93d49296b6..827610a2610 100644
--- a/tests/ui/sanitizer/cfi/self-ref.rs
+++ b/tests/ui/sanitizer/cfi/self-ref.rs
@@ -6,7 +6,7 @@
 //@ ignore-backends: gcc
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C target-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/sized-associated-ty.rs b/tests/ui/sanitizer/cfi/sized-associated-ty.rs
index eefc3e2e9db..da8c385c6fc 100644
--- a/tests/ui/sanitizer/cfi/sized-associated-ty.rs
+++ b/tests/ui/sanitizer/cfi/sized-associated-ty.rs
@@ -7,7 +7,7 @@
 //@ ignore-backends: gcc
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C target-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/supertraits.rs b/tests/ui/sanitizer/cfi/supertraits.rs
index f5a984b9583..b2782dff5d5 100644
--- a/tests/ui/sanitizer/cfi/supertraits.rs
+++ b/tests/ui/sanitizer/cfi/supertraits.rs
@@ -6,7 +6,7 @@
 //@ ignore-backends: gcc
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C target-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/cfi/transparent-has-regions.rs b/tests/ui/sanitizer/cfi/transparent-has-regions.rs
index b70e1ea1791..b82850133c1 100644
--- a/tests/ui/sanitizer/cfi/transparent-has-regions.rs
+++ b/tests/ui/sanitizer/cfi/transparent-has-regions.rs
@@ -1,5 +1,5 @@
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
 //@ build-pass
diff --git a/tests/ui/sanitizer/cfi/virtual-auto.rs b/tests/ui/sanitizer/cfi/virtual-auto.rs
index e6f2ebd4b2c..d3a715c079a 100644
--- a/tests/ui/sanitizer/cfi/virtual-auto.rs
+++ b/tests/ui/sanitizer/cfi/virtual-auto.rs
@@ -6,7 +6,7 @@
 //@ ignore-backends: gcc
 //@ [cfi] needs-sanitizer-cfi
 //@ [kcfi] needs-sanitizer-kcfi
-//@ compile-flags: -C target-feature=-crt-static
+//@ compile-flags: -C target-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ [cfi] compile-flags: -C codegen-units=1 -C lto -C prefer-dynamic=off -C opt-level=0
 //@ [cfi] compile-flags: -Z sanitizer=cfi
 //@ [kcfi] compile-flags: -Z sanitizer=kcfi
diff --git a/tests/ui/sanitizer/dataflow.rs b/tests/ui/sanitizer/dataflow.rs
index 658a9e48086..d99a1a6ac24 100644
--- a/tests/ui/sanitizer/dataflow.rs
+++ b/tests/ui/sanitizer/dataflow.rs
@@ -4,7 +4,7 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-dataflow
 //@ run-pass
-//@ compile-flags: -Zsanitizer=dataflow -Zsanitizer-dataflow-abilist={{src-base}}/sanitizer/dataflow-abilist.txt
+//@ compile-flags: -Zsanitizer=dataflow -Zsanitizer-dataflow-abilist={{src-base}}/sanitizer/dataflow-abilist.txt -C unsafe-allow-abi-mismatch=sanitizer
 
 use std::mem::size_of;
 use std::os::raw::{c_int, c_long, c_void};
diff --git a/tests/ui/sanitizer/hwaddress.rs b/tests/ui/sanitizer/hwaddress.rs
index e5939eb734b..05fcab17506 100644
--- a/tests/ui/sanitizer/hwaddress.rs
+++ b/tests/ui/sanitizer/hwaddress.rs
@@ -5,7 +5,7 @@
 //@ ignore-aarch64-unknown-linux-gnu
 //
 // FIXME(#83989): codegen-units=1 triggers linker errors on aarch64-gnu
-//@ compile-flags: -Z sanitizer=hwaddress -O -g -C codegen-units=16
+//@ compile-flags: -Z sanitizer=hwaddress -O -g -C codegen-units=16 -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail
 //@ error-pattern: HWAddressSanitizer: tag-mismatch
diff --git a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
index 7d0c73c2841..be81c7bd0ca 100644
--- a/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
+++ b/tests/ui/sanitizer/issue-111184-cfi-coroutine-witness.rs
@@ -2,7 +2,7 @@
 // encode_ty and caused the compiler to ICE.
 //
 //@ needs-sanitizer-cfi
-//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ compile-flags: -Ccodegen-units=1 -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi -C unsafe-allow-abi-mismatch=sanitizer
 //@ edition: 2021
 //@ no-prefer-dynamic
 //@ only-x86_64-unknown-linux-gnu
diff --git a/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs b/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
index b1b7487fa2a..f7af2842ad6 100644
--- a/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
+++ b/tests/ui/sanitizer/issue-114275-cfi-const-expr-in-arry-len.rs
@@ -2,7 +2,7 @@
 // was expecting array type lengths to be evaluated, this was causing an ICE.
 //
 //@ build-pass
-//@ compile-flags: -Ccodegen-units=1 -Clto -Zsanitizer=cfi -Ctarget-feature=-crt-static
+//@ compile-flags: -Ccodegen-units=1 -Clto -Zsanitizer=cfi -Ctarget-feature=-crt-static -C unsafe-allow-abi-mismatch=sanitizer
 //@ needs-sanitizer-cfi
 
 #![crate_type = "lib"]
diff --git a/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs b/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
index aa0c19db9a1..edeb1b0bf94 100644
--- a/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
+++ b/tests/ui/sanitizer/issue-72154-address-lifetime-markers.rs
@@ -7,7 +7,7 @@
 //@ needs-sanitizer-address
 //@ ignore-cross-compile
 //
-//@ compile-flags: -Copt-level=0 -Zsanitizer=address
+//@ compile-flags: -Copt-level=0 -Zsanitizer=address -C unsafe-allow-abi-mismatch=sanitizer
 //@ run-pass
 
 pub struct Wrap {
diff --git a/tests/ui/sanitizer/kcfi-mangling.rs b/tests/ui/sanitizer/kcfi-mangling.rs
index ba36dc184ec..371f34ba72a 100644
--- a/tests/ui/sanitizer/kcfi-mangling.rs
+++ b/tests/ui/sanitizer/kcfi-mangling.rs
@@ -2,7 +2,7 @@
 
 //@ needs-sanitizer-kcfi
 //@ no-prefer-dynamic
-//@ compile-flags: -C panic=abort -Zsanitizer=kcfi -C symbol-mangling-version=v0
+//@ compile-flags: -C panic=abort -Zsanitizer=kcfi -C symbol-mangling-version=v0 -C unsafe-allow-abi-mismatch=sanitizer
 //@ build-pass
 //@ ignore-backends: gcc
 
diff --git a/tests/ui/sanitizer/leak.rs b/tests/ui/sanitizer/leak.rs
index 65915ec24b7..4ce3f7ab1b9 100644
--- a/tests/ui/sanitizer/leak.rs
+++ b/tests/ui/sanitizer/leak.rs
@@ -1,7 +1,7 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-leak
 //
-//@ compile-flags: -Z sanitizer=leak -O
+//@ compile-flags: -Z sanitizer=leak -O -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail
 //@ error-pattern: LeakSanitizer: detected memory leaks
diff --git a/tests/ui/sanitizer/memory-eager.rs b/tests/ui/sanitizer/memory-eager.rs
index 709299f87d4..9498336abb7 100644
--- a/tests/ui/sanitizer/memory-eager.rs
+++ b/tests/ui/sanitizer/memory-eager.rs
@@ -1,6 +1,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-memory
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ revisions: unoptimized optimized
 //
 //@ [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
diff --git a/tests/ui/sanitizer/memory-passing.rs b/tests/ui/sanitizer/memory-passing.rs
index 96a4cd909c7..6ac41b178fe 100644
--- a/tests/ui/sanitizer/memory-passing.rs
+++ b/tests/ui/sanitizer/memory-passing.rs
@@ -1,6 +1,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-memory
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ revisions: unoptimized optimized
 //
 //@ [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
diff --git a/tests/ui/sanitizer/memory.rs b/tests/ui/sanitizer/memory.rs
index a91fefe4d16..1566637acd2 100644
--- a/tests/ui/sanitizer/memory.rs
+++ b/tests/ui/sanitizer/memory.rs
@@ -1,6 +1,8 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-memory
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ revisions: unoptimized optimized
 //
 //@ [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
diff --git a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
index c1a2c2f26ac..b6656847427 100644
--- a/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
+++ b/tests/ui/sanitizer/new-llvm-pass-manager-thin-lto.rs
@@ -6,6 +6,8 @@
 //@ needs-sanitizer-address
 //@ ignore-cross-compile
 //
+//@ compile-flags: -C unsafe-allow-abi-mismatch=sanitizer
+//
 //@ no-prefer-dynamic
 //@ revisions: opt0 opt1
 //@ compile-flags: -Zsanitizer=address -Clto=thin
diff --git a/tests/ui/sanitizer/thread.rs b/tests/ui/sanitizer/thread.rs
index 9073124d1bd..8f72b1b41a8 100644
--- a/tests/ui/sanitizer/thread.rs
+++ b/tests/ui/sanitizer/thread.rs
@@ -13,7 +13,7 @@
 //@ needs-sanitizer-support
 //@ needs-sanitizer-thread
 //
-//@ compile-flags: -Z sanitizer=thread -O
+//@ compile-flags: -Z sanitizer=thread -O -C unsafe-allow-abi-mismatch=sanitizer
 //
 //@ run-fail-or-crash
 //@ error-pattern: WARNING: ThreadSanitizer: data race
diff --git a/tests/ui/sanitizer/use-after-scope.rs b/tests/ui/sanitizer/use-after-scope.rs
index 106dc6466d6..1c477d0be14 100644
--- a/tests/ui/sanitizer/use-after-scope.rs
+++ b/tests/ui/sanitizer/use-after-scope.rs
@@ -2,7 +2,7 @@
 //@ needs-sanitizer-address
 //@ ignore-cross-compile
 //
-//@ compile-flags: -Zsanitizer=address
+//@ compile-flags: -Zsanitizer=address -C unsafe-allow-abi-mismatch=sanitizer
 //@ run-fail-or-crash
 //@ error-pattern: ERROR: AddressSanitizer: stack-use-after-scope
 
diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr
index 73fcc5c8477..eb18969c3c0 100644
--- a/tests/ui/span/issue-39698.stderr
+++ b/tests/ui/span/issue-39698.stderr
@@ -7,6 +7,12 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |         |                      |    pattern doesn't bind `b`
    |         |                      variable not in all patterns
    |         pattern doesn't bind `b`
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL -         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+LL +         T::T1(a, d) | T::T2(d, c) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+   |
 
 error[E0408]: variable `c` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:9
@@ -17,6 +23,12 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |         |             |                   variable not in all patterns
    |         |             pattern doesn't bind `c`
    |         pattern doesn't bind `c`
+   |
+help: you might have meant to use the similarly named previously used binding `d`
+   |
+LL -         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+LL +         T::T1(a, d) | T::T2(d, b) | T::T3(d) | T::T4(a) => { println!("{:?}", a); }
+   |
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:23
@@ -27,6 +39,12 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |               |       |             pattern doesn't bind `a`
    |               |       pattern doesn't bind `a`
    |               variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL -         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+LL +         T::T1(c, d) | T::T2(d, b) | T::T3(c) | T::T4(c) => { println!("{:?}", a); }
+   |
 
 error[E0408]: variable `d` is not bound in all patterns
   --> $DIR/issue-39698.rs:10:37
@@ -37,6 +55,12 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |                  |          |       pattern doesn't bind `d`
    |                  |          variable not in all patterns
    |                  variable not in all patterns
+   |
+help: you might have meant to use the similarly named previously used binding `c`
+   |
+LL -         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+LL +         T::T1(a, c) | T::T2(c, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+   |
 
 error[E0381]: used binding `a` is possibly-uninitialized
   --> $DIR/issue-39698.rs:10:79
diff --git a/tests/ui/statics/mutable_memory_validation.stderr b/tests/ui/statics/mutable_memory_validation.stderr
index df36287cc69..1d6ba195fa2 100644
--- a/tests/ui/statics/mutable_memory_validation.stderr
+++ b/tests/ui/statics/mutable_memory_validation.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value at .x.<deref>: encountered `UnsafeCell`
 LL | const MUH: Meh = Meh { x: unsafe { &mut *(&READONLY as *const _ as *mut _) } };
    | ^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
                HEX_DUMP
            }
diff --git a/tests/ui/target-feature/inline-always.aarch64.stderr b/tests/ui/target-feature/inline-always.aarch64.stderr
new file mode 100644
index 00000000000..a9ffb425c52
--- /dev/null
+++ b/tests/ui/target-feature/inline-always.aarch64.stderr
@@ -0,0 +1,60 @@
+warning: call to `#[inline(always)]`-annotated `target_feature_identity` requires the same target features to be inlined
+  --> $DIR/inline-always.rs:19:5
+   |
+LL |     target_feature_identity();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: function will not be inlined
+   = note: the following target features are on `target_feature_identity` but missing from `call_no_target_features`: neon, fp16
+note: `target_feature_identity` is defined here
+  --> $DIR/inline-always.rs:16:1
+   |
+LL | pub unsafe fn target_feature_identity() {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(inline_always_mismatching_target_features)]` on by default
+help: add `#[target_feature]` attribute to `call_no_target_features`
+   |
+LL + #[target_feature(enable = "neon,fp16")]
+LL | unsafe fn call_no_target_features() {
+   |
+
+warning: call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined
+  --> $DIR/inline-always.rs:22:5
+   |
+LL |     multiple_target_features();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: function will not be inlined
+   = note: the following target features are on `multiple_target_features` but missing from `call_no_target_features`: fp16, sve, rdm
+note: `multiple_target_features` is defined here
+  --> $DIR/inline-always.rs:52:1
+   |
+LL | fn multiple_target_features() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: add `#[target_feature]` attribute to `call_no_target_features`
+   |
+LL + #[target_feature(enable = "fp16,sve,rdm")]
+LL | unsafe fn call_no_target_features() {
+   |
+
+warning: call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined
+  --> $DIR/inline-always.rs:28:5
+   |
+LL |     multiple_target_features();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: function will not be inlined
+   = note: the following target features are on `multiple_target_features` but missing from `call_to_first_set`: rdm
+note: `multiple_target_features` is defined here
+  --> $DIR/inline-always.rs:52:1
+   |
+LL | fn multiple_target_features() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: add `#[target_feature]` attribute to `call_to_first_set`
+   |
+LL + #[target_feature(enable = "rdm")]
+LL | unsafe fn call_to_first_set() {
+   |
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/target-feature/inline-always.rs b/tests/ui/target-feature/inline-always.rs
new file mode 100644
index 00000000000..dbf46537caa
--- /dev/null
+++ b/tests/ui/target-feature/inline-always.rs
@@ -0,0 +1,54 @@
+//@ add-core-stubs
+//@ build-pass
+//@ compile-flags: --crate-type=lib
+//@ revisions: aarch64
+//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64] needs-llvm-components: aarch64
+
+#![feature(no_core, target_feature_inline_always)]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+#[inline(always)]
+#[target_feature(enable = "neon,fp16")]
+pub unsafe fn target_feature_identity() {}
+
+unsafe fn call_no_target_features() {
+    target_feature_identity();
+    //~^ WARNING call to `#[inline(always)]`-annotated `target_feature_identity` requires the same target features to be inlined [inline_always_mismatching_target_features]
+    global_feature_enabled();
+    multiple_target_features();
+    //~^ WARNING call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined [inline_always_mismatching_target_features]
+}
+
+#[target_feature(enable = "fp16,sve")]
+unsafe fn call_to_first_set() {
+    multiple_target_features();
+    //~^ WARNING call to `#[inline(always)]`-annotated `multiple_target_features` requires the same target features to be inlined [inline_always_mismatching_target_features]
+}
+
+/* You can't have "fhm" without "fp16" */
+#[target_feature(enable = "fhm")]
+unsafe fn mismatching_features() {
+    target_feature_identity()
+}
+
+#[target_feature(enable = "fp16")]
+unsafe fn matching_target_features() {
+    target_feature_identity()
+}
+
+#[inline(always)]
+#[target_feature(enable = "neon")]
+unsafe fn global_feature_enabled() {
+
+}
+
+#[inline(always)]
+#[target_feature(enable = "fp16,sve")]
+#[target_feature(enable="rdm")]
+fn multiple_target_features() {
+
+ }
diff --git a/tests/ui/target-feature/invalid-attribute.rs b/tests/ui/target-feature/invalid-attribute.rs
index b34a48aba26..a958700231a 100644
--- a/tests/ui/target-feature/invalid-attribute.rs
+++ b/tests/ui/target-feature/invalid-attribute.rs
@@ -61,6 +61,8 @@ trait Baz {}
 
 #[inline(always)]
 //~^ ERROR: cannot use `#[inline(always)]`
+//~| NOTE: see issue #145574 <https://github.com/rust-lang/rust/issues/145574> for more information
+//~| NOTE: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 #[target_feature(enable = "sse2")]
 unsafe fn test() {}
 
diff --git a/tests/ui/target-feature/invalid-attribute.stderr b/tests/ui/target-feature/invalid-attribute.stderr
index 7b75367b48c..d85bccce441 100644
--- a/tests/ui/target-feature/invalid-attribute.stderr
+++ b/tests/ui/target-feature/invalid-attribute.stderr
@@ -106,7 +106,7 @@ LL | #[target_feature(enable = "sse2")]
    = help: `#[target_feature]` can only be applied to functions
 
 error: `#[target_feature]` attribute cannot be used on statics
-  --> $DIR/invalid-attribute.rs:67:1
+  --> $DIR/invalid-attribute.rs:69:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +114,7 @@ LL | #[target_feature(enable = "sse2")]
    = help: `#[target_feature]` can only be applied to functions
 
 error: `#[target_feature]` attribute cannot be used on trait impl blocks
-  --> $DIR/invalid-attribute.rs:71:1
+  --> $DIR/invalid-attribute.rs:73:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -122,7 +122,7 @@ LL | #[target_feature(enable = "sse2")]
    = help: `#[target_feature]` can only be applied to functions
 
 error: `#[target_feature]` attribute cannot be used on inherent impl blocks
-  --> $DIR/invalid-attribute.rs:77:1
+  --> $DIR/invalid-attribute.rs:79:1
    |
 LL | #[target_feature(enable = "sse2")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -130,7 +130,7 @@ LL | #[target_feature(enable = "sse2")]
    = help: `#[target_feature]` can only be applied to functions
 
 error: `#[target_feature]` attribute cannot be used on expressions
-  --> $DIR/invalid-attribute.rs:98:5
+  --> $DIR/invalid-attribute.rs:100:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,18 +138,22 @@ LL |     #[target_feature(enable = "sse2")]
    = help: `#[target_feature]` can only be applied to functions
 
 error: `#[target_feature]` attribute cannot be used on closures
-  --> $DIR/invalid-attribute.rs:104:5
+  --> $DIR/invalid-attribute.rs:106:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: `#[target_feature]` can be applied to methods and functions
 
-error: cannot use `#[inline(always)]` with `#[target_feature]`
+error[E0658]: cannot use `#[inline(always)]` with `#[target_feature]`
   --> $DIR/invalid-attribute.rs:62:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #145574 <https://github.com/rust-lang/rust/issues/145574> for more information
+   = help: add `#![feature(target_feature_inline_always)]` 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: the feature named `foo` is not valid for this target
   --> $DIR/invalid-attribute.rs:20:18
@@ -158,7 +162,7 @@ LL | #[target_feature(enable = "foo")]
    |                  ^^^^^^^^^^^^^^ `foo` is not valid for this target
 
 error[E0046]: not all trait items implemented, missing: `foo`
-  --> $DIR/invalid-attribute.rs:73:1
+  --> $DIR/invalid-attribute.rs:75:1
    |
 LL | impl Quux for u8 {}
    | ^^^^^^^^^^^^^^^^ missing `foo` in implementation
@@ -167,7 +171,7 @@ LL |     fn foo();
    |     --------- `foo` from trait
 
 error: `#[target_feature(..)]` cannot be applied to safe trait method
-  --> $DIR/invalid-attribute.rs:87:5
+  --> $DIR/invalid-attribute.rs:89:5
    |
 LL |     #[target_feature(enable = "sse2")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot be applied to safe trait method
@@ -176,13 +180,13 @@ LL |     fn foo() {}
    |     -------- not an `unsafe` function
 
 error[E0053]: method `foo` has an incompatible type for trait
-  --> $DIR/invalid-attribute.rs:90:5
+  --> $DIR/invalid-attribute.rs:92:5
    |
 LL |     fn foo() {}
    |     ^^^^^^^^ expected safe fn, found unsafe fn
    |
 note: type in trait
-  --> $DIR/invalid-attribute.rs:82:5
+  --> $DIR/invalid-attribute.rs:84:5
    |
 LL |     fn foo();
    |     ^^^^^^^^^
@@ -190,7 +194,7 @@ LL |     fn foo();
               found signature `#[target_features] fn()`
 
 error: the feature named `+sse2` is not valid for this target
-  --> $DIR/invalid-attribute.rs:109:18
+  --> $DIR/invalid-attribute.rs:111:18
    |
 LL | #[target_feature(enable = "+sse2")]
    |                  ^^^^^^^^^^^^^^^^ `+sse2` is not valid for this target
@@ -199,5 +203,5 @@ LL | #[target_feature(enable = "+sse2")]
 
 error: aborting due to 24 previous errors
 
-Some errors have detailed explanations: E0046, E0053, E0539.
+Some errors have detailed explanations: E0046, E0053, E0539, E0658.
 For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs b/tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs
new file mode 100644
index 00000000000..f97005a1450
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/kcfi-normalize-ints.rs
@@ -0,0 +1,7 @@
+//@ no-prefer-dynamic
+//@ needs-sanitizer-kcfi
+//@ compile-flags: -C panic=abort -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
diff --git a/tests/ui/target_modifiers/auxiliary/no-sanitizers.rs b/tests/ui/target_modifiers/auxiliary/no-sanitizers.rs
new file mode 100644
index 00000000000..1d47ff6826d
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/no-sanitizers.rs
@@ -0,0 +1,6 @@
+//@ no-prefer-dynamic
+//@ compile-flags: -C panic=abort
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
diff --git a/tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs b/tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs
new file mode 100644
index 00000000000..029744d2a1f
--- /dev/null
+++ b/tests/ui/target_modifiers/auxiliary/safestack-and-kcfi.rs
@@ -0,0 +1,10 @@
+//@ no-prefer-dynamic
+
+//@ needs-sanitizer-kcfi
+//@ needs-sanitizer-safestack
+
+//@ compile-flags: -C panic=abort -Zsanitizer=safestack,kcfi
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs
new file mode 100644
index 00000000000..cb9f701349a
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.rs
@@ -0,0 +1,18 @@
+// For kCFI, the helper flag -Zsanitizer-cfi-normalize-integers should also be a target modifier.
+
+//@ needs-sanitizer-kcfi
+//@ aux-build:kcfi-normalize-ints.rs
+//@ compile-flags: -Cpanic=abort
+
+//@ revisions: ok wrong_flag wrong_sanitizer
+//@[ok] compile-flags: -Zsanitizer=kcfi -Zsanitizer-cfi-normalize-integers
+//@[wrong_flag] compile-flags: -Zsanitizer=kcfi
+//@[ok] check-pass
+
+#![feature(no_core)]
+//[wrong_flag]~^ ERROR mixing `-Zsanitizer-cfi-normalize-integers` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+//[wrong_sanitizer]~^^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+#![crate_type = "rlib"]
+#![no_core]
+
+extern crate kcfi_normalize_ints;
diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr
new file mode 100644
index 00000000000..1db79b025e9
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_flag.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer-cfi-normalize-integers` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+  --> $DIR/sanitizer-kcfi-normalize-ints.rs:12:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer-cfi-normalize-integers` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: unset `-Zsanitizer-cfi-normalize-integers` in this crate is incompatible with `-Zsanitizer-cfi-normalize-integers=` in dependency `kcfi_normalize_ints`
+   = help: set `-Zsanitizer-cfi-normalize-integers=` in this crate or unset `-Zsanitizer-cfi-normalize-integers` in `kcfi_normalize_ints`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer-cfi-normalize-integers` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr
new file mode 100644
index 00000000000..5b949c87350
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizer-kcfi-normalize-ints.wrong_sanitizer.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizer_kcfi_normalize_ints`
+  --> $DIR/sanitizer-kcfi-normalize-ints.rs:12:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: unset `-Zsanitizer` in this crate is incompatible with `-Zsanitizer=kcfi` in dependency `kcfi_normalize_ints`
+   = help: set `-Zsanitizer=kcfi` in this crate or unset `-Zsanitizer` in `kcfi_normalize_ints`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs b/tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs
new file mode 100644
index 00000000000..abda7be9e40
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-good-for-inconsistency.rs
@@ -0,0 +1,19 @@
+// AddressSanitizer, LeakSanitizer are good to be inconsistent (they are not a target modifiers)
+
+//@ revisions: wrong_address_san wrong_leak_san
+
+//@[wrong_address_san] needs-sanitizer-address
+//@[wrong_leak_san] needs-sanitizer-leak
+
+//@ aux-build:no-sanitizers.rs
+//@ compile-flags: -Cpanic=abort -C target-feature=-crt-static
+
+//@[wrong_address_san] compile-flags: -Zsanitizer=address
+//@[wrong_leak_san] compile-flags: -Zsanitizer=leak
+//@ check-pass
+
+#![feature(no_core)]
+#![crate_type = "rlib"]
+#![no_core]
+
+extern crate no_sanitizers;
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr
new file mode 100644
index 00000000000..440a91c7707
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_both.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+  --> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: unset `-Zsanitizer` in this crate is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi`
+   = help: set `-Zsanitizer=safestack,kcfi` in this crate or unset `-Zsanitizer` in `safestack_and_kcfi`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr
new file mode 100644
index 00000000000..6cdd7facc37
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_kcfi.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+  --> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: `-Zsanitizer=safestack` in this crate is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi`
+   = help: set `-Zsanitizer=safestack,kcfi` in this crate or `-Zsanitizer=safestack` in `safestack_and_kcfi`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr
new file mode 100644
index 00000000000..ecfbcace39f
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.missed_safestack.stderr
@@ -0,0 +1,13 @@
+error: mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+  --> $DIR/sanitizers-safestack-and-kcfi.rs:16:1
+   |
+LL | #![feature(no_core)]
+   | ^
+   |
+   = help: the `-Zsanitizer` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
+   = note: `-Zsanitizer=kcfi` in this crate is incompatible with `-Zsanitizer=safestack,kcfi` in dependency `safestack_and_kcfi`
+   = help: set `-Zsanitizer=safestack,kcfi` in this crate or `-Zsanitizer=kcfi` in `safestack_and_kcfi`
+   = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=sanitizer` to silence this error
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs
new file mode 100644
index 00000000000..6c3ceb7e910
--- /dev/null
+++ b/tests/ui/target_modifiers/sanitizers-safestack-and-kcfi.rs
@@ -0,0 +1,23 @@
+//@ needs-sanitizer-kcfi
+//@ needs-sanitizer-safestack
+
+//@ aux-build:safestack-and-kcfi.rs
+//@ compile-flags: -Cpanic=abort
+
+//@ revisions: good good_reverted missed_safestack missed_kcfi missed_both
+//@[good] compile-flags: -Zsanitizer=safestack,kcfi
+//@[good_reverted] compile-flags: -Zsanitizer=kcfi,safestack
+//@[missed_safestack] compile-flags: -Zsanitizer=kcfi
+//@[missed_kcfi] compile-flags: -Zsanitizer=safestack
+// [missed_both] no additional compile-flags:
+//@[good] check-pass
+//@[good_reverted] check-pass
+
+#![feature(no_core)]
+//[missed_safestack]~^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+//[missed_kcfi]~^^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+//[missed_both]~^^^ ERROR mixing `-Zsanitizer` will cause an ABI mismatch in crate `sanitizers_safestack_and_kcfi`
+#![crate_type = "rlib"]
+#![no_core]
+
+extern crate safestack_and_kcfi;
diff --git a/tests/ui/type/pattern_types/validity.stderr b/tests/ui/type/pattern_types/validity.stderr
index b545cd75ddb..e19915a58a3 100644
--- a/tests/ui/type/pattern_types/validity.stderr
+++ b/tests/ui/type/pattern_types/validity.stderr
@@ -4,7 +4,7 @@ error[E0080]: constructing invalid value: encountered 0, but expected something
 LL | const BAD: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                HEX_DUMP
            }
@@ -34,7 +34,7 @@ error[E0080]: constructing invalid value at .0: encountered 0, but expected some
 LL | const BAD_AGGREGATE: (pattern_type!(u32 is 1..), u32) = (unsafe { std::mem::transmute(0) }, 0);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 8, align: 4) {
                HEX_DUMP
            }
@@ -45,7 +45,7 @@ error[E0080]: constructing invalid value at .0.0: encountered 0, but expected so
 LL | const BAD_FOO: Foo = Foo(Bar(unsafe { std::mem::transmute(0) }));
    | ^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                HEX_DUMP
            }
@@ -66,7 +66,7 @@ error[E0080]: constructing invalid value: encountered 97, but expected something
 LL | const CHAR_OOB_PAT: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute('a') };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                HEX_DUMP
            }
@@ -77,7 +77,7 @@ error[E0080]: constructing invalid value: encountered 0xffffffff, but expected a
 LL | const CHAR_OOB: pattern_type!(char is 'A'..'Z') = unsafe { std::mem::transmute(u32::MAX) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ it is undefined behavior to use this value
    |
-   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+   = note: the rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
    = note: the raw bytes of the constant (size: 4, align: 4) {
                HEX_DUMP
            }
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs
index 1a9652c1023..5a683884238 100644
--- a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.rs
@@ -9,6 +9,6 @@
 #[stable(feature = "a", since = "1.1.1")]
 #[unstable_feature_bound(feat_bar)]
 fn bar() {}
-//~^ ERROR Item annotated with `#[unstable_feature_bound]` should not be stable
+//~^ ERROR item annotated with `#[unstable_feature_bound]` should not be stable
 
 fn main() {}
diff --git a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr
index 9cb6a181bef..9f07e63e454 100644
--- a/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr
+++ b/tests/ui/unstable-feature-bound/unstable_feature_bound_incompatible_stability.stderr
@@ -1,4 +1,4 @@
-error: Item annotated with `#[unstable_feature_bound]` should not be stable
+error: item annotated with `#[unstable_feature_bound]` should not be stable
   --> $DIR/unstable_feature_bound_incompatible_stability.rs:11:1
    |
 LL | fn bar() {}
diff --git a/triagebot.toml b/triagebot.toml
index cf2e95203fa..b957c6465e6 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -1306,6 +1306,21 @@ cc = ["@m-ou-se"]
 [mentions."compiler/rustc_ast_lowering/src/format.rs"]
 cc = ["@m-ou-se"]
 
+[mentions."#[miri::intrinsic_fallback_is_spec]"]
+type = "content"
+message = """
+`#[miri::intrinsic_fallback_is_spec]` must only be used if the function actively checks for all UB cases,
+and explores the possible non-determinism of the intrinsic.
+"""
+cc = ["@rust-lang/miri"]
+[mentions."#[rustc_allow_const_fn_unstable"]
+type = "content"
+message = """
+`#[rustc_allow_const_fn_unstable]` needs careful audit to avoid accidentally exposing unstable
+implementation details on stable.
+"""
+cc = ["@rust-lang/wg-const-eval"]
+
 
 # ------------------------------------------------------------------------------
 # PR assignments