about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Conjob Bot <miri@cron.bot>2023-09-27 05:48:00 +0000
committerThe Miri Conjob Bot <miri@cron.bot>2023-09-27 05:48:00 +0000
commitb1f5c6683bb38da2cef8d1aa3fb3f88c357d4ae4 (patch)
treef8a0d9b55658cff808aa5a8fd51d468c446ef950
parentfc0d833f6fb9876c367bb738927525102e5761a7 (diff)
parent085acd02d4abaf2ccaf629134caa83cfe23283c8 (diff)
downloadrust-b1f5c6683bb38da2cef8d1aa3fb3f88c357d4ae4.tar.gz
rust-b1f5c6683bb38da2cef8d1aa3fb3f88c357d4ae4.zip
Merge from rustc
-rw-r--r--Cargo.lock138
-rw-r--r--compiler/rustc/Cargo.toml1
-rw-r--r--compiler/rustc_arena/src/lib.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs24
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs8
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs14
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs11
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs9
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs25
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/filter_profile.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs103
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs73
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs23
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs5
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs4
-rw-r--r--compiler/rustc_data_structures/src/lib.rs3
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs4
-rw-r--r--compiler/rustc_data_structures/src/small_c_str.rs6
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs8
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0038.md7
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0094.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0211.md4
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs5
-rw-r--r--compiler/rustc_hir/src/def.rs10
-rw-r--r--compiler/rustc_hir/src/target.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs96
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs29
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs22
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/variance/terms.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs87
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs7
-rw-r--r--compiler/rustc_incremental/src/lib.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs132
-rw-r--r--compiler/rustc_incremental/src/persist/mod.rs3
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs2
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs7
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs4
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs6
-rw-r--r--compiler/rustc_interface/src/queries.rs47
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs52
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp4
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs30
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs3
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs4
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs2
-rw-r--r--compiler/rustc_middle/src/mir/query.rs3
-rw-r--r--compiler/rustc_middle/src/query/mod.rs10
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs6
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs4
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs2
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs12
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs24
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs10
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs2
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs10
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_middle/src/values.rs2
-rw-r--r--compiler/rustc_mir_build/messages.ftl3
-rw-r--r--compiler/rustc_mir_build/src/errors.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs37
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs4
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs21
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs2
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs43
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs6
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs2
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
-rw-r--r--compiler/rustc_monomorphize/src/util.rs4
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/abi_test.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs26
-rw-r--r--compiler/rustc_passes/src/dead.rs4
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--compiler/rustc_passes/src/layout_test.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs6
-rw-r--r--compiler/rustc_query_system/src/query/job.rs4
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs4
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs7
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs6
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs4
-rw-r--r--compiler/rustc_smir/Cargo.toml26
-rw-r--r--compiler/rustc_smir/src/lib.rs16
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs93
-rw-r--r--compiler/rustc_smir/src/rustc_smir/alloc.rs8
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs73
-rw-r--r--compiler/rustc_span/src/lib.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs2
-rw-r--r--compiler/rustc_target/src/spec/riscv64_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/uefi_msvc_base.rs1
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs5
-rw-r--r--compiler/rustc_trait_selection/src/solve/canonicalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs74
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs9
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs4
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs8
-rw-r--r--compiler/rustc_type_ir/src/sty.rs24
-rw-r--r--compiler/stable_mir/Cargo.toml8
-rw-r--r--compiler/stable_mir/README.md (renamed from compiler/rustc_smir/README.md)0
-rw-r--r--compiler/stable_mir/rust-toolchain.toml (renamed from compiler/rustc_smir/rust-toolchain.toml)0
-rw-r--r--compiler/stable_mir/src/fold.rs (renamed from compiler/rustc_smir/src/stable_mir/fold.rs)2
-rw-r--r--compiler/stable_mir/src/lib.rs (renamed from compiler/rustc_smir/src/stable_mir/mod.rs)78
-rw-r--r--compiler/stable_mir/src/mir.rs (renamed from compiler/rustc_smir/src/stable_mir/mir.rs)0
-rw-r--r--compiler/stable_mir/src/mir/body.rs (renamed from compiler/rustc_smir/src/stable_mir/mir/body.rs)22
-rw-r--r--compiler/stable_mir/src/ty.rs (renamed from compiler/rustc_smir/src/stable_mir/ty.rs)41
-rw-r--r--compiler/stable_mir/src/visitor.rs (renamed from compiler/rustc_smir/src/stable_mir/visitor.rs)2
-rw-r--r--library/core/src/macros/mod.rs89
-rw-r--r--library/core/src/marker.rs7
-rw-r--r--library/core/src/num/uint_macros.rs16
-rw-r--r--library/core/src/pin.rs5
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/core/tests/macros.rs154
-rw-r--r--library/panic_abort/src/lib.rs3
-rw-r--r--library/proc_macro/src/lib.rs10
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/build.rs2
-rw-r--r--library/std/src/io/error.rs8
-rw-r--r--library/std/src/io/mod.rs35
-rw-r--r--library/std/src/lib.rs3
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/uefi/env.rs92
-rw-r--r--library/std/src/os/uefi/mod.rs8
-rw-r--r--library/std/src/os/unix/io/mod.rs11
-rw-r--r--library/std/src/os/windows/io/mod.rs11
-rw-r--r--library/std/src/sys/common/thread_local/mod.rs2
-rw-r--r--library/std/src/sys/mod.rs4
-rw-r--r--library/std/src/sys/uefi/alloc.rs33
-rw-r--r--library/std/src/sys/uefi/env.rs9
-rw-r--r--library/std/src/sys/uefi/helpers.rs141
-rw-r--r--library/std/src/sys/uefi/mod.rs244
-rw-r--r--library/std/src/sys/uefi/os.rs237
-rw-r--r--library/std/src/sys/uefi/path.rs25
-rw-r--r--library/std/src/sys/uefi/tests.rs21
-rw-r--r--library/std/src/sys_common/mod.rs1
-rw-r--r--src/bootstrap/compile.rs5
-rw-r--r--src/bootstrap/config.rs6
-rwxr-xr-xsrc/ci/scripts/setup-environment.sh2
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/platform-support/unknown-uefi.md77
-rw-r--r--src/doc/rustdoc/src/unstable-features.md2
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs27
-rw-r--r--src/librustdoc/clean/types.rs44
-rw-r--r--src/librustdoc/formats/item_type.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml8
-rw-r--r--src/tools/clippy/CHANGELOG.md5
-rw-r--r--src/tools/clippy/Cargo.toml1
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md14
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/default_union_representation.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs374
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_variants.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/error_impl_error.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/format_impl.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/init_numbered_fields.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_futures.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/utils.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/needless_match.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs101
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs89
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs176
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs410
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs71
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/raw_strings.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs93
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs110
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs31
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs35
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs40
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs16
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/compile-test.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed6
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr18
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr21
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs3
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed10
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr17
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs17
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed7
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed10
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs14
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs9
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs5
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed9
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs9
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs18
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml3
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr (renamed from src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr)74
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr (renamed from src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr)132
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs30
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed7
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr11
-rw-r--r--src/tools/clippy/tests/ui/cast.rs4
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.fixed11
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.rs11
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.stderr14
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed3
-rw-r--r--src/tools/clippy/tests/ui/eta.rs3
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr54
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed15
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters.rs15
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.fixed24
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.rs24
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.stderr26
-rw-r--r--src/tools/clippy/tests/ui/len_without_is_empty.rs23
-rw-r--r--src/tools/clippy/tests/ui/len_without_is_empty.stderr8
-rw-r--r--src/tools/clippy/tests/ui/let_unit.fixed2
-rw-r--r--src/tools/clippy/tests/ui/let_unit.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.stderr42
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed290
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs290
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr90
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed287
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs287
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr77
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs40
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr34
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr26
-rw-r--r--src/tools/clippy/tests/ui/no_effect_return.rs1
-rw-r--r--src/tools/clippy/tests/ui/no_effect_return.stderr8
-rw-r--r--src/tools/clippy/tests/ui/option_filter_map.fixed2
-rw-r--r--src/tools/clippy/tests/ui/option_filter_map.rs2
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.fixed36
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.rs36
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.stderr17
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.rs5
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.fixed24
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.rs24
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.stderr17
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.fixed11
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.rs11
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.stderr2
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.fixed50
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.rs50
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.stderr116
-rw-r--r--src/tools/clippy/tests/ui/regex.rs3
-rw-r--r--src/tools/clippy/tests/ui/regex.stderr48
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_null_to_fn.rs11
-rw-r--r--src/tools/clippy/tests/ui/transmute_null_to_fn.stderr26
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs534
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed56
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs56
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr53
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs2
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.rs28
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.stderr47
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.fixed91
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.rs91
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.stderr70
-rw-r--r--src/tools/clippy/tests/ui/vec_box_sized.fixed5
-rw-r--r--src/tools/clippy/tests/ui/vec_box_sized.rs5
-rw-r--r--src/tools/tidy/src/deps.rs8
-rw-r--r--src/tools/tidy/src/pal.rs1
-rw-r--r--tests/assembly/closure-inherit-target-feature.rs58
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff119
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff123
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff119
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff123
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff111
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff115
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff111
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff115
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs17
-rw-r--r--tests/rustdoc-ui/issue-102467.rs15
-rw-r--r--tests/rustdoc-ui/issue-102467.stderr9
-rw-r--r--tests/rustdoc/inline_cross/async-fn.rs19
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/async-fn.rs18
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs6
-rw-r--r--tests/rustdoc/inline_cross/impl_trait.rs8
-rw-r--r--tests/ui-fulldeps/stable-mir/compilation-result.rs3
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs30
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs8
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr55
-rw-r--r--tests/ui/async-await/const-async-fn-in-main.rs7
-rw-r--r--tests/ui/async-await/const-async-fn-in-main.stderr11
-rw-r--r--tests/ui/closures/issue-112547.rs15
-rw-r--r--tests/ui/closures/issue-112547.stderr23
-rw-r--r--tests/ui/codegen/issue-79865-llvm-miscompile.rs38
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs2
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr35
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.rs3
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.stderr23
-rw-r--r--tests/ui/error-codes/E0094.rs2
-rw-r--r--tests/ui/extern/extern-with-type-bounds.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs13
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs26
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs23
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr16
-rw-r--r--tests/ui/impl-trait/opaque-cast-field-access-in-future.rs27
-rw-r--r--tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr9
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.rs6
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr20
-rw-r--r--tests/ui/intrinsics/intrinsic-alignment.rs2
-rw-r--r--tests/ui/issues/issue-27042.stderr15
-rw-r--r--tests/ui/loops/loop-break-value.rs60
-rw-r--r--tests/ui/loops/loop-break-value.stderr135
-rw-r--r--tests/ui/loops/loop-labeled-break-value.stderr39
-rw-r--r--tests/ui/loops/loop-properly-diverging-2.stderr13
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.rs (renamed from tests/ui/match/issue-72896.rs)3
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.stderr23
-rw-r--r--tests/ui/never_type/issue-52443.stderr10
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr4
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-val.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr2
-rw-r--r--tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr4
-rw-r--r--tests/ui/proc-macro/auxiliary/print-tokens.rs16
-rw-r--r--tests/ui/proc-macro/literal-to-string.rs26
-rw-r--r--tests/ui/proc-macro/literal-to-string.stdout107
-rw-r--r--tests/ui/repr/16-bit-repr-c-enum.rs2
-rw-r--r--tests/ui/structs-enums/rec-align-u32.rs2
-rw-r--r--tests/ui/structs-enums/rec-align-u64.rs2
-rw-r--r--tests/ui/type/type-error-break-tail.stderr13
-rw-r--r--triagebot.toml4
459 files changed, 8299 insertions, 3493 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d9aaedb8544..014e14e5399 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -118,16 +118,15 @@ dependencies = [
 
 [[package]]
 name = "anstream"
-version = "0.3.2"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
+checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
 dependencies = [
  "anstyle",
  "anstyle-parse",
  "anstyle-query",
  "anstyle-wincon",
  "colorchoice",
- "is-terminal",
  "utf8parse",
 ]
 
@@ -157,9 +156,9 @@ dependencies = [
 
 [[package]]
 name = "anstyle-wincon"
-version = "1.0.1"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
+checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
 dependencies = [
  "anstyle",
  "windows-sys 0.48.0",
@@ -291,9 +290,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.3.3"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
+checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
 
 [[package]]
 name = "block-buffer"
@@ -459,25 +458,23 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.3.10"
+version = "4.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a"
+checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136"
 dependencies = [
  "clap_builder",
  "clap_derive",
- "once_cell",
 ]
 
 [[package]]
 name = "clap_builder"
-version = "4.3.10"
+version = "4.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef137bbe35aab78bdb468ccfba75a5f4d8321ae011d34063770780545176af2d"
+checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56"
 dependencies = [
  "anstream",
  "anstyle",
  "clap_lex",
- "once_cell",
  "strsim",
  "terminal_size",
 ]
@@ -493,9 +490,9 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.3.2"
+version = "4.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f"
+checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -515,7 +512,6 @@ version = "0.1.74"
 dependencies = [
  "clippy_lints",
  "clippy_utils",
- "derive-new",
  "filetime",
  "futures",
  "if_chain",
@@ -945,17 +941,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "derive-new"
-version = "0.5.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
 name = "derive_builder"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1253,12 +1238,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 
 [[package]]
 name = "fastrand"
-version = "1.9.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
-dependencies = [
- "instant",
-]
+checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
 
 [[package]]
 name = "field-offset"
@@ -1994,17 +1976,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "io-lifetimes"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
-dependencies = [
- "hermit-abi 0.3.2",
- "libc",
- "windows-sys 0.48.0",
-]
-
-[[package]]
 name = "ipnet"
 version = "2.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2017,7 +1988,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb"
 dependencies = [
  "hermit-abi 0.3.2",
- "rustix 0.38.2",
+ "rustix",
  "windows-sys 0.48.0",
 ]
 
@@ -2214,15 +2185,9 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.4.3"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0"
+checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
 
 [[package]]
 name = "litemap"
@@ -3007,6 +2972,27 @@ dependencies = [
 ]
 
 [[package]]
+name = "r-efi"
+version = "4.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "575fc2d9b3da54adbdfaddf6eca48fec256d977c8630a1750b8991347d1ac911"
+dependencies = [
+ "compiler_builtins",
+ "rustc-std-workspace-core",
+]
+
+[[package]]
+name = "r-efi-alloc"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31d6f09fe2b6ad044bc3d2c34ce4979796581afd2f1ebc185837e02421e02fd7"
+dependencies = [
+ "compiler_builtins",
+ "r-efi",
+ "rustc-std-workspace-core",
+]
+
+[[package]]
 name = "rand"
 version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3259,6 +3245,7 @@ dependencies = [
  "rustc_driver",
  "rustc_driver_impl",
  "rustc_smir",
+ "stable_mir",
 ]
 
 [[package]]
@@ -4423,7 +4410,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
- "scoped-tls",
+ "stable_mir",
  "tracing",
 ]
 
@@ -4690,28 +4677,14 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.37.22"
+version = "0.38.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
+checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
 dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.0",
  "errno",
- "io-lifetimes",
  "libc",
- "linux-raw-sys 0.3.8",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "rustix"
-version = "0.38.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4"
-dependencies = [
- "bitflags 2.3.3",
- "errno",
- "libc",
- "linux-raw-sys 0.4.3",
+ "linux-raw-sys",
  "windows-sys 0.48.0",
 ]
 
@@ -4975,6 +4948,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 
 [[package]]
+name = "stable_mir"
+version = "0.1.0-preview"
+dependencies = [
+ "scoped-tls",
+ "tracing",
+]
+
+[[package]]
 name = "stacker"
 version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5012,6 +4993,8 @@ dependencies = [
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
+ "r-efi",
+ "r-efi-alloc",
  "rand",
  "rand_xorshift",
  "rustc-demangle",
@@ -5173,15 +5156,14 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.6.0"
+version = "3.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
+checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
 dependencies = [
- "autocfg",
  "cfg-if",
  "fastrand",
  "redox_syscall 0.3.5",
- "rustix 0.37.22",
+ "rustix",
  "windows-sys 0.48.0",
 ]
 
@@ -5218,11 +5200,11 @@ dependencies = [
 
 [[package]]
 name = "terminal_size"
-version = "0.2.6"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
+checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
 dependencies = [
- "rustix 0.37.22",
+ "rustix",
  "windows-sys 0.48.0",
 ]
 
diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index 41003ad83f3..dcb165f9fdb 100644
--- a/compiler/rustc/Cargo.toml
+++ b/compiler/rustc/Cargo.toml
@@ -13,6 +13,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
 # Make sure rustc_smir ends up in the sysroot, because this
 # crate is intended to be used by stable MIR consumers, which are not in-tree
 rustc_smir = { path = "../rustc_smir" }
+stable_mir = { path = "../stable_mir" }
 
 [dependencies.jemalloc-sys]
 version = "0.5.0"
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index f14463fe940..23fdd272ffd 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -37,9 +37,10 @@ use std::ptr::{self, NonNull};
 use std::slice;
 use std::{cmp, intrinsics};
 
+/// This calls the passed function while ensuring it won't be inlined into the caller.
 #[inline(never)]
 #[cold]
-fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
+fn outline<F: FnOnce() -> R, R>(f: F) -> R {
     f()
 }
 
@@ -600,7 +601,7 @@ impl DroplessArena {
                 unsafe { self.write_from_iter(iter, len, mem) }
             }
             (_, _) => {
-                cold_path(move || -> &mut [T] {
+                outline(move || -> &mut [T] {
                     let mut vec: SmallVec<[_; 8]> = iter.collect();
                     if vec.is_empty() {
                         return &mut [];
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5b172b863ab..85ab5e7223b 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1664,7 +1664,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     lifetime.ident,
                 ));
 
-                // Now make an arg that we can use for the substs of the opaque tykind.
+                // Now make an arg that we can use for the generic params of the opaque tykind.
                 let id = self.next_node_id();
                 let lifetime_arg = self.new_named_lifetime_with_res(id, lifetime.ident, res);
                 let duplicated_lifetime_def_id = self.local_def_id(duplicated_lifetime_node_id);
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 8405ae6ff8e..62dc7ae58a2 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -578,11 +578,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
         }
     }
 
-    // All uses of `gate_all!` below this point were added in #65742,
+    // All uses of `gate_all_legacy_dont_use!` below this point were added in #65742,
     // and subsequently disabled (with the non-early gating readded).
     // We emit an early future-incompatible warning for these.
     // New syntax gates should go above here to get a hard error gate.
-    macro_rules! gate_all {
+    macro_rules! gate_all_legacy_dont_use {
         ($gate:ident, $msg:literal) => {
             for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                 gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg);
@@ -590,13 +590,19 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
         };
     }
 
-    gate_all!(trait_alias, "trait aliases are experimental");
-    gate_all!(associated_type_bounds, "associated type bounds are unstable");
-    gate_all!(return_type_notation, "return type notation is experimental");
-    gate_all!(decl_macro, "`macro` is experimental");
-    gate_all!(box_patterns, "box pattern syntax is experimental");
-    gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
-    gate_all!(try_blocks, "`try` blocks are unstable");
+    gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental");
+    gate_all_legacy_dont_use!(associated_type_bounds, "associated type bounds are unstable");
+    // Despite being a new feature, `where T: Trait<Assoc(): Sized>`, which is RTN syntax now,
+    // used to be gated under associated_type_bounds, which are right above, so RTN needs to
+    // be too.
+    gate_all_legacy_dont_use!(return_type_notation, "return type notation is experimental");
+    gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental");
+    gate_all_legacy_dont_use!(box_patterns, "box pattern syntax is experimental");
+    gate_all_legacy_dont_use!(
+        exclusive_range_pattern,
+        "exclusive range pattern syntax is experimental"
+    );
+    gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable");
 
     visit::walk_crate(&mut visitor, krate);
 }
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 096bf826cfb..55d581b3ab1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -27,7 +27,7 @@ pub(crate) struct RegionName {
 /// This helps to print the right kinds of diagnostics.
 #[derive(Debug, Clone)]
 pub(crate) enum RegionNameSource {
-    /// A bound (not free) region that was substituted at the def site (not an HRTB).
+    /// A bound (not free) region that was instantiated at the def site (not an HRTB).
     NamedEarlyBoundRegion(Span),
     /// A free region that the user has a name (`'a`) for.
     NamedFreeRegion(Span),
@@ -354,7 +354,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                     })
                 }
 
-                ty::BoundRegionKind::BrAnon(..) => None,
+                ty::BoundRegionKind::BrAnon => None,
             },
 
             ty::ReLateBound(..)
@@ -516,7 +516,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                         // be the same as those of the ADT.
                         // FIXME: We should be able to do something similar to
                         // match_adt_and_segment in this case.
-                        Res::Def(DefKind::TyAlias { .. }, _) => (),
+                        Res::Def(DefKind::TyAlias, _) => (),
                         _ => {
                             if let Some(last_segment) = path.segments.last() {
                                 if let Some(highlight) = self.match_adt_and_segment(
@@ -619,7 +619,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                     // programs, so we need to use delay_span_bug here. See #82126.
                     self.infcx.tcx.sess.delay_span_bug(
                         hir_arg.span(),
-                        format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"),
+                        format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
                     );
                 }
             }
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 1049e7a8bbe..852935676b6 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -2250,7 +2250,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
     pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
         // Query canonicalization can create local superuniverses (for example in
-        // `InferCtx::query_response_substitution_guess`), but they don't have an associated
+        // `InferCtx::query_response_instantiation_guess`), but they don't have an associated
         // `UniverseInfo` explaining why they were created.
         // This can cause ICEs if these causes are accessed in diagnostics, for example in issue
         // #114907 where this happens via liveness and dropck outlives results.
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index 4c7c4982050..5d6f5cc8967 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -7,7 +7,7 @@ use rustc_middle::mir::visit::{MutVisitor, TyContext};
 use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc_span::{Span, Symbol};
+use rustc_span::Symbol;
 
 /// Replaces all free regions appearing in the MIR with fresh
 /// inference variables, returning the number of variables created.
@@ -29,20 +29,14 @@ pub fn renumber_mir<'tcx>(
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
-pub(crate) enum BoundRegionInfo {
-    Name(Symbol),
-    Span(Span),
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
 pub(crate) enum RegionCtxt {
     Location(Location),
     TyContext(TyContext),
     Free(Symbol),
-    Bound(BoundRegionInfo),
-    LateBound(BoundRegionInfo),
+    Bound(Symbol),
+    LateBound(Symbol),
     Existential(Option<Symbol>),
-    Placeholder(BoundRegionInfo),
+    Placeholder(Symbol),
     Unknown,
 }
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 60e6dcaf0b8..9b952f3fe36 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1007,7 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     }
 
     pub(super) fn register_predefined_opaques_in_new_solver(&mut self) {
-        // OK to use the identity substitutions for each opaque type key, since
+        // OK to use the identity arguments for each opaque type key, since
         // we remap opaques from HIR typeck back to their definition params.
         let opaques: Vec<_> = self
             .infcx
@@ -1367,14 +1367,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
                 };
                 let (sig, map) = tcx.replace_late_bound_regions(sig, |br| {
-                    use crate::renumber::{BoundRegionInfo, RegionCtxt};
+                    use crate::renumber::RegionCtxt;
 
                     let region_ctxt_fn = || {
                         let reg_info = match br.kind {
-                            ty::BoundRegionKind::BrAnon(Some(span)) => BoundRegionInfo::Span(span),
-                            ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(sym::anon),
-                            ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
-                            ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env),
+                            ty::BoundRegionKind::BrAnon => sym::anon,
+                            ty::BoundRegionKind::BrNamed(_, name) => name,
+                            ty::BoundRegionKind::BrEnv => sym::env,
                         };
 
                         RegionCtxt::LateBound(reg_info)
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index e0c6295627b..c1f82e19c02 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -11,7 +11,7 @@ use rustc_span::{Span, Symbol};
 
 use crate::constraints::OutlivesConstraint;
 use crate::diagnostics::UniverseInfo;
-use crate::renumber::{BoundRegionInfo, RegionCtxt};
+use crate::renumber::RegionCtxt;
 use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker};
 
 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@@ -126,10 +126,9 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
             .placeholder_region(self.type_checker.infcx, placeholder);
 
         let reg_info = match placeholder.bound.kind {
-            ty::BoundRegionKind::BrAnon(Some(span)) => BoundRegionInfo::Span(span),
-            ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(sym::anon),
-            ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
-            ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env),
+            ty::BoundRegionKind::BrAnon => sym::anon,
+            ty::BoundRegionKind::BrNamed(_, name) => name,
+            ty::BoundRegionKind::BrEnv => sym::env,
         };
 
         if cfg!(debug_assertions) {
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 02b52784ede..af437f36b9f 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -28,7 +28,7 @@ use rustc_span::symbol::{kw, sym};
 use rustc_span::Symbol;
 use std::iter;
 
-use crate::renumber::{BoundRegionInfo, RegionCtxt};
+use crate::renumber::RegionCtxt;
 use crate::BorrowckInferCtxt;
 
 #[derive(Debug)]
@@ -446,9 +446,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     if !indices.indices.contains_key(&r) {
                         let region_vid = {
                             let name = r.get_name_or_anon();
-                            self.infcx.next_nll_region_var(FR, || {
-                                RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                            })
+                            self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                         };
 
                         debug!(?region_vid);
@@ -480,9 +478,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             if !indices.indices.contains_key(&r) {
                 let region_vid = {
                     let name = r.get_name_or_anon();
-                    self.infcx.next_nll_region_var(FR, || {
-                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                    })
+                    self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                 };
 
                 debug!(?region_vid);
@@ -643,10 +639,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         };
 
         let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
-        let subst_mapping =
-            iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
+        let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
 
-        UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
+        UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static }
     }
 
     fn compute_inputs_and_output(
@@ -796,7 +791,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
                     _ => sym::anon,
                 };
 
-                self.next_nll_region_var(origin, || RegionCtxt::Bound(BoundRegionInfo::Name(name)))
+                self.next_nll_region_var(origin, || RegionCtxt::Bound(name))
             };
 
             indices.insert_late_bound_region(liberated_region, region_vid.as_var());
@@ -826,9 +821,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
             if !indices.indices.contains_key(&r) {
                 let region_vid = {
                     let name = r.get_name_or_anon();
-                    self.next_nll_region_var(FR, || {
-                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                    })
+                    self.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                 };
 
                 debug!(?region_vid);
@@ -848,9 +841,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
             if !indices.indices.contains_key(&r) {
                 let region_vid = {
                     let name = r.get_name_or_anon();
-                    self.next_nll_region_var(FR, || {
-                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                    })
+                    self.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                 };
 
                 indices.insert_late_bound_region(r, region_vid.as_var());
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 2c8e6f99c67..8027ca2e7bb 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -41,7 +41,7 @@ pub fn expand_deriving_const_param_ty(
         path: path_std!(marker::ConstParamTy),
         skip_path_as_bound: false,
         needs_copy_as_bound_if_packed: false,
-        additional_bounds: Vec::new(),
+        additional_bounds: vec![ty::Ty::Path(path_std!(cmp::Eq))],
         supports_unions: false,
         methods: Vec::new(),
         associated_types: Vec::new(),
diff --git a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
index f782671fe36..03912b18ea5 100755
--- a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
+++ b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
@@ -100,9 +100,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
             stack = &stack[..index + ENCODE_METADATA.len()];
         }
 
-        const SUBST_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::subst_and_normalize_erasing_regions";
-        if let Some(index) = stack.find(SUBST_AND_NORMALIZE_ERASING_REGIONS) {
-            stack = &stack[..index + SUBST_AND_NORMALIZE_ERASING_REGIONS.len()];
+        const INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::instantiate_and_normalize_erasing_regions";
+        if let Some(index) = stack.find(INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS) {
+            stack = &stack[..index + INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS.len()];
         }
 
         const NORMALIZE_ERASING_LATE_BOUND_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::normalize_erasing_late_bound_regions";
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index ec2da39398b..359b430b4e5 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -359,7 +359,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
-        self.instance.subst_mir_and_normalize_erasing_regions(
+        self.instance.instantiate_mir_and_normalize_erasing_regions(
             self.tcx,
             ty::ParamEnv::reveal_all(),
             ty::EarlyBinder::bind(value),
diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
new file mode 100644
index 00000000000..36484c3c3fc
--- /dev/null
+++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
@@ -0,0 +1,103 @@
+use std::{
+    ffi::{c_char, CStr},
+    marker::PhantomData,
+    ops::Deref,
+    ptr::NonNull,
+};
+
+use rustc_data_structures::small_c_str::SmallCStr;
+
+use crate::{errors::LlvmError, llvm};
+
+/// Responsible for safely creating and disposing llvm::TargetMachine via ffi functions.
+/// Not cloneable as there is no clone function for llvm::TargetMachine.
+#[repr(transparent)]
+pub struct OwnedTargetMachine {
+    tm_unique: NonNull<llvm::TargetMachine>,
+    phantom: PhantomData<llvm::TargetMachine>,
+}
+
+impl OwnedTargetMachine {
+    pub fn new(
+        triple: &CStr,
+        cpu: &CStr,
+        features: &CStr,
+        abi: &CStr,
+        model: llvm::CodeModel,
+        reloc: llvm::RelocModel,
+        level: llvm::CodeGenOptLevel,
+        use_soft_fp: bool,
+        function_sections: bool,
+        data_sections: bool,
+        unique_section_names: bool,
+        trap_unreachable: bool,
+        singletree: bool,
+        asm_comments: bool,
+        emit_stack_size_section: bool,
+        relax_elf_relocations: bool,
+        use_init_array: bool,
+        split_dwarf_file: &CStr,
+        output_obj_file: &CStr,
+        debug_info_compression: &CStr,
+        force_emulated_tls: bool,
+        args_cstr_buff: &[u8],
+    ) -> Result<Self, LlvmError<'static>> {
+        assert!(args_cstr_buff.len() > 0);
+        assert!(
+            *args_cstr_buff.last().unwrap() == 0,
+            "The last character must be a null terminator."
+        );
+
+        // SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data
+        let tm_ptr = unsafe {
+            llvm::LLVMRustCreateTargetMachine(
+                triple.as_ptr(),
+                cpu.as_ptr(),
+                features.as_ptr(),
+                abi.as_ptr(),
+                model,
+                reloc,
+                level,
+                use_soft_fp,
+                function_sections,
+                data_sections,
+                unique_section_names,
+                trap_unreachable,
+                singletree,
+                asm_comments,
+                emit_stack_size_section,
+                relax_elf_relocations,
+                use_init_array,
+                split_dwarf_file.as_ptr(),
+                output_obj_file.as_ptr(),
+                debug_info_compression.as_ptr(),
+                force_emulated_tls,
+                args_cstr_buff.as_ptr() as *const c_char,
+                args_cstr_buff.len(),
+            )
+        };
+
+        NonNull::new(tm_ptr)
+            .map(|tm_unique| Self { tm_unique, phantom: PhantomData })
+            .ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
+    }
+}
+
+impl Deref for OwnedTargetMachine {
+    type Target = llvm::TargetMachine;
+
+    fn deref(&self) -> &Self::Target {
+        // SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
+        unsafe { self.tm_unique.as_ref() }
+    }
+}
+
+impl Drop for OwnedTargetMachine {
+    fn drop(&mut self) {
+        // SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
+        // OwnedTargetMachine is not copyable so there is no double free or use after free
+        unsafe {
+            llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
+        }
+    }
+}
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 1f394a7335c..c778a6e017f 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -1,4 +1,5 @@
 use crate::back::lto::ThinBuffer;
+use crate::back::owned_target_machine::OwnedTargetMachine;
 use crate::back::profiling::{
     selfprofile_after_pass_callback, selfprofile_before_pass_callback, LlvmSelfProfiler,
 };
@@ -98,8 +99,8 @@ pub fn write_output_file<'ll>(
     }
 }
 
-pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm::TargetMachine {
-    let config = TargetMachineFactoryConfig { split_dwarf_file: None };
+pub fn create_informational_target_machine(sess: &Session) -> OwnedTargetMachine {
+    let config = TargetMachineFactoryConfig { split_dwarf_file: None, output_obj_file: None };
     // Can't use query system here quite yet because this function is invoked before the query
     // system/tcx is set up.
     let features = llvm_util::global_llvm_features(sess, false);
@@ -107,7 +108,7 @@ pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm:
         .unwrap_or_else(|err| llvm_err(sess.diagnostic(), err).raise())
 }
 
-pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
+pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
     let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
         tcx.output_filenames(()).split_dwarf_path(
             tcx.sess.split_debuginfo(),
@@ -117,7 +118,11 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut ll
     } else {
         None
     };
-    let config = TargetMachineFactoryConfig { split_dwarf_file };
+
+    let output_obj_file =
+        Some(tcx.output_filenames(()).temp_path(OutputType::Object, Some(mod_name)));
+    let config = TargetMachineFactoryConfig { split_dwarf_file, output_obj_file };
+
     target_machine_factory(
         &tcx.sess,
         tcx.backend_optimization_level(()),
@@ -255,38 +260,38 @@ pub fn target_machine_factory(
     let debuginfo_compression = SmallCStr::new(&debuginfo_compression);
 
     Arc::new(move |config: TargetMachineFactoryConfig| {
-        let split_dwarf_file =
-            path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0;
-        let split_dwarf_file = CString::new(split_dwarf_file.to_str().unwrap()).unwrap();
-
-        let tm = unsafe {
-            llvm::LLVMRustCreateTargetMachine(
-                triple.as_ptr(),
-                cpu.as_ptr(),
-                features.as_ptr(),
-                abi.as_ptr(),
-                code_model,
-                reloc_model,
-                opt_level,
-                use_softfp,
-                ffunction_sections,
-                fdata_sections,
-                funique_section_names,
-                trap_unreachable,
-                singlethread,
-                asm_comments,
-                emit_stack_size_section,
-                relax_elf_relocations,
-                use_init_array,
-                split_dwarf_file.as_ptr(),
-                debuginfo_compression.as_ptr(),
-                force_emulated_tls,
-                args_cstr_buff.as_ptr() as *const c_char,
-                args_cstr_buff.len(),
-            )
+        let path_to_cstring_helper = |path: Option<PathBuf>| -> CString {
+            let path = path_mapping.map_prefix(path.unwrap_or_default()).0;
+            CString::new(path.to_str().unwrap()).unwrap()
         };
 
-        tm.ok_or_else(|| LlvmError::CreateTargetMachine { triple: triple.clone() })
+        let split_dwarf_file = path_to_cstring_helper(config.split_dwarf_file);
+        let output_obj_file = path_to_cstring_helper(config.output_obj_file);
+
+        OwnedTargetMachine::new(
+            &triple,
+            &cpu,
+            &features,
+            &abi,
+            code_model,
+            reloc_model,
+            opt_level,
+            use_softfp,
+            ffunction_sections,
+            fdata_sections,
+            funique_section_names,
+            trap_unreachable,
+            singlethread,
+            asm_comments,
+            emit_stack_size_section,
+            relax_elf_relocations,
+            use_init_array,
+            &split_dwarf_file,
+            &output_obj_file,
+            &debuginfo_compression,
+            force_emulated_tls,
+            &args_cstr_buff,
+        )
     })
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 8e8290279ab..b4b2ab1e1f8 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -160,9 +160,9 @@ pub unsafe fn create_module<'ll>(
 
     // Ensure the data-layout values hardcoded remain the defaults.
     if sess.target.is_builtin {
+        // tm is disposed by its drop impl
         let tm = crate::back::write::create_informational_target_machine(tcx.sess);
-        llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm);
-        llvm::LLVMRustDisposeTargetMachine(tm);
+        llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
 
         let llvm_data_layout = llvm::LLVMGetDataLayoutStr(llmod);
         let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 5ca2942ac4e..aff764f0224 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -90,7 +90,7 @@ fn make_mir_scope<'ll, 'tcx>(
         Some((callee, _)) => {
             // FIXME(eddyb) this would be `self.monomorphize(&callee)`
             // if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
-            let callee = cx.tcx.subst_and_normalize_erasing_regions(
+            let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
                 instance.args,
                 ty::ParamEnv::reveal_all(),
                 ty::EarlyBinder::bind(callee),
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index c862acdc7de..30cc9ea9b82 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) {
                 // If the method does *not* belong to a trait, proceed
                 if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
-                    let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
+                    let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
                         instance.args,
                         ty::ParamEnv::reveal_all(),
                         cx.tcx.type_of(impl_def_id),
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index fe87446f5c3..59d1ea05d8a 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -22,6 +22,7 @@ extern crate rustc_macros;
 #[macro_use]
 extern crate tracing;
 
+use back::owned_target_machine::OwnedTargetMachine;
 use back::write::{create_informational_target_machine, create_target_machine};
 
 use errors::ParseTargetMachineConfig;
@@ -52,6 +53,7 @@ use std::io::Write;
 mod back {
     pub mod archive;
     pub mod lto;
+    pub mod owned_target_machine;
     mod profiling;
     pub mod write;
 }
@@ -162,7 +164,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
 impl WriteBackendMethods for LlvmCodegenBackend {
     type Module = ModuleLlvm;
     type ModuleBuffer = back::lto::ModuleBuffer;
-    type TargetMachine = &'static mut llvm::TargetMachine;
+    type TargetMachine = OwnedTargetMachine;
     type TargetMachineError = crate::errors::LlvmError<'static>;
     type ThinData = back::lto::ThinData;
     type ThinBuffer = back::lto::ThinBuffer;
@@ -401,7 +403,9 @@ impl CodegenBackend for LlvmCodegenBackend {
 pub struct ModuleLlvm {
     llcx: &'static mut llvm::Context,
     llmod_raw: *const llvm::Module,
-    tm: &'static mut llvm::TargetMachine,
+
+    // independent from llcx and llmod_raw, resources get disposed by drop impl
+    tm: OwnedTargetMachine,
 }
 
 unsafe impl Send for ModuleLlvm {}
@@ -453,7 +457,6 @@ impl ModuleLlvm {
 impl Drop for ModuleLlvm {
     fn drop(&mut self) {
         unsafe {
-            llvm::LLVMRustDisposeTargetMachine(&mut *(self.tm as *mut _));
             llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 2ebfdae39e8..a038b3af03d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2112,6 +2112,8 @@ extern "C" {
     );
 
     pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
+
+    // This function makes copies of pointed to data, so the data's lifetime may end after this function returns
     pub fn LLVMRustCreateTargetMachine(
         Triple: *const c_char,
         CPU: *const c_char,
@@ -2131,13 +2133,14 @@ extern "C" {
         RelaxELFRelocations: bool,
         UseInitArray: bool,
         SplitDwarfFile: *const c_char,
+        OutputObjFile: *const c_char,
         DebugInfoCompression: *const c_char,
         ForceEmulatedTls: bool,
         ArgsCstrBuff: *const c_char,
         ArgsCstrBuffLen: usize,
-    ) -> Option<&'static mut TargetMachine>;
+    ) -> *mut TargetMachine;
 
-    pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
+    pub fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine);
     pub fn LLVMRustAddLibraryInfo<'a>(
         PM: &PassManager<'a>,
         M: &'a Module,
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index a76c9c9b735..7c8ef67ffd1 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -303,7 +303,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
             // check that all features in a given smallvec are enabled
             for llvm_feature in to_llvm_features(sess, feature) {
                 let cstr = SmallCStr::new(llvm_feature);
-                if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
+                if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
                     return false;
                 }
             }
@@ -422,14 +422,14 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess
             }
             unsafe {
                 llvm::LLVMRustPrintTargetCPUs(
-                    tm,
+                    &tm,
                     cpu_cstring.as_ptr(),
                     callback,
                     &mut out as *mut &mut dyn PrintBackendInfo as *mut c_void,
                 );
             }
         }
-        PrintKind::TargetFeatures => print_target_features(out, sess, tm),
+        PrintKind::TargetFeatures => print_target_features(out, sess, &tm),
         _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 3bf98c46dea..f192747c8ab 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -286,6 +286,10 @@ pub struct TargetMachineFactoryConfig {
     /// so the path to the dwarf object has to be provided when we create the target machine.
     /// This can be ignored by backends which do not need it for their Split DWARF support.
     pub split_dwarf_file: Option<PathBuf>,
+
+    /// The name of the output object file. Used for setting OutputFilenames in target options
+    /// so that LLVM can emit the CodeView S_OBJNAME record in pdb files
+    pub output_obj_file: Option<PathBuf>,
 }
 
 impl TargetMachineFactoryConfig {
@@ -302,7 +306,10 @@ impl TargetMachineFactoryConfig {
         } else {
             None
         };
-        TargetMachineFactoryConfig { split_dwarf_file }
+
+        let output_obj_file =
+            Some(cgcx.output_filenames.temp_path(OutputType::Object, Some(module_name)));
+        TargetMachineFactoryConfig { split_dwarf_file, output_obj_file }
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index cd19885faa0..6c51dffedbf 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -420,9 +420,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         rust_main_def_id: DefId,
         entry_type: EntryFnType,
     ) -> Bx::Function {
-        // The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
-        // depending on whether the target needs `argc` and `argv` to be passed in.
-        let llfty = if cx.sess().target.main_needs_argc_argv {
+        // The entry function is either `int main(void)` or `int main(int argc, char **argv)`, or
+        // `usize efi_main(void *handle, void *system_table)` depending on the target.
+        let llfty = if cx.sess().target.os.contains("uefi") {
+            cx.type_func(&[cx.type_ptr(), cx.type_ptr()], cx.type_isize())
+        } else if cx.sess().target.main_needs_argc_argv {
             cx.type_func(&[cx.type_int(), cx.type_ptr()], cx.type_int())
         } else {
             cx.type_func(&[], cx.type_int())
@@ -485,8 +487,12 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         };
 
         let result = bx.call(start_ty, None, None, start_fn, &args, None);
-        let cast = bx.intcast(result, cx.type_int(), true);
-        bx.ret(cast);
+        if cx.sess().target.os.contains("uefi") {
+            bx.ret(result);
+        } else {
+            let cast = bx.intcast(result, cx.type_int(), true);
+            bx.ret(cast);
+        }
 
         llfn
     }
@@ -497,7 +503,17 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx,
     bx: &mut Bx,
 ) -> (Bx::Value, Bx::Value) {
-    if cx.sess().target.main_needs_argc_argv {
+    if cx.sess().target.os.contains("uefi") {
+        // Params for UEFI
+        let param_handle = bx.get_param(0);
+        let param_system_table = bx.get_param(1);
+        let arg_argc = bx.const_int(cx.type_isize(), 2);
+        let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), Align::ONE);
+        bx.store(param_handle, arg_argv, Align::ONE);
+        let arg_argv_el1 = bx.gep(cx.type_ptr(), arg_argv, &[bx.const_int(cx.type_int(), 1)]);
+        bx.store(param_system_table, arg_argv_el1, Align::ONE);
+        (arg_argc, arg_argv)
+    } else if cx.sess().target.main_needs_argc_argv {
         // Params from native `main()` used as args for rust start function
         let param_argc = bx.get_param(0);
         let param_argv = bx.get_param(1);
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 1e905a7c78e..a61018f9870 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -118,7 +118,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         T: Copy + TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!("monomorphize: self.instance={:?}", self.instance);
-        self.instance.subst_mir_and_normalize_erasing_regions(
+        self.instance.instantiate_mir_and_normalize_erasing_regions(
             self.cx.tcx(),
             ty::ParamEnv::reveal_all(),
             ty::EarlyBinder::bind(value),
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 9205acc527e..0ab2b7ecd9c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -135,15 +135,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         assert_eq!(alloc_align, layout.align.abi);
 
         let read_scalar = |start, size, s: abi::Scalar, ty| {
-            let val = alloc
-                .0
-                .read_scalar(
-                    bx,
-                    alloc_range(start, size),
-                    /*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
-                )
-                .unwrap();
-            bx.scalar_to_backend(val, s, ty)
+            match alloc.0.read_scalar(
+                bx,
+                alloc_range(start, size),
+                /*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
+            ) {
+                Ok(val) => bx.scalar_to_backend(val, s, ty),
+                Err(_) => bx.const_poison(ty),
+            }
         };
 
         // It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point.
@@ -156,7 +155,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             Abi::Scalar(s @ abi::Scalar::Initialized { .. }) => {
                 let size = s.size(bx);
                 assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
-                let val = read_scalar(Size::ZERO, size, s, bx.type_ptr());
+                let val = read_scalar(offset, size, s, bx.backend_type(layout));
                 OperandRef { val: OperandValue::Immediate(val), layout }
             }
             Abi::ScalarPair(
@@ -164,10 +163,10 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                 b @ abi::Scalar::Initialized { .. },
             ) => {
                 let (a_size, b_size) = (a.size(bx), b.size(bx));
-                let b_offset = a_size.align_to(b.align(bx).abi);
+                let b_offset = (offset + a_size).align_to(b.align(bx).abi);
                 assert!(b_offset.bytes() > 0);
                 let a_val = read_scalar(
-                    Size::ZERO,
+                    offset,
                     a_size,
                     a,
                     bx.scalar_pair_element_backend_type(layout, 0, true),
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 7c743a21d93..94a5cc67d31 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -569,7 +569,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> Result<T, ErrorHandled> {
         frame
             .instance
-            .try_subst_mir_and_normalize_erasing_regions(
+            .try_instantiate_mir_and_normalize_erasing_regions(
                 *self.tcx,
                 self.param_env,
                 ty::EarlyBinder::bind(value),
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index b3319442388..eb639ded70f 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -4,7 +4,7 @@ use rustc_middle::ty::{
 };
 use std::ops::ControlFlow;
 
-/// Checks whether a type contains generic parameters which require substitution.
+/// Checks whether a type contains generic parameters which must be instantiated.
 ///
 /// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization
 /// types may be "concrete enough" even though they still contain generic parameters in
@@ -43,7 +43,8 @@ where
                             .try_into()
                             .expect("more generic parameters than can fit into a `u32`");
                         // Only recurse when generic parameters in fns, closures and generators
-                        // are used and require substitution.
+                        // are used and have to be instantiated.
+                        //
                         // Just in case there are closures or generators within this subst,
                         // recurse.
                         if unused_params.is_used(index) && subst.has_param() {
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 2f5f2ad6534..0d8733070a4 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -558,8 +558,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
     }
 }
 
-/// A faster version of the validation pass that only checks those things which may break when apply
-/// generic substitutions.
+/// A faster version of the validation pass that only checks those things which may break when
+/// instantiating any generic parameters.
 pub fn validate_types<'tcx>(
     tcx: TyCtxt<'tcx>,
     mir_phase: MirPhase,
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 7d037ddfa98..461ec3a90ed 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -51,9 +51,10 @@ use std::fmt;
 
 pub use rustc_index::static_assert_size;
 
+/// This calls the passed function while ensuring it won't be inlined into the caller.
 #[inline(never)]
 #[cold]
-pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
+pub fn outline<F: FnOnce() -> R, R>(f: F) -> R {
     f()
 }
 
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 3c76c2b7991..e688feb5fe1 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -81,8 +81,8 @@
 //!
 //! [mm]: https://github.com/rust-lang/measureme/
 
-use crate::cold_path;
 use crate::fx::FxHashMap;
+use crate::outline;
 
 use std::borrow::Borrow;
 use std::collections::hash_map::Entry;
@@ -697,7 +697,7 @@ impl<'a> TimingGuard<'a> {
     #[inline]
     pub fn finish_with_query_invocation_id(self, query_invocation_id: QueryInvocationId) {
         if let Some(guard) = self.0 {
-            cold_path(|| {
+            outline(|| {
                 let event_id = StringId::new_virtual(query_invocation_id.0);
                 let event_id = EventId::from_virtual(event_id);
                 guard.finish_with_override_event_id(event_id);
diff --git a/compiler/rustc_data_structures/src/small_c_str.rs b/compiler/rustc_data_structures/src/small_c_str.rs
index 719e4e3d974..349fd7f9769 100644
--- a/compiler/rustc_data_structures/src/small_c_str.rs
+++ b/compiler/rustc_data_structures/src/small_c_str.rs
@@ -79,3 +79,9 @@ impl<'a> FromIterator<&'a str> for SmallCStr {
         Self { data }
     }
 }
+
+impl From<&ffi::CStr> for SmallCStr {
+    fn from(s: &ffi::CStr) -> Self {
+        Self { data: SmallVec::from_slice(s.to_bytes()) }
+    }
+}
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index 1f838cc4648..ffafdba13ce 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -6,7 +6,7 @@ use std::ptr;
 use std::sync::Arc;
 
 #[cfg(parallel_compiler)]
-use {crate::cold_path, crate::sync::CacheAligned};
+use {crate::outline, crate::sync::CacheAligned};
 
 /// A pointer to the `RegistryData` which uniquely identifies a registry.
 /// This identifier can be reused if the registry gets freed.
@@ -25,11 +25,7 @@ impl RegistryId {
     fn verify(self) -> usize {
         let (id, index) = THREAD_DATA.with(|data| (data.registry_id.get(), data.index.get()));
 
-        if id == self {
-            index
-        } else {
-            cold_path(|| panic!("Unable to verify registry association"))
-        }
+        if id == self { index } else { outline(|| panic!("Unable to verify registry association")) }
     }
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0038.md b/compiler/rustc_error_codes/src/error_codes/E0038.md
index 584b78554ef..8f8eabb1519 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0038.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0038.md
@@ -162,14 +162,13 @@ fn foo<T>(x: T) {
 ```
 
 The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any
-other type substitution is different. Hence the compiler generates the
+other instantiation is different. Hence the compiler generates the
 implementation on-demand. If you call `foo()` with a `bool` parameter, the
 compiler will only generate code for `foo::<bool>()`. When we have additional
 type parameters, the number of monomorphized implementations the compiler
 generates does not grow drastically, since the compiler will only generate an
-implementation if the function is called with unparameterized substitutions
-(i.e., substitutions where none of the substituted types are themselves
-parameterized).
+implementation if the function is called with fully concrete arguments
+(i.e., arguments which do not contain any generic parameters).
 
 However, with trait objects we have to make a table containing _every_ object
 that implements the trait. Now, if it has type parameters, we need to add
diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md
index 67a8c3678c5..d8c1a3cb55c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0094.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0094.md
@@ -3,7 +3,7 @@ An invalid number of generic parameters was passed to an intrinsic function.
 Erroneous code example:
 
 ```compile_fail,E0094
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
@@ -18,7 +18,7 @@ and verify with the function declaration in the Rust source code.
 Example:
 
 ```
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md
index 70f14fffae6..19a482f6c93 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0211.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0211.md
@@ -4,7 +4,7 @@ You used a function or type which doesn't fit the requirements for where it was
 used. Erroneous code examples:
 
 ```compile_fail
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
@@ -41,7 +41,7 @@ impl Foo {
 For the first code example, please check the function definition. Example:
 
 ```
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 04ebe22a9eb..18397af565f 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -537,7 +537,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         allow_internal_unsafe, Normal, template!(Word), WarnFollowing,
         "allow_internal_unsafe side-steps the unsafe_code lint",
     ),
-    ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk),
     rustc_attr!(rustc_allowed_through_unstable_modules, Normal, template!(Word), WarnFollowing,
     "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
     through unstable paths"),
@@ -806,6 +805,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
         r#"`rustc_doc_primitive` is a rustc internal attribute"#,
     ),
+    rustc_attr!(
+        rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
+        "the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
+    ),
 
     // ==========================================================================
     // Internal attributes, Testing:
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 64271309664..3a4eb90f7f9 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -61,9 +61,7 @@ pub enum DefKind {
     Variant,
     Trait,
     /// Type alias: `type Foo = Bar;`
-    TyAlias {
-        lazy: bool,
-    },
+    TyAlias,
     /// Type from an `extern` block.
     ForeignTy,
     /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
@@ -143,7 +141,7 @@ impl DefKind {
             DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
             DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
             DefKind::OpaqueTy => "opaque type",
-            DefKind::TyAlias { .. } => "type alias",
+            DefKind::TyAlias => "type alias",
             DefKind::TraitAlias => "trait alias",
             DefKind::AssocTy => "associated type",
             DefKind::Union => "union",
@@ -199,7 +197,7 @@ impl DefKind {
             | DefKind::Variant
             | DefKind::Trait
             | DefKind::OpaqueTy
-            | DefKind::TyAlias { .. }
+            | DefKind::TyAlias
             | DefKind::ForeignTy
             | DefKind::TraitAlias
             | DefKind::AssocTy
@@ -250,7 +248,7 @@ impl DefKind {
             | DefKind::Enum
             | DefKind::Variant
             | DefKind::Trait
-            | DefKind::TyAlias { .. }
+            | DefKind::TyAlias
             | DefKind::ForeignTy
             | DefKind::TraitAlias
             | DefKind::AssocTy
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 644c4d8265d..0d65ddb5642 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -101,7 +101,7 @@ impl Target {
             DefKind::Mod => Target::Mod,
             DefKind::ForeignMod => Target::ForeignMod,
             DefKind::GlobalAsm => Target::GlobalAsm,
-            DefKind::TyAlias { .. } => Target::TyAlias,
+            DefKind::TyAlias => Target::TyAlias,
             DefKind::OpaqueTy => Target::OpaqueTy,
             DefKind::Enum => Target::Enum,
             DefKind::Struct => Target::Struct,
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index ba152cd48de..21611e9c586 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -427,7 +427,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
             let bound_vars = tcx.late_bound_vars(binding.hir_id);
             ty::Binder::bind_with_vars(subst_output, bound_vars)
         } else {
-            // Include substitutions for generic parameters of associated types
+            // Append the generic arguments of the associated type to the `trait_ref`.
             candidate.map_bound(|trait_ref| {
                 let ident = Ident::new(assoc_item.name, binding.item_name.span);
                 let item_segment = hir::PathSegment {
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 1372cc896be..e3621ef933a 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -139,22 +139,22 @@ fn generic_arg_mismatch_err(
     err.emit()
 }
 
-/// Creates the relevant generic argument substitutions
+/// Creates the relevant generic arguments
 /// corresponding to a set of generic parameters. This is a
 /// rather complex function. Let us try to explain the role
 /// of each of its parameters:
 ///
-/// To start, we are given the `def_id` of the thing we are
-/// creating the substitutions for, and a partial set of
-/// substitutions `parent_args`. In general, the substitutions
-/// for an item begin with substitutions for all the "parents" of
+/// To start, we are given the `def_id` of the thing whose generic
+/// parameters we are instantiating, and a partial set of
+/// arguments `parent_args`. In general, the generic arguments
+/// for an item begin with arguments for all the "parents" of
 /// that item -- e.g., for a method it might include the
 /// parameters from the impl.
 ///
 /// Therefore, the method begins by walking down these parents,
 /// starting with the outermost parent and proceed inwards until
 /// it reaches `def_id`. For each parent `P`, it will check `parent_args`
-/// first to see if the parent's substitutions are listed in there. If so,
+/// first to see if the parent's arguments are listed in there. If so,
 /// we can append those and move on. Otherwise, it invokes the
 /// three callback functions:
 ///
@@ -188,7 +188,7 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
         stack.push((def_id, parent_defs));
     }
 
-    // We manually build up the substitution, rather than using convenience
+    // We manually build up the generic arguments, rather than using convenience
     // methods in `subst.rs`, so that we can iterate over the arguments and
     // parameters in lock-step linearly, instead of trying to match each pair.
     let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
@@ -196,7 +196,8 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
     while let Some((def_id, defs)) = stack.pop() {
         let mut params = defs.params.iter().peekable();
 
-        // If we have already computed substitutions for parents, we can use those directly.
+        // If we have already computed the generic arguments for parents,
+        // we can use those directly.
         while let Some(&param) = params.peek() {
             if let Some(&kind) = parent_args.get(param.index as usize) {
                 args.push(kind);
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 3a97a383ee1..56b1fd36973 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -289,7 +289,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     }
 
     /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
-    /// returns an appropriate set of substitutions for this particular reference to `I`.
+    /// returns an appropriate set of generic arguments for this particular reference to `I`.
     pub fn ast_path_args_for_ty(
         &self,
         span: Span,
@@ -315,7 +315,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
     /// Given the type/lifetime/const arguments provided to some path (along with
     /// an implicit `Self`, if this is a trait reference), returns the complete
-    /// set of substitutions. This may involve applying defaulted type parameters.
+    /// set of generic arguments. This may involve applying defaulted type parameters.
     /// Constraints on associated types are created from `create_assoc_bindings_for_generic_args`.
     ///
     /// Example:
@@ -909,23 +909,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let tcx = self.tcx();
         let args = self.ast_path_args_for_ty(span, did, item_segment);
 
-        if let DefKind::TyAlias { lazy: true } = tcx.def_kind(did) {
+        if let DefKind::TyAlias = tcx.def_kind(did)
+            && tcx.type_alias_is_lazy(did)
+        {
             // Type aliases defined in crates that have the
             // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
             // then actually instantiate the where bounds of.
             let alias_ty = tcx.mk_alias_ty(did, args);
             Ty::new_alias(tcx, ty::Weak, alias_ty)
         } else {
-            let ty = tcx.at(span).type_of(did);
-            if ty.skip_binder().has_opaque_types() {
-                // Type aliases referring to types that contain opaque types (but aren't just directly
-                // referencing a single opaque type) get encoded as a type alias that normalization will
-                // then actually instantiate the where bounds of.
-                let alias_ty = tcx.mk_alias_ty(did, args);
-                Ty::new_alias(tcx, ty::Weak, alias_ty)
-            } else {
-                ty.instantiate(tcx, args)
-            }
+            tcx.at(span).type_of(did).instantiate(tcx, args)
         }
     }
 
@@ -2164,7 +2157,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             Res::Def(
                 DefKind::Enum
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::Struct
                 | DefKind::Union
                 | DefKind::ForeignTy,
@@ -2781,7 +2774,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     ) {
         for br in referenced_regions.difference(&constrained_regions) {
             let br_name = match *br {
-                ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) | ty::BrEnv => {
+                ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon | ty::BrEnv => {
                     "an anonymous lifetime".to_string()
                 }
                 ty::BrNamed(_, name) => format!("lifetime `{name}`"),
@@ -2789,7 +2782,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
             let mut err = generate_err(&br_name);
 
-            if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) = *br {
+            if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon = *br {
                 // The only way for an anonymous lifetime to wind up
                 // in the return type but **also** be unconstrained is
                 // if it only appears in "associated types" in the
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 564206f9e4b..eb1f48d23ff 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -640,7 +640,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
                 check_opaque(tcx, id);
             }
         }
-        DefKind::TyAlias { .. } => {
+        DefKind::TyAlias => {
             let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
             let generics = tcx.generics_of(id.owner_id);
             check_type_params_are_used(tcx, &generics, pty_ty);
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index ba58f0d57ad..d081b0e35c6 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -14,6 +14,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::util::ExplicitSelf;
 use rustc_middle::ty::{
     self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
@@ -661,8 +662,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
     let impl_trait_ref =
         tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
-    let param_env = tcx.param_env(impl_m_def_id);
-
     // First, check a few of the same things as `compare_impl_method`,
     // just so we don't ICE during substitution later.
     check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
@@ -688,13 +687,26 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     let trait_to_placeholder_args =
         impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
 
+    let hybrid_preds = tcx
+        .predicates_of(impl_m.container_id(tcx))
+        .instantiate_identity(tcx)
+        .into_iter()
+        .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_placeholder_args))
+        .map(|(clause, _)| clause);
+    let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
+    let param_env = traits::normalize_param_env_or_error(
+        tcx,
+        param_env,
+        ObligationCause::misc(tcx.def_span(impl_m_def_id), impl_m_def_id),
+    );
+
     let infcx = &tcx.infer_ctxt().build();
     let ocx = ObligationCtxt::new(infcx);
 
     // Normalize the impl signature with fresh variables for lifetime inference.
-    let norm_cause = ObligationCause::misc(return_span, impl_m_def_id);
+    let misc_cause = ObligationCause::misc(return_span, impl_m_def_id);
     let impl_sig = ocx.normalize(
-        &norm_cause,
+        &misc_cause,
         param_env,
         tcx.liberate_late_bound_regions(
             impl_m.def_id,
@@ -725,12 +737,68 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         );
     }
 
-    let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig);
+    let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig);
     trait_sig.error_reported()?;
     let trait_return_ty = trait_sig.output();
 
+    // RPITITs are allowed to use the implied predicates of the method that
+    // defines them. This is because we want code like:
+    // ```
+    // trait Foo {
+    //     fn test<'a, T>(_: &'a T) -> impl Sized;
+    // }
+    // impl Foo for () {
+    //     fn test<'a, T>(x: &'a T) -> &'a T { x }
+    // }
+    // ```
+    // .. to compile. However, since we use both the normalized and unnormalized
+    // inputs and outputs from the substituted trait signature, we will end up
+    // seeing the hidden type of an RPIT in the signature itself. Naively, this
+    // means that we will use the hidden type to imply the hidden type's own
+    // well-formedness.
+    //
+    // To avoid this, we replace the infer vars used for hidden type inference
+    // with placeholders, which imply nothing about outlives bounds, and then
+    // prove below that the hidden types are well formed.
+    let universe = infcx.create_next_universe();
+    let mut idx = 0;
+    let mapping: FxHashMap<_, _> = collector
+        .types
+        .iter()
+        .map(|(_, &(ty, _))| {
+            assert!(
+                infcx.resolve_vars_if_possible(ty) == ty && ty.is_ty_var(),
+                "{ty:?} should not have been constrained via normalization",
+                ty = infcx.resolve_vars_if_possible(ty)
+            );
+            idx += 1;
+            (
+                ty,
+                Ty::new_placeholder(
+                    tcx,
+                    ty::Placeholder {
+                        universe,
+                        bound: ty::BoundTy {
+                            var: ty::BoundVar::from_usize(idx),
+                            kind: ty::BoundTyKind::Anon,
+                        },
+                    },
+                ),
+            )
+        })
+        .collect();
+    let mut type_mapper = BottomUpFolder {
+        tcx,
+        ty_op: |ty| *mapping.get(&ty).unwrap_or(&ty),
+        lt_op: |lt| lt,
+        ct_op: |ct| ct,
+    };
     let wf_tys = FxIndexSet::from_iter(
-        unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()),
+        unnormalized_trait_sig
+            .inputs_and_output
+            .iter()
+            .chain(trait_sig.inputs_and_output.iter())
+            .map(|ty| ty.fold_with(&mut type_mapper)),
     );
 
     match ocx.eq(&cause, param_env, trait_return_ty, impl_return_ty) {
@@ -787,6 +855,20 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         }
     }
 
+    // FIXME: This has the same issue as #108544, but since this isn't breaking
+    // existing code, I'm not particularly inclined to do the same hack as above
+    // where we process wf obligations manually. This can be fixed in a forward-
+    // compatible way later.
+    let collected_types = collector.types;
+    for (_, &(ty, _)) in &collected_types {
+        ocx.register_obligation(traits::Obligation::new(
+            tcx,
+            misc_cause.clone(),
+            param_env,
+            ty::ClauseKind::WellFormed(ty.into()),
+        ));
+    }
+
     // Check that all obligations are satisfied by the implementation's
     // RPITs.
     let errors = ocx.select_all_or_error();
@@ -795,8 +877,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         return Err(reported);
     }
 
-    let collected_types = collector.types;
-
     // Finally, resolve all regions. This catches wily misuses of
     // lifetime parameters.
     let outlives_env = OutlivesEnvironment::with_bounds(
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index a8149b634ef..d9e0e87eb47 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -5,7 +5,7 @@ use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
 use rustc_lint_defs::builtin::REFINING_IMPL_TRAIT;
 use rustc_middle::traits::{ObligationCause, Reveal};
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
+    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 use rustc_span::{Span, DUMMY_SP};
 use rustc_trait_selection::traits::{
@@ -176,9 +176,13 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
         return;
     };
 
-    // For quicker lookup, use an `IndexSet`
-    // (we don't use one earlier because it's not foldable..)
-    let trait_bounds = FxIndexSet::from_iter(trait_bounds);
+    // For quicker lookup, use an `IndexSet` (we don't use one earlier because
+    // it's not foldable..).
+    // Also, We have to anonymize binders in these types because they may contain
+    // `BrNamed` bound vars, which contain unique `DefId`s which correspond to syntax
+    // locations that we don't care about when checking bound equality.
+    let trait_bounds = FxIndexSet::from_iter(trait_bounds.fold_with(&mut Anonymize { tcx }));
+    let impl_bounds = impl_bounds.fold_with(&mut Anonymize { tcx });
 
     // Find any clauses that are present in the impl's RPITITs that are not
     // present in the trait's RPITITs. This will trigger on trivial predicates,
@@ -309,3 +313,20 @@ fn type_visibility<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<ty::Visibili
         _ => None,
     }
 }
+
+struct Anonymize<'tcx> {
+    tcx: TyCtxt<'tcx>,
+}
+
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Anonymize<'tcx> {
+    fn interner(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
+    where
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        self.tcx.anonymize_bound_vars(t)
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 444103ffe8f..3c0d977917f 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -137,7 +137,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let name_str = intrinsic_name.as_str();
 
     let bound_vars = tcx.mk_bound_variable_kinds(&[
-        ty::BoundVariableKind::Region(ty::BrAnon(None)),
+        ty::BoundVariableKind::Region(ty::BrAnon),
         ty::BoundVariableKind::Region(ty::BrEnv),
     ]);
     let mk_va_list_ty = |mutbl| {
@@ -145,7 +145,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             let region = ty::Region::new_late_bound(
                 tcx,
                 ty::INNERMOST,
-                ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) },
+                ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
             );
             let env_region = ty::Region::new_late_bound(
                 tcx,
@@ -405,7 +405,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 );
                 let discriminant_def_id = assoc_items[0];
 
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
+                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
                 (
                     1,
                     vec![Ty::new_imm_ref(
@@ -463,7 +463,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             }
 
             sym::raw_eq => {
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
+                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
                 let param_ty = Ty::new_imm_ref(
                     tcx,
                     ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 00a684f2963..b7b162ce27b 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -246,9 +246,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
         // `ForeignItem`s are handled separately.
         hir::ItemKind::ForeignMod { .. } => {}
         hir::ItemKind::TyAlias(hir_ty, ast_generics) => {
-            if tcx.features().lazy_type_alias
-                || tcx.type_of(item.owner_id).skip_binder().has_opaque_types()
-            {
+            if tcx.type_alias_is_lazy(item.owner_id) {
                 // Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
                 // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
                 check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
@@ -1711,10 +1709,8 @@ fn check_variances_for_type_defn<'tcx>(
             }
         }
         ItemKind::TyAlias(..) => {
-            let ty = tcx.type_of(item.owner_id).instantiate_identity();
-
-            if tcx.features().lazy_type_alias || ty.has_opaque_types() {
-                if ty.references_error() {
+            if tcx.type_alias_is_lazy(item.owner_id) {
+                if tcx.type_of(item.owner_id).skip_binder().references_error() {
                     return;
                 }
             } else {
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 01e40c62a8b..cd37221ae6f 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -58,6 +58,7 @@ pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         type_of: type_of::type_of,
         type_of_opaque: type_of::type_of_opaque,
+        type_alias_is_lazy: type_of::type_alias_is_lazy,
         item_bounds: item_bounds::item_bounds,
         explicit_item_bounds: item_bounds::explicit_item_bounds,
         generics_of: generics_of::generics_of,
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index a39cfd7b6e1..eb4466449a0 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -856,22 +856,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
         let scope = Scope::TraitRefBoundary { s: self.scope };
         self.with(scope, |this| {
             walk_list!(this, visit_generic_param, generics.params);
-            for param in generics.params {
-                match param.kind {
-                    GenericParamKind::Lifetime { .. } => {}
-                    GenericParamKind::Type { default, .. } => {
-                        if let Some(ty) = default {
-                            this.visit_ty(ty);
-                        }
-                    }
-                    GenericParamKind::Const { ty, default } => {
-                        this.visit_ty(ty);
-                        if let Some(default) = default {
-                            this.visit_body(this.tcx.hir().body(default.body));
-                        }
-                    }
-                }
-            }
             walk_list!(this, visit_where_predicate, generics.predicates);
         })
     }
@@ -1000,6 +984,21 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 // like implicit `?Sized` or const-param-has-ty predicates.
             }
         }
+
+        match p.kind {
+            GenericParamKind::Lifetime { .. } => {}
+            GenericParamKind::Type { default, .. } => {
+                if let Some(ty) = default {
+                    self.visit_ty(ty);
+                }
+            }
+            GenericParamKind::Const { ty, default } => {
+                self.visit_ty(ty);
+                if let Some(default) = default {
+                    self.visit_body(self.tcx.hir().body(default.body));
+                }
+            }
+        }
     }
 }
 
@@ -1520,7 +1519,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 DefKind::Struct
                 | DefKind::Union
                 | DefKind::Enum
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::Trait,
                 def_id,
             ) if depth == 0 => Some(def_id),
@@ -2030,7 +2029,7 @@ fn is_late_bound_map(
 
                 hir::TyKind::Path(hir::QPath::Resolved(
                     None,
-                    hir::Path { res: Res::Def(DefKind::TyAlias { .. }, alias_def), segments, span },
+                    hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
                 )) => {
                     // See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
                     // args to be unconstrained.
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index d12337687e2..ae62119b182 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -623,3 +623,25 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
         .emit();
     }
 }
+
+pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
+    use hir::intravisit::Visitor;
+    if tcx.features().lazy_type_alias {
+        return true;
+    }
+    struct HasTait {
+        has_type_alias_impl_trait: bool,
+    }
+    impl<'tcx> Visitor<'tcx> for HasTait {
+        fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
+            if let hir::TyKind::OpaqueDef(..) = t.kind {
+                self.has_type_alias_impl_trait = true;
+            } else {
+                hir::intravisit::walk_ty(self, t);
+            }
+        }
+    }
+    let mut has_tait = HasTait { has_type_alias_impl_trait: false };
+    has_tait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0);
+    has_tait.has_type_alias_impl_trait
+}
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 9aac7160f2e..61d9c989e2f 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -6,7 +6,7 @@
 use hir::def_id::{DefId, LocalDefId};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
 
 use super::terms::VarianceTerm::*;
@@ -78,9 +78,7 @@ pub fn add_constraints_from_crate<'a, 'tcx>(
                 }
             }
             DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
-            DefKind::TyAlias { lazy }
-                if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
-            {
+            DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
                 constraint_cx.build_constraints_for_item(def_id)
             }
             _ => {}
@@ -110,8 +108,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
         // The type as returned by `type_of` is the underlying type and generally not a weak projection.
         // Therefore we need to check the `DefKind` first.
-        if let DefKind::TyAlias { lazy } = tcx.def_kind(def_id)
-            && (lazy || ty.has_opaque_types())
+        if let DefKind::TyAlias = tcx.def_kind(def_id)
+            && tcx.type_alias_is_lazy(def_id)
         {
             self.add_constraints_from_ty(current_item, ty, self.covariant);
             return;
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index d69d7ff904a..85e0000ab47 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -8,7 +8,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
-use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
+use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
 use std::ops::ControlFlow;
 
 /// Defines the `TermsContext` basically houses an arena where we can
@@ -56,9 +56,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
             let crate_map = tcx.crate_variances(());
             return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
         }
-        DefKind::TyAlias { lazy }
-            if lazy || tcx.type_of(item_def_id).instantiate_identity().has_opaque_types() =>
-        {
+        DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
             // These are inferred.
             let crate_map = tcx.crate_variances(());
             return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs
index 1a8ec5f0853..275df24956c 100644
--- a/compiler/rustc_hir_analysis/src/variance/terms.rs
+++ b/compiler/rustc_hir_analysis/src/variance/terms.rs
@@ -12,7 +12,7 @@
 use rustc_arena::DroplessArena;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
-use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, TyCtxt};
 use std::fmt;
 
 use self::VarianceTerm::*;
@@ -97,9 +97,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
                 }
             }
             DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
-            DefKind::TyAlias { lazy }
-                if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
-            {
+            DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
                 terms_cx.add_inferreds_for_item(def_id)
             }
             _ => {}
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 041cc1abd54..1fa0ec173a7 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -204,7 +204,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         &[ty::GenericArg::from(ty::Region::new_late_bound(
             tcx,
             ty::INNERMOST,
-            ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon(None) },
+            ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon },
         ))],
     );
     let panic_info_ref_ty = Ty::new_imm_ref(
@@ -212,14 +212,14 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         ty::Region::new_late_bound(
             tcx,
             ty::INNERMOST,
-            ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) },
+            ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
         ),
         panic_info_ty,
     );
 
     let bounds = tcx.mk_bound_variable_kinds(&[
-        ty::BoundVariableKind::Region(ty::BrAnon(None)),
-        ty::BoundVariableKind::Region(ty::BrAnon(None)),
+        ty::BoundVariableKind::Region(ty::BrAnon),
+        ty::BoundVariableKind::Region(ty::BrAnon),
     ]);
     let expected_sig = ty::Binder::bind_with_vars(
         tcx.mk_fn_sig([panic_info_ref_ty], tcx.types.never, false, fn_sig.unsafety, Abi::Rust),
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index c08629a5269..256a4bf9449 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -530,7 +530,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     // When encountering a type error on the value of a `break`, try to point at the reason for the
     // expected type.
-    fn annotate_loop_expected_due_to_inference(
+    pub fn annotate_loop_expected_due_to_inference(
         &self,
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
@@ -540,16 +540,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         };
         let mut parent_id = self.tcx.hir().parent_id(expr.hir_id);
-        loop {
+        let mut parent;
+        'outer: loop {
             // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement.
-            let Some(hir::Node::Expr(parent)) = self.tcx.hir().find(parent_id) else {
+            let Some(
+                hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
+                | hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
+                | hir::Node::Expr(&ref p),
+            ) = self.tcx.hir().find(parent_id)
+            else {
                 break;
             };
-            parent_id = self.tcx.hir().parent_id(parent.hir_id);
+            parent = p;
+            parent_id = self.tcx.hir().parent_id(parent_id);
             let hir::ExprKind::Break(destination, _) = parent.kind else {
                 continue;
             };
-            let mut parent_id = parent.hir_id;
+            let mut parent_id = parent_id;
+            let mut direct = false;
             loop {
                 // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
                 let parent = match self.tcx.hir().find(parent_id) {
@@ -565,14 +573,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         parent_id = self.tcx.hir().parent_id(*hir_id);
                         parent
                     }
-                    Some(hir::Node::Block(hir::Block { .. })) => {
+                    Some(hir::Node::Block(_)) => {
                         parent_id = self.tcx.hir().parent_id(parent_id);
                         parent
                     }
                     _ => break,
                 };
-                if let hir::ExprKind::Loop(_, label, _, span) = parent.kind
-                    && destination.label == label
+                if let hir::ExprKind::Loop(..) = parent.kind {
+                    // When you have `'a: loop { break; }`, the `break` corresponds to the labeled
+                    // loop, so we need to account for that.
+                    direct = !direct;
+                }
+                if let hir::ExprKind::Loop(block, label, _, span) = parent.kind
+                    && (destination.label == label || direct)
                 {
                     if let Some((reason_span, message)) =
                         self.maybe_get_coercion_reason(parent_id, parent.span)
@@ -582,8 +595,64 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             span,
                             format!("this loop is expected to be of type `{expected}`"),
                         );
+                        break 'outer;
+                    } else {
+                        // Locate all other `break` statements within the same `loop` that might
+                        // have affected inference.
+                        struct FindBreaks<'tcx> {
+                            label: Option<rustc_ast::Label>,
+                            uses: Vec<&'tcx hir::Expr<'tcx>>,
+                            nest_depth: usize,
+                        }
+                        impl<'tcx> Visitor<'tcx> for FindBreaks<'tcx> {
+                            fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
+                                let nest_depth = self.nest_depth;
+                                if let hir::ExprKind::Loop(_, label, _, _) = ex.kind {
+                                    if label == self.label {
+                                        // Account for `'a: loop { 'a: loop {...} }`.
+                                        return;
+                                    }
+                                    self.nest_depth += 1;
+                                }
+                                if let hir::ExprKind::Break(destination, _) = ex.kind
+                                    && (self.label == destination.label
+                                        // Account for `loop { 'a: loop { loop { break; } } }`.
+                                        || destination.label.is_none() && self.nest_depth == 0)
+                                {
+                                    self.uses.push(ex);
+                                }
+                                hir::intravisit::walk_expr(self, ex);
+                                self.nest_depth = nest_depth;
+                            }
+                        }
+                        let mut expr_finder = FindBreaks { label, uses: vec![], nest_depth: 0 };
+                        expr_finder.visit_block(block);
+                        let mut exit = false;
+                        for ex in expr_finder.uses {
+                            let hir::ExprKind::Break(_, val) = ex.kind else {
+                                continue;
+                            };
+                            let ty = match val {
+                                Some(val) => {
+                                    match self.typeck_results.borrow().expr_ty_adjusted_opt(val) {
+                                        None => continue,
+                                        Some(ty) => ty,
+                                    }
+                                }
+                                None => self.tcx.types.unit,
+                            };
+                            if self.can_eq(self.param_env, ty, expected) {
+                                err.span_label(
+                                    ex.span,
+                                    format!("expected because of this `break`"),
+                                );
+                                exit = true;
+                            }
+                        }
+                        if exit {
+                            break 'outer;
+                        }
                     }
-                    break;
                 }
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 4ad14ce3059..eead4da5e3e 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -43,7 +43,10 @@ use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::middle::stability;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
-use rustc_middle::ty::error::TypeError::FieldMisMatch;
+use rustc_middle::ty::error::{
+    ExpectedFound,
+    TypeError::{FieldMisMatch, Sorts},
+};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
 use rustc_session::errors::ExprParenthesesNeeded;
@@ -664,15 +667,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.suggest_mismatched_types_on_tail(
                                 &mut err, expr, ty, e_ty, target_id,
                             );
+                            let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty }));
+                            self.annotate_loop_expected_due_to_inference(&mut err, expr, error);
                             if let Some(val) = ty_kind_suggestion(ty) {
-                                let label = destination
-                                    .label
-                                    .map(|l| format!(" {}", l.ident))
-                                    .unwrap_or_else(String::new);
-                                err.span_suggestion(
-                                    expr.span,
+                                err.span_suggestion_verbose(
+                                    expr.span.shrink_to_hi(),
                                     "give it a value of the expected type",
-                                    format!("break{label} {val}"),
+                                    format!(" {val}"),
                                     Applicability::HasPlaceholders,
                                 );
                             }
@@ -717,7 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // ... except when we try to 'break rust;'.
                 // ICE this expression in particular (see #43162).
                 if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind {
-                    if path.segments.len() == 1 && path.segments[0].ident.name == sym::rust {
+                    if let [segment] = path.segments && segment.ident.name == sym::rust {
                         fatally_break_rust(self.tcx);
                     }
                 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 37ea94d821e..c0332a48be3 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1370,10 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
                 _ => bug!("unexpected type: {:?}", ty.normalized),
             },
-            Res::Def(
-                DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy,
-                _,
-            )
+            Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
             | Res::SelfTyParam { .. }
             | Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() {
                 Some(adt) if !adt.is_enum() => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 41f815a812a..abb68989218 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -65,6 +65,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expr = expr.peel_drop_temps();
         self.suggest_missing_semicolon(err, expr, expected, false);
         let mut pointing_at_return_type = false;
+        if let hir::ExprKind::Break(..) = expr.kind {
+            // `break` type mismatches provide better context for tail `loop` expressions.
+            return false;
+        }
         if let Some((fn_id, fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
             pointing_at_return_type = self.suggest_missing_return_type(
                 err,
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index 7fb1dc2347e..337d12b2d51 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -464,7 +464,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         // Opaque types can't have field projections, but we can instead convert
         // the current place in-place (heh) to the hidden type, and then apply all
         // follow up projections on that.
-        if node_ty != place_ty && place_ty.has_opaque_types() {
+        if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) {
             projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
         }
         projections.push(Projection { kind, ty });
@@ -557,10 +557,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                 Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
             }
             Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
-            | Res::Def(
-                DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy,
-                _,
-            )
+            | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
             | Res::SelfCtor(..)
             | Res::SelfTyParam { .. }
             | Res::SelfTyAlias { .. } => {
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index b9171fad55b..220ea194a6d 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -28,8 +28,8 @@ pub use persist::load_query_result_cache;
 pub use persist::prepare_session_directory;
 pub use persist::save_dep_graph;
 pub use persist::save_work_product_index;
+pub use persist::setup_dep_graph;
 pub use persist::LoadResult;
-pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture};
 
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 25e694fa1c1..2310d0b12ef 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -3,17 +3,19 @@
 use crate::errors;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::unord::UnordMap;
-use rustc_middle::dep_graph::{DepsType, SerializedDepGraph, WorkProductMap};
+use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProductMap};
 use rustc_middle::query::on_disk_cache::OnDiskCache;
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::Decodable;
 use rustc_session::config::IncrementalStateAssertion;
-use rustc_session::Session;
+use rustc_session::{Session, StableCrateId};
+use rustc_span::{ErrorGuaranteed, Symbol};
 use std::path::{Path, PathBuf};
 
 use super::data::*;
 use super::file_format;
 use super::fs::*;
+use super::save::build_dep_graph;
 use super::work_product;
 
 #[derive(Debug)]
@@ -72,21 +74,12 @@ impl<T: Default> LoadResult<T> {
 }
 
 fn load_data(path: &Path, sess: &Session) -> LoadResult<(Mmap, usize)> {
-    load_data_no_sess(
+    match file_format::read_file(
         path,
         sess.opts.unstable_opts.incremental_info,
         sess.is_nightly_build(),
         sess.cfg_version,
-    )
-}
-
-fn load_data_no_sess(
-    path: &Path,
-    report_incremental_info: bool,
-    is_nightly_build: bool,
-    cfg_version: &'static str,
-) -> LoadResult<(Mmap, usize)> {
-    match file_format::read_file(path, report_incremental_info, is_nightly_build, cfg_version) {
+    ) {
         Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
         Ok(None) => {
             // The file either didn't exist or was produced by an incompatible
@@ -102,39 +95,12 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) {
     work_product::delete_workproduct_files(sess, &swp.work_product);
 }
 
-/// Either a result that has already be computed or a
-/// handle that will let us wait until it is computed
-/// by a background thread.
-pub enum MaybeAsync<T> {
-    Sync(T),
-    Async(std::thread::JoinHandle<T>),
-}
-
-impl<T> MaybeAsync<LoadResult<T>> {
-    /// Accesses the data returned in [`LoadResult::Ok`] in an asynchronous way if possible.
-    pub fn open(self) -> LoadResult<T> {
-        match self {
-            MaybeAsync::Sync(result) => result,
-            MaybeAsync::Async(handle) => {
-                handle.join().unwrap_or_else(|e| LoadResult::DecodeIncrCache(e))
-            }
-        }
-    }
-}
-
-/// An asynchronous type for computing the dependency graph.
-pub type DepGraphFuture = MaybeAsync<LoadResult<(SerializedDepGraph, WorkProductMap)>>;
-
-/// Launch a thread and load the dependency graph in the background.
-pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
-    // Since `sess` isn't `Sync`, we perform all accesses to `sess`
-    // before we fire the background thread.
-
+fn load_dep_graph(sess: &Session) -> LoadResult<(SerializedDepGraph, WorkProductMap)> {
     let prof = sess.prof.clone();
 
     if sess.opts.incremental.is_none() {
         // No incremental compilation.
-        return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() });
+        return LoadResult::Ok { data: Default::default() };
     }
 
     let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph");
@@ -142,7 +108,6 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
     // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
     // Fortunately, we just checked that this isn't the case.
     let path = dep_graph_path(&sess);
-    let report_incremental_info = sess.opts.unstable_opts.incremental_info;
     let expected_hash = sess.opts.dep_tracking_hash(false);
 
     let mut prev_work_products = UnordMap::default();
@@ -180,40 +145,35 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
         }
     }
 
-    let is_nightly_build = sess.is_nightly_build();
-    let cfg_version = sess.cfg_version;
-
-    MaybeAsync::Async(std::thread::spawn(move || {
-        let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
+    let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
 
-        match load_data_no_sess(&path, report_incremental_info, is_nightly_build, cfg_version) {
-            LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
-            LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
-            LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
-            LoadResult::Ok { data: (bytes, start_pos) } => {
-                let mut decoder = MemDecoder::new(&bytes, start_pos);
-                let prev_commandline_args_hash = u64::decode(&mut decoder);
+    match load_data(&path, sess) {
+        LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
+        LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
+        LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
+        LoadResult::Ok { data: (bytes, start_pos) } => {
+            let mut decoder = MemDecoder::new(&bytes, start_pos);
+            let prev_commandline_args_hash = u64::decode(&mut decoder);
 
-                if prev_commandline_args_hash != expected_hash {
-                    if report_incremental_info {
-                        eprintln!(
-                            "[incremental] completely ignoring cache because of \
+            if prev_commandline_args_hash != expected_hash {
+                if sess.opts.unstable_opts.incremental_info {
+                    eprintln!(
+                        "[incremental] completely ignoring cache because of \
                                     differing commandline arguments"
-                        );
-                    }
-                    // We can't reuse the cache, purge it.
-                    debug!("load_dep_graph_new: differing commandline arg hashes");
-
-                    // No need to do any further work
-                    return LoadResult::DataOutOfDate;
+                    );
                 }
+                // We can't reuse the cache, purge it.
+                debug!("load_dep_graph_new: differing commandline arg hashes");
 
-                let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
-
-                LoadResult::Ok { data: (dep_graph, prev_work_products) }
+                // No need to do any further work
+                return LoadResult::DataOutOfDate;
             }
+
+            let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
+
+            LoadResult::Ok { data: (dep_graph, prev_work_products) }
         }
-    }))
+    }
 }
 
 /// Attempts to load the query result cache from disk
@@ -235,3 +195,35 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
         _ => Some(OnDiskCache::new_empty(sess.source_map())),
     }
 }
+
+/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
+/// new graph to an incremental session directory.
+pub fn setup_dep_graph(
+    sess: &Session,
+    crate_name: Symbol,
+    stable_crate_id: StableCrateId,
+) -> Result<DepGraph, ErrorGuaranteed> {
+    // `load_dep_graph` can only be called after `prepare_session_directory`.
+    prepare_session_directory(sess, crate_name, stable_crate_id)?;
+
+    let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));
+
+    if sess.opts.incremental.is_some() {
+        sess.time("incr_comp_garbage_collect_session_directories", || {
+            if let Err(e) = garbage_collect_session_directories(sess) {
+                warn!(
+                    "Error while trying to garbage collect incremental \
+                     compilation cache directory: {}",
+                    e
+                );
+            }
+        });
+    }
+
+    Ok(res
+        .and_then(|result| {
+            let (prev_graph, prev_work_products) = result.open(sess);
+            build_dep_graph(sess, prev_graph, prev_work_products)
+        })
+        .unwrap_or_else(DepGraph::new_disabled))
+}
diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs
index 1336189bc0d..fdecaca5a2d 100644
--- a/compiler/rustc_incremental/src/persist/mod.rs
+++ b/compiler/rustc_incremental/src/persist/mod.rs
@@ -16,9 +16,8 @@ pub use fs::in_incr_comp_dir;
 pub use fs::in_incr_comp_dir_sess;
 pub use fs::prepare_session_directory;
 pub use load::load_query_result_cache;
+pub use load::setup_dep_graph;
 pub use load::LoadResult;
-pub use load::{load_dep_graph, DepGraphFuture};
-pub use save::build_dep_graph;
 pub use save::save_dep_graph;
 pub use save::save_work_product_index;
 pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir;
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 7719482890e..210da751d95 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -147,7 +147,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult
 /// execution, the new dependency information is not kept in memory but directly
 /// output to this file. `save_dep_graph` then finalizes the staging dep-graph
 /// and moves it to the permanent dep-graph path
-pub fn build_dep_graph(
+pub(crate) fn build_dep_graph(
     sess: &Session,
     prev_graph: SerializedDepGraph,
     prev_work_products: WorkProductMap,
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index bd168f047fa..9276bb0a7b7 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -56,11 +56,8 @@ impl<'a> DescriptionCtx<'a> {
                                 (Some(span), "as_defined", name.to_string())
                             }
                         }
-                        ty::BrAnon(span) => {
-                            let span = match span {
-                                Some(_) => span,
-                                None => Some(tcx.def_span(scope)),
-                            };
+                        ty::BrAnon => {
+                            let span = Some(tcx.def_span(scope));
                             (span, "defined_here", String::new())
                         }
                         _ => {
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 5978e2c743c..4124c9eada9 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -775,7 +775,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         let var = self.canonical_var(info, r.into());
-        let br = ty::BoundRegion { var, kind: ty::BrAnon(None) };
+        let br = ty::BoundRegion { var, kind: ty::BrAnon };
         ty::Region::new_late_bound(self.interner(), self.binder_index, br)
     }
 
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index e418864026f..72cfc1337e2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -242,12 +242,9 @@ fn msg_span_from_named_region<'tcx>(
                         };
                         (text, Some(span))
                     }
-                    ty::BrAnon(span) => (
+                    ty::BrAnon => (
                         "the anonymous lifetime as defined here".to_string(),
-                        Some(match span {
-                            Some(span) => span,
-                            None => tcx.def_span(scope)
-                        })
+                        Some(tcx.def_span(scope))
                     ),
                     _ => (
                         format!("the lifetime `{region}` as defined here"),
@@ -262,11 +259,7 @@ fn msg_span_from_named_region<'tcx>(
             ..
         }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))),
         ty::RePlaceholder(ty::PlaceholderRegion {
-            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. },
-            ..
-        }) => ("the anonymous lifetime defined here".to_owned(), Some(span)),
-        ty::RePlaceholder(ty::PlaceholderRegion {
-            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. },
+            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon, .. },
             ..
         }) => ("an anonymous lifetime".to_owned(), None),
         _ => bug!("{:?}", region),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index bcaa4091c3a..a9029a8cec0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -918,7 +918,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
             //
             // See the `need_type_info/issue-103053.rs` test for
             // a example.
-            if !matches!(path.res, Res::Def(DefKind::TyAlias { .. }, _)) => {
+            if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => {
                 if let Some(ty) = self.opt_node_type(expr.hir_id)
                     && let ty::Adt(_, args) = ty.kind()
                 {
@@ -1047,7 +1047,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                         ) => {
                             if tcx.res_generics_def_id(path.res) != Some(def.did()) {
                                 match path.res {
-                                    Res::Def(DefKind::TyAlias { .. }, _) => {
+                                    Res::Def(DefKind::TyAlias, _) => {
                                         // FIXME: Ideally we should support this. For that
                                         // we have to map back from the self type to the
                                         // type alias though. That's difficult.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 07f04ec1e44..1b43022f8f7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -61,7 +61,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         let is_impl_item = region_info.is_impl_item;
 
         match br {
-            ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) => {}
+            ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon => {}
             _ => {
                 /* not an anonymous region */
                 debug!("try_report_named_anon_conflict: not an anonymous region");
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
index 8a78a1956c9..f5b8912532b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
@@ -36,15 +36,13 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                     ty::BrNamed(def_id, symbol) => {
                         (Some(self.tcx().def_span(def_id)), Some(symbol))
                     }
-                    ty::BrAnon(span) => (*span, None),
-                    ty::BrEnv => (None, None),
+                    ty::BrAnon | ty::BrEnv => (None, None),
                 };
                 let (sup_span, sup_symbol) = match sup_name {
                     ty::BrNamed(def_id, symbol) => {
                         (Some(self.tcx().def_span(def_id)), Some(symbol))
                     }
-                    ty::BrAnon(span) => (*span, None),
-                    ty::BrEnv => (None, None),
+                    ty::BrAnon | ty::BrEnv => (None, None),
                 };
                 let diag = match (sub_span, sup_span, sub_symbol, sup_symbol) {
                     (Some(sub_span), Some(sup_span), Some(&sub_symbol), Some(&sup_symbol)) => {
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 449d7a29590..fe253febfc7 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, Lrc, OnceLock, WorkerLocal};
 use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
-use rustc_incremental::DepGraphFuture;
+use rustc_incremental::setup_dep_graph;
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
@@ -19,7 +19,6 @@ use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
 use rustc_session::cstore::Untracked;
 use rustc_session::{output::find_crate_name, Session};
 use rustc_span::symbol::sym;
-use rustc_span::Symbol;
 use std::any::Any;
 use std::cell::{RefCell, RefMut};
 use std::sync::Arc;
@@ -132,43 +131,6 @@ impl<'tcx> Queries<'tcx> {
         })
     }
 
-    fn dep_graph_future(
-        &self,
-        crate_name: Symbol,
-        stable_crate_id: StableCrateId,
-    ) -> Result<Option<DepGraphFuture>> {
-        let sess = self.session();
-
-        // `load_dep_graph` can only be called after `prepare_session_directory`.
-        rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
-        let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
-
-        if sess.opts.incremental.is_some() {
-            sess.time("incr_comp_garbage_collect_session_directories", || {
-                if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
-                    warn!(
-                        "Error while trying to garbage collect incremental \
-                         compilation cache directory: {}",
-                        e
-                    );
-                }
-            });
-        }
-
-        Ok(res)
-    }
-
-    fn dep_graph(&self, dep_graph_future: Option<DepGraphFuture>) -> DepGraph {
-        dep_graph_future
-            .and_then(|future| {
-                let sess = self.session();
-                let (prev_graph, prev_work_products) =
-                    sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
-                rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
-            })
-            .unwrap_or_else(DepGraph::new_disabled)
-    }
-
     pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
         self.gcx.compute(|| {
             let sess = self.session();
@@ -184,10 +146,7 @@ impl<'tcx> Queries<'tcx> {
                 sess.opts.cg.metadata.clone(),
                 sess.cfg_version,
             );
-
-            // Compute the dependency graph (in the background). We want to do this as early as
-            // possible, to give the DepGraph maximum time to load before `dep_graph` is called.
-            let dep_graph_future = self.dep_graph_future(crate_name, stable_crate_id)?;
+            let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
 
             let lint_store = Lrc::new(passes::create_lint_store(
                 sess,
@@ -210,7 +169,7 @@ impl<'tcx> Queries<'tcx> {
                 crate_types,
                 stable_crate_id,
                 lint_store,
-                self.dep_graph(dep_graph_future),
+                dep_graph,
                 untracked,
                 &self.gcx_cell,
                 &self.arena,
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 4f6b79d9aee..536f78a73ed 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1454,13 +1454,13 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
         let hir::ItemKind::TyAlias(hir_ty, type_alias_generics) = &item.kind else { return };
 
-        if cx.tcx.features().lazy_type_alias {
-            // Bounds of lazy type aliases are respected.
+        // Bounds of lazy type aliases and TAITs are respected.
+        if cx.tcx.type_alias_is_lazy(item.owner_id) {
             return;
         }
 
         let ty = cx.tcx.type_of(item.owner_id).skip_binder();
-        if ty.has_opaque_types() || ty.has_inherent_projections() {
+        if ty.has_inherent_projections() {
             // Bounds of type aliases that contain opaque types or inherent projections are respected.
             // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X = Type::Inherent;`.
             return;
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 21575bf6b04..69b462d32bd 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2312,6 +2312,57 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `const_patterns_without_partial_eq` lint detects constants that are used in patterns,
+    /// whose type does not implement `PartialEq`.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(const_patterns_without_partial_eq)]
+    ///
+    /// trait EnumSetType {
+    ///    type Repr;
+    /// }
+    ///
+    /// enum Enum8 { }
+    /// impl EnumSetType for Enum8 {
+    ///     type Repr = u8;
+    /// }
+    ///
+    /// #[derive(PartialEq, Eq)]
+    /// struct EnumSet<T: EnumSetType> {
+    ///     __enumset_underlying: T::Repr,
+    /// }
+    ///
+    /// const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
+    ///
+    /// fn main() {
+    ///     match CONST_SET {
+    ///         CONST_SET => { /* ok */ }
+    ///         _ => panic!("match fell through?"),
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Previous versions of Rust accepted constants in patterns, even if those constants' types
+    /// did not have `PartialEq` implemented. The compiler falls back to comparing the value
+    /// field-by-field. In the future we'd like to ensure that pattern matching always
+    /// follows `PartialEq` semantics, so that trait bound will become a requirement for
+    /// matching on constants.
+    pub CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
+    Warn,
+    "constant in pattern does not implement `PartialEq`",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
+        reference: "issue #116122 <https://github.com/rust-lang/rust/issues/116122>",
+    };
+}
+
+declare_lint! {
     /// The `ambiguous_associated_items` lint detects ambiguity between
     /// [associated items] and [enum variants].
     ///
@@ -3357,6 +3408,7 @@ declare_lint_pass! {
         CONFLICTING_REPR_HINTS,
         CONST_EVALUATABLE_UNCHECKED,
         CONST_ITEM_MUTATION,
+        CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
         DEAD_CODE,
         DEPRECATED,
         DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 461b5290e69..b729c40228b 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -416,6 +416,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     bool RelaxELFRelocations,
     bool UseInitArray,
     const char *SplitDwarfFile,
+    const char *OutputObjFile,
     const char *DebugInfoCompression,
     bool ForceEmulatedTls,
     const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
@@ -448,6 +449,9 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   if (SplitDwarfFile) {
       Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
   }
+  if (OutputObjFile) {
+      Options.ObjectFilenameForDebug = OutputObjFile;
+  }
 #if LLVM_VERSION_GE(16, 0)
   if (!strcmp("zlib", DebugInfoCompression) && llvm::compression::zlib::isAvailable()) {
     Options.CompressDebugSections = DebugCompressionType::Zlib;
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index b56fe375849..f27eee0d79a 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -210,6 +210,7 @@ provide! { tcx, def_id, other, cdata,
     inferred_outlives_of => { table_defaulted_array }
     super_predicates_of => { table }
     type_of => { table }
+    type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) }
     variances_of => { table }
     fn_sig => { table }
     codegen_fn_attrs => { table }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 7506fc1bb05..a4ba943275e 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -31,7 +31,6 @@ use rustc_middle::query::Providers;
 use rustc_middle::traits::specialization_graph;
 use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
-use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, AssocItemContainer, SymbolName, Ty, TyCtxt};
 use rustc_middle::util::common::to_readable_str;
 use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
@@ -827,7 +826,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -862,7 +861,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -903,7 +902,7 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool {
         | DefKind::Variant
         | DefKind::Trait
         | DefKind::Impl { .. } => true,
-        DefKind::TyAlias { .. }
+        DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -938,7 +937,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -982,7 +981,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
         | DefKind::Const
         | DefKind::Fn
         | DefKind::ForeignMod
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::Enum
         | DefKind::Union
@@ -1092,9 +1091,7 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
         | DefKind::Closure
         | DefKind::Generator
         | DefKind::ExternCrate => false,
-        DefKind::TyAlias { lazy } => {
-            lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types()
-        }
+        DefKind::TyAlias => tcx.type_alias_is_lazy(def_id),
     }
 }
 
@@ -1105,7 +1102,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -1145,7 +1142,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         | DefKind::Fn
         | DefKind::Const
         | DefKind::Static(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::Impl { .. }
         | DefKind::AssocFn
@@ -1205,7 +1202,7 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool {
         | DefKind::Const
         | DefKind::Static(..)
         | DefKind::Ctor(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::ForeignTy
         | DefKind::Impl { .. }
@@ -1246,7 +1243,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
         | DefKind::AssocConst
         | DefKind::AnonConst
         | DefKind::Static(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::Impl { of_trait: false }
         | DefKind::ForeignTy
@@ -1279,7 +1276,7 @@ fn should_encode_const(def_kind: DefKind) -> bool {
         | DefKind::Field
         | DefKind::Fn
         | DefKind::Static(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::ForeignTy
         | DefKind::Impl { .. }
@@ -1451,6 +1448,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if let DefKind::Macro(_) = def_kind {
                 self.encode_info_for_macro(local_id);
             }
+            if let DefKind::TyAlias = def_kind {
+                self.tables
+                    .type_alias_is_lazy
+                    .set(def_id.index, self.tcx.type_alias_is_lazy(def_id));
+            }
             if let DefKind::OpaqueTy = def_kind {
                 self.encode_explicit_item_bounds(def_id);
                 self.tables
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 09b2a1a0cb2..42764af52c4 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -383,6 +383,7 @@ define_tables! {
     is_intrinsic: Table<DefIndex, bool>,
     is_macro_rules: Table<DefIndex, bool>,
     is_type_alias_impl_trait: Table<DefIndex, bool>,
+    type_alias_is_lazy: Table<DefIndex, bool>,
     attr_flags: Table<DefIndex, AttrFlags>,
     def_path_hashes: Table<DefIndex, DefPathHash>,
     explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index d105dab4814..bb1320942b0 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -145,8 +145,7 @@ fixed_size_enum! {
         ( Enum                                     )
         ( Variant                                  )
         ( Trait                                    )
-        ( TyAlias { lazy: false }                  )
-        ( TyAlias { lazy: true }                   )
+        ( TyAlias                                  )
         ( ForeignTy                                )
         ( TraitAlias                               )
         ( AssocTy                                  )
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 3491c487f3e..4af2d83e9c7 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -196,9 +196,7 @@ impl<'hir> Map<'hir> {
                 ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
                 ItemKind::Mod(..) => DefKind::Mod,
                 ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
-                ItemKind::TyAlias(..) => {
-                    DefKind::TyAlias { lazy: self.tcx.features().lazy_type_alias }
-                }
+                ItemKind::TyAlias(..) => DefKind::TyAlias,
                 ItemKind::Enum(..) => DefKind::Enum,
                 ItemKind::Struct(..) => DefKind::Struct,
                 ItemKind::Union(..) => DefKind::Union,
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 2f2597d6b22..41beca072bf 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -455,7 +455,7 @@ impl<'tcx> CanonicalVarValues<'tcx> {
                         CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => {
                             let br = ty::BoundRegion {
                                 var: ty::BoundVar::from_usize(i),
-                                kind: ty::BrAnon(None),
+                                kind: ty::BrAnon,
                             };
                             ty::Region::new_late_bound(tcx, ty::INNERMOST, br).into()
                         }
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index c157b7052ab..c74a9536b63 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -414,8 +414,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
     pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
         let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
             ty::ReVar(vid) => {
-                let br =
-                    ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon(None) };
+                let br = ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon };
                 ty::Region::new_late_bound(tcx, depth, br)
             }
             _ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 5986a8b1cd8..340c5a769db 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -229,7 +229,7 @@ rustc_queries! {
             action = {
                 use rustc_hir::def::DefKind;
                 match tcx.def_kind(key) {
-                    DefKind::TyAlias { .. } => "expanding type alias",
+                    DefKind::TyAlias => "expanding type alias",
                     DefKind::TraitAlias => "expanding trait alias",
                     _ => "computing type of",
                 }
@@ -251,6 +251,14 @@ rustc_queries! {
         }
     }
 
+    query type_alias_is_lazy(key: DefId) -> bool {
+        desc { |tcx|
+            "computing whether `{path}` is a lazy type alias",
+            path = tcx.def_path_str(key),
+        }
+        separate_provide_extern
+    }
+
     query collect_return_position_impl_trait_in_trait_tys(key: DefId)
         -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
     {
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 219927f5ab4..f50969dd967 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -448,7 +448,7 @@ impl<'tcx> AdtDef<'tcx> {
             Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
             Res::Def(DefKind::Struct, _)
             | Res::Def(DefKind::Union, _)
-            | Res::Def(DefKind::TyAlias { .. }, _)
+            | Res::Def(DefKind::TyAlias, _)
             | Res::Def(DefKind::AssocTy, _)
             | Res::SelfTyParam { .. }
             | Res::SelfTyAlias { .. }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 400d4bcad5b..c06b8b2dfa0 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -318,7 +318,7 @@ pub struct CommonLifetimes<'tcx> {
     pub re_vars: Vec<Region<'tcx>>,
 
     /// Pre-interned values of the form:
-    /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(None) })`
+    /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon })`
     /// for small values of `i` and `v`.
     pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
 }
@@ -395,7 +395,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
                     .map(|v| {
                         mk(ty::ReLateBound(
                             ty::DebruijnIndex::from(i),
-                            ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon(None) },
+                            ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon },
                         ))
                     })
                     .collect()
@@ -1114,7 +1114,7 @@ impl<'tcx> TyCtxt<'tcx> {
         if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id)
             && let hir::TyKind::Path(hir::QPath::Resolved(
                 None,
-                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias { .. }, def_id), .. }, )) = hir_output.kind
+                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
             && let Some(local_id) = def_id.as_local()
             && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias
             && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics()
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index e7ebb985ca4..f03813a459b 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -493,7 +493,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
             Alias(Opaque, AliasTy { def_id, .. }) => {
                 let parent = self.tcx.parent(def_id);
                 let parent_ty = self.tcx.type_of(parent).instantiate_identity();
-                if let DefKind::TyAlias { .. } | DefKind::AssocTy = self.tcx.def_kind(parent)
+                if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent)
                     && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
                     && parent_opaque_def_id == def_id
                 {
@@ -577,7 +577,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
             Alias(Opaque, AliasTy { def_id, .. }) => {
                 let parent = self.tcx.parent(def_id);
                 let parent_ty = self.tcx.type_of(parent).instantiate_identity();
-                if let hir::def::DefKind::TyAlias { .. } | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
+                if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
                     && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
                     && parent_opaque_def_id == def_id
                 {
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 77cf6bee79d..00529a1e066 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -385,7 +385,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 let index = entry.index();
                 let var = ty::BoundVar::from_usize(index);
                 let kind = entry
-                    .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon(None)))
+                    .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon))
                     .expect_region();
                 let br = ty::BoundRegion { var, kind };
                 ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br)
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 2b75f6c4e8f..0b0a708e42b 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -118,7 +118,7 @@ impl<'tcx> Instance<'tcx> {
     /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
     pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
         let ty = tcx.type_of(self.def.def_id());
-        tcx.subst_and_normalize_erasing_regions(self.args, param_env, ty)
+        tcx.instantiate_and_normalize_erasing_regions(self.args, param_env, ty)
     }
 
     /// Finds a crate that contains a monomorphization of this instance that
@@ -580,7 +580,7 @@ impl<'tcx> Instance<'tcx> {
         self.def.has_polymorphic_mir_body().then_some(self.args)
     }
 
-    pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
+    pub fn instantiate_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
@@ -593,7 +593,7 @@ impl<'tcx> Instance<'tcx> {
     }
 
     #[inline(always)]
-    pub fn subst_mir_and_normalize_erasing_regions<T>(
+    pub fn instantiate_mir_and_normalize_erasing_regions<T>(
         &self,
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -603,14 +603,14 @@ impl<'tcx> Instance<'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
         if let Some(args) = self.args_for_mir_body() {
-            tcx.subst_and_normalize_erasing_regions(args, param_env, v)
+            tcx.instantiate_and_normalize_erasing_regions(args, param_env, v)
         } else {
             tcx.normalize_erasing_regions(param_env, v.skip_binder())
         }
     }
 
     #[inline(always)]
-    pub fn try_subst_mir_and_normalize_erasing_regions<T>(
+    pub fn try_instantiate_mir_and_normalize_erasing_regions<T>(
         &self,
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -620,7 +620,7 @@ impl<'tcx> Instance<'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
         if let Some(args) = self.args_for_mir_body() {
-            tcx.try_subst_and_normalize_erasing_regions(args, param_env, v)
+            tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v)
         } else {
             tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
         }
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 2415d50b278..fd125af2074 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -134,8 +134,9 @@ impl<'tcx> TyCtxt<'tcx> {
     /// in-scope substitutions and then normalizing any associated
     /// types.
     /// Panics if normalization fails. In case normalization might fail
-    /// use `try_subst_and_normalize_erasing_regions` instead.
-    pub fn subst_and_normalize_erasing_regions<T>(
+    /// use `try_instantiate_and_normalize_erasing_regions` instead.
+    #[instrument(level = "debug", skip(self))]
+    pub fn instantiate_and_normalize_erasing_regions<T>(
         self,
         param_args: GenericArgsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -144,22 +145,16 @@ impl<'tcx> TyCtxt<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        debug!(
-            "subst_and_normalize_erasing_regions(\
-             param_args={:?}, \
-             value={:?}, \
-             param_env={:?})",
-            param_args, value, param_env,
-        );
         let substituted = value.instantiate(self, param_args);
         self.normalize_erasing_regions(param_env, substituted)
     }
 
     /// Monomorphizes a type from the AST by first applying the
     /// in-scope substitutions and then trying to normalize any associated
-    /// types. Contrary to `subst_and_normalize_erasing_regions` this does
+    /// types. Contrary to `instantiate_and_normalize_erasing_regions` this does
     /// not assume that normalization succeeds.
-    pub fn try_subst_and_normalize_erasing_regions<T>(
+    #[instrument(level = "debug", skip(self))]
+    pub fn try_instantiate_and_normalize_erasing_regions<T>(
         self,
         param_args: GenericArgsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -168,13 +163,6 @@ impl<'tcx> TyCtxt<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        debug!(
-            "subst_and_normalize_erasing_regions(\
-             param_args={:?}, \
-             value={:?}, \
-             param_env={:?})",
-            param_args, value, param_env,
-        );
         let substituted = value.instantiate(self, param_args);
         self.try_normalize_erasing_regions(param_env, substituted)
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 34e3479c58e..2d7350387ca 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -360,7 +360,7 @@ pub trait PrettyPrinter<'tcx>:
                 self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?;
                 self.write_str("::")?;
             } else if let DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Trait
-                | DefKind::TyAlias { .. } | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind
+                | DefKind::TyAlias | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind
             {
             } else {
                 // If not covered above, like for example items out of `impl` blocks, fallback.
@@ -766,7 +766,7 @@ pub trait PrettyPrinter<'tcx>:
 
                 let parent = self.tcx().parent(def_id);
                 match self.tcx().def_kind(parent) {
-                    DefKind::TyAlias { .. } | DefKind::AssocTy => {
+                    DefKind::TyAlias | DefKind::AssocTy => {
                         // NOTE: I know we should check for NO_QUERIES here, but it's alright.
                         // `type_of` on a type alias or assoc type should never cause a cycle.
                         if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) =
@@ -2330,7 +2330,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
                 // If this is an anonymous placeholder, don't rename. Otherwise, in some
                 // async fns, we get a `for<'r> Send` bound
                 match kind {
-                    ty::BrAnon(..) | ty::BrEnv => r,
+                    ty::BrAnon | ty::BrEnv => r,
                     _ => {
                         // Index doesn't matter, since this is just for naming and these never get bound
                         let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
@@ -2451,7 +2451,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                             binder_level_idx: ty::DebruijnIndex,
                             br: ty::BoundRegion| {
                 let (name, kind) = match br.kind {
-                    ty::BrAnon(..) | ty::BrEnv => {
+                    ty::BrAnon | ty::BrEnv => {
                         let name = next_name(&self);
 
                         if let Some(lt_idx) = lifetime_idx {
@@ -2998,7 +2998,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
 
             match child.res {
                 def::Res::Def(DefKind::AssocTy, _) => {}
-                def::Res::Def(DefKind::TyAlias { .. }, _) => {}
+                def::Res::Def(DefKind::TyAlias, _) => {}
                 def::Res::Def(defkind, def_id) => {
                     if let Some(ns) = defkind.ns() {
                         collect_fn(&child.ident, ns, def_id);
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index f6372ef3f2f..2adbe9e0309 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -68,7 +68,7 @@ impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
 impl fmt::Debug for ty::BoundRegionKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            ty::BrAnon(span) => write!(f, "BrAnon({span:?})"),
+            ty::BrAnon => write!(f, "BrAnon"),
             ty::BrNamed(did, name) => {
                 if did.is_crate_root() {
                     write!(f, "BrNamed({name})")
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index d2c42235adb..1e57392e0e7 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -69,7 +69,7 @@ pub struct FreeRegion {
 #[derive(HashStable)]
 pub enum BoundRegionKind {
     /// An anonymous region parameter for a given fn (&T)
-    BrAnon(Option<Span>),
+    BrAnon,
 
     /// Named region parameters for functions (a in &'a T)
     ///
@@ -1223,7 +1223,7 @@ impl<'tcx> AliasTy<'tcx> {
             DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
             DefKind::AssocTy => ty::Projection,
             DefKind::OpaqueTy => ty::Opaque,
-            DefKind::TyAlias { .. } => ty::Weak,
+            DefKind::TyAlias => ty::Weak,
             kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
         }
     }
@@ -1465,7 +1465,7 @@ impl<'tcx> Region<'tcx> {
         bound_region: ty::BoundRegion,
     ) -> Region<'tcx> {
         // Use a pre-interned one when possible.
-        if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region
+        if let ty::BoundRegion { var, kind: ty::BrAnon } = bound_region
             && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize())
             && let Some(re) = inner.get(var.as_usize()).copied()
         {
@@ -1959,7 +1959,7 @@ impl<'tcx> Ty<'tcx> {
             (kind, tcx.def_kind(alias_ty.def_id)),
             (ty::Opaque, DefKind::OpaqueTy)
                 | (ty::Projection | ty::Inherent, DefKind::AssocTy)
-                | (ty::Weak, DefKind::TyAlias { .. })
+                | (ty::Weak, DefKind::TyAlias)
         );
         Ty::new(tcx, Alias(kind, alias_ty))
     }
@@ -3010,7 +3010,7 @@ mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
-    static_assert_size!(RegionKind<'_>, 28);
+    static_assert_size!(RegionKind<'_>, 24);
     static_assert_size!(TyKind<'_>, 32);
     // tidy-alphabetical-end
 }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 0dda7cd83be..31b52677b27 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -156,7 +156,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 | DefKind::Enum
                 | DefKind::Trait
                 | DefKind::OpaqueTy
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::ForeignTy
                 | DefKind::TraitAlias
                 | DefKind::AssocTy
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index dec06363380..578d8e7a975 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -217,7 +217,7 @@ fn find_item_ty_spans(
     match ty.kind {
         hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
             if let Res::Def(kind, def_id) = path.res
-                && !matches!(kind, DefKind::TyAlias { .. }) {
+                && !matches!(kind, DefKind::TyAlias) {
                 let check_params = def_id.as_local().map_or(true, |def_id| {
                     if def_id == needle {
                         spans.push(ty.span);
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 938f3edd31b..ce021923f64 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -229,6 +229,9 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type
     .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
     .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
+mir_build_non_partial_eq_match =
+    to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq`
+
 mir_build_nontrivial_structural_match =
     to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
 
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 3ff3387a781..bee5ac550dd 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -749,6 +749,12 @@ pub struct NontrivialStructuralMatch<'tcx> {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(mir_build_non_partial_eq_match)]
+pub struct NonPartialEqMatch<'tcx> {
+    pub non_peq_ty: Ty<'tcx>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(mir_build_overlapping_range_endpoints)]
 #[note]
 pub struct OverlappingRangeEndpoints<'tcx> {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 00d9fe72cfc..4758ace73b6 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -16,8 +16,8 @@ use std::cell::Cell;
 
 use super::PatCtxt;
 use crate::errors::{
-    FloatPattern, IndirectStructuralMatch, InvalidPattern, NontrivialStructuralMatch,
-    PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
+    FloatPattern, IndirectStructuralMatch, InvalidPattern, NonPartialEqMatch,
+    NontrivialStructuralMatch, PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
 };
 
 impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
@@ -155,8 +155,9 @@ impl<'tcx> ConstToPat<'tcx> {
         };
 
         if !self.saw_const_match_error.get() {
-            // If we were able to successfully convert the const to some pat,
-            // double-check that all types in the const implement `Structural`.
+            // If we were able to successfully convert the const to some pat (possibly with some
+            // lints, but no errors), double-check that all types in the const implement
+            // `Structural` and `PartialEq`.
 
             let structural =
                 traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
@@ -178,7 +179,7 @@ impl<'tcx> ConstToPat<'tcx> {
             }
 
             if let Some(non_sm_ty) = structural {
-                if !self.type_may_have_partial_eq_impl(cv.ty()) {
+                if !self.type_has_partial_eq_impl(cv.ty()) {
                     if let ty::Adt(def, ..) = non_sm_ty.kind() {
                         if def.is_union() {
                             let err = UnionPattern { span: self.span };
@@ -192,8 +193,10 @@ impl<'tcx> ConstToPat<'tcx> {
                     } else {
                         let err = InvalidPattern { span: self.span, non_sm_ty };
                         self.tcx().sess.emit_err(err);
-                        return Box::new(Pat { span: self.span, ty: cv.ty(), kind: PatKind::Wild });
                     }
+                    // All branches above emitted an error. Don't print any more lints.
+                    // The pattern we return is irrelevant since we errored.
+                    return Box::new(Pat { span: self.span, ty: cv.ty(), kind: PatKind::Wild });
                 } else if !self.saw_const_match_lint.get() {
                     if let Some(mir_structural_match_violation) = mir_structural_match_violation {
                         match non_sm_ty.kind() {
@@ -238,13 +241,24 @@ impl<'tcx> ConstToPat<'tcx> {
                     _ => {}
                 }
             }
+
+            // Always check for `PartialEq`, even if we emitted other lints. (But not if there were
+            // any errors.) This ensures it shows up in cargo's future-compat reports as well.
+            if !self.type_has_partial_eq_impl(cv.ty()) {
+                self.tcx().emit_spanned_lint(
+                    lint::builtin::CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
+                    self.id,
+                    self.span,
+                    NonPartialEqMatch { non_peq_ty: cv.ty() },
+                );
+            }
         }
 
         inlined_const_as_pat
     }
 
     #[instrument(level = "trace", skip(self), ret)]
-    fn type_may_have_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
+    fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
         // double-check there even *is* a semantic `PartialEq` to dispatch to.
         //
         // (If there isn't, then we can safely issue a hard
@@ -259,8 +273,13 @@ impl<'tcx> ConstToPat<'tcx> {
             ty::TraitRef::new(self.tcx(), partial_eq_trait_id, [ty, ty]),
         );
 
-        // FIXME: should this call a `predicate_must_hold` variant instead?
-        self.infcx.predicate_may_hold(&partial_eq_obligation)
+        // This *could* accept a type that isn't actually `PartialEq`, because region bounds get
+        // ignored. However that should be pretty much impossible since consts that do not depend on
+        // generics can only mention the `'static` lifetime, and how would one have a type that's
+        // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
+        // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
+        // can ensure that the type really implements `PartialEq`.
+        self.infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
     }
 
     fn field_pats(
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index f1f75c26717..fe47a1cd78c 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -439,7 +439,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 DefKind::Struct
                 | DefKind::Ctor(CtorOf::Struct, ..)
                 | DefKind::Union
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::AssocTy,
                 _,
             )
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index dd20e5d7430..83766f31148 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -758,7 +758,9 @@ impl Map {
             self.value_count += 1;
         }
 
-        if let Some(ref_ty) = ty.builtin_deref(true) && let ty::Slice(..) = ref_ty.ty.kind() {
+        if let ty::Ref(_, ref_ty, _) | ty::RawPtr(ty::TypeAndMut { ty: ref_ty, .. }) = ty.kind()
+            && let ty::Slice(..) = ref_ty.kind()
+        {
             assert!(self.places[place].value_index.is_none(), "slices are not scalars");
 
             // Prepend new child to the linked list.
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 1d9c89477cb..ebd61f8ad95 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -193,7 +193,7 @@ impl<'tcx> Inliner<'tcx> {
             return Err("optimization fuel exhausted");
         }
 
-        let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
+        let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions(
             self.tcx,
             self.param_env,
             ty::EarlyBinder::bind(callee_body.clone()),
@@ -481,9 +481,10 @@ impl<'tcx> Inliner<'tcx> {
                 work_list.push(target);
 
                 // If the place doesn't actually need dropping, treat it like a regular goto.
-                let ty = callsite
-                    .callee
-                    .subst_mir(self.tcx, ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty));
+                let ty = callsite.callee.instantiate_mir(
+                    self.tcx,
+                    ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty),
+                );
                 if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind {
                     work_list.push(unwind);
                 }
@@ -650,7 +651,7 @@ impl<'tcx> Inliner<'tcx> {
                 // Copy only unevaluated constants from the callee_body into the caller_body.
                 // Although we are only pushing `ConstKind::Unevaluated` consts to
                 // `required_consts`, here we may not only have `ConstKind::Unevaluated`
-                // because we are calling `subst_and_normalize_erasing_regions`.
+                // because we are calling `instantiate_and_normalize_erasing_regions`.
                 caller_body.required_consts.extend(
                     callee_body.required_consts.iter().copied().filter(|&ct| match ct.const_ {
                         Const::Ty(_) => {
@@ -811,9 +812,10 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
         match terminator.kind {
             TerminatorKind::Drop { ref place, unwind, .. } => {
                 // If the place doesn't actually need dropping, treat it like a regular goto.
-                let ty = self
-                    .instance
-                    .subst_mir(tcx, ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty));
+                let ty = self.instance.instantiate_mir(
+                    tcx,
+                    ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty),
+                );
                 if ty.needs_drop(tcx, self.param_env) {
                     self.cost += CALL_PENALTY;
                     if let UnwindAction::Cleanup(_) = unwind {
@@ -824,7 +826,8 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
                 }
             }
             TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
-                let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty()));
+                let fn_ty =
+                    self.instance.instantiate_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty()));
                 self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
                     // Don't give intrinsics the extra penalty for calls
                     INSTR_COST
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index 822634129fc..d30e0bad813 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -44,7 +44,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
     ) -> bool {
         trace!(%caller);
         for &(callee, args) in tcx.mir_inliner_callees(caller.def) {
-            let Ok(args) = caller.try_subst_mir_and_normalize_erasing_regions(
+            let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions(
                 tcx,
                 param_env,
                 ty::EarlyBinder::bind(args),
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index b7a51cfd619..2795cf15702 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -29,6 +29,7 @@
 
 use crate::MirPass;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
+use rustc_index::bit_set::BitSet;
 use rustc_index::{Idx, IndexSlice, IndexVec};
 use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
@@ -345,24 +346,22 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 
     let basic_blocks = body.basic_blocks.as_mut();
     let source_scopes = &body.source_scopes;
-    let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
-    let mut used_blocks = 0;
-    for alive_index in reachable.iter() {
-        let alive_index = alive_index.index();
-        replacements[alive_index] = BasicBlock::new(used_blocks);
-        if alive_index != used_blocks {
-            // Swap the next alive block data with the current available slot. Since
-            // alive_index is non-decreasing this is a valid operation.
-            basic_blocks.raw.swap(alive_index, used_blocks);
-        }
-        used_blocks += 1;
-    }
-
     if tcx.sess.instrument_coverage() {
-        save_unreachable_coverage(basic_blocks, source_scopes, used_blocks);
+        save_unreachable_coverage(basic_blocks, source_scopes, &reachable);
     }
 
-    basic_blocks.raw.truncate(used_blocks);
+    let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
+    let mut orig_index = 0;
+    let mut used_index = 0;
+    basic_blocks.raw.retain(|_| {
+        let keep = reachable.contains(BasicBlock::new(orig_index));
+        if keep {
+            replacements[orig_index] = BasicBlock::new(used_index);
+            used_index += 1;
+        }
+        orig_index += 1;
+        keep
+    });
 
     for block in basic_blocks {
         for target in block.terminator_mut().successors_mut() {
@@ -404,11 +403,12 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 fn save_unreachable_coverage(
     basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'_>>,
     source_scopes: &IndexSlice<SourceScope, SourceScopeData<'_>>,
-    first_dead_block: usize,
+    reachable: &BitSet<BasicBlock>,
 ) {
     // Identify instances that still have some live coverage counters left.
     let mut live = FxHashSet::default();
-    for basic_block in &basic_blocks.raw[0..first_dead_block] {
+    for bb in reachable.iter() {
+        let basic_block = &basic_blocks[bb];
         for statement in &basic_block.statements {
             let StatementKind::Coverage(coverage) = &statement.kind else { continue };
             let CoverageKind::Counter { .. } = coverage.kind else { continue };
@@ -417,7 +417,8 @@ fn save_unreachable_coverage(
         }
     }
 
-    for block in &mut basic_blocks.raw[..first_dead_block] {
+    for bb in reachable.iter() {
+        let block = &mut basic_blocks[bb];
         for statement in &mut block.statements {
             let StatementKind::Coverage(_) = &statement.kind else { continue };
             let instance = statement.source_info.scope.inlined_instance(source_scopes);
@@ -433,7 +434,11 @@ fn save_unreachable_coverage(
 
     // Retain coverage for instances that still have some live counters left.
     let mut retained_coverage = Vec::new();
-    for dead_block in &basic_blocks.raw[first_dead_block..] {
+    for dead_block in basic_blocks.indices() {
+        if reachable.contains(dead_block) {
+            continue;
+        }
+        let dead_block = &basic_blocks[dead_block];
         for statement in &dead_block.statements {
             let StatementKind::Coverage(coverage) = &statement.kind else { continue };
             let Some(code_region) = &coverage.code_region else { continue };
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index bd1724bf842..0b9311a20ef 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -13,7 +13,11 @@ pub struct UnreachablePropagation;
 impl MirPass<'_> for UnreachablePropagation {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         // Enable only under -Zmir-opt-level=2 as this can make programs less debuggable.
-        sess.mir_opt_level() >= 2
+
+        // FIXME(#116171) Coverage gets confused by MIR passes that can remove all
+        // coverage statements from an instrumented function. This pass can be
+        // re-enabled when coverage codegen is robust against that happening.
+        sess.mir_opt_level() >= 2 && !sess.instrument_coverage()
     }
 
     fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 4afa4e597f7..1a9f0e8352e 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -606,7 +606,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!("monomorphize: self.instance={:?}", self.instance);
-        self.instance.subst_mir_and_normalize_erasing_regions(
+        self.instance.instantiate_mir_and_normalize_erasing_regions(
             self.tcx,
             ty::ParamEnv::reveal_all(),
             ty::EarlyBinder::bind(value),
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index c993e64477b..1d8cbe0e21b 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -647,7 +647,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
                 // parameters, but the self-type of their impl block do will fail to normalize.
                 if !tcx.sess.opts.unstable_opts.polymorphize || !instance.has_param() {
                     // This is a method within an impl, find out what the self-type is:
-                    let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
+                    let impl_self_ty = tcx.instantiate_and_normalize_erasing_regions(
                         instance.args,
                         ty::ParamEnv::reveal_all(),
                         tcx.type_of(impl_def_id),
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index 0e85f35fc1b..6c206a6bac8 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -143,7 +143,7 @@ fn mark_used_by_default_parameters<'tcx>(
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs
index a3433d3d13d..e25c5c9f27c 100644
--- a/compiler/rustc_monomorphize/src/util.rs
+++ b/compiler/rustc_monomorphize/src/util.rs
@@ -26,12 +26,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
         let ClosureSizeProfileData { before_feature_tys, after_feature_tys } =
             typeck_results.closure_size_eval[&closure_def_id];
 
-        let before_feature_tys = tcx.subst_and_normalize_erasing_regions(
+        let before_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
             closure_instance.args,
             param_env,
             ty::EarlyBinder::bind(before_feature_tys),
         );
-        let after_feature_tys = tcx.subst_and_normalize_erasing_regions(
+        let after_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
             closure_instance.args,
             param_env,
             ty::EarlyBinder::bind(after_feature_tys),
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index dc0776c5dad..214c6d70960 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -648,6 +648,10 @@ passes_rustc_lint_opt_ty =
     `#[rustc_lint_opt_ty]` should be applied to a struct
     .label = not a struct
 
+passes_rustc_safe_intrinsic =
+    attribute should be applied to intrinsic functions
+    .label = not an intrinsic function
+
 passes_rustc_std_internal_symbol =
     attribute should be applied to functions or statics
     .label = not a function or static
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs
index 9e4d960af14..153c39977bb 100644
--- a/compiler/rustc_passes/src/abi_test.rs
+++ b/compiler/rustc_passes/src/abi_test.rs
@@ -21,7 +21,7 @@ pub fn test_abi(tcx: TyCtxt<'_>) {
                 DefKind::Fn | DefKind::AssocFn => {
                     dump_abi_of_fn_item(tcx, id, attr);
                 }
-                DefKind::TyAlias { .. } => {
+                DefKind::TyAlias => {
                     dump_abi_of_fn_type(tcx, id, attr);
                 }
                 _ => {
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index afba366a365..9a7564cb213 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -195,6 +195,9 @@ impl CheckAttrVisitor<'_> {
                 | sym::rustc_promotable => self.check_stability_promotable(&attr, span, target),
                 sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
                 sym::rustc_confusables => self.check_confusables(&attr, target),
+                sym::rustc_safe_intrinsic => {
+                    self.check_rustc_safe_intrinsic(hir_id, attr, span, target)
+                }
                 _ => true,
             };
 
@@ -2042,6 +2045,29 @@ impl CheckAttrVisitor<'_> {
         }
     }
 
+    fn check_rustc_safe_intrinsic(
+        &self,
+        hir_id: HirId,
+        attr: &Attribute,
+        span: Span,
+        target: Target,
+    ) -> bool {
+        let hir = self.tcx.hir();
+
+        if let Target::ForeignFn = target
+            && let Some(parent) = hir.opt_parent_id(hir_id)
+            && let hir::Node::Item(Item {
+                kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. },
+                ..
+            }) = hir.get(parent)
+        {
+            return true;
+        }
+
+        self.tcx.sess.emit_err(errors::RustcSafeIntrinsic { attr_span: attr.span, span });
+        false
+    }
+
     fn check_rustc_std_internal_symbol(
         &self,
         attr: &Attribute,
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index d1c3bcf3839..493daf314ce 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -96,7 +96,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
 
     fn handle_res(&mut self, res: Res) {
         match res {
-            Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias { .. }, def_id) => {
+            Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias, def_id) => {
                 self.check_def_id(def_id);
             }
             _ if self.in_pat => {}
@@ -923,7 +923,7 @@ impl<'tcx> DeadVisitor<'tcx> {
             | DefKind::Fn
             | DefKind::Static(_)
             | DefKind::Const
-            | DefKind::TyAlias { .. }
+            | DefKind::TyAlias
             | DefKind::Enum
             | DefKind::Union
             | DefKind::ForeignTy => self.warn_dead_code(def_id, "used"),
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 2ec6a0b9241..bcf5abbfe7d 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -621,6 +621,15 @@ pub struct RustcAllowConstFnUnstable {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_rustc_safe_intrinsic)]
+pub struct RustcSafeIntrinsic {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_rustc_std_internal_symbol)]
 pub struct RustcStdInternalSymbol {
     #[primary_span]
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index e3a63f2e004..e195f9ab6da 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -23,7 +23,7 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
     for id in tcx.hir_crate_items(()).definitions() {
         for attr in tcx.get_attrs(id, sym::rustc_layout) {
             match tcx.def_kind(id) {
-                DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union => {
+                DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union => {
                     dump_layout_of(tcx, id, attr);
                 }
                 _ => {
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 2e71ac8d7dc..ab85f680fcf 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -588,7 +588,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
         self.update(def_id, macro_ev, Level::Reachable);
         match def_kind {
             // No type privacy, so can be directly marked as reachable.
-            DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias { .. } => {
+            DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => {
                 if vis.is_accessible_from(module, self.tcx) {
                     self.update(def_id, macro_ev, Level::Reachable);
                 }
@@ -1637,8 +1637,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
         let def_kind = tcx.def_kind(def_id);
 
         match def_kind {
-            DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias { .. } => {
-                if let DefKind::TyAlias { .. } = def_kind {
+            DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
+                if let DefKind::TyAlias = def_kind {
                     self.check_unnameable(def_id, effective_vis);
                 }
                 self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 2e9ebde296c..f2c1f84fccc 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -580,9 +580,7 @@ pub(crate) fn report_cycle<'a>(
         });
     }
 
-    let alias = if stack
-        .iter()
-        .all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias { .. })))
+    let alias = if stack.iter().all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias)))
     {
         Some(crate::error::Alias::Ty)
     } else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) {
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index f93edffca79..ae8414ebba6 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -18,7 +18,7 @@ use rustc_data_structures::sharded::Sharded;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::Lock;
 #[cfg(parallel_compiler)]
-use rustc_data_structures::{cold_path, sync};
+use rustc_data_structures::{outline, sync};
 use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError};
 use rustc_span::{Span, DUMMY_SP};
 use std::cell::Cell;
@@ -265,7 +265,7 @@ where
     match result {
         Ok(()) => {
             let Some((v, index)) = query.query_cache(qcx).lookup(&key) else {
-                cold_path(|| {
+                outline(|| {
                     // We didn't find the query result in the query cache. Check if it was
                     // poisoned due to a panic instead.
                     let lock = query.query_state(qcx).active.get_shard_by_value(&key).lock();
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 2c36c83ae72..a18109574fe 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -698,10 +698,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
             // These items live in the type namespace.
             ItemKind::TyAlias(..) => {
-                let res = Res::Def(
-                    DefKind::TyAlias { lazy: self.r.tcx.features().lazy_type_alias },
-                    def_id,
-                );
+                let res = Res::Def(DefKind::TyAlias, def_id);
                 self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
@@ -950,7 +947,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 DefKind::Struct
                 | DefKind::Union
                 | DefKind::Variant
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::ForeignTy
                 | DefKind::OpaqueTy
                 | DefKind::TraitAlias
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 9b7fd76d103..907a6b1c46c 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -2596,7 +2596,9 @@ fn show_candidates(
             );
             if let [first, .., last] = &path[..] {
                 let sp = first.ident.span.until(last.ident.span);
-                if sp.can_be_used_for_suggestions() {
+                // Our suggestion is empty, so make sure the span is not empty (or we'd ICE).
+                // Can happen for derive-generated spans.
+                if sp.can_be_used_for_suggestions() && !sp.is_empty() {
                     err.span_suggestion_verbose(
                         sp,
                         format!("if you import `{}`, refer to it directly", last.ident),
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 01f9f060594..c3c43346ed8 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -474,7 +474,7 @@ impl<'a> PathSource<'a> {
                         | DefKind::Enum
                         | DefKind::Trait
                         | DefKind::TraitAlias
-                        | DefKind::TyAlias { .. }
+                        | DefKind::TyAlias
                         | DefKind::AssocTy
                         | DefKind::TyParam
                         | DefKind::OpaqueTy
@@ -513,7 +513,7 @@ impl<'a> PathSource<'a> {
                     DefKind::Struct
                         | DefKind::Union
                         | DefKind::Variant
-                        | DefKind::TyAlias { .. }
+                        | DefKind::TyAlias
                         | DefKind::AssocTy,
                     _,
                 ) | Res::SelfTyParam { .. }
@@ -1766,7 +1766,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 Res::Def(DefKind::Struct, def_id)
                 | Res::Def(DefKind::Union, def_id)
                 | Res::Def(DefKind::Enum, def_id)
-                | Res::Def(DefKind::TyAlias { .. }, def_id)
+                | Res::Def(DefKind::TyAlias, def_id)
                 | Res::Def(DefKind::Trait, def_id)
                     if i + 1 == proj_start =>
                 {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 06a08f29a1e..64440a6c04e 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1429,7 +1429,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
             (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => {
                 err.span_label(span, fallback_label.to_string());
             }
-            (Res::Def(DefKind::TyAlias { .. }, def_id), PathSource::Trait(_)) => {
+            (Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {
                 err.span_label(span, "type aliases cannot be used as traits");
                 if self.r.tcx.sess.is_nightly_build() {
                     let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
@@ -1598,7 +1598,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 err.span_label(span, fallback_label.to_string());
                 err.note("can't use `Self` as a constructor, you must use the implemented struct");
             }
-            (Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, _), _) if ns == ValueNS => {
+            (Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => {
                 err.note("can't use a type alias as a constructor");
             }
             _ => return false,
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index 21ec904e43c..4c29f743708 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -4,24 +4,14 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
-# Use optional dependencies for rustc_* in order to support building this crate separately.
-rustc_hir = { path = "../rustc_hir", optional = true }
-rustc_middle = { path = "../rustc_middle", optional = true }
-rustc_span = { path = "../rustc_span", optional = true }
-rustc_target = { path = "../rustc_target", optional = true }
-rustc_driver = { path = "../rustc_driver", optional = true }
-rustc_interface = { path = "../rustc_interface", optional = true}
-rustc_session = {path = "../rustc_session", optional = true}
+rustc_hir = { path = "../rustc_hir" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+rustc_driver = { path = "../rustc_driver" }
+rustc_interface = { path = "../rustc_interface" }
+rustc_session = {path = "../rustc_session" }
 tracing = "0.1"
-scoped-tls = "1.0"
+stable_mir = {path = "../stable_mir" }
 
 [features]
-default = [
-    "rustc_hir",
-    "rustc_middle",
-    "rustc_span",
-    "rustc_target",
-    "rustc_driver",
-    "rustc_interface",
-    "rustc_session",
-]
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 8cb533c8d67..b6c36678db5 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -10,26 +10,12 @@
     html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
     test(attr(allow(unused_variables), deny(warnings)))
 )]
-#![cfg_attr(not(feature = "default"), feature(rustc_private))]
+#![feature(rustc_private)]
 #![feature(ptr_metadata)]
 #![feature(type_alias_impl_trait)] // Used to define opaque types.
 #![feature(intra_doc_pointers)]
 
-// Declare extern rustc_* crates to enable building this crate separately from the compiler.
-#[cfg(not(feature = "default"))]
-extern crate rustc_hir;
-#[cfg(not(feature = "default"))]
-extern crate rustc_middle;
-#[cfg(not(feature = "default"))]
-extern crate rustc_span;
-#[cfg(not(feature = "default"))]
-extern crate rustc_target;
-
 pub mod rustc_internal;
-pub mod stable_mir;
 
 // Make this module private for now since external users should not call these directly.
 mod rustc_smir;
-
-#[macro_use]
-extern crate scoped_tls;
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 10ee5af86c6..441aafd1257 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -3,75 +3,17 @@
 //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
 //! until stable MIR is complete.
 
-use std::fmt::Debug;
 use std::ops::{ControlFlow, Index};
 
 use crate::rustc_internal;
-use crate::stable_mir::CompilerError;
-use crate::{
-    rustc_smir::Tables,
-    stable_mir::{self, with},
-};
+use crate::rustc_smir::Tables;
 use rustc_driver::{Callbacks, Compilation, RunCompiler};
 use rustc_interface::{interface, Queries};
 use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::ty::TyCtxt;
 pub use rustc_span::def_id::{CrateNum, DefId};
 use rustc_span::Span;
-
-fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
-    let mut ret = None;
-    with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t))));
-    ret.unwrap()
-}
-
-pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
-    with_tables(|t| t[item.0])
-}
-
-pub fn crate_item(did: DefId) -> stable_mir::CrateItem {
-    with_tables(|t| t.crate_item(did))
-}
-
-pub fn adt_def(did: DefId) -> stable_mir::ty::AdtDef {
-    with_tables(|t| t.adt_def(did))
-}
-
-pub fn foreign_def(did: DefId) -> stable_mir::ty::ForeignDef {
-    with_tables(|t| t.foreign_def(did))
-}
-
-pub fn fn_def(did: DefId) -> stable_mir::ty::FnDef {
-    with_tables(|t| t.fn_def(did))
-}
-
-pub fn closure_def(did: DefId) -> stable_mir::ty::ClosureDef {
-    with_tables(|t| t.closure_def(did))
-}
-
-pub fn generator_def(did: DefId) -> stable_mir::ty::GeneratorDef {
-    with_tables(|t| t.generator_def(did))
-}
-
-pub fn alias_def(did: DefId) -> stable_mir::ty::AliasDef {
-    with_tables(|t| t.alias_def(did))
-}
-
-pub fn param_def(did: DefId) -> stable_mir::ty::ParamDef {
-    with_tables(|t| t.param_def(did))
-}
-
-pub fn br_named_def(did: DefId) -> stable_mir::ty::BrNamedDef {
-    with_tables(|t| t.br_named_def(did))
-}
-
-pub fn trait_def(did: DefId) -> stable_mir::ty::TraitDef {
-    with_tables(|t| t.trait_def(did))
-}
-
-pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef {
-    with_tables(|t| t.impl_def(did))
-}
+use stable_mir::CompilerError;
 
 impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
     type Output = DefId;
@@ -82,6 +24,15 @@ impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
     }
 }
 
+impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
+    type Output = Span;
+
+    #[inline(always)]
+    fn index(&self, index: stable_mir::ty::Span) -> &Self::Output {
+        &self.spans[index.0]
+    }
+}
+
 impl<'tcx> Tables<'tcx> {
     pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
         stable_mir::CrateItem(self.create_def_id(did))
@@ -178,32 +129,12 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
 }
 
 pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
-    crate::stable_mir::run(
+    stable_mir::run(
         Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] },
         f,
     );
 }
 
-/// A type that provides internal information but that can still be used for debug purpose.
-#[derive(Clone)]
-pub struct Opaque(String);
-
-impl std::fmt::Display for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
-
-impl std::fmt::Debug for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{:?}", self.0)
-    }
-}
-
-pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
-    Opaque(format!("{value:?}"))
-}
-
 pub struct StableMir<B = (), C = ()>
 where
     B: Send,
diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs
index d8766cf8ce2..63a2a145069 100644
--- a/compiler/rustc_smir/src/rustc_smir/alloc.rs
+++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs
@@ -3,11 +3,9 @@ use rustc_middle::mir::{
     ConstValue,
 };
 
-use crate::{
-    rustc_smir::{Stable, Tables},
-    stable_mir::mir::Mutability,
-    stable_mir::ty::{Allocation, ProvenanceMap},
-};
+use crate::rustc_smir::{Stable, Tables};
+use stable_mir::mir::Mutability;
+use stable_mir::ty::{Allocation, ProvenanceMap};
 
 /// Creates new empty `Allocation` from given `Align`.
 fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 07aeac6b539..5ff17613b4e 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,19 +7,16 @@
 //!
 //! For now, we are developing everything inside `rustc`, thus, we keep this module private.
 
-use crate::rustc_internal::{self, opaque};
-use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
-use crate::stable_mir::ty::{
-    FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy,
-};
-use crate::stable_mir::{self, CompilerError, Context};
+use hir::def::DefKind;
 use rustc_hir as hir;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
 use rustc_middle::ty::{self, Ty, TyCtxt, Variance};
 use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc_span::ErrorGuaranteed;
 use rustc_target::abi::FieldIdx;
+use stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
+use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy};
+use stable_mir::{self, opaque, Context};
 use tracing::debug;
 
 mod alloc;
@@ -44,6 +41,14 @@ impl<'tcx> Context for Tables<'tcx> {
         self.tcx.def_path_str(self[def_id])
     }
 
+    fn print_span(&self, span: stable_mir::ty::Span) -> String {
+        self.tcx.sess.source_map().span_to_diagnostic_string(self[span])
+    }
+
+    fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
+        self.tcx.def_kind(self[def_id]).stable(self)
+    }
+
     fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span {
         self.tcx.def_span(self[def_id]).stable(self)
     }
@@ -104,11 +109,7 @@ impl<'tcx> Context for Tables<'tcx> {
         }
     }
 
-    fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) {
-        f(self)
-    }
-
-    fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind {
+    fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind {
         self.types[ty.0].clone().stable(self)
     }
 
@@ -276,7 +277,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 place.stable(tables),
             ),
             ThreadLocalRef(def_id) => {
-                stable_mir::mir::Rvalue::ThreadLocalRef(rustc_internal::crate_item(*def_id))
+                stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
             }
             AddressOf(mutability, place) => {
                 stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
@@ -739,7 +740,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
             mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
             mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
                 stable_mir::mir::AggregateKind::Adt(
-                    rustc_internal::adt_def(*def_id),
+                    tables.adt_def(*def_id),
                     var_idx.index(),
                     generic_arg.stable(tables),
                     user_ty_index.map(|idx| idx.index()),
@@ -748,13 +749,13 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
             }
             mir::AggregateKind::Closure(def_id, generic_arg) => {
                 stable_mir::mir::AggregateKind::Closure(
-                    rustc_internal::closure_def(*def_id),
+                    tables.closure_def(*def_id),
                     generic_arg.stable(tables),
                 )
             }
             mir::AggregateKind::Generator(def_id, generic_arg, movability) => {
                 stable_mir::mir::AggregateKind::Generator(
-                    rustc_internal::generator_def(*def_id),
+                    tables.generator_def(*def_id),
                     generic_arg.stable(tables),
                     movability.stable(tables),
                 )
@@ -964,13 +965,13 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
 impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
     type T = stable_mir::ty::BoundTyKind;
 
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use stable_mir::ty::BoundTyKind;
 
         match self {
             ty::BoundTyKind::Anon => BoundTyKind::Anon,
             ty::BoundTyKind::Param(def_id, symbol) => {
-                BoundTyKind::Param(rustc_internal::param_def(*def_id), symbol.to_string())
+                BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string())
             }
         }
     }
@@ -983,11 +984,9 @@ impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
         use stable_mir::ty::BoundRegionKind;
 
         match self {
-            ty::BoundRegionKind::BrAnon(option_span) => {
-                BoundRegionKind::BrAnon(option_span.map(|span| span.stable(tables)))
-            }
+            ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon,
             ty::BoundRegionKind::BrNamed(def_id, symbol) => {
-                BoundRegionKind::BrNamed(rustc_internal::br_named_def(*def_id), symbol.to_string())
+                BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string())
             }
             ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv,
         }
@@ -1074,12 +1073,10 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
             ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))),
             ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))),
             ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt(
-                rustc_internal::adt_def(adt_def.did()),
+                tables.adt_def(adt_def.did()),
                 generic_args.stable(tables),
             )),
-            ty::Foreign(def_id) => {
-                TyKind::RigidTy(RigidTy::Foreign(rustc_internal::foreign_def(*def_id)))
-            }
+            ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))),
             ty::Str => TyKind::RigidTy(RigidTy::Str),
             ty::Array(ty, constant) => {
                 TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables)))
@@ -1093,10 +1090,9 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
                 tables.intern_ty(*ty),
                 mutbl.stable(tables),
             )),
-            ty::FnDef(def_id, generic_args) => TyKind::RigidTy(RigidTy::FnDef(
-                rustc_internal::fn_def(*def_id),
-                generic_args.stable(tables),
-            )),
+            ty::FnDef(def_id, generic_args) => {
+                TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables)))
+            }
             ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))),
             ty::Dynamic(existential_predicates, region, dyn_kind) => {
                 TyKind::RigidTy(RigidTy::Dynamic(
@@ -1109,11 +1105,11 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
                 ))
             }
             ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure(
-                rustc_internal::closure_def(*def_id),
+                tables.closure_def(*def_id),
                 generic_args.stable(tables),
             )),
             ty::Generator(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Generator(
-                rustc_internal::generator_def(*def_id),
+                tables.generator_def(*def_id),
                 generic_args.stable(tables),
                 movability.stable(tables),
             )),
@@ -1225,7 +1221,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
         use stable_mir::ty::TraitDecl;
 
         TraitDecl {
-            def_id: rustc_internal::trait_def(self.def_id),
+            def_id: tables.trait_def(self.def_id),
             unsafety: self.unsafety.stable(tables),
             paren_sugar: self.paren_sugar,
             has_auto_impl: self.has_auto_impl,
@@ -1274,7 +1270,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use stable_mir::ty::TraitRef;
 
-        TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
+        TraitRef { def_id: tables.trait_def(self.def_id), args: self.args.stable(tables) }
     }
 }
 
@@ -1518,8 +1514,11 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
     }
 }
 
-impl<T> From<ErrorGuaranteed> for CompilerError<T> {
-    fn from(_error: ErrorGuaranteed) -> Self {
-        CompilerError::CompilationFailed
+impl<'tcx> Stable<'tcx> for DefKind {
+    type T = stable_mir::DefKind;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        // FIXME: add a real implementation of stable DefKind
+        opaque(self)
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 68724c48037..c58fdbcb5e1 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -33,7 +33,7 @@ extern crate rustc_macros;
 #[macro_use]
 extern crate tracing;
 
-use rustc_data_structures::{cold_path, AtomicRef};
+use rustc_data_structures::{outline, AtomicRef};
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 
@@ -1592,7 +1592,7 @@ impl SourceFile {
             return &lines[..];
         }
 
-        cold_path(|| {
+        outline(|| {
             self.convert_diffs_to_lines_frozen();
             if let Some(SourceFileLines::Lines(lines)) = self.lines.get() {
                 return &lines[..];
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index ec94deb4658..82b1a772e3d 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -329,7 +329,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
 
             // Late-bound lifetimes use indices starting at 1,
             // see `BinderLevel` for more details.
-            ty::ReLateBound(debruijn, ty::BoundRegion { var, kind: ty::BrAnon(_) }) => {
+            ty::ReLateBound(debruijn, ty::BoundRegion { var, kind: ty::BrAnon }) => {
                 let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
                 let depth = binder.lifetime_depths.start + var.as_u32();
 
diff --git a/compiler/rustc_target/src/spec/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/riscv64_linux_android.rs
index af0d6855494..91f5e562d8b 100644
--- a/compiler/rustc_target/src/spec/riscv64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/riscv64_linux_android.rs
@@ -9,7 +9,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+Zba,+Zbb,+Zbs".into(),
             llvm_abiname: "lp64d".into(),
             supported_sanitizers: SanitizerSet::ADDRESS,
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
index 8968d3c8fc1..a50a55ad7e0 100644
--- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
@@ -46,6 +46,7 @@ pub fn opts() -> TargetOptions {
         stack_probes: StackProbeType::Call,
         singlethread: true,
         linker: Some("rust-lld".into()),
+        entry_name: "efi_main".into(),
         ..base
     }
 }
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
index 67664a74710..41ba768068a 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
@@ -5,13 +5,14 @@
 // The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
 // LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
 
-use crate::spec::Target;
+use crate::{abi::call::Conv, spec::Target};
 
 pub fn target() -> Target {
     let mut base = super::uefi_msvc_base::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
     base.max_atomic_width = Some(64);
+    base.entry_abi = Conv::X86_64Win64;
 
     // We disable MMX and SSE for now, even though UEFI allows using them. Problem is, you have to
     // enable these CPU features explicitly before their first use, otherwise their instructions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index 5935c614ffd..26c68acddff 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -94,8 +94,7 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
     let mut counter = 0;
     let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
         ty::ReErased => {
-            let br =
-                ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon(None) };
+            let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon };
             counter += 1;
             ty::Region::new_late_bound(tcx, current_depth, br)
         }
@@ -103,7 +102,7 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
         r => bug!("unexpected region: {r:?}"),
     });
     let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
-        (0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))),
+        (0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)),
     );
     ty::Binder::bind_with_vars(ty, bound_vars)
 }
diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
index 64b1321e51d..aa92b924ef2 100644
--- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
@@ -269,7 +269,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
             self.primitive_var_infos.push(CanonicalVarInfo { kind });
             var
         });
-        let br = ty::BoundRegion { var, kind: BrAnon(None) };
+        let br = ty::BoundRegion { var, kind: BrAnon };
         ty::Region::new_late_bound(self.interner(), self.binder_index, br)
     }
 
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index c579da61e38..0f9d36342ad 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -59,7 +59,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
             DefKind::AnonConst => self.normalize_anon_const(goal),
             DefKind::OpaqueTy => self.normalize_opaque_type(goal),
-            DefKind::TyAlias { .. } => self.normalize_weak_type(goal),
+            DefKind::TyAlias => self.normalize_weak_type(goal),
             kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
         }
     }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 748ecdc01b4..15f2ba809a4 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -49,7 +49,7 @@ use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
 #[derive(Debug)]
 pub enum GeneratorInteriorOrUpvar {
     // span of interior type
-    Interior(Span, Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>),
+    Interior(Span, Option<(Span, Option<Span>)>),
     // span of upvar
     Upvar(Span),
 }
@@ -249,7 +249,6 @@ pub trait TypeErrCtxtExt<'tcx> {
         outer_generator: Option<DefId>,
         trait_pred: ty::TraitPredicate<'tcx>,
         target_ty: Ty<'tcx>,
-        typeck_results: &ty::TypeckResults<'tcx>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
     );
@@ -2316,7 +2315,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     if ty_matches(ty::Binder::dummy(decl.ty)) && !decl.ignore_for_traits {
                         interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(
                             decl.source_info.span,
-                            Some((None, source_info.span, None, from_awaited_ty)),
+                            Some((source_info.span, from_awaited_ty)),
                         ));
                         break 'find_source;
                     }
@@ -2336,7 +2335,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         debug!(?interior_or_upvar_span);
         if let Some(interior_or_upvar_span) = interior_or_upvar_span {
             let is_async = self.tcx.generator_is_async(generator_did);
-            let typeck_results = generator_data.0;
             self.note_obligation_cause_for_async_await(
                 err,
                 interior_or_upvar_span,
@@ -2344,7 +2342,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 outer_generator,
                 trait_ref,
                 target_ty,
-                typeck_results,
                 obligation,
                 next_code,
             );
@@ -2365,7 +2362,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         outer_generator: Option<DefId>,
         trait_pred: ty::TraitPredicate<'tcx>,
         target_ty: Ty<'tcx>,
-        typeck_results: &ty::TypeckResults<'tcx>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
     ) {
@@ -2423,9 +2419,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             format!("does not implement `{}`", trait_pred.print_modifiers_and_trait_path())
         };
 
-        let mut explain_yield = |interior_span: Span,
-                                 yield_span: Span,
-                                 scope_span: Option<Span>| {
+        let mut explain_yield = |interior_span: Span, yield_span: Span| {
             let mut span = MultiSpan::from_span(yield_span);
             let snippet = match source_map.span_to_snippet(interior_span) {
                 // #70935: If snippet contains newlines, display "the value" instead
@@ -2457,22 +2451,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 interior_span,
                 format!("has type `{target_ty}` which {trait_explanation}"),
             );
-            if let Some(scope_span) = scope_span {
-                let scope_span = source_map.end_point(scope_span);
-
-                let msg = format!("{snippet} is later dropped here");
-                span.push_span_label(scope_span, msg);
-            }
             err.span_note(
-                    span,
-                    format!(
-                        "{future_or_generator} {trait_explanation} as this value is used across {an_await_or_yield}"
-                    ),
-                );
+                span,
+                format!("{future_or_generator} {trait_explanation} as this value is used across {an_await_or_yield}"),
+            );
         };
         match interior_or_upvar_span {
             GeneratorInteriorOrUpvar::Interior(interior_span, interior_extra_info) => {
-                if let Some((scope_span, yield_span, expr, from_awaited_ty)) = interior_extra_info {
+                if let Some((yield_span, from_awaited_ty)) = interior_extra_info {
                     if let Some(await_span) = from_awaited_ty {
                         // The type causing this obligation is one being awaited at await_span.
                         let mut span = MultiSpan::from_span(await_span);
@@ -2490,51 +2476,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         );
                     } else {
                         // Look at the last interior type to get a span for the `.await`.
-                        explain_yield(interior_span, yield_span, scope_span);
-                    }
-
-                    if let Some(expr_id) = expr {
-                        let expr = hir.expect_expr(expr_id);
-                        debug!("target_ty evaluated from {:?}", expr);
-
-                        let parent = hir.parent_id(expr_id);
-                        if let Some(hir::Node::Expr(e)) = hir.find(parent) {
-                            let parent_span = hir.span(parent);
-                            let parent_did = parent.owner.to_def_id();
-                            // ```rust
-                            // impl T {
-                            //     fn foo(&self) -> i32 {}
-                            // }
-                            // T.foo();
-                            // ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
-                            // ```
-                            //
-                            let is_region_borrow = typeck_results
-                                .expr_adjustments(expr)
-                                .iter()
-                                .any(|adj| adj.is_region_borrow());
-
-                            // ```rust
-                            // struct Foo(*const u8);
-                            // bar(Foo(std::ptr::null())).await;
-                            //     ^^^^^^^^^^^^^^^^^^^^^ raw-ptr `*T` created inside this struct ctor.
-                            // ```
-                            debug!(parent_def_kind = ?self.tcx.def_kind(parent_did));
-                            let is_raw_borrow_inside_fn_like_call =
-                                match self.tcx.def_kind(parent_did) {
-                                    DefKind::Fn | DefKind::Ctor(..) => target_ty.is_unsafe_ptr(),
-                                    _ => false,
-                                };
-                            if (typeck_results.is_method_call(e) && is_region_borrow)
-                                || is_raw_borrow_inside_fn_like_call
-                            {
-                                err.span_help(
-                                    parent_span,
-                                    "consider moving this into a `let` \
-                        binding to create a shorter lived borrow",
-                                );
-                            }
-                        }
+                        explain_yield(interior_span, yield_span);
                     }
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 7d672e658c7..bc9ba85fc9f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -3102,7 +3102,7 @@ fn bind_generator_hidden_types_above<'tcx>(
                         ty::ReErased => {
                             let br = ty::BoundRegion {
                                 var: ty::BoundVar::from_u32(counter),
-                                kind: ty::BrAnon(None),
+                                kind: ty::BrAnon,
                             };
                             counter += 1;
                             ty::Region::new_late_bound(tcx, current_depth, br)
@@ -3118,8 +3118,9 @@ fn bind_generator_hidden_types_above<'tcx>(
     if considering_regions {
         debug_assert!(!hidden_types.has_erased_regions());
     }
-    let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain(
-        (num_bound_variables..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))),
-    ));
+    let bound_vars =
+        tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain(
+            (num_bound_variables..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)),
+        ));
     ty::Binder::bind_with_vars(hidden_types, bound_vars)
 }
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index 436f10a4f7b..ec2e0daaf88 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -119,7 +119,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
         },
         DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
         DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
-            DefKind::TyAlias { .. } => ty::List::empty(),
+            DefKind::TyAlias => ty::List::empty(),
             DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
             // Nested opaque types only occur in associated types:
             // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
@@ -136,7 +136,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::TyParam
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 38768f0a05b..06a30677d20 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -53,9 +53,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
 
     fn parent(&self) -> Option<LocalDefId> {
         match self.tcx.def_kind(self.item) {
-            DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias { .. } => {
-                None
-            }
+            DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias => None,
             DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
                 Some(self.tcx.local_parent(self.item))
             }
@@ -118,7 +116,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
             #[instrument(level = "trace", skip(self))]
             fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
                 let id = id.owner_id.def_id;
-                if let DefKind::TyAlias { .. } = self.collector.tcx.def_kind(id) {
+                if let DefKind::TyAlias = self.collector.tcx.def_kind(id) {
                     let items = self.collector.tcx.opaque_types_defined_by(id);
                     self.collector.opaques.extend(items);
                 }
@@ -297,7 +295,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
             collector.collect_body_and_predicate_taits();
         }
         // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds`
-        DefKind::TyAlias { .. } | DefKind::AssocTy => {
+        DefKind::TyAlias | DefKind::AssocTy => {
             tcx.type_of(item).instantiate_identity().visit_with(&mut collector);
         }
         DefKind::OpaqueTy => {
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index c7fa0dcffa9..091b51440a6 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -531,22 +531,18 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
             }
             Never => write!(f, "!"),
             Tuple(t) => {
-                let mut iter = t.clone().into_iter();
-
                 write!(f, "(")?;
-
-                match iter.next() {
-                    None => return write!(f, ")"),
-                    Some(ty) => write!(f, "{:?}", &this.wrap(ty))?,
-                };
-
-                match iter.next() {
-                    None => return write!(f, ",)"),
-                    Some(ty) => write!(f, "{:?})", &this.wrap(ty))?,
+                let mut count = 0;
+                for ty in t.clone() {
+                    if count > 0 {
+                        write!(f, ", ")?;
+                    }
+                    write!(f, "{:?}", &this.wrap(ty))?;
+                    count += 1;
                 }
-
-                for ty in iter {
-                    write!(f, ", {:?}", &this.wrap(ty))?;
+                // unary tuples need a trailing comma
+                if count == 1 {
+                    write!(f, ",")?;
                 }
                 write!(f, ")")
             }
diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml
new file mode 100644
index 00000000000..c61e217bf9f
--- /dev/null
+++ b/compiler/stable_mir/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "stable_mir"
+version = "0.1.0-preview"
+edition = "2021"
+
+[dependencies]
+tracing = "0.1"
+scoped-tls = "1.0"
diff --git a/compiler/rustc_smir/README.md b/compiler/stable_mir/README.md
index 31dee955f49..31dee955f49 100644
--- a/compiler/rustc_smir/README.md
+++ b/compiler/stable_mir/README.md
diff --git a/compiler/rustc_smir/rust-toolchain.toml b/compiler/stable_mir/rust-toolchain.toml
index d75e8e33b1c..d75e8e33b1c 100644
--- a/compiler/rustc_smir/rust-toolchain.toml
+++ b/compiler/stable_mir/rust-toolchain.toml
diff --git a/compiler/rustc_smir/src/stable_mir/fold.rs b/compiler/stable_mir/src/fold.rs
index 831cfb40a15..16ae62311aa 100644
--- a/compiler/rustc_smir/src/stable_mir/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -1,6 +1,6 @@
 use std::ops::ControlFlow;
 
-use crate::rustc_internal::Opaque;
+use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/stable_mir/src/lib.rs
index 3c86cb4038a..104985493ef 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -1,15 +1,21 @@
-//! Module that implements the public interface to the Stable MIR.
+//! The WIP stable interface to rustc internals.
 //!
-//! This module shall contain all type definitions and APIs that we expect third-party tools to invoke to
-//! interact with the compiler.
+//! For more information see <https://github.com/rust-lang/project-stable-mir>
 //!
-//! The goal is to eventually move this module to its own crate which shall be published on
-//! [crates.io](https://crates.io).
+//! # Note
+//!
+//! This API is still completely unstable and subject to change.
+
+#![doc(
+    html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
+    test(attr(allow(unused_variables), deny(warnings)))
+)]
 //!
-//! ## Note:
+//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to
+//! interact with the compiler.
 //!
-//! There shouldn't be any direct references to internal compiler constructs in this module.
-//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`.
+//! The goal is to eventually be published on
+//! [crates.io](https://crates.io).
 
 use std::cell::Cell;
 use std::fmt;
@@ -18,7 +24,9 @@ use std::fmt::Debug;
 use self::ty::{
     GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind,
 };
-use crate::rustc_smir::Tables;
+
+#[macro_use]
+extern crate scoped_tls;
 
 pub mod fold;
 pub mod mir;
@@ -33,11 +41,11 @@ pub type CrateNum = usize;
 
 /// A unique identification number for each item accessible for the current compilation unit.
 #[derive(Clone, Copy, PartialEq, Eq)]
-pub struct DefId(pub(crate) usize);
+pub struct DefId(pub usize);
 
 impl Debug for DefId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("DefId:")
+        f.debug_struct("DefId")
             .field("id", &self.0)
             .field("name", &with(|cx| cx.name_of_def_id(*self)))
             .finish()
@@ -46,7 +54,7 @@ impl Debug for DefId {
 
 /// A unique identification number for each provenance
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AllocId(pub(crate) usize);
+pub struct AllocId(pub usize);
 
 /// A list of crate items.
 pub type CrateItems = Vec<CrateItem>;
@@ -74,16 +82,18 @@ pub enum CompilerError<T> {
 /// Holds information about a crate.
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct Crate {
-    pub(crate) id: CrateNum,
+    pub id: CrateNum,
     pub name: Symbol,
     pub is_local: bool,
 }
 
+pub type DefKind = Opaque;
+
 /// Holds information about an item in the crate.
 /// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to
 /// use this item.
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub struct CrateItem(pub(crate) DefId);
+pub struct CrateItem(pub DefId);
 
 impl CrateItem {
     pub fn body(&self) -> mir::Body {
@@ -93,6 +103,14 @@ impl CrateItem {
     pub fn span(&self) -> Span {
         with(|cx| cx.span_of_an_item(self.0))
     }
+
+    pub fn name(&self) -> String {
+        with(|cx| cx.name_of_def_id(self.0))
+    }
+
+    pub fn kind(&self) -> DefKind {
+        with(|cx| cx.def_kind(self.0))
+    }
 }
 
 /// Return the function where execution starts if the current
@@ -161,6 +179,12 @@ pub trait Context {
     /// Prints the name of given `DefId`
     fn name_of_def_id(&self, def_id: DefId) -> String;
 
+    /// Prints a human readable form of `Span`
+    fn print_span(&self, span: Span) -> String;
+
+    /// Prints the kind of given `DefId`
+    fn def_kind(&mut self, def_id: DefId) -> DefKind;
+
     /// `Span` of an item
     fn span_of_an_item(&mut self, def_id: DefId) -> Span;
 
@@ -169,10 +193,6 @@ pub trait Context {
 
     /// Create a new `Ty` from scratch without information from rustc.
     fn mk_ty(&mut self, kind: TyKind) -> Ty;
-
-    /// HACK: Until we have fully stable consumers, we need an escape hatch
-    /// to get `DefId`s out of `CrateItem`s.
-    fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>));
 }
 
 // A thread local variable that stores a pointer to the tables mapping between TyCtxt
@@ -192,7 +212,7 @@ pub fn run(mut context: impl Context, f: impl FnOnce()) {
 
 /// Loads the current context and calls a function with it.
 /// Do not nest these, as that will ICE.
-pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
+pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
     assert!(TLV.is_set());
     TLV.with(|tlv| {
         let ptr = tlv.get();
@@ -200,3 +220,23 @@ pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
         f(unsafe { *(ptr as *mut &mut dyn Context) })
     })
 }
+
+/// A type that provides internal information but that can still be used for debug purpose.
+#[derive(Clone)]
+pub struct Opaque(String);
+
+impl std::fmt::Display for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl std::fmt::Debug for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?}", self.0)
+    }
+}
+
+pub fn opaque<T: Debug>(value: &T) -> Opaque {
+    Opaque(format!("{value:?}"))
+}
diff --git a/compiler/rustc_smir/src/stable_mir/mir.rs b/compiler/stable_mir/src/mir.rs
index a9dbc3463f8..a9dbc3463f8 100644
--- a/compiler/rustc_smir/src/stable_mir/mir.rs
+++ b/compiler/stable_mir/src/mir.rs
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 449ca4b8145..6f8f7b06fa3 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -1,8 +1,6 @@
-use crate::rustc_internal::Opaque;
-use crate::stable_mir::ty::{
-    AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region,
-};
-use crate::stable_mir::{self, ty::Ty, Span};
+use crate::ty::{AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region};
+use crate::Opaque;
+use crate::{ty::Ty, Span};
 
 #[derive(Clone, Debug)]
 pub struct Body {
@@ -135,7 +133,7 @@ pub enum AsyncGeneratorKind {
 }
 
 pub(crate) type LocalDefId = Opaque;
-/// [`rustc_middle::mir::Coverage`] is heavily tied to internal details of the
+/// The rustc coverage data structures are heavily tied to internal details of the
 /// coverage implementation that are likely to change, and are unlikely to be
 /// useful to third-party tools for the foreseeable future.
 pub(crate) type Coverage = Opaque;
@@ -215,7 +213,7 @@ pub enum Rvalue {
     /// generator lowering, `Generator` aggregate kinds are disallowed too.
     Aggregate(AggregateKind, Vec<Operand>),
 
-    /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
+    /// * `Offset` has the same semantics as `<*const T>::offset`, except that the second
     ///   parameter may be a `usize` as well.
     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
     ///   raw pointers, or function pointers and return a `bool`. The types of the operands must be
@@ -245,16 +243,14 @@ pub enum Rvalue {
     /// deref operation, immediately followed by one or more projections.
     CopyForDeref(Place),
 
-    /// Computes the discriminant of the place, returning it as an integer of type
-    /// [`discriminant_ty`]. Returns zero for types without discriminant.
+    /// Computes the discriminant of the place, returning it as an integer.
+    /// Returns zero for types without discriminant.
     ///
     /// The validity requirements for the underlying value are undecided for this rvalue, see
     /// [#91095]. Note too that the value of the discriminant is not the same thing as the
-    /// variant index; use [`discriminant_for_variant`] to convert.
+    /// variant index;
     ///
-    /// [`discriminant_ty`]: rustc_middle::ty::Ty::discriminant_ty
     /// [#91095]: https://github.com/rust-lang/rust/issues/91095
-    /// [`discriminant_for_variant`]: rustc_middle::ty::Ty::discriminant_for_variant
     Discriminant(Place),
 
     /// Yields the length of the place, as a `usize`.
@@ -295,7 +291,7 @@ pub enum Rvalue {
     ///
     /// **Needs clarification**: Are there weird additional semantics here related to the runtime
     /// nature of this operation?
-    ThreadLocalRef(stable_mir::CrateItem),
+    ThreadLocalRef(crate::CrateItem),
 
     /// Computes a value as described by the operation.
     NullaryOp(NullOp, Ty),
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/stable_mir/src/ty.rs
index 3a8fc1a502e..82007e30683 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -3,7 +3,7 @@ use super::{
     mir::{Body, Mutability},
     with, AllocId, DefId,
 };
-use crate::rustc_internal::Opaque;
+use crate::Opaque;
 use std::fmt::{self, Debug, Formatter};
 
 #[derive(Copy, Clone)]
@@ -34,15 +34,16 @@ pub struct Const {
 }
 
 type Ident = Opaque;
-pub(crate) type Region = Opaque;
+pub type Region = Opaque;
 #[derive(Clone, Copy, PartialEq, Eq)]
-pub struct Span(pub(crate) usize);
+pub struct Span(pub usize);
 
 impl Debug for Span {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        let mut span = None;
-        with(|context| context.rustc_tables(&mut |tables| span = Some(tables.spans[self.0])));
-        f.write_fmt(format_args!("{:?}", &span.unwrap()))
+        f.debug_struct("Span")
+            .field("id", &self.0)
+            .field("repr", &with(|cx| cx.print_span(*self)))
+            .finish()
     }
 }
 
@@ -110,10 +111,10 @@ pub enum Movability {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ForeignDef(pub(crate) DefId);
+pub struct ForeignDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct FnDef(pub(crate) DefId);
+pub struct FnDef(pub DefId);
 
 impl FnDef {
     pub fn body(&self) -> Body {
@@ -122,34 +123,34 @@ impl FnDef {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ClosureDef(pub(crate) DefId);
+pub struct ClosureDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct GeneratorDef(pub(crate) DefId);
+pub struct GeneratorDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ParamDef(pub(crate) DefId);
+pub struct ParamDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct BrNamedDef(pub(crate) DefId);
+pub struct BrNamedDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AdtDef(pub(crate) DefId);
+pub struct AdtDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AliasDef(pub(crate) DefId);
+pub struct AliasDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct TraitDef(pub(crate) DefId);
+pub struct TraitDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct GenericDef(pub(crate) DefId);
+pub struct GenericDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ConstDef(pub(crate) DefId);
+pub struct ConstDef(pub DefId);
 
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ImplDef(pub(crate) DefId);
+pub struct ImplDef(pub DefId);
 
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);
@@ -286,7 +287,7 @@ pub enum BoundTyKind {
 
 #[derive(Clone, Debug)]
 pub enum BoundRegionKind {
-    BrAnon(Option<Span>),
+    BrAnon,
     BrNamed(BrNamedDef, String),
     BrEnv,
 }
@@ -333,7 +334,7 @@ pub type Bytes = Vec<Option<u8>>;
 pub type Size = usize;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct Prov(pub(crate) AllocId);
+pub struct Prov(pub AllocId);
 pub type Align = u64;
 pub type Promoted = u32;
 pub type InitMaskMaterialized = Vec<u64>;
diff --git a/compiler/rustc_smir/src/stable_mir/visitor.rs b/compiler/stable_mir/src/visitor.rs
index c86063d2ed6..9c3b4cd994a 100644
--- a/compiler/rustc_smir/src/stable_mir/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -1,6 +1,6 @@
 use std::ops::ControlFlow;
 
-use crate::rustc_internal::Opaque;
+use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 646100fe27b..c27be8d2ffd 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -321,6 +321,95 @@ pub macro debug_assert_matches($($arg:tt)*) {
     }
 }
 
+/// A macro for defining `#[cfg]` match-like statements.
+///
+/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
+/// `#[cfg]` cases, emitting the implementation which matches first.
+///
+/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
+/// without having to rewrite each clause multiple times.
+///
+/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
+/// all previous declarations do not evaluate to true.
+///
+/// # Example
+///
+/// ```
+/// #![feature(cfg_match)]
+///
+/// cfg_match! {
+///     cfg(unix) => {
+///         fn foo() { /* unix specific functionality */ }
+///     }
+///     cfg(target_pointer_width = "32") => {
+///         fn foo() { /* non-unix, 32-bit functionality */ }
+///     }
+///     _ => {
+///         fn foo() { /* fallback implementation */ }
+///     }
+/// }
+/// ```
+#[macro_export]
+#[unstable(feature = "cfg_match", issue = "115585")]
+#[rustc_diagnostic_item = "cfg_match"]
+macro_rules! cfg_match {
+    // with a final wildcard
+    (
+        $(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
+        _ => { $($extra_tokens:item)* }
+    ) => {
+        cfg_match! {
+            @__items ();
+            $((($initial_meta) ($($initial_tokens)*)),)+
+            (() ($($extra_tokens)*)),
+        }
+    };
+
+    // without a final wildcard
+    (
+        $(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
+    ) => {
+        cfg_match! {
+            @__items ();
+            $((($extra_meta) ($($extra_tokens)*)),)*
+        }
+    };
+
+    // Internal and recursive macro to emit all the items
+    //
+    // Collects all the previous cfgs in a list at the beginning, so they can be
+    // negated. After the semicolon is all the remaining items.
+    (@__items ($($_:meta,)*);) => {};
+    (
+        @__items ($($no:meta,)*);
+        (($($yes:meta)?) ($($tokens:item)*)),
+        $($rest:tt,)*
+    ) => {
+        // Emit all items within one block, applying an appropriate #[cfg]. The
+        // #[cfg] will require all `$yes` matchers specified and must also negate
+        // all previous matchers.
+        #[cfg(all(
+            $($yes,)?
+            not(any($($no),*))
+        ))]
+        cfg_match! { @__identity $($tokens)* }
+
+        // Recurse to emit all other items in `$rest`, and when we do so add all
+        // our `$yes` matchers to the list of `$no` matchers as future emissions
+        // will have to negate everything we just matched as well.
+        cfg_match! {
+            @__items ($($no,)* $($yes,)?);
+            $($rest,)*
+        }
+    };
+
+    // Internal macro to make __apply work out right for different match types,
+    // because of how macros match/expand stuff.
+    (@__identity $($tokens:item)*) => {
+        $($tokens)*
+    };
+}
+
 /// Returns whether the given expression matches any of the given patterns.
 ///
 /// Like in a `match` expression, the pattern can be optionally followed by `if`
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 5ec751e5168..5ed82e26a0a 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -986,11 +986,16 @@ pub trait Tuple {}
 pub trait PointerLike {}
 
 /// A marker for types which can be used as types of `const` generic parameters.
+///
+/// These types must have a proper equivalence relation (`Eq`) and it must be automatically
+/// derived (`StructuralPartialEq`). There's a hard-coded check in the compiler ensuring
+/// that all fields are also `ConstParamTy`, which implies that recursively, all fields
+/// are `StructuralPartialEq`.
 #[lang = "const_param_ty"]
 #[unstable(feature = "adt_const_params", issue = "95174")]
 #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
 #[allow(multiple_supertrait_upcastable)]
-pub trait ConstParamTy: StructuralEq + StructuralPartialEq {}
+pub trait ConstParamTy: StructuralEq + StructuralPartialEq + Eq {}
 
 /// Derive macro generating an impl of the trait `ConstParamTy`.
 #[rustc_builtin_macro]
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 23ca37817d4..7cbef9e7793 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1259,6 +1259,10 @@ macro_rules! uint_impl {
         /// This function exists, so that all operations
         /// are accounted for in the wrapping operations.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1284,6 +1288,10 @@ macro_rules! uint_impl {
         /// definitions of division are equal, this
         /// is exactly equal to `self.wrapping_div(rhs)`.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1307,6 +1315,10 @@ macro_rules! uint_impl {
         /// This function exists, so that all operations
         /// are accounted for in the wrapping operations.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1333,6 +1345,10 @@ macro_rules! uint_impl {
         /// definitions of division are equal, this
         /// is exactly equal to `self.wrapping_rem(rhs)`.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 6b319b4355c..94c682b615a 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -572,7 +572,10 @@ impl<P: Deref> Pin<P> {
     ///     // though we have previously pinned it! We have violated the pinning API contract.
     /// }
     /// ```
-    /// A value, once pinned, must remain pinned forever (unless its type implements `Unpin`).
+    /// A value, once pinned, must remain pinned until it is dropped (unless its type implements
+    /// `Unpin`). Because `Pin<&mut T>` does not own the value, dropping the `Pin` will not drop
+    /// the value and will not end the pinning contract. So moving the value after dropping the
+    /// `Pin<&mut T>` is still a violation of the API contract.
     ///
     /// Similarly, calling `Pin::new_unchecked` on an `Rc<T>` is unsafe because there could be
     /// aliases to the same data that are not subject to the pinning restrictions:
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 17011b845cf..773f2b955d8 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -96,6 +96,7 @@
 #![feature(const_option_ext)]
 #![feature(const_result)]
 #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
+#![cfg_attr(test, feature(cfg_match))]
 #![feature(int_roundings)]
 #![feature(slice_group_by)]
 #![feature(split_array)]
@@ -139,6 +140,7 @@ mod hash;
 mod intrinsics;
 mod iter;
 mod lazy;
+#[cfg(test)]
 mod macros;
 mod manually_drop;
 mod mem;
diff --git a/library/core/tests/macros.rs b/library/core/tests/macros.rs
index ff3632e3550..eb886def164 100644
--- a/library/core/tests/macros.rs
+++ b/library/core/tests/macros.rs
@@ -1,3 +1,25 @@
+trait Trait {
+    fn blah(&self);
+}
+
+#[allow(dead_code)]
+struct Struct;
+
+impl Trait for Struct {
+    cfg_match! {
+        cfg(feature = "blah") => {
+            fn blah(&self) {
+                unimplemented!();
+            }
+        }
+        _ => {
+            fn blah(&self) {
+                unimplemented!();
+            }
+        }
+    }
+}
+
 #[test]
 fn assert_eq_trailing_comma() {
     assert_eq!(1, 1,);
@@ -18,3 +40,135 @@ fn assert_ne_trailing_comma() {
 fn matches_leading_pipe() {
     matches!(1, | 1 | 2 | 3);
 }
+
+#[test]
+fn cfg_match_basic() {
+    cfg_match! {
+        cfg(target_pointer_width = "64") => { fn f0_() -> bool { true }}
+    }
+
+    cfg_match! {
+        cfg(unix) => { fn f1_() -> bool { true }}
+        cfg(any(target_os = "macos", target_os = "linux")) => { fn f1_() -> bool { false }}
+    }
+
+    cfg_match! {
+        cfg(target_pointer_width = "32") => { fn f2_() -> bool { false }}
+        cfg(target_pointer_width = "64") => { fn f2_() -> bool { true }}
+    }
+
+    cfg_match! {
+        cfg(target_pointer_width = "16") => { fn f3_() -> i32 { 1 }}
+        _ => { fn f3_() -> i32 { 2 }}
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    assert!(f0_());
+
+    #[cfg(unix)]
+    assert!(f1_());
+
+    #[cfg(target_pointer_width = "32")]
+    assert!(!f2_());
+    #[cfg(target_pointer_width = "64")]
+    assert!(f2_());
+
+    #[cfg(not(target_pointer_width = "16"))]
+    assert_eq!(f3_(), 2);
+}
+
+#[test]
+fn cfg_match_debug_assertions() {
+    cfg_match! {
+        cfg(debug_assertions) => {
+            assert!(cfg!(debug_assertions));
+            assert_eq!(4, 2+2);
+        }
+        _ => {
+            assert!(cfg!(not(debug_assertions)));
+            assert_eq!(10, 5+5);
+        }
+    }
+}
+
+#[cfg(target_pointer_width = "64")]
+#[test]
+fn cfg_match_no_duplication_on_64() {
+    cfg_match! {
+        cfg(windows) => {
+            fn foo() {}
+        }
+        cfg(unix) => {
+            fn foo() {}
+        }
+        cfg(target_pointer_width = "64") => {
+            fn foo() {}
+        }
+    }
+    foo();
+}
+
+#[test]
+fn cfg_match_options() {
+    cfg_match! {
+        cfg(test) => {
+            use core::option::Option as Option2;
+            fn works1() -> Option2<u32> { Some(1) }
+        }
+        _ => { fn works1() -> Option<u32> { None } }
+    }
+
+    cfg_match! {
+        cfg(feature = "foo") => { fn works2() -> bool { false } }
+        cfg(test) => { fn works2() -> bool { true } }
+        _ => { fn works2() -> bool { false } }
+    }
+
+    cfg_match! {
+        cfg(feature = "foo") => { fn works3() -> bool { false } }
+        _ => { fn works3() -> bool { true } }
+    }
+
+    cfg_match! {
+        cfg(test) => {
+            use core::option::Option as Option3;
+            fn works4() -> Option3<u32> { Some(1) }
+        }
+    }
+
+    cfg_match! {
+        cfg(feature = "foo") => { fn works5() -> bool { false } }
+        cfg(test) => { fn works5() -> bool { true } }
+    }
+
+    assert!(works1().is_some());
+    assert!(works2());
+    assert!(works3());
+    assert!(works4().is_some());
+    assert!(works5());
+}
+
+#[test]
+fn cfg_match_two_functions() {
+    cfg_match! {
+        cfg(target_pointer_width = "64") => {
+            fn foo1() {}
+            fn bar1() {}
+        }
+        _ => {
+            fn foo2() {}
+            fn bar2() {}
+        }
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    {
+        foo1();
+        bar1();
+    }
+    #[cfg(not(target_pointer_width = "64"))]
+    {
+        foo2();
+        bar2();
+    }
+}
diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index d675696f13f..6e097e2caf2 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -44,7 +44,8 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
             }
         } else if #[cfg(any(target_os = "hermit",
                             all(target_vendor = "fortanix", target_env = "sgx"),
-                            target_os = "xous"
+                            target_os = "xous",
+                            target_os = "uefi",
         ))] {
             unsafe fn abort() -> ! {
                 // call std::sys::abort_internal
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index d322d882cc1..0a70c488aec 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1418,7 +1418,15 @@ impl Literal {
                 let hashes = get_hashes_str(n);
                 f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
             }
-            _ => f(&[symbol, suffix]),
+            bridge::LitKind::CStr => f(&["c\"", symbol, "\"", suffix]),
+            bridge::LitKind::CStrRaw(n) => {
+                let hashes = get_hashes_str(n);
+                f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
+            }
+
+            bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::Err => {
+                f(&[symbol, suffix])
+            }
         })
     }
 }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index e8f642586cd..965132bdedb 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -48,6 +48,10 @@ hermit-abi = { version = "0.3.2", features = ['rustc-dep-of-std'], public = true
 [target.'cfg(target_os = "wasi")'.dependencies]
 wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
 
+[target.'cfg(target_os = "uefi")'.dependencies]
+r-efi = { version = "4.2.0", features = ['rustc-dep-of-std']}
+r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std']}
+
 [features]
 backtrace = [
   "gimli-symbolize",
diff --git a/library/std/build.rs b/library/std/build.rs
index e5509504b84..36516978b7a 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -39,6 +39,7 @@ fn main() {
         || target.contains("nto")
         || target.contains("xous")
         || target.contains("hurd")
+        || target.contains("uefi")
         // See src/bootstrap/synthetic_targets.rs
         || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
     {
@@ -51,7 +52,6 @@ fn main() {
         // - mipsel-sony-psp
         // - nvptx64-nvidia-cuda
         // - arch=avr
-        // - uefi (x86_64-unknown-uefi, i686-unknown-uefi)
         // - JSON targets
         // - Any new targets that have not been explicitly added above.
         println!("cargo:rustc-cfg=feature=\"restricted-std\"");
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index f63142ff01f..5966416e32a 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -1,14 +1,14 @@
 #[cfg(test)]
 mod tests;
 
-#[cfg(target_pointer_width = "64")]
+#[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))]
 mod repr_bitpacked;
-#[cfg(target_pointer_width = "64")]
+#[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))]
 use repr_bitpacked::Repr;
 
-#[cfg(not(target_pointer_width = "64"))]
+#[cfg(any(not(target_pointer_width = "64"), target_os = "uefi"))]
 mod repr_unpacked;
-#[cfg(not(target_pointer_width = "64"))]
+#[cfg(any(not(target_pointer_width = "64"), target_os = "uefi"))]
 use repr_unpacked::Repr;
 
 use crate::error;
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 7582c7444f0..604b795cd52 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1236,22 +1236,22 @@ impl<'a> IoSliceMut<'a> {
     pub fn advance_slices(bufs: &mut &mut [IoSliceMut<'a>], n: usize) {
         // Number of buffers to remove.
         let mut remove = 0;
-        // Total length of all the to be removed buffers.
-        let mut accumulated_len = 0;
+        // Remaining length before reaching n.
+        let mut left = n;
         for buf in bufs.iter() {
-            if accumulated_len + buf.len() > n {
-                break;
-            } else {
-                accumulated_len += buf.len();
+            if let Some(remainder) = left.checked_sub(buf.len()) {
+                left = remainder;
                 remove += 1;
+            } else {
+                break;
             }
         }
 
         *bufs = &mut take(bufs)[remove..];
         if bufs.is_empty() {
-            assert!(n == accumulated_len, "advancing io slices beyond their length");
+            assert!(left == 0, "advancing io slices beyond their length");
         } else {
-            bufs[0].advance(n - accumulated_len)
+            bufs[0].advance(left);
         }
     }
 }
@@ -1379,22 +1379,25 @@ impl<'a> IoSlice<'a> {
     pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize) {
         // Number of buffers to remove.
         let mut remove = 0;
-        // Total length of all the to be removed buffers.
-        let mut accumulated_len = 0;
+        // Remaining length before reaching n. This prevents overflow
+        // that could happen if the length of slices in `bufs` were instead
+        // accumulated. Those slice may be aliased and, if they are large
+        // enough, their added length may overflow a `usize`.
+        let mut left = n;
         for buf in bufs.iter() {
-            if accumulated_len + buf.len() > n {
-                break;
-            } else {
-                accumulated_len += buf.len();
+            if let Some(remainder) = left.checked_sub(buf.len()) {
+                left = remainder;
                 remove += 1;
+            } else {
+                break;
             }
         }
 
         *bufs = &mut take(bufs)[remove..];
         if bufs.is_empty() {
-            assert!(n == accumulated_len, "advancing io slices beyond their length");
+            assert!(left == 0, "advancing io slices beyond their length");
         } else {
-            bufs[0].advance(n - accumulated_len)
+            bufs[0].advance(left);
         }
     }
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 5e3249655b8..f1f0f8b1653 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -665,6 +665,9 @@ pub use core::{
 )]
 pub use core::concat_bytes;
 
+#[unstable(feature = "cfg_match", issue = "115585")]
+pub use core::cfg_match;
+
 #[stable(feature = "core_primitive", since = "1.43.0")]
 pub use core::primitive;
 
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 24d16e64c86..11ad21515fd 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -142,6 +142,8 @@ pub mod solid;
 #[cfg(target_os = "tvos")]
 #[path = "ios/mod.rs"]
 pub(crate) mod tvos;
+#[cfg(target_os = "uefi")]
+pub mod uefi;
 #[cfg(target_os = "vita")]
 pub mod vita;
 #[cfg(target_os = "vxworks")]
diff --git a/library/std/src/os/uefi/env.rs b/library/std/src/os/uefi/env.rs
new file mode 100644
index 00000000000..5d082e7c113
--- /dev/null
+++ b/library/std/src/os/uefi/env.rs
@@ -0,0 +1,92 @@
+//! UEFI-specific extensions to the primitives in `std::env` module
+
+#![unstable(feature = "uefi_std", issue = "100499")]
+
+use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
+use crate::{ffi::c_void, ptr::NonNull};
+
+static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
+static IMAGE_HANDLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
+// Flag to check if BootServices are still valid.
+// Start with assuming that they are not available
+static BOOT_SERVICES_FLAG: AtomicBool = AtomicBool::new(false);
+
+/// Initializes the global System Table and Image Handle pointers.
+///
+/// The standard library requires access to the UEFI System Table and the Application Image Handle
+/// to operate. Those are provided to UEFI Applications via their application entry point. By
+/// calling `init_globals()`, those pointers are retained by the standard library for future use.
+/// Thus this function must be called before any of the standard library services are used.
+///
+/// The pointers are never exposed to any entity outside of this application and it is guaranteed
+/// that, once the application exited, these pointers are never dereferenced again.
+///
+/// Callers are required to ensure the pointers are valid for the entire lifetime of this
+/// application. In particular, UEFI Boot Services must not be exited while an application with the
+/// standard library is loaded.
+///
+/// # SAFETY
+/// Calling this function more than once will panic
+pub(crate) unsafe fn init_globals(handle: NonNull<c_void>, system_table: NonNull<c_void>) {
+    IMAGE_HANDLE
+        .compare_exchange(
+            crate::ptr::null_mut(),
+            handle.as_ptr(),
+            Ordering::Release,
+            Ordering::Acquire,
+        )
+        .unwrap();
+    SYSTEM_TABLE
+        .compare_exchange(
+            crate::ptr::null_mut(),
+            system_table.as_ptr(),
+            Ordering::Release,
+            Ordering::Acquire,
+        )
+        .unwrap();
+    BOOT_SERVICES_FLAG.store(true, Ordering::Release)
+}
+
+/// Get the SystemTable Pointer.
+/// If you want to use `BootServices` then please use [`boot_services`] as it performs some
+/// additional checks.
+///
+/// Note: This function panics if the System Table or Image Handle is not initialized
+pub fn system_table() -> NonNull<c_void> {
+    try_system_table().unwrap()
+}
+
+/// Get the ImageHandle Pointer.
+///
+/// Note: This function panics if the System Table or Image Handle is not initialized
+pub fn image_handle() -> NonNull<c_void> {
+    try_image_handle().unwrap()
+}
+
+/// Get the BootServices Pointer.
+/// This function also checks if `ExitBootServices` has already been called.
+pub fn boot_services() -> Option<NonNull<c_void>> {
+    if BOOT_SERVICES_FLAG.load(Ordering::Acquire) {
+        let system_table: NonNull<r_efi::efi::SystemTable> = try_system_table()?.cast();
+        let boot_services = unsafe { (*system_table.as_ptr()).boot_services };
+        NonNull::new(boot_services).map(|x| x.cast())
+    } else {
+        None
+    }
+}
+
+/// Get the SystemTable Pointer.
+/// This function is mostly intended for places where panic is not an option
+pub(crate) fn try_system_table() -> Option<NonNull<c_void>> {
+    NonNull::new(SYSTEM_TABLE.load(Ordering::Acquire))
+}
+
+/// Get the SystemHandle Pointer.
+/// This function is mostly intended for places where panicking is not an option
+pub(crate) fn try_image_handle() -> Option<NonNull<c_void>> {
+    NonNull::new(IMAGE_HANDLE.load(Ordering::Acquire))
+}
+
+pub(crate) fn disable_boot_services() {
+    BOOT_SERVICES_FLAG.store(false, Ordering::Release)
+}
diff --git a/library/std/src/os/uefi/mod.rs b/library/std/src/os/uefi/mod.rs
new file mode 100644
index 00000000000..8ef05eee1f4
--- /dev/null
+++ b/library/std/src/os/uefi/mod.rs
@@ -0,0 +1,8 @@
+//! Platform-specific extensions to `std` for UEFI.
+
+#![unstable(feature = "uefi_std", issue = "100499")]
+#![doc(cfg(target_os = "uefi"))]
+
+pub mod env;
+#[path = "../windows/ffi.rs"]
+pub mod ffi;
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index c12d89ed637..827278f8b26 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -6,7 +6,8 @@
 //!
 //! This module provides three types for representing file descriptors,
 //! with different ownership properties: raw, borrowed, and owned, which are
-//! analogous to types used for representing pointers. These types reflect the Unix version of [I/O safety].
+//! analogous to types used for representing pointers. These types reflect concepts of [I/O
+//! safety][io-safety] on Unix.
 //!
 //! | Type               | Analogous to |
 //! | ------------------ | ------------ |
@@ -17,8 +18,8 @@
 //! Like raw pointers, `RawFd` values are primitive values. And in new code,
 //! they should be considered unsafe to do I/O on (analogous to dereferencing
 //! them). Rust did not always provide this guidance, so existing code in the
-//! Rust ecosystem often doesn't mark `RawFd` usage as unsafe. Once the
-//! `io_safety` feature is stable, libraries will be encouraged to migrate,
+//! Rust ecosystem often doesn't mark `RawFd` usage as unsafe.
+//! Libraries are encouraged to migrate,
 //! either by adding `unsafe` to APIs that dereference `RawFd` values, or by
 //! using to `BorrowedFd` or `OwnedFd` instead.
 //!
@@ -54,6 +55,8 @@
 //! Like boxes, `OwnedFd` values conceptually own the resource they point to,
 //! and free (close) it when they are dropped.
 //!
+//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
+//!
 //! ## `/proc/self/mem` and similar OS features
 //!
 //! Some platforms have special files, such as `/proc/self/mem`, which
@@ -74,7 +77,7 @@
 //! necessary to use *sandboxing*, which is outside the scope of `std`.
 //!
 //! [`BorrowedFd<'a>`]: crate::os::unix::io::BorrowedFd
-//! [I/O safety]: crate::io#io-safety
+//! [io-safety]: crate::io#io-safety
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/windows/io/mod.rs b/library/std/src/os/windows/io/mod.rs
index 3d4bb96d458..3d3ae387886 100644
--- a/library/std/src/os/windows/io/mod.rs
+++ b/library/std/src/os/windows/io/mod.rs
@@ -6,7 +6,8 @@
 //!
 //! This module provides three types for representing raw handles and sockets
 //! with different ownership properties: raw, borrowed, and owned, which are
-//! analogous to types used for representing pointers. These types reflect the Windows version of [I/O safety].
+//! analogous to types used for representing pointers. These types reflect concepts of [I/O
+//! safety][io-safety] on Windows.
 //!
 //! | Type                   | Analogous to |
 //! | ---------------------- | ------------ |
@@ -23,8 +24,8 @@
 //! And in new code, they should be considered unsafe to do I/O on (analogous
 //! to dereferencing them). Rust did not always provide this guidance, so
 //! existing code in the Rust ecosystem often doesn't mark `RawHandle` and
-//! `RawSocket` usage as unsafe. Once the `io_safety` feature is stable,
-//! libraries will be encouraged to migrate, either by adding `unsafe` to APIs
+//! `RawSocket` usage as unsafe.
+//! Libraries are encouraged to migrate, either by adding `unsafe` to APIs
 //! that dereference `RawHandle` and `RawSocket` values, or by using to
 //! `BorrowedHandle`, `BorrowedSocket`, `OwnedHandle`, or `OwnedSocket`.
 //!
@@ -45,9 +46,11 @@
 //! Like boxes, `OwnedHandle` and `OwnedSocket` values conceptually own the
 //! resource they point to, and free (close) it when they are dropped.
 //!
+//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
+//!
 //! [`BorrowedHandle<'a>`]: crate::os::windows::io::BorrowedHandle
 //! [`BorrowedSocket<'a>`]: crate::os::windows::io::BorrowedSocket
-//! [I/O safety]: crate::io#io-safety
+//! [io-safety]: crate::io#io-safety
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/sys/common/thread_local/mod.rs b/library/std/src/sys/common/thread_local/mod.rs
index 975509bd412..8b2c839f837 100644
--- a/library/std/src/sys/common/thread_local/mod.rs
+++ b/library/std/src/sys/common/thread_local/mod.rs
@@ -6,7 +6,7 @@
 // "static" is for single-threaded platforms where a global static is sufficient.
 
 cfg_if::cfg_if! {
-    if #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))] {
+    if #[cfg(any(all(target_family = "wasm", not(target_feature = "atomics")), target_os = "uefi"))] {
         #[doc(hidden)]
         mod static_local;
         #[doc(hidden)]
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 457eb782ccc..159ffe7ac96 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -47,6 +47,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "xous")] {
         mod xous;
         pub use self::xous::*;
+    } else if #[cfg(target_os = "uefi")] {
+        mod uefi;
+        pub use self::uefi::*;
     } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
         mod sgx;
         pub use self::sgx::*;
@@ -114,4 +117,5 @@ pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
     log_fn(n)
 }
 
+#[cfg(not(target_os = "uefi"))]
 pub type RawOsError = i32;
diff --git a/library/std/src/sys/uefi/alloc.rs b/library/std/src/sys/uefi/alloc.rs
new file mode 100644
index 00000000000..789e3cbd81a
--- /dev/null
+++ b/library/std/src/sys/uefi/alloc.rs
@@ -0,0 +1,33 @@
+//! Global Allocator for UEFI.
+//! Uses [r-efi-alloc](https://crates.io/crates/r-efi-alloc)
+
+use crate::alloc::{GlobalAlloc, Layout, System};
+
+const MEMORY_TYPE: u32 = r_efi::efi::LOADER_DATA;
+
+#[stable(feature = "alloc_system_type", since = "1.28.0")]
+unsafe impl GlobalAlloc for System {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        // Return null pointer if boot services are not available
+        if crate::os::uefi::env::boot_services().is_none() {
+            return crate::ptr::null_mut();
+        }
+
+        // If boot services is valid then SystemTable is not null.
+        let system_table = crate::os::uefi::env::system_table().as_ptr().cast();
+        // The caller must ensure non-0 layout
+        unsafe { r_efi_alloc::raw::alloc(system_table, layout, MEMORY_TYPE) }
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        // Do nothing if boot services are not available
+        if crate::os::uefi::env::boot_services().is_none() {
+            return;
+        }
+
+        // If boot services is valid then SystemTable is not null.
+        let system_table = crate::os::uefi::env::system_table().as_ptr().cast();
+        // The caller must ensure non-0 layout
+        unsafe { r_efi_alloc::raw::dealloc(system_table, ptr, layout) }
+    }
+}
diff --git a/library/std/src/sys/uefi/env.rs b/library/std/src/sys/uefi/env.rs
new file mode 100644
index 00000000000..c106d5fed3e
--- /dev/null
+++ b/library/std/src/sys/uefi/env.rs
@@ -0,0 +1,9 @@
+pub mod os {
+    pub const FAMILY: &str = "";
+    pub const OS: &str = "uefi";
+    pub const DLL_PREFIX: &str = "";
+    pub const DLL_SUFFIX: &str = "";
+    pub const DLL_EXTENSION: &str = "";
+    pub const EXE_SUFFIX: &str = ".efi";
+    pub const EXE_EXTENSION: &str = "efi";
+}
diff --git a/library/std/src/sys/uefi/helpers.rs b/library/std/src/sys/uefi/helpers.rs
new file mode 100644
index 00000000000..126661bfc96
--- /dev/null
+++ b/library/std/src/sys/uefi/helpers.rs
@@ -0,0 +1,141 @@
+//! Contains most of the shared UEFI specific stuff. Some of this might be moved to `std::os::uefi`
+//! if needed but no point in adding extra public API when there is not Std support for UEFI in the
+//! first place
+//!
+//! Some Nomenclature
+//! * Protocol:
+//! - Protocols serve to enable communication between separately built modules, including drivers.
+//! - Every protocol has a GUID associated with it. The GUID serves as the name for the protocol.
+//! - Protocols are produced and consumed.
+//! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles)
+
+use r_efi::efi::{self, Guid};
+
+use crate::mem::{size_of, MaybeUninit};
+use crate::os::uefi;
+use crate::ptr::NonNull;
+use crate::{
+    io::{self, const_io_error},
+    os::uefi::env::boot_services,
+};
+
+const BOOT_SERVICES_UNAVAILABLE: io::Error =
+    const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");
+
+/// Locate Handles with a particular Protocol GUID
+/// Implemented using `EFI_BOOT_SERVICES.LocateHandles()`
+///
+/// Returns an array of [Handles](r_efi::efi::Handle) that support a specified protocol.
+pub(crate) fn locate_handles(mut guid: Guid) -> io::Result<Vec<NonNull<crate::ffi::c_void>>> {
+    fn inner(
+        guid: &mut Guid,
+        boot_services: NonNull<r_efi::efi::BootServices>,
+        buf_size: &mut usize,
+        buf: *mut r_efi::efi::Handle,
+    ) -> io::Result<()> {
+        let r = unsafe {
+            ((*boot_services.as_ptr()).locate_handle)(
+                r_efi::efi::BY_PROTOCOL,
+                guid,
+                crate::ptr::null_mut(),
+                buf_size,
+                buf,
+            )
+        };
+
+        if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
+    }
+
+    let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let mut buf_len = 0usize;
+
+    // This should always fail since the size of buffer is 0. This call should update the buf_len
+    // variable with the required buffer length
+    match inner(&mut guid, boot_services, &mut buf_len, crate::ptr::null_mut()) {
+        Ok(()) => unreachable!(),
+        Err(e) => match e.kind() {
+            io::ErrorKind::FileTooLarge => {}
+            _ => return Err(e),
+        },
+    }
+
+    // The returned buf_len is in bytes
+    assert_eq!(buf_len % size_of::<r_efi::efi::Handle>(), 0);
+    let num_of_handles = buf_len / size_of::<r_efi::efi::Handle>();
+    let mut buf: Vec<r_efi::efi::Handle> = Vec::with_capacity(num_of_handles);
+    match inner(&mut guid, boot_services, &mut buf_len, buf.as_mut_ptr()) {
+        Ok(()) => {
+            // This is safe because the call will succeed only if buf_len >= required length.
+            // Also, on success, the `buf_len` is updated with the size of bufferv (in bytes) written
+            unsafe { buf.set_len(num_of_handles) };
+            Ok(buf.into_iter().filter_map(|x| NonNull::new(x)).collect())
+        }
+        Err(e) => Err(e),
+    }
+}
+
+/// Open Protocol on a handle.
+/// Internally just a call to `EFI_BOOT_SERVICES.OpenProtocol()`.
+///
+/// Queries a handle to determine if it supports a specified protocol. If the protocol is
+/// supported by the handle, it opens the protocol on behalf of the calling agent.
+pub(crate) fn open_protocol<T>(
+    handle: NonNull<crate::ffi::c_void>,
+    mut protocol_guid: Guid,
+) -> io::Result<NonNull<T>> {
+    let boot_services: NonNull<efi::BootServices> =
+        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let system_handle = uefi::env::image_handle();
+    let mut protocol: MaybeUninit<*mut T> = MaybeUninit::uninit();
+
+    let r = unsafe {
+        ((*boot_services.as_ptr()).open_protocol)(
+            handle.as_ptr(),
+            &mut protocol_guid,
+            protocol.as_mut_ptr().cast(),
+            system_handle.as_ptr(),
+            crate::ptr::null_mut(),
+            r_efi::system::OPEN_PROTOCOL_GET_PROTOCOL,
+        )
+    };
+
+    if r.is_error() {
+        Err(crate::io::Error::from_raw_os_error(r.as_usize()))
+    } else {
+        NonNull::new(unsafe { protocol.assume_init() })
+            .ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
+    }
+}
+
+pub(crate) fn create_event(
+    signal: u32,
+    tpl: efi::Tpl,
+    handler: Option<efi::EventNotify>,
+    context: *mut crate::ffi::c_void,
+) -> io::Result<NonNull<crate::ffi::c_void>> {
+    let boot_services: NonNull<efi::BootServices> =
+        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let mut event: r_efi::efi::Event = crate::ptr::null_mut();
+    let r = unsafe {
+        let create_event = (*boot_services.as_ptr()).create_event;
+        (create_event)(signal, tpl, handler, context, &mut event)
+    };
+    if r.is_error() {
+        Err(crate::io::Error::from_raw_os_error(r.as_usize()))
+    } else {
+        NonNull::new(event).ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
+    }
+}
+
+/// # SAFETY
+/// - The supplied event must be valid
+pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result<()> {
+    let boot_services: NonNull<efi::BootServices> =
+        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let r = unsafe {
+        let close_event = (*boot_services.as_ptr()).close_event;
+        (close_event)(evt.as_ptr())
+    };
+
+    if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
+}
diff --git a/library/std/src/sys/uefi/mod.rs b/library/std/src/sys/uefi/mod.rs
new file mode 100644
index 00000000000..9a10395af8e
--- /dev/null
+++ b/library/std/src/sys/uefi/mod.rs
@@ -0,0 +1,244 @@
+//! Platform-specific extensions to `std` for UEFI platforms.
+//!
+//! Provides access to platform-level information on UEFI platforms, and
+//! exposes UEFI-specific functions that would otherwise be inappropriate as
+//! part of the core `std` library.
+//!
+//! It exposes more ways to deal with platform-specific strings ([`OsStr`],
+//! [`OsString`]), allows to set permissions more granularly, extract low-level
+//! file descriptors from files and sockets, and has platform-specific helpers
+//! for spawning processes.
+//!
+//! [`OsStr`]: crate::ffi::OsStr
+//! [`OsString`]: crate::ffi::OsString
+
+pub mod alloc;
+#[path = "../unsupported/args.rs"]
+pub mod args;
+#[path = "../unix/cmath.rs"]
+pub mod cmath;
+pub mod env;
+#[path = "../unsupported/fs.rs"]
+pub mod fs;
+#[path = "../unsupported/io.rs"]
+pub mod io;
+#[path = "../unsupported/locks/mod.rs"]
+pub mod locks;
+#[path = "../unsupported/net.rs"]
+pub mod net;
+#[path = "../unsupported/once.rs"]
+pub mod once;
+pub mod os;
+#[path = "../windows/os_str.rs"]
+pub mod os_str;
+pub mod path;
+#[path = "../unsupported/pipe.rs"]
+pub mod pipe;
+#[path = "../unsupported/process.rs"]
+pub mod process;
+#[path = "../unsupported/stdio.rs"]
+pub mod stdio;
+#[path = "../unsupported/thread.rs"]
+pub mod thread;
+#[path = "../unsupported/thread_local_key.rs"]
+pub mod thread_local_key;
+#[path = "../unsupported/thread_parking.rs"]
+pub mod thread_parking;
+#[path = "../unsupported/time.rs"]
+pub mod time;
+
+mod helpers;
+
+#[cfg(test)]
+mod tests;
+
+pub type RawOsError = usize;
+
+use crate::io as std_io;
+use crate::os::uefi;
+use crate::ptr::NonNull;
+use crate::sync::atomic::{AtomicPtr, Ordering};
+
+pub mod memchr {
+    pub use core::slice::memchr::{memchr, memrchr};
+}
+
+static EXIT_BOOT_SERVICE_EVENT: AtomicPtr<crate::ffi::c_void> =
+    AtomicPtr::new(crate::ptr::null_mut());
+
+/// # SAFETY
+/// - must be called only once during runtime initialization.
+/// - argc must be 2.
+/// - argv must be &[Handle, *mut SystemTable].
+pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
+    assert_eq!(argc, 2);
+    let image_handle = unsafe { NonNull::new(*argv as *mut crate::ffi::c_void).unwrap() };
+    let system_table = unsafe { NonNull::new(*argv.add(1) as *mut crate::ffi::c_void).unwrap() };
+    unsafe { uefi::env::init_globals(image_handle, system_table) };
+
+    // Register exit boot services handler
+    match helpers::create_event(
+        r_efi::efi::EVT_SIGNAL_EXIT_BOOT_SERVICES,
+        r_efi::efi::TPL_NOTIFY,
+        Some(exit_boot_service_handler),
+        crate::ptr::null_mut(),
+    ) {
+        Ok(x) => {
+            if EXIT_BOOT_SERVICE_EVENT
+                .compare_exchange(
+                    crate::ptr::null_mut(),
+                    x.as_ptr(),
+                    Ordering::Release,
+                    Ordering::Acquire,
+                )
+                .is_err()
+            {
+                abort_internal();
+            };
+        }
+        Err(_) => abort_internal(),
+    }
+}
+
+/// # SAFETY
+/// this is not guaranteed to run, for example when the program aborts.
+/// - must be called only once during runtime cleanup.
+pub unsafe fn cleanup() {
+    if let Some(exit_boot_service_event) =
+        NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire))
+    {
+        let _ = unsafe { helpers::close_event(exit_boot_service_event) };
+    }
+}
+
+#[inline]
+pub const fn unsupported<T>() -> std_io::Result<T> {
+    Err(unsupported_err())
+}
+
+#[inline]
+pub const fn unsupported_err() -> std_io::Error {
+    std_io::const_io_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",)
+}
+
+pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind {
+    use crate::io::ErrorKind;
+    use r_efi::efi::Status;
+
+    match r_efi::efi::Status::from_usize(code) {
+        Status::ALREADY_STARTED
+        | Status::COMPROMISED_DATA
+        | Status::CONNECTION_FIN
+        | Status::CRC_ERROR
+        | Status::DEVICE_ERROR
+        | Status::END_OF_MEDIA
+        | Status::HTTP_ERROR
+        | Status::ICMP_ERROR
+        | Status::INCOMPATIBLE_VERSION
+        | Status::LOAD_ERROR
+        | Status::MEDIA_CHANGED
+        | Status::NO_MAPPING
+        | Status::NO_MEDIA
+        | Status::NOT_STARTED
+        | Status::PROTOCOL_ERROR
+        | Status::PROTOCOL_UNREACHABLE
+        | Status::TFTP_ERROR
+        | Status::VOLUME_CORRUPTED => ErrorKind::Other,
+        Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => ErrorKind::InvalidData,
+        Status::ABORTED => ErrorKind::ConnectionAborted,
+        Status::ACCESS_DENIED => ErrorKind::PermissionDenied,
+        Status::BUFFER_TOO_SMALL => ErrorKind::FileTooLarge,
+        Status::CONNECTION_REFUSED => ErrorKind::ConnectionRefused,
+        Status::CONNECTION_RESET => ErrorKind::ConnectionReset,
+        Status::END_OF_FILE => ErrorKind::UnexpectedEof,
+        Status::HOST_UNREACHABLE => ErrorKind::HostUnreachable,
+        Status::INVALID_PARAMETER => ErrorKind::InvalidInput,
+        Status::IP_ADDRESS_CONFLICT => ErrorKind::AddrInUse,
+        Status::NETWORK_UNREACHABLE => ErrorKind::NetworkUnreachable,
+        Status::NO_RESPONSE => ErrorKind::HostUnreachable,
+        Status::NOT_FOUND => ErrorKind::NotFound,
+        Status::NOT_READY => ErrorKind::ResourceBusy,
+        Status::OUT_OF_RESOURCES => ErrorKind::OutOfMemory,
+        Status::SECURITY_VIOLATION => ErrorKind::PermissionDenied,
+        Status::TIMEOUT => ErrorKind::TimedOut,
+        Status::UNSUPPORTED => ErrorKind::Unsupported,
+        Status::VOLUME_FULL => ErrorKind::StorageFull,
+        Status::WRITE_PROTECTED => ErrorKind::ReadOnlyFilesystem,
+        _ => ErrorKind::Uncategorized,
+    }
+}
+
+pub fn abort_internal() -> ! {
+    if let Some(exit_boot_service_event) =
+        NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
+    {
+        let _ = unsafe { helpers::close_event(exit_boot_service_event) };
+    }
+
+    if let (Some(boot_services), Some(handle)) =
+        (uefi::env::boot_services(), uefi::env::try_image_handle())
+    {
+        let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
+        let _ = unsafe {
+            ((*boot_services.as_ptr()).exit)(
+                handle.as_ptr(),
+                r_efi::efi::Status::ABORTED,
+                0,
+                crate::ptr::null_mut(),
+            )
+        };
+    }
+
+    // In case SystemTable and ImageHandle cannot be reached, use `core::intrinsics::abort`
+    core::intrinsics::abort();
+}
+
+// This function is needed by the panic runtime. The symbol is named in
+// pre-link args for the target specification, so keep that in sync.
+#[cfg(not(test))]
+#[no_mangle]
+pub extern "C" fn __rust_abort() {
+    abort_internal();
+}
+
+#[inline]
+pub fn hashmap_random_keys() -> (u64, u64) {
+    get_random().unwrap()
+}
+
+fn get_random() -> Option<(u64, u64)> {
+    use r_efi::protocols::rng;
+
+    let mut buf = [0u8; 16];
+    let handles = helpers::locate_handles(rng::PROTOCOL_GUID).ok()?;
+    for handle in handles {
+        if let Ok(protocol) = helpers::open_protocol::<rng::Protocol>(handle, rng::PROTOCOL_GUID) {
+            let r = unsafe {
+                ((*protocol.as_ptr()).get_rng)(
+                    protocol.as_ptr(),
+                    crate::ptr::null_mut(),
+                    buf.len(),
+                    buf.as_mut_ptr(),
+                )
+            };
+            if r.is_error() {
+                continue;
+            } else {
+                return Some((
+                    u64::from_le_bytes(buf[..8].try_into().ok()?),
+                    u64::from_le_bytes(buf[8..].try_into().ok()?),
+                ));
+            }
+        }
+    }
+    None
+}
+
+/// Disable access to BootServices if `EVT_SIGNAL_EXIT_BOOT_SERVICES` is signaled
+extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) {
+    uefi::env::disable_boot_services();
+}
+
+pub fn is_interrupted(_code: RawOsError) -> bool {
+    false
+}
diff --git a/library/std/src/sys/uefi/os.rs b/library/std/src/sys/uefi/os.rs
new file mode 100644
index 00000000000..e6693db68e6
--- /dev/null
+++ b/library/std/src/sys/uefi/os.rs
@@ -0,0 +1,237 @@
+use super::{unsupported, RawOsError};
+use crate::error::Error as StdError;
+use crate::ffi::{OsStr, OsString};
+use crate::fmt;
+use crate::io;
+use crate::marker::PhantomData;
+use crate::os::uefi;
+use crate::path::{self, PathBuf};
+use crate::ptr::NonNull;
+use r_efi::efi::Status;
+
+pub fn errno() -> RawOsError {
+    0
+}
+
+pub fn error_string(errno: RawOsError) -> String {
+    // Keep the List in Alphabetical Order
+    // The Messages are taken from UEFI Specification Appendix D - Status Codes
+    match r_efi::efi::Status::from_usize(errno) {
+        Status::ABORTED => "The operation was aborted.".to_owned(),
+        Status::ACCESS_DENIED => "Access was denied.".to_owned(),
+        Status::ALREADY_STARTED => "The protocol has already been started.".to_owned(),
+        Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.".to_owned(),
+        Status::BUFFER_TOO_SMALL => {
+                "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.".to_owned()
+        }
+        Status::COMPROMISED_DATA => {
+                "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.".to_owned()
+        }
+        Status::CONNECTION_FIN => {
+                "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.".to_owned()
+        }
+        Status::CONNECTION_REFUSED => {
+                "The receiving or transmission operation fails because this connection is refused.".to_owned()
+        }
+        Status::CONNECTION_RESET => {
+                "The connect fails because the connection is reset either by instance itself or the communication peer.".to_owned()
+        }
+        Status::CRC_ERROR => "A CRC error was detected.".to_owned(),
+        Status::DEVICE_ERROR =>             "The physical device reported an error while attempting the operation.".to_owned()
+        ,
+        Status::END_OF_FILE => {
+            "The end of the file was reached.".to_owned()
+        }
+        Status::END_OF_MEDIA => {
+            "Beginning or end of media was reached".to_owned()
+        }
+        Status::HOST_UNREACHABLE => {
+            "The remote host is not reachable.".to_owned()
+        }
+        Status::HTTP_ERROR => {
+            "A HTTP error occurred during the network operation.".to_owned()
+        }
+        Status::ICMP_ERROR => {
+                "An ICMP error occurred during the network operation.".to_owned()
+        }
+        Status::INCOMPATIBLE_VERSION => {
+                "The function encountered an internal version that was incompatible with a version requested by the caller.".to_owned()
+        }
+        Status::INVALID_LANGUAGE => {
+            "The language specified was invalid.".to_owned()
+        }
+        Status::INVALID_PARAMETER => {
+            "A parameter was incorrect.".to_owned()
+        }
+        Status::IP_ADDRESS_CONFLICT => {
+            "There is an address conflict address allocation".to_owned()
+        }
+        Status::LOAD_ERROR => {
+            "The image failed to load.".to_owned()
+        }
+        Status::MEDIA_CHANGED => {
+                "The medium in the device has changed since the last access.".to_owned()
+        }
+        Status::NETWORK_UNREACHABLE => {
+                "The network containing the remote host is not reachable.".to_owned()
+        }
+        Status::NO_MAPPING => {
+            "A mapping to a device does not exist.".to_owned()
+        }
+        Status::NO_MEDIA => {
+                "The device does not contain any medium to perform the operation.".to_owned()
+        }
+        Status::NO_RESPONSE => {
+                "The server was not found or did not respond to the request.".to_owned()
+        }
+        Status::NOT_FOUND => "The item was not found.".to_owned(),
+        Status::NOT_READY => {
+            "There is no data pending upon return.".to_owned()
+        }
+        Status::NOT_STARTED => {
+            "The protocol has not been started.".to_owned()
+        }
+        Status::OUT_OF_RESOURCES => {
+            "A resource has run out.".to_owned()
+        }
+        Status::PROTOCOL_ERROR => {
+                "A protocol error occurred during the network operation.".to_owned()
+        }
+        Status::PROTOCOL_UNREACHABLE => {
+            "An ICMP protocol unreachable error is received.".to_owned()
+        }
+        Status::SECURITY_VIOLATION => {
+                "The function was not performed due to a security violation.".to_owned()
+        }
+        Status::TFTP_ERROR => {
+            "A TFTP error occurred during the network operation.".to_owned()
+        }
+        Status::TIMEOUT => "The timeout time expired.".to_owned(),
+        Status::UNSUPPORTED => {
+            "The operation is not supported.".to_owned()
+        }
+        Status::VOLUME_FULL => {
+            "There is no more space on the file system.".to_owned()
+        }
+        Status::VOLUME_CORRUPTED => {
+                "An inconstancy was detected on the file system causing the operating to fail.".to_owned()
+        }
+        Status::WRITE_PROTECTED => {
+            "The device cannot be written to.".to_owned()
+        }
+        _ => format!("Status: {}", errno),
+    }
+}
+
+pub fn getcwd() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn chdir(_: &path::Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);
+
+pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
+    panic!("unsupported")
+}
+
+impl<'a> Iterator for SplitPaths<'a> {
+    type Item = PathBuf;
+    fn next(&mut self) -> Option<PathBuf> {
+        self.0
+    }
+}
+
+#[derive(Debug)]
+pub struct JoinPathsError;
+
+pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
+where
+    I: Iterator<Item = T>,
+    T: AsRef<OsStr>,
+{
+    Err(JoinPathsError)
+}
+
+impl fmt::Display for JoinPathsError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        "not supported on this platform yet".fmt(f)
+    }
+}
+
+impl StdError for JoinPathsError {}
+
+pub fn current_exe() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub struct Env(!);
+
+impl Env {
+    // FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self(inner) = self;
+        match *inner {}
+    }
+}
+
+impl Iterator for Env {
+    type Item = (OsString, OsString);
+    fn next(&mut self) -> Option<(OsString, OsString)> {
+        self.0
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self(inner) = self;
+        match *inner {}
+    }
+}
+
+pub fn env() -> Env {
+    panic!("not supported on this platform")
+}
+
+pub fn getenv(_: &OsStr) -> Option<OsString> {
+    None
+}
+
+pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
+    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
+}
+
+pub fn unsetenv(_: &OsStr) -> io::Result<()> {
+    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
+}
+
+pub fn temp_dir() -> PathBuf {
+    panic!("no filesystem on this platform")
+}
+
+pub fn home_dir() -> Option<PathBuf> {
+    None
+}
+
+pub fn exit(code: i32) -> ! {
+    if let (Some(boot_services), Some(handle)) =
+        (uefi::env::boot_services(), uefi::env::try_image_handle())
+    {
+        let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
+        let _ = unsafe {
+            ((*boot_services.as_ptr()).exit)(
+                handle.as_ptr(),
+                Status::from_usize(code as usize),
+                0,
+                crate::ptr::null_mut(),
+            )
+        };
+    }
+    crate::intrinsics::abort()
+}
+
+pub fn getpid() -> u32 {
+    panic!("no pids on this platform")
+}
diff --git a/library/std/src/sys/uefi/path.rs b/library/std/src/sys/uefi/path.rs
new file mode 100644
index 00000000000..106682eee56
--- /dev/null
+++ b/library/std/src/sys/uefi/path.rs
@@ -0,0 +1,25 @@
+use super::unsupported;
+use crate::ffi::OsStr;
+use crate::io;
+use crate::path::{Path, PathBuf, Prefix};
+
+pub const MAIN_SEP_STR: &str = "\\";
+pub const MAIN_SEP: char = '\\';
+
+#[inline]
+pub fn is_sep_byte(b: u8) -> bool {
+    b == b'\\'
+}
+
+#[inline]
+pub fn is_verbatim_sep(b: u8) -> bool {
+    b == b'\\'
+}
+
+pub fn parse_prefix(_p: &OsStr) -> Option<Prefix<'_>> {
+    None
+}
+
+pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
+    unsupported()
+}
diff --git a/library/std/src/sys/uefi/tests.rs b/library/std/src/sys/uefi/tests.rs
new file mode 100644
index 00000000000..8806eda3ac0
--- /dev/null
+++ b/library/std/src/sys/uefi/tests.rs
@@ -0,0 +1,21 @@
+use super::alloc::*;
+
+#[test]
+fn align() {
+    // UEFI ABI specifies that allocation alignment minimum is always 8. So this can be
+    // statically verified.
+    assert_eq!(POOL_ALIGNMENT, 8);
+
+    // Loop over allocation-request sizes from 0-256 and alignments from 1-128, and verify
+    // that in case of overalignment there is at least space for one additional pointer to
+    // store in the allocation.
+    for i in 0..256 {
+        for j in &[1, 2, 4, 8, 16, 32, 64, 128] {
+            if *j <= 8 {
+                assert_eq!(align_size(i, *j), i);
+            } else {
+                assert!(align_size(i, *j) > i + std::mem::size_of::<*mut ()>());
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index f7d82175063..e18638f2a5f 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -44,6 +44,7 @@ cfg_if::cfg_if! {
 
 cfg_if::cfg_if! {
     if #[cfg(any(target_os = "l4re",
+                 target_os = "uefi",
                  feature = "restricted-std",
                  all(target_family = "wasm", not(target_os = "emscripten")),
                  target_os = "xous",
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 4f19ffa83db..292ccc5780f 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1789,7 +1789,10 @@ pub fn run_cargo(
                 // During check builds we need to keep crate metadata
                 keep = true;
             } else if rlib_only_metadata {
-                if filename.contains("jemalloc_sys") || filename.contains("rustc_smir") {
+                if filename.contains("jemalloc_sys")
+                    || filename.contains("rustc_smir")
+                    || filename.contains("stable_mir")
+                {
                     // jemalloc_sys and rustc_smir are not linked into librustc_driver.so,
                     // so we need to distribute them as rlib to be able to use them.
                     keep |= filename.ends_with(".rlib");
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 176ef8e92db..836328f94ef 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -532,11 +532,7 @@ pub struct Target {
 impl Target {
     pub fn from_triple(triple: &str) -> Self {
         let mut target: Self = Default::default();
-        if triple.contains("-none")
-            || triple.contains("nvptx")
-            || triple.contains("switch")
-            || triple.contains("-uefi")
-        {
+        if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") {
             target.no_std = true;
         }
         target
diff --git a/src/ci/scripts/setup-environment.sh b/src/ci/scripts/setup-environment.sh
index 0bc35f93283..d3c55a4d6b4 100755
--- a/src/ci/scripts/setup-environment.sh
+++ b/src/ci/scripts/setup-environment.sh
@@ -10,7 +10,7 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
 
 # Load extra environment variables
 vars="${EXTRA_VARIABLES-}"
-echo "${vars}" | jq '' >/dev/null  # Validate JSON and exit on errors
+echo "${vars}" | jq '.' >/dev/null  # Validate JSON and exit on errors
 for key in $(echo "${vars}" | jq "keys[]" -r); do
     # On Windows, for whatever reason, $key contains the BOM character in it,
     # and that messes up `jq ".${key}"`. This line strips the BOM from the key.
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 99ad2847b865e96d8ae7b333d3ee96963557e62
+Subproject eac173690b8cc99094e1d88bd49dd61127fbd28
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject e3f3af69dce71cd37a785bccb7e58449197d940
+Subproject ddfa4214487686e91b21aa29afb972c08a8f0d5
diff --git a/src/doc/reference b/src/doc/reference
-Subproject ee7c676fd6e287459cb407337652412c990686c
+Subproject 5262e1c3b43a2c489df8f6717683a44c7a2260f
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 08bb147d51e815b96e8db7ba4cf870f201c11ff
+Subproject a13b7c28ed705891c681ce5417b3d1cdb12cecd
diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md
index 03fa284620e..68cd7fae319 100644
--- a/src/doc/rustc/src/platform-support/unknown-uefi.md
+++ b/src/doc/rustc/src/platform-support/unknown-uefi.md
@@ -19,8 +19,8 @@ Available targets:
 ## Requirements
 
 All UEFI targets can be used as `no-std` environments via cross-compilation.
-Support for `std` is missing, but actively worked on. `alloc` is supported if
-an allocator is provided by the user. No host tools are supported.
+Support for `std` is present, but incomplete and extremely new. `alloc` is supported if
+an allocator is provided by the user or if using std. No host tools are supported.
 
 The UEFI environment resembles the environment for Microsoft Windows, with some
 minor differences. Therefore, cross-compiling for UEFI works with the same
@@ -230,3 +230,76 @@ pub extern "C" fn main(_h: efi::Handle, st: *mut efi::SystemTable) -> efi::Statu
     efi::Status::SUCCESS
 }
 ```
+
+## Rust std for UEFI
+This section contains information on how to use std on UEFI.
+
+### Build std
+The building std part is pretty much the same as the official [docs](https://rustc-dev-guide.rust-lang.org/getting-started.html).
+The linker that should be used is `rust-lld`. Here is a sample `config.toml`:
+```toml
+[rust]
+lld = true
+```
+Then just build using `x.py`:
+```sh
+./x.py build --target x86_64-unknown-uefi --stage 1
+```
+Alternatively, it is possible to use the `build-std` feature. However, you must use a toolchain which has the UEFI std patches.
+Then just build the project using the following command:
+```sh
+cargo build --target x86_64-unknown-uefi -Zbuild-std=std,panic_abort
+```
+
+### Implemented features
+#### alloc
+- Implemented using `EFI_BOOT_SERVICES.AllocatePool()` and `EFI_BOOT_SERVICES.FreePool()`.
+- Passes all the tests.
+- Currently uses `EfiLoaderData` as the `EFI_ALLOCATE_POOL->PoolType`.
+#### cmath
+- Provided by compiler-builtins.
+#### env
+- Just some global constants.
+#### locks
+- The provided locks should work on all standard single-threaded UEFI implementations.
+#### os_str
+- While the strings in UEFI should be valid UCS-2, in practice, many implementations just do not care and use UTF-16 strings.
+- Thus, the current implementation supports full UTF-16 strings.
+
+## Example: Hello World With std
+The following code features a valid UEFI application, including stdio and `alloc` (`OsString` and `Vec`):
+
+This example can be compiled as binary crate via `cargo` using the toolchain
+compiled from the above source (named custom):
+
+```sh
+cargo +custom build --target x86_64-unknown-uefi
+```
+
+```rust,ignore (platform-specific)
+#![feature(uefi_std)]
+
+use r_efi::{efi, protocols::simple_text_output};
+use std::{
+  ffi::OsString,
+  os::uefi::{env, ffi::OsStrExt}
+};
+
+pub fn main() {
+  let st = env::system_table().as_ptr() as *mut efi::SystemTable;
+  let mut s: Vec<u16> = OsString::from("Hello World!\n").encode_wide().collect();
+  s.push(0);
+  let r =
+      unsafe {
+        let con_out: *mut simple_text_output::Protocol = (*st).con_out;
+        let output_string: extern "efiapi" fn(_: *mut simple_text_output::Protocol, *mut u16) -> efi::Status = (*con_out).output_string;
+        output_string(con_out, s.as_ptr() as *mut efi::Char16)
+      };
+  assert!(!r.is_error())
+}
+```
+
+### BootServices
+The current implementation of std makes `BootServices` unavailable once `ExitBootServices` is called. Refer to [Runtime Drivers](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/7_driver_entry_point/711_runtime_drivers) for more information regarding how to handle switching from using physical addresses to using virtual addresses.
+
+Note: It should be noted that it is up to the user to drop all allocated memory before `ExitBootServices` is called.
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index 0d3f6338af4..7473b09920f 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -375,7 +375,7 @@ library, as an equivalent command-line argument is provided to `rustc` when buil
 This feature allows you to generate an index-page with a given markdown file. A good example of it
 is the [rust documentation index](https://doc.rust-lang.org/nightly/index.html).
 
-With this, you'll have a page which you can custom as much as you want at the top of your crates.
+With this, you'll have a page which you can customize as much as you want at the top of your crates.
 
 Using `index-page` option enables `enable-index-page` option as well.
 
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index dd43ee03383..fcbcfbf5c67 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -80,7 +80,7 @@ pub(crate) fn try_inline(
             build_impls(cx, did, attrs_without_docs, &mut ret);
             clean::UnionItem(build_union(cx, did))
         }
-        Res::Def(DefKind::TyAlias { .. }, did) => {
+        Res::Def(DefKind::TyAlias, did) => {
             record_extern_fqn(cx, did, ItemType::TypeAlias);
             build_impls(cx, did, attrs_without_docs, &mut ret);
             clean::TypeAliasItem(build_type_alias(cx, did))
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e0ac769dadd..34d81f51f76 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1108,10 +1108,7 @@ fn clean_function<'tcx>(
                 clean_args_from_types_and_names(cx, sig.decl.inputs, names)
             }
         };
-        let mut decl = clean_fn_decl_with_args(cx, sig.decl, args);
-        if sig.header.is_async() {
-            decl.output = decl.sugared_async_return_type();
-        }
+        let decl = clean_fn_decl_with_args(cx, sig.decl, Some(&sig.header), args);
         (generics, decl)
     });
     Box::new(Function { decl, generics })
@@ -1162,12 +1159,16 @@ fn clean_args_from_types_and_body_id<'tcx>(
 fn clean_fn_decl_with_args<'tcx>(
     cx: &mut DocContext<'tcx>,
     decl: &hir::FnDecl<'tcx>,
+    header: Option<&hir::FnHeader>,
     args: Arguments,
 ) -> FnDecl {
-    let output = match decl.output {
+    let mut output = match decl.output {
         hir::FnRetTy::Return(typ) => clean_ty(typ, cx),
         hir::FnRetTy::DefaultReturn(..) => Type::Tuple(Vec::new()),
     };
+    if let Some(header) = header && header.is_async() {
+        output = output.sugared_async_return_type();
+    }
     FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
 }
 
@@ -1180,7 +1181,11 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
 
     // We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
     // but shouldn't change any code meaning.
-    let output = clean_middle_ty(sig.output(), cx, None, None);
+    let mut output = clean_middle_ty(sig.output(), cx, None, None);
+
+    if let Some(did) = did && cx.tcx.asyncness(did).is_async() {
+        output = output.sugared_async_return_type();
+    }
 
     FnDecl {
         output,
@@ -1753,7 +1758,7 @@ fn maybe_expand_private_type_alias<'tcx>(
     cx: &mut DocContext<'tcx>,
     path: &hir::Path<'tcx>,
 ) -> Option<Type> {
-    let Res::Def(DefKind::TyAlias { .. }, def_id) = path.res else { return None };
+    let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None };
     // Substitute private type aliases
     let def_id = def_id.as_local()?;
     let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id())
@@ -2022,7 +2027,7 @@ impl<'tcx> ContainerTy<'tcx> {
                 let (DefKind::Struct
                 | DefKind::Union
                 | DefKind::Enum
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::Trait) = tcx.def_kind(container)
                 else {
                     return ObjectLifetimeDefault::Empty;
@@ -2566,7 +2571,7 @@ fn clean_bare_fn_ty<'tcx>(
             .map(|x| clean_generic_param(cx, None, x))
             .collect();
         let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_names);
-        let decl = clean_fn_decl_with_args(cx, bare_fn.decl, args);
+        let decl = clean_fn_decl_with_args(cx, bare_fn.decl, None, args);
         (generic_params, decl)
     });
     BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
@@ -2854,7 +2859,7 @@ fn clean_impl<'tcx>(
     let for_ = clean_ty(impl_.self_ty, cx);
     let type_alias =
         for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) {
-            DefKind::TyAlias { .. } => Some(clean_middle_ty(
+            DefKind::TyAlias => Some(clean_middle_ty(
                 ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()),
                 cx,
                 Some(def_id.to_def_id()),
@@ -3077,7 +3082,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
                     // NOTE: generics must be cleaned before args
                     let generics = clean_generics(generics, cx);
                     let args = clean_args_from_types_and_names(cx, decl.inputs, names);
-                    let decl = clean_fn_decl_with_args(cx, decl, args);
+                    let decl = clean_fn_decl_with_args(cx, decl, None, args);
                     (generics, decl)
                 });
                 ForeignFunctionItem(Box::new(Function { decl, generics }))
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index b665f684167..f5251f50b7a 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1384,28 +1384,6 @@ impl FnDecl {
     pub(crate) fn self_type(&self) -> Option<SelfTy> {
         self.inputs.values.get(0).and_then(|v| v.to_self())
     }
-
-    /// Returns the sugared return type for an async function.
-    ///
-    /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
-    /// will return `i32`.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if the return type does not match the expected sugaring for async
-    /// functions.
-    pub(crate) fn sugared_async_return_type(&self) -> Type {
-        if let Type::ImplTrait(v) = &self.output &&
-            let [GenericBound::TraitBound(PolyTrait { trait_, .. }, _ )] = &v[..]
-        {
-            let bindings = trait_.bindings().unwrap();
-            let ret_ty = bindings[0].term();
-            let ty = ret_ty.ty().expect("Unexpected constant return term");
-            ty.clone()
-        } else {
-            panic!("unexpected desugaring of async function")
-        }
-    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -1617,6 +1595,28 @@ impl Type {
         }
     }
 
+    /// Returns the sugared return type for an async function.
+    ///
+    /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
+    /// will return `i32`.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if the return type does not match the expected sugaring for async
+    /// functions.
+    pub(crate) fn sugared_async_return_type(&self) -> Type {
+        if let Type::ImplTrait(v) = self &&
+            let [GenericBound::TraitBound(PolyTrait { trait_, .. }, _ )] = &v[..]
+        {
+            let bindings = trait_.bindings().unwrap();
+            let ret_ty = bindings[0].term();
+            let ty = ret_ty.ty().expect("unexpected constant in async fn return term");
+            ty.clone()
+        } else {
+            panic!("unexpected async fn return type")
+        }
+    }
+
     /// Checks if this is a `T::Name` path for an associated type.
     pub(crate) fn is_assoc_ty(&self) -> bool {
         match self {
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index fd79160ff4a..be2ee791588 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -115,7 +115,7 @@ impl From<DefKind> for ItemType {
             DefKind::Struct => Self::Struct,
             DefKind::Union => Self::Union,
             DefKind::Trait => Self::Trait,
-            DefKind::TyAlias { .. } => Self::TypeAlias,
+            DefKind::TyAlias => Self::TypeAlias,
             DefKind::TraitAlias => Self::TraitAlias,
             DefKind::Macro(kind) => match kind {
                 MacroKind::Bang => ItemType::Macro,
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 8ea9b7a418b..d216305e6a9 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -593,7 +593,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         .unwrap_or(Vec::new())
                 }
             }
-            Res::Def(DefKind::TyAlias { .. }, did) => {
+            Res::Def(DefKind::TyAlias, did) => {
                 // Resolve the link on the type the alias points to.
                 // FIXME: if the associated item is defined directly on the type alias,
                 // it will show up on its documentation page, we should link there instead.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 414d9e3a6d8096f3e276234ce220c868767a879
+Subproject e6aabe8b3fcf639be3a5bf68e77853bd7b3fa27
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 7d25b6a2b79..30bd476332f 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -21,7 +21,7 @@ jobs:
     - name: Setup Node.js
       uses: actions/setup-node@v3
       with:
-        node-version: '14.x'
+        node-version: '18.x'
 
     - name: Install remark
       run: npm install remark-cli remark-lint remark-lint-maximum-line-length remark-preset-lint-recommended remark-gfm
@@ -29,19 +29,19 @@ jobs:
     - name: Install mdbook
       run: |
         mkdir mdbook
-        curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.28/mdbook-v0.4.28-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
+        curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdbook-v0.4.34-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
         echo `pwd`/mdbook >> $GITHUB_PATH
 
     # Run
     - name: Check *.md files
-      run: git ls-files -z '*.md' | xargs -0 -n 1 -I {} ./node_modules/.bin/remark {} -u lint -f > /dev/null
+      run: ./node_modules/.bin/remark -u lint -f .
 
     - name: Linkcheck book
       run: |
         rustup toolchain install nightly --component rust-docs
         curl https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh -o linkcheck.sh
         sh linkcheck.sh clippy --path ./book
-        
+
     - name: Build mdbook
       run: mdbook build book
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index a7ae4a0ee2c..8c9ab1e2402 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5171,6 +5171,7 @@ Released 2018-09-13
 [`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign
 [`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
 [`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
+[`needless_borrows_for_generic_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args
 [`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
 [`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
 [`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
@@ -5245,6 +5246,7 @@ Released 2018-09-13
 [`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
 [`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none
 [`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite
+[`path_ends_with_ext`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext
 [`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch
 [`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false
 [`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters
@@ -5279,6 +5281,7 @@ Released 2018-09-13
 [`readonly_write_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#readonly_write_lock
 [`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl
 [`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation
+[`redundant_as_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_as_str
 [`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_async_block
 [`redundant_at_rest_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_at_rest_pattern
 [`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
@@ -5437,6 +5440,7 @@ Released 2018-09-13
 [`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join
 [`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
 [`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap
+[`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor
 [`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
 [`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
 [`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings
@@ -5574,5 +5578,6 @@ Released 2018-09-13
 [`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
 [`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
 [`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
+[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
 [`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
 <!-- end autogenerated links to configuration documentation -->
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 2d8b590dbe3..66786004f6e 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -38,7 +38,6 @@ itertools = "0.10.1"
 
 # UI test dependencies
 clippy_utils = { path = "clippy_utils" }
-derive-new = "0.5"
 if_chain = "1.0"
 quote = "1.0"
 serde = { version = "1.0.125", features = ["derive"] }
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 52c795e04fe..b980083f1f5 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -703,7 +703,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted.
 ## `accept-comment-above-statement`
 Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
 
-**Default Value:** `false` (`bool`)
+**Default Value:** `true` (`bool`)
 
 ---
 **Affected lints:**
@@ -713,7 +713,7 @@ Whether to accept a safety comment to be placed above the statement containing t
 ## `accept-comment-above-attributes`
 Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
 
-**Default Value:** `false` (`bool`)
+**Default Value:** `true` (`bool`)
 
 ---
 **Affected lints:**
@@ -751,6 +751,16 @@ Which crates to allow absolute paths from
 * [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
 
 
+## `allowed-dotfiles`
+Additional dotfiles (files or directories starting with a dot) to allow
+
+**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
+
+---
+**Affected lints:**
+* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
+
+
 ## `enforce-iter-loop-reborrow`
 #### Example
 ```
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index a88f2b51c82..0546807bac4 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -616,7 +616,7 @@ fn check_should_panic_reason(cx: &LateContext<'_>, attr: &Attribute) {
             attr.span,
             "#[should_panic] attribute without a reason",
             "consider specifying the expected panic",
-            r#"#[should_panic(expected = /* panic message */)]"#.into(),
+            "#[should_panic(expected = /* panic message */)]".into(),
             Applicability::HasPlaceholders,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
index cf07e050ccc..c586b572be9 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -25,7 +25,7 @@ pub(super) fn check(
     // The suggestion is to use a function call, so if the original expression
     // has parens on the outside, they are no longer needed.
     let mut applicability = Applicability::MachineApplicable;
-    let opt = snippet_opt(cx, cast_op.span);
+    let opt = snippet_opt(cx, cast_op.span.source_callsite());
     let sugg = opt.as_ref().map_or_else(
         || {
             applicability = Applicability::HasPlaceholders;
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 84b99ad5c24..f99a51e2b88 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -44,7 +44,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
                 .unwrap_or(u64::max_value())
                 .min(apply_reductions(cx, nbits, left, signed)),
             BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)
-                .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))),
+                .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).unwrap_or_default())),
             _ => nbits,
         },
         ExprKind::MethodCall(method, left, [right], _) => {
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index 88ffbb55486..b00130ffd76 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -20,6 +20,7 @@ mod ptr_as_ptr;
 mod ptr_cast_constness;
 mod unnecessary_cast;
 mod utils;
+mod zero_ptr;
 
 use clippy_utils::is_hir_ty_cfg_dependant;
 use clippy_utils::msrvs::{self, Msrv};
@@ -665,6 +666,29 @@ declare_clippy_lint! {
     "casting a known floating-point NaN into an integer"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Catch casts from `0` to some pointer type
+    ///
+    /// ### Why is this bad?
+    /// This generally means `null` and is better expressed as
+    /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
+    ///
+    /// ### Example
+    /// ```rust
+    /// let a = 0 as *const u32;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust
+    /// let a = std::ptr::null::<u32>();
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub ZERO_PTR,
+    style,
+    "using `0 as *{const, mut} T`"
+}
+
 pub struct Casts {
     msrv: Msrv,
 }
@@ -699,6 +723,7 @@ impl_lint_pass!(Casts => [
     CAST_SLICE_FROM_RAW_PARTS,
     AS_PTR_CAST_MUT,
     CAST_NAN_TO_INT,
+    ZERO_PTR,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -729,6 +754,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
             fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
             fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
+            zero_ptr::check(cx, expr, cast_expr, cast_to_hir);
 
             if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
                 cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to, cast_to_hir.span);
diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
new file mode 100644
index 00000000000..5071af5ecb9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
@@ -0,0 +1,39 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_opt;
+use clippy_utils::{in_constant, is_integer_literal, std_or_core};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, Mutability, Ty, TyKind};
+use rustc_lint::LateContext;
+
+use super::ZERO_PTR;
+
+pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {
+    if let TyKind::Ptr(ref mut_ty) = to.kind
+        && is_integer_literal(from, 0)
+        && !in_constant(cx, from.hir_id)
+        && let Some(std_or_core) = std_or_core(cx)
+    {
+        let (msg, sugg_fn) = match mut_ty.mutbl {
+            Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
+            Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
+        };
+
+        let sugg = if let TyKind::Infer = mut_ty.ty.kind {
+            format!("{std_or_core}::{sugg_fn}()")
+        } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
+            format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()")
+        } else {
+            return;
+        };
+
+        span_lint_and_sugg(
+            cx,
+            ZERO_PTR,
+            expr.span,
+            msg,
+            "try",
+            sugg,
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index a4d40df52e7..4d1281ec1e7 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -97,6 +97,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::casts::PTR_AS_PTR_INFO,
     crate::casts::PTR_CAST_CONSTNESS_INFO,
     crate::casts::UNNECESSARY_CAST_INFO,
+    crate::casts::ZERO_PTR_INFO,
     crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
     crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
     crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,
@@ -399,9 +400,11 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::methods::OR_FUN_CALL_INFO,
     crate::methods::OR_THEN_UNWRAP_INFO,
     crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,
+    crate::methods::PATH_ENDS_WITH_EXT_INFO,
     crate::methods::RANGE_ZIP_WITH_LEN_INFO,
     crate::methods::READONLY_WRITE_LOCK_INFO,
     crate::methods::READ_LINE_WITHOUT_TRIM_INFO,
+    crate::methods::REDUNDANT_AS_STR_INFO,
     crate::methods::REPEAT_ONCE_INFO,
     crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,
     crate::methods::SEARCH_IS_SOME_INFO,
@@ -441,7 +444,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
     crate::misc::TOPLEVEL_REF_ARG_INFO,
     crate::misc::USED_UNDERSCORE_BINDING_INFO,
-    crate::misc::ZERO_PTR_INFO,
     crate::misc_early::BUILTIN_TYPE_SHADOW_INFO,
     crate::misc_early::DOUBLE_NEG_INFO,
     crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO,
@@ -479,6 +481,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::needless_bool::NEEDLESS_BOOL_INFO,
     crate::needless_bool::NEEDLESS_BOOL_ASSIGN_INFO,
     crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO,
+    crate::needless_borrows_for_generic_args::NEEDLESS_BORROWS_FOR_GENERIC_ARGS_INFO,
     crate::needless_continue::NEEDLESS_CONTINUE_INFO,
     crate::needless_else::NEEDLESS_ELSE_INFO,
     crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,
@@ -671,6 +674,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO,
     crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO,
     crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,
+    crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
     crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
     crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
     crate::unnecessary_struct_initialization::UNNECESSARY_STRUCT_INITIALIZATION_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
index bbce6e1dd8f..63ec8195020 100644
--- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{self as hir, HirId, Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{HirId, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::ty::{self, FieldDef, GenericArg, List};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
 
@@ -52,7 +52,10 @@ declare_lint_pass!(DefaultUnionRepresentation => [DEFAULT_UNION_REPRESENTATION])
 
 impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
-        if is_union_with_two_non_zst_fields(cx, item) && !has_c_repr_attr(cx, item.hir_id()) {
+        if !item.span.from_expansion()
+            && is_union_with_two_non_zst_fields(cx, item)
+            && !has_c_repr_attr(cx, item.hir_id())
+        {
             span_lint_and_help(
                 cx,
                 DEFAULT_UNION_REPRESENTATION,
@@ -73,18 +76,17 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
 /// if there is only one field left after ignoring ZST fields then the offset
 /// of that field does not matter either.)
 fn is_union_with_two_non_zst_fields(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
-    if let ItemKind::Union(data, _) = &item.kind {
-        data.fields().iter().filter(|f| !is_zst(cx, f.ty)).count() >= 2
+    if let ItemKind::Union(..) = &item.kind
+        && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
+    {
+        adt_def.all_fields().filter(|f| !is_zst(cx, f, args)).count() >= 2
     } else {
         false
     }
 }
 
-fn is_zst(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) -> bool {
-    if hir_ty.span.from_expansion() {
-        return false;
-    }
-    let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: &'tcx List<GenericArg<'tcx>>) -> bool {
+    let ty = field.ty(cx.tcx, args);
     if let Ok(layout) = cx.layout_of(ty) {
         layout.is_zst()
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index fe37fd4a0c1..14877385646 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1,41 +1,24 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
-use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::ty::{implements_trait, is_copy, peel_mid_ty_refs};
+use clippy_utils::ty::{implements_trait, peel_mid_ty_refs};
 use clippy_utils::{
     expr_use_ctxt, get_parent_expr, get_parent_node, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode,
 };
-
-use hir::def::DefKind;
-use hir::MatchSource;
 use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::graph::iterate::{CycleDetector, TriColorDepthFirstSearch};
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
-use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_ty, Visitor};
 use rustc_hir::{
-    self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind,
-    Path, QPath, TyKind, UnOp,
+    self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node,
+    Pat, PatKind, Path, QPath, TyKind, UnOp,
 };
-use rustc_index::bit_set::BitSet;
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::{Rvalue, StatementKind};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
-use rustc_middle::ty::{
-    self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, List, ParamEnv, ParamTy, ProjectionPredicate, Ty,
-    TyCtxt, TypeVisitableExt, TypeckResults,
-};
+use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
-use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
-use rustc_trait_selection::traits::{Obligation, ObligationCause};
-use std::collections::VecDeque;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -183,24 +166,6 @@ pub struct Dereferencing<'tcx> {
     ///
     /// e.g. `m!(x) | Foo::Bar(ref x)`
     ref_locals: FxIndexMap<HirId, Option<RefPat>>,
-
-    /// Stack of (body owner, `PossibleBorrowerMap`) pairs. Used by
-    /// `needless_borrow_impl_arg_position` to determine when a borrowed expression can instead
-    /// be moved.
-    possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
-
-    // `IntoIterator` for arrays requires Rust 1.53.
-    msrv: Msrv,
-}
-
-impl<'tcx> Dereferencing<'tcx> {
-    #[must_use]
-    pub fn new(msrv: Msrv) -> Self {
-        Self {
-            msrv,
-            ..Dereferencing::default()
-        }
-    }
 }
 
 #[derive(Debug)]
@@ -355,52 +320,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                         ));
                     },
                     (Some(use_cx), RefOp::AddrOf(mutability)) => {
-                        let defined_ty = use_cx.node.defined_ty(cx);
-
-                        // Check needless_borrow for generic arguments.
-                        if !use_cx.is_ty_unified
-                            && let Some(DefinedTy::Mir(ty)) = defined_ty
-                            && let ty::Param(ty) = *ty.value.skip_binder().kind()
-                            && let Some((hir_id, fn_id, i)) = match use_cx.node {
-                                ExprUseNode::MethodArg(_, _, 0) => None,
-                                ExprUseNode::MethodArg(hir_id, None, i) => {
-                                    typeck.type_dependent_def_id(hir_id).map(|id| (hir_id, id, i))
-                                },
-                                ExprUseNode::FnArg(&Expr { kind: ExprKind::Path(ref p), hir_id, .. }, i)
-                                if !path_has_args(p) => match typeck.qpath_res(p, hir_id) {
-                                    Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => {
-                                        Some((hir_id, id, i))
-                                    },
-                                    _ => None,
-                                },
-                                _ => None,
-                            } && let count = needless_borrow_generic_arg_count(
-                                cx,
-                                &mut self.possible_borrowers,
-                                fn_id,
-                                typeck.node_args(hir_id),
-                                i,
-                                ty,
-                                expr,
-                                &self.msrv,
-                            ) && count != 0
-                        {
-                            self.state = Some((
-                                State::DerefedBorrow(DerefedBorrow {
-                                    count: count - 1,
-                                    msg: "the borrowed expression implements the required traits",
-                                    stability: TyCoercionStability::None,
-                                    for_field_access: None,
-                                }),
-                                StateData {
-                                    span: expr.span,
-                                    hir_id: expr.hir_id,
-                                    adjusted_ty: use_cx.adjustments.last().map_or(expr_ty, |a| a.target),
-                                },
-                            ));
-                            return;
-                        }
-
                         // Find the number of times the borrow is auto-derefed.
                         let mut iter = use_cx.adjustments.iter();
                         let mut deref_count = 0usize;
@@ -419,7 +338,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                             };
                         };
 
-                        let stability = defined_ty.map_or(TyCoercionStability::None, |ty| {
+                        let stability = use_cx.node.defined_ty(cx).map_or(TyCoercionStability::None, |ty| {
                             TyCoercionStability::for_defined_ty(cx, ty, use_cx.node.is_return())
                         });
                         let can_auto_borrow = match use_cx.node {
@@ -700,12 +619,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
     }
 
     fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
-        if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
-            local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
-        }) {
-            self.possible_borrowers.pop();
-        }
-
         if Some(body.id()) == self.current_body {
             for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {
                 let replacements = pat.replacements;
@@ -729,8 +642,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
             self.current_body = None;
         }
     }
-
-    extract_msrv_attr!(LateContext);
 }
 
 fn try_parse_ref_op<'tcx>(
@@ -788,13 +699,6 @@ fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
     }
 }
 
-fn path_has_args(p: &QPath<'_>) -> bool {
-    match *p {
-        QPath::Resolved(_, Path { segments: [.., s], .. }) | QPath::TypeRelative(_, s) => s.args.is_some(),
-        _ => false,
-    }
-}
-
 fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
     if let Some(parent) = get_parent_expr(cx, e)
         && parent.span.ctxt() == e.span.ctxt()
@@ -980,274 +884,6 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
     v.0
 }
 
-/// Checks for the number of borrow expressions which can be removed from the given expression
-/// where the expression is used as an argument to a function expecting a generic type.
-///
-/// The following constraints will be checked:
-/// * The borrowed expression meets all the generic type's constraints.
-/// * The generic type appears only once in the functions signature.
-/// * The borrowed value will not be moved if it is used later in the function.
-#[expect(clippy::too_many_arguments)]
-fn needless_borrow_generic_arg_count<'tcx>(
-    cx: &LateContext<'tcx>,
-    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
-    fn_id: DefId,
-    callee_args: &'tcx List<GenericArg<'tcx>>,
-    arg_index: usize,
-    param_ty: ParamTy,
-    mut expr: &Expr<'tcx>,
-    msrv: &Msrv,
-) -> usize {
-    let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
-    let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
-
-    let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
-    let predicates = cx.tcx.param_env(fn_id).caller_bounds();
-    let projection_predicates = predicates
-        .iter()
-        .filter_map(|predicate| {
-            if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
-                Some(projection_predicate)
-            } else {
-                None
-            }
-        })
-        .collect::<Vec<_>>();
-
-    let mut trait_with_ref_mut_self_method = false;
-
-    // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.
-    if predicates
-        .iter()
-        .filter_map(|predicate| {
-            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
-                && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
-            {
-                Some(trait_predicate.trait_ref.def_id)
-            } else {
-                None
-            }
-        })
-        .inspect(|trait_def_id| {
-            trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);
-        })
-        .all(|trait_def_id| {
-            Some(trait_def_id) == destruct_trait_def_id
-                || Some(trait_def_id) == sized_trait_def_id
-                || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
-        })
-    {
-        return 0;
-    }
-
-    // See:
-    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
-    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
-    if projection_predicates
-        .iter()
-        .any(|projection_predicate| is_mixed_projection_predicate(cx, fn_id, projection_predicate))
-    {
-        return 0;
-    }
-
-    // `args_with_referent_ty` can be constructed outside of `check_referent` because the same
-    // elements are modified each time `check_referent` is called.
-    let mut args_with_referent_ty = callee_args.to_vec();
-
-    let mut check_reference_and_referent = |reference, referent| {
-        let referent_ty = cx.typeck_results().expr_ty(referent);
-
-        if !is_copy(cx, referent_ty)
-            && (referent_ty.has_significant_drop(cx.tcx, cx.param_env)
-                || !referent_used_exactly_once(cx, possible_borrowers, reference))
-        {
-            return false;
-        }
-
-        // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-        if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
-            return false;
-        }
-
-        if !replace_types(
-            cx,
-            param_ty,
-            referent_ty,
-            fn_sig,
-            arg_index,
-            &projection_predicates,
-            &mut args_with_referent_ty,
-        ) {
-            return false;
-        }
-
-        predicates.iter().all(|predicate| {
-            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
-                && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
-                && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
-                && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack()
-                && ty.is_array()
-                && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
-            {
-                return false;
-            }
-
-            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
-            let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
-            let infcx = cx.tcx.infer_ctxt().build();
-            infcx.predicate_must_hold_modulo_regions(&obligation)
-        })
-    };
-
-    let mut count = 0;
-    while let ExprKind::AddrOf(_, _, referent) = expr.kind {
-        if !check_reference_and_referent(expr, referent) {
-            break;
-        }
-        expr = referent;
-        count += 1;
-    }
-    count
-}
-
-fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
-    cx.tcx
-        .associated_items(trait_def_id)
-        .in_definition_order()
-        .any(|assoc_item| {
-            if assoc_item.fn_has_self_parameter {
-                let self_ty = cx
-                    .tcx
-                    .fn_sig(assoc_item.def_id)
-                    .instantiate_identity()
-                    .skip_binder()
-                    .inputs()[0];
-                matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
-            } else {
-                false
-            }
-        })
-}
-
-fn is_mixed_projection_predicate<'tcx>(
-    cx: &LateContext<'tcx>,
-    callee_def_id: DefId,
-    projection_predicate: &ProjectionPredicate<'tcx>,
-) -> bool {
-    let generics = cx.tcx.generics_of(callee_def_id);
-    // The predicate requires the projected type to equal a type parameter from the parent context.
-    if let Some(term_ty) = projection_predicate.term.ty()
-        && let ty::Param(term_param_ty) = term_ty.kind()
-        && (term_param_ty.index as usize) < generics.parent_count
-    {
-        // The inner-most self type is a type parameter from the current function.
-        let mut projection_ty = projection_predicate.projection_ty;
-        loop {
-            match projection_ty.self_ty().kind() {
-                ty::Alias(ty::Projection, inner_projection_ty) => {
-                    projection_ty = *inner_projection_ty;
-                }
-                ty::Param(param_ty) => {
-                    return (param_ty.index as usize) >= generics.parent_count;
-                }
-                _ => {
-                    return false;
-                }
-            }
-        }
-    } else {
-        false
-    }
-}
-
-fn referent_used_exactly_once<'tcx>(
-    cx: &LateContext<'tcx>,
-    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
-    reference: &Expr<'tcx>,
-) -> bool {
-    if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)
-        && let Some(local) = expr_local(cx.tcx, reference)
-        && let [location] = *local_assignments(mir, local).as_slice()
-        && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
-        && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
-        && !place.is_indirect_first_projection()
-        // Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
-        && TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
-    {
-        let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
-        if possible_borrowers
-            .last()
-            .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id)
-        {
-            possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));
-        }
-        let possible_borrower = &mut possible_borrowers.last_mut().unwrap().1;
-        // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
-        // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
-        // itself. See the comment in that method for an explanation as to why.
-        possible_borrower.bounded_borrowers(&[local], &[local, place.local], place.local, location)
-            && used_exactly_once(mir, place.local).unwrap_or(false)
-    } else {
-        false
-    }
-}
-
-// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
-// projected type that is a type parameter. Returns `false` if replacing the types would have an
-// effect on the function signature beyond substituting `new_ty` for `param_ty`.
-// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
-fn replace_types<'tcx>(
-    cx: &LateContext<'tcx>,
-    param_ty: ParamTy,
-    new_ty: Ty<'tcx>,
-    fn_sig: FnSig<'tcx>,
-    arg_index: usize,
-    projection_predicates: &[ProjectionPredicate<'tcx>],
-    args: &mut [ty::GenericArg<'tcx>],
-) -> bool {
-    let mut replaced = BitSet::new_empty(args.len());
-
-    let mut deque = VecDeque::with_capacity(args.len());
-    deque.push_back((param_ty, new_ty));
-
-    while let Some((param_ty, new_ty)) = deque.pop_front() {
-        // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
-        if !fn_sig
-            .inputs_and_output
-            .iter()
-            .enumerate()
-            .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))
-        {
-            return false;
-        }
-
-        args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
-
-        // The `replaced.insert(...)` check provides some protection against infinite loops.
-        if replaced.insert(param_ty.index) {
-            for projection_predicate in projection_predicates {
-                if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
-                    && let Some(term_ty) = projection_predicate.term.ty()
-                    && let ty::Param(term_param_ty) = term_ty.kind()
-                {
-                    let projection = cx.tcx.mk_ty_from_kind(ty::Alias(
-                        ty::Projection,
-                        projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty),
-                    ));
-
-                    if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
-                        && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
-                    {
-                        deque.push_back((*term_param_ty, projected_ty));
-                    }
-                }
-            }
-        }
-    }
-
-    true
-}
-
 fn ty_contains_field(ty: Ty<'_>, name: Symbol) -> bool {
     if let ty::Adt(adt, _) = *ty.kind() {
         adt.is_struct() && adt.all_fields().any(|f| f.name == name)
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index bf2add6aa64..e789e0da679 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -459,7 +459,7 @@ struct Fragments<'a> {
 
 impl Fragments<'_> {
     fn span(self, cx: &LateContext<'_>, range: Range<usize>) -> Option<Span> {
-        source_span_for_markdown_range(cx.tcx, &self.doc, &range, &self.fragments)
+        source_span_for_markdown_range(cx.tcx, self.doc, &range, self.fragments)
     }
 }
 
@@ -513,6 +513,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
 
 const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail"];
 
+#[allow(clippy::too_many_lines)] // Only a big match statement
 fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(
     cx: &LateContext<'_>,
     valid_idents: &FxHashSet<String>,
diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs
index d4df6f7aa2d..e332f681b6d 100644
--- a/src/tools/clippy/clippy_lints/src/enum_variants.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs
@@ -167,7 +167,10 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n
         return;
     }
 
-    let first = &def.variants[0].ident.name.as_str();
+    let first = match def.variants.first() {
+        Some(variant) => variant.ident.name.as_str(),
+        None => return,
+    };
     let mut pre = camel_case_split(first);
     let mut post = pre.clone();
     post.reverse();
diff --git a/src/tools/clippy/clippy_lints/src/error_impl_error.rs b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
index 379af9b2234..f24577c7382 100644
--- a/src/tools/clippy/clippy_lints/src/error_impl_error.rs
+++ b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
@@ -3,7 +3,6 @@ use clippy_utils::path_res;
 use clippy_utils::ty::implements_trait;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Visibility;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -42,9 +41,10 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
         };
 
         match item.kind {
-            ItemKind::TyAlias(ty, _) if implements_trait(cx, hir_ty_to_ty(cx.tcx, ty), error_def_id, &[])
-                && item.ident.name == sym::Error
-                && is_visible_outside_module(cx, item.owner_id.def_id) =>
+            ItemKind::TyAlias(..) if item.ident.name == sym::Error
+                && is_visible_outside_module(cx, item.owner_id.def_id)
+                && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
+                && implements_trait(cx, ty, error_def_id, &[]) =>
             {
                 span_lint(
                     cx,
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 4b9ca8c917e..b612cc00bf9 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -57,54 +57,52 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
             } else {
                 None
             }
+            && let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root())
         {
-            find_format_args(cx, write_arg, ExpnId::root(), |format_args| {
-                let calling_macro =
-                    // ordering is important here, since `writeln!` uses `write!` internally
-                    if is_expn_of(write_call.span, "writeln").is_some() {
-                        Some("writeln")
-                    } else if is_expn_of(write_call.span, "write").is_some() {
-                        Some("write")
-                    } else {
-                        None
-                    };
-                let prefix = if dest_name == "stderr" {
-                    "e"
-                } else {
-                    ""
-                };
+            // ordering is important here, since `writeln!` uses `write!` internally
+            let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() {
+                Some("writeln")
+            } else if is_expn_of(write_call.span, "write").is_some() {
+                Some("write")
+            } else {
+                None
+            };
+            let prefix = if dest_name == "stderr" {
+                "e"
+            } else {
+                ""
+            };
 
-                // We need to remove the last trailing newline from the string because the
-                // underlying `fmt::write` function doesn't know whether `println!` or `print!` was
-                // used.
-                let (used, sugg_mac) = if let Some(macro_name) = calling_macro {
-                    (
-                        format!("{macro_name}!({dest_name}(), ...)"),
-                        macro_name.replace("write", "print"),
-                    )
-                } else {
-                    (
-                        format!("{dest_name}().write_fmt(...)"),
-                        "print".into(),
-                    )
-                };
-                let mut applicability = Applicability::MachineApplicable;
-                let inputs_snippet = snippet_with_applicability(
-                    cx,
-                    format_args_inputs_span(format_args),
-                    "..",
-                    &mut applicability,
-                );
-                span_lint_and_sugg(
-                    cx,
-                    EXPLICIT_WRITE,
-                    expr.span,
-                    &format!("use of `{used}.unwrap()`"),
-                    "try",
-                    format!("{prefix}{sugg_mac}!({inputs_snippet})"),
-                    applicability,
-                );
-            });
+            // We need to remove the last trailing newline from the string because the
+            // underlying `fmt::write` function doesn't know whether `println!` or `print!` was
+            // used.
+            let (used, sugg_mac) = if let Some(macro_name) = calling_macro {
+                (
+                    format!("{macro_name}!({dest_name}(), ...)"),
+                    macro_name.replace("write", "print"),
+                )
+            } else {
+                (
+                    format!("{dest_name}().write_fmt(...)"),
+                    "print".into(),
+                )
+            };
+            let mut applicability = Applicability::MachineApplicable;
+            let inputs_snippet = snippet_with_applicability(
+                cx,
+                format_args_inputs_span(&format_args),
+                "..",
+                &mut applicability,
+            );
+            span_lint_and_sugg(
+                cx,
+                EXPLICIT_WRITE,
+                expr.span,
+                &format!("use of `{used}.unwrap()`"),
+                "try",
+                format!("{prefix}{sugg_mac}!({inputs_snippet})"),
+                applicability,
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index c18006a71c2..0a885984abb 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -246,8 +246,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for TypeWalker<'cx, 'tcx> {
                 {
                     self.ty_params.remove(&def_id);
                 }
+            } else {
+                // If the bounded type isn't a generic param, but is instead a concrete generic
+                // type, any params we find nested inside of it are being used as concrete types,
+                // and can therefore can be considered used. So, we're fine to walk the left-hand
+                // side of the where bound.
+                walk_ty(self, predicate.bounded_ty);
             }
-            // Only walk the right-hand side of where bounds
             for bound in predicate.bounds {
                 walk_param_bound(self, bound);
             }
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index f4f8bdc2c44..b748d329367 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -43,14 +43,10 @@ declare_lint_pass!(UselessFormat => [USELESS_FORMAT]);
 
 impl<'tcx> LateLintPass<'tcx> for UselessFormat {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
-            return;
-        };
-        if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
-            return;
-        }
-
-        find_format_args(cx, expr, macro_call.expn, |format_args| {
+        if let Some(macro_call) = root_macro_call_first_node(cx, expr)
+            && cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
+            && let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
+        {
             let mut applicability = Applicability::MachineApplicable;
             let call_site = macro_call.span;
 
@@ -91,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
                 },
                 _ => {},
             }
-        });
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 01c714c414b..39abf5c2def 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -186,15 +186,10 @@ impl FormatArgs {
 
 impl<'tcx> LateLintPass<'tcx> for FormatArgs {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
-            return;
-        };
-        if !is_format_macro(cx, macro_call.def_id) {
-            return;
-        }
-        let name = cx.tcx.item_name(macro_call.def_id);
-
-        find_format_args(cx, expr, macro_call.expn, |format_args| {
+        if let Some(macro_call) = root_macro_call_first_node(cx, expr)
+            && is_format_macro(cx, macro_call.def_id)
+            && let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
+        {
             for piece in &format_args.template {
                 if let FormatArgsPiece::Placeholder(placeholder) = piece
                     && let Ok(index) = placeholder.argument.index
@@ -206,12 +201,13 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
 
                     if placeholder.format_trait != FormatTrait::Display
                         || placeholder.format_options != FormatOptions::default()
-                        || is_aliased(format_args, index)
+                        || is_aliased(&format_args, index)
                     {
                         continue;
                     }
 
                     if let Ok(arg_hir_expr) = arg_expr {
+                        let name = cx.tcx.item_name(macro_call.def_id);
                         check_format_in_format_args(cx, macro_call.span, name, arg_hir_expr);
                         check_to_string_in_format_args(cx, name, arg_hir_expr);
                     }
@@ -219,9 +215,9 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
             }
 
             if self.msrv.meets(msrvs::FORMAT_ARGS_CAPTURE) {
-                check_uninlined_args(cx, format_args, macro_call.span, macro_call.def_id, self.ignore_mixed);
+                check_uninlined_args(cx, &format_args, macro_call.span, macro_call.def_id, self.ignore_mixed);
             }
-        });
+        }
     }
 
     extract_msrv_attr!(LateContext);
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index 76369bccf9e..1d2f7cb7130 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -170,30 +170,29 @@ fn check_self_in_format_args<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>,
     if let Some(outer_macro) = root_macro_call_first_node(cx, expr)
         && let macro_def_id = outer_macro.def_id
         && is_format_macro(cx, macro_def_id)
+        && let Some(format_args) = find_format_args(cx, expr, outer_macro.expn)
     {
-        find_format_args(cx, expr, outer_macro.expn, |format_args| {
-            for piece in &format_args.template {
-                if let FormatArgsPiece::Placeholder(placeholder) = piece
-                    && let trait_name = match placeholder.format_trait {
-                        FormatTrait::Display => sym::Display,
-                        FormatTrait::Debug => sym::Debug,
-                        FormatTrait::LowerExp => sym!(LowerExp),
-                        FormatTrait::UpperExp => sym!(UpperExp),
-                        FormatTrait::Octal => sym!(Octal),
-                        FormatTrait::Pointer => sym::Pointer,
-                        FormatTrait::Binary => sym!(Binary),
-                        FormatTrait::LowerHex => sym!(LowerHex),
-                        FormatTrait::UpperHex => sym!(UpperHex),
-                    }
-                    && trait_name == impl_trait.name
-                    && let Ok(index) = placeholder.argument.index
-                    && let Some(arg) = format_args.arguments.all_args().get(index)
-                    && let Ok(arg_expr) = find_format_arg_expr(expr, arg)
-                {
-                    check_format_arg_self(cx, expr.span, arg_expr, impl_trait);
+        for piece in &format_args.template {
+            if let FormatArgsPiece::Placeholder(placeholder) = piece
+                && let trait_name = match placeholder.format_trait {
+                    FormatTrait::Display => sym::Display,
+                    FormatTrait::Debug => sym::Debug,
+                    FormatTrait::LowerExp => sym!(LowerExp),
+                    FormatTrait::UpperExp => sym!(UpperExp),
+                    FormatTrait::Octal => sym!(Octal),
+                    FormatTrait::Pointer => sym::Pointer,
+                    FormatTrait::Binary => sym!(Binary),
+                    FormatTrait::LowerHex => sym!(LowerHex),
+                    FormatTrait::UpperHex => sym!(UpperHex),
                 }
+                && trait_name == impl_trait.name
+                && let Ok(index) = placeholder.argument.index
+                && let Some(arg) = format_args.arguments.all_args().get(index)
+                && let Ok(arg_expr) = find_format_arg_expr(expr, arg)
+            {
+                check_format_arg_self(cx, expr.span, arg_expr, impl_trait);
             }
-        });
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
index b00fa104f98..f95d2c2edb1 100644
--- a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
+++ b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
@@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for NumberedFields {
                 && fields
                     .iter()
                     .all(|f| f.ident.as_str().as_bytes().iter().all(u8::is_ascii_digit))
-                && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias { .. }, ..))
+                && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias, ..))
             {
                 let expr_spans = fields
                     .iter()
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index 9b26c3573e1..a4f3d498345 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, ConstKind};
@@ -50,12 +49,12 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if_chain! {
             if !item.span.from_expansion();
-            if let ItemKind::Const(hir_ty, generics, _) = &item.kind;
+            if let ItemKind::Const(_, generics, _) = &item.kind;
             // Since static items may not have generics, skip generic const items.
             // FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it
             // doesn't account for empty where-clauses that only consist of keyword `where` IINM.
             if generics.params.is_empty() && !generics.has_where_clause_predicates;
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+            let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
             if let ty::Array(element_type, cst) = ty.kind();
             if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind();
             if let Ok(element_count) = element_count.try_to_target_usize(cx.tcx);
diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs
index d67d5899350..19f1e08b57a 100644
--- a/src/tools/clippy/clippy_lints/src/large_futures.rs
+++ b/src/tools/clippy/clippy_lints/src/large_futures.rs
@@ -17,26 +17,20 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```rust
-    /// async fn wait(f: impl std::future::Future<Output = ()>) {}
+    /// async fn large_future(_x: [u8; 16 * 1024]) {}
     ///
-    /// async fn big_fut(arg: [u8; 1024]) {}
-    ///
-    /// pub async fn test() {
-    ///     let fut = big_fut([0u8; 1024]);
-    ///     wait(fut).await;
+    /// pub async fn trigger() {
+    ///     large_future([0u8; 16 * 1024]).await;
     /// }
     /// ```
     ///
     /// `Box::pin` the big future instead.
     ///
     /// ```rust
-    /// async fn wait(f: impl std::future::Future<Output = ()>) {}
-    ///
-    /// async fn big_fut(arg: [u8; 1024]) {}
+    /// async fn large_future(_x: [u8; 16 * 1024]) {}
     ///
-    /// pub async fn test() {
-    ///     let fut = Box::pin(big_fut([0u8; 1024]));
-    ///     wait(fut).await;
+    /// pub async fn trigger() {
+    ///     Box::pin(large_future([0u8; 16 * 1024])).await;
     /// }
     /// ```
     #[clippy::version = "1.70.0"]
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index deba232bdd2..c06b35ca0da 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -424,6 +424,14 @@ fn check_for_is_empty(
     item_name: Symbol,
     item_kind: &str,
 ) {
+    // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to
+    // find the correct inherent impls.
+    let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() {
+        adt.did()
+    } else {
+        return;
+    };
+
     let is_empty = Symbol::intern("is_empty");
     let is_empty = cx
         .tcx
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index f52614b6208..1271be2fd93 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -230,6 +230,7 @@ mod mutex_atomic;
 mod needless_arbitrary_self_type;
 mod needless_bool;
 mod needless_borrowed_ref;
+mod needless_borrows_for_generic_args;
 mod needless_continue;
 mod needless_else;
 mod needless_for_each;
@@ -331,6 +332,7 @@ mod unit_return_expecting_ord;
 mod unit_types;
 mod unnamed_address;
 mod unnecessary_box_returns;
+mod unnecessary_map_on_constructor;
 mod unnecessary_owned_empty_strings;
 mod unnecessary_self_imports;
 mod unnecessary_struct_initialization;
@@ -610,7 +612,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
                 .collect(),
         ))
     });
-    store.register_early_pass(|| Box::new(utils::format_args_collector::FormatArgsCollector));
+    store.register_early_pass(|| Box::<utils::format_args_collector::FormatArgsCollector>::default());
     store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
     store.register_late_pass(|_| Box::new(utils::author::Author));
     let await_holding_invalid_types = conf.await_holding_invalid_types.clone();
@@ -637,7 +639,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
     store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
     store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
-    store.register_late_pass(|_| Box::<misc::LintPass>::default());
+    store.register_late_pass(|_| Box::new(misc::LintPass));
     store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
     store.register_late_pass(|_| Box::new(mut_mut::MutMut));
     store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
@@ -663,12 +665,19 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
     let suppress_restriction_lint_in_const = conf.suppress_restriction_lint_in_const;
     store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv())));
+    let allowed_dotfiles = conf
+        .allowed_dotfiles
+        .iter()
+        .cloned()
+        .chain(methods::DEFAULT_ALLOWED_DOTFILES.iter().copied().map(ToOwned::to_owned))
+        .collect::<FxHashSet<_>>();
     store.register_late_pass(move |_| {
         Box::new(methods::Methods::new(
             avoid_breaking_exported_api,
             msrv(),
             allow_expect_in_tests,
             allow_unwrap_in_tests,
+            allowed_dotfiles.clone(),
         ))
     });
     store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv())));
@@ -881,7 +890,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
     store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
     store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
-    store.register_late_pass(move |_| Box::new(dereference::Dereferencing::new(msrv())));
+    store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
     store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
     store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
     let future_size_threshold = conf.future_size_threshold;
@@ -1104,6 +1113,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::<reserve_after_initialization::ReserveAfterInitialization>::default());
     store.register_late_pass(|_| Box::new(implied_bounds_in_impls::ImpliedBoundsInImpls));
     store.register_late_pass(|_| Box::new(missing_asserts_for_indexing::MissingAssertsForIndexing));
+    store.register_late_pass(|_| Box::new(unnecessary_map_on_constructor::UnnecessaryMapOnConstructor));
+    store.register_late_pass(move |_| {
+        Box::new(needless_borrows_for_generic_args::NeedlessBorrowsForGenericArgs::new(
+            msrv(),
+        ))
+    });
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs
index 6edca2d55f6..0a2bd89eb3c 100644
--- a/src/tools/clippy/clippy_lints/src/loops/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs
@@ -5,7 +5,6 @@ use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, walk_local, walk_pat, walk_stmt, Visitor};
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, Pat, PatKind, Stmt};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty};
@@ -150,7 +149,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
             if l.pat.hir_id == self.var_id;
             if let PatKind::Binding(.., ident, _) = l.pat.kind;
             then {
-                let ty = l.ty.map(|ty| hir_ty_to_ty(self.cx.tcx, ty));
+                let ty = l.ty.map(|_| self.cx.typeck_results().pat_ty(l.pat));
 
                 self.state = l.init.map_or(InitializeVisitorState::Declared(ident.name, ty), |init| {
                     InitializeVisitorState::Initialized {
diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
index c4f6852aedc..44dc29c36a6 100644
--- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
@@ -8,8 +8,7 @@ use clippy_utils::{
 };
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, Guard, ItemKind, Node, Pat, PatKind, Path, QPath};
 use rustc_lint::LateContext;
 use rustc_span::sym;
 
@@ -141,11 +140,15 @@ fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>
                 return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
             },
             // compare match_expr ty with RetTy in `fn foo() -> RetTy`
-            Node::Item(..) => {
-                if let Some(fn_decl) = p_node.fn_decl() {
-                    if let FnRetTy::Return(ret_ty) = fn_decl.output {
-                        return same_type_and_consts(hir_ty_to_ty(cx.tcx, ret_ty), cx.typeck_results().expr_ty(expr));
-                    }
+            Node::Item(item) => {
+                if let ItemKind::Fn(..) = item.kind {
+                    let output = cx
+                        .tcx
+                        .fn_sig(item.owner_id)
+                        .instantiate_identity()
+                        .output()
+                        .skip_binder();
+                    return same_type_and_consts(output, cx.typeck_results().expr_ty(expr));
                 }
             },
             // check the parent expr for this whole block `{ match match_expr {..} }`
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index 29af4812351..0efeeacc9d9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -2,11 +2,12 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::path_to_local;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::visitors::{for_each_expr, is_local_used};
-use rustc_ast::LitKind;
+use rustc_ast::{BorrowKind, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, Guard, MatchSource, Node, Pat, PatKind};
 use rustc_lint::LateContext;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use std::ops::ControlFlow;
 
@@ -34,32 +35,45 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
                 ],
                 MatchSource::Normal,
             ) = if_expr.kind
+            && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm)
         {
+            let pat_span = match (arm.pat.kind, binding.byref_ident) {
+                (PatKind::Ref(pat, _), Some(_)) => pat.span,
+                (PatKind::Ref(..), None) | (_, Some(_)) => continue,
+                _ => arm.pat.span,
+            };
             emit_redundant_guards(
                 cx,
                 outer_arm,
                 if_expr.span,
-                scrutinee,
-                arm.pat.span,
+                pat_span,
+                &binding,
                 arm.guard,
             );
         }
         // `Some(x) if let Some(2) = x`
-        else if let Guard::IfLet(let_expr) = guard {
+        else if let Guard::IfLet(let_expr) = guard
+            && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm)
+        {
+            let pat_span = match (let_expr.pat.kind, binding.byref_ident) {
+                (PatKind::Ref(pat, _), Some(_)) => pat.span,
+                (PatKind::Ref(..), None) | (_, Some(_)) => continue,
+                _ => let_expr.pat.span,
+            };
             emit_redundant_guards(
                 cx,
                 outer_arm,
                 let_expr.span,
-                let_expr.init,
-                let_expr.pat.span,
+                pat_span,
+                &binding,
                 None,
             );
         }
         // `Some(x) if x == Some(2)`
+        // `Some(x) if Some(2) == x`
         else if let Guard::If(if_expr) = guard
             && let ExprKind::Binary(bin_op, local, pat) = if_expr.kind
             && matches!(bin_op.node, BinOpKind::Eq)
-            && expr_can_be_pat(cx, pat)
             // Ensure they have the same type. If they don't, we'd need deref coercion which isn't
             // possible (currently) in a pattern. In some cases, you can use something like
             // `as_deref` or similar but in general, we shouldn't lint this as it'd create an
@@ -67,43 +81,68 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
             //
             // This isn't necessary in the other two checks, as they must be a pattern already.
             && cx.typeck_results().expr_ty(local) == cx.typeck_results().expr_ty(pat)
+            // Since we want to lint on both `x == Some(2)` and `Some(2) == x`, we might have to "swap"
+            // `local` and `pat`, depending on which side they are.
+            && let Some((binding, pat)) = get_pat_binding(cx, local, outer_arm)
+                .map(|binding| (binding, pat))
+                .or_else(|| get_pat_binding(cx, pat, outer_arm).map(|binding| (binding, local)))
+            && expr_can_be_pat(cx, pat)
         {
+            let pat_span = match (pat.kind, binding.byref_ident) {
+                (ExprKind::AddrOf(BorrowKind::Ref, _, expr), Some(_)) => expr.span,
+                (ExprKind::AddrOf(..), None) | (_, Some(_)) => continue,
+                _ => pat.span,
+            };
             emit_redundant_guards(
                 cx,
                 outer_arm,
                 if_expr.span,
-                local,
-                pat.span,
+                pat_span,
+                &binding,
                 None,
             );
         }
     }
 }
 
-fn get_pat_binding<'tcx>(cx: &LateContext<'tcx>, guard_expr: &Expr<'_>, outer_arm: &Arm<'tcx>) -> Option<(Span, bool)> {
+struct PatBindingInfo {
+    span: Span,
+    byref_ident: Option<Ident>,
+    is_field: bool,
+}
+
+fn get_pat_binding<'tcx>(
+    cx: &LateContext<'tcx>,
+    guard_expr: &Expr<'_>,
+    outer_arm: &Arm<'tcx>,
+) -> Option<PatBindingInfo> {
     if let Some(local) = path_to_local(guard_expr) && !is_local_used(cx, outer_arm.body, local) {
         let mut span = None;
+        let mut byref_ident = None;
         let mut multiple_bindings = false;
         // `each_binding` gives the `HirId` of the `Pat` itself, not the binding
         outer_arm.pat.walk(|pat| {
-            if let PatKind::Binding(_, hir_id, _, _) = pat.kind
+            if let PatKind::Binding(bind_annot, hir_id, ident, _) = pat.kind
                 && hir_id == local
-                && span.replace(pat.span).is_some()
             {
-                multiple_bindings = true;
-                return false;
+                if matches!(bind_annot.0, rustc_ast::ByRef::Yes) {
+                    let _ = byref_ident.insert(ident);
+                }
+                // the second call of `replace()` returns a `Some(span)`, meaning a multi-binding pattern
+                if span.replace(pat.span).is_some() {
+                    multiple_bindings = true;
+                    return false;
+                }
             }
-
             true
         });
 
         // Ignore bindings from or patterns, like `First(x) | Second(x, _) | Third(x, _, _)`
         if !multiple_bindings {
-            return span.map(|span| {
-                (
-                    span,
-                    !matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
-                )
+            return span.map(|span| PatBindingInfo {
+                span,
+                byref_ident,
+                is_field: matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
             });
         }
     }
@@ -115,14 +154,11 @@ fn emit_redundant_guards<'tcx>(
     cx: &LateContext<'tcx>,
     outer_arm: &Arm<'tcx>,
     guard_span: Span,
-    local: &Expr<'_>,
     pat_span: Span,
+    pat_binding: &PatBindingInfo,
     inner_guard: Option<Guard<'_>>,
 ) {
     let mut app = Applicability::MaybeIncorrect;
-    let Some((pat_binding, can_use_shorthand)) = get_pat_binding(cx, local, outer_arm) else {
-        return;
-    };
 
     span_lint_and_then(
         cx,
@@ -131,14 +167,21 @@ fn emit_redundant_guards<'tcx>(
         "redundant guard",
         |diag| {
             let binding_replacement = snippet_with_applicability(cx, pat_span, "<binding_repl>", &mut app);
+            let suggestion_span = match *pat_binding {
+                PatBindingInfo {
+                    span,
+                    byref_ident: Some(ident),
+                    is_field: true,
+                } => (span, format!("{ident}: {binding_replacement}")),
+                PatBindingInfo {
+                    span, is_field: true, ..
+                } => (span.shrink_to_hi(), format!(": {binding_replacement}")),
+                PatBindingInfo { span, .. } => (span, binding_replacement.into_owned()),
+            };
             diag.multipart_suggestion_verbose(
                 "try",
                 vec![
-                    if can_use_shorthand {
-                        (pat_binding, binding_replacement.into_owned())
-                    } else {
-                        (pat_binding.shrink_to_hi(), format!(": {binding_replacement}"))
-                    },
+                    suggestion_span,
                     (
                         guard_span.source_callsite().with_lo(outer_arm.pat.span.hi()),
                         inner_guard.map_or_else(String::new, |guard| {
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
index d3e90e4bba3..40e487bf650 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
@@ -131,13 +131,12 @@ pub(super) fn check<'tcx>(
 
     let mut applicability = Applicability::MachineApplicable;
 
-    //Special handling for `format!` as arg_root
+    // Special handling for `format!` as arg_root
     if let Some(macro_call) = root_macro_call_first_node(cx, arg_root) {
-        if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
-            return;
-        }
-        find_format_args(cx, arg_root, macro_call.expn, |format_args| {
-            let span = format_args_inputs_span(format_args);
+        if cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
+            && let Some(format_args) = find_format_args(cx, arg_root, macro_call.expn)
+        {
+            let span = format_args_inputs_span(&format_args);
             let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
             span_lint_and_sugg(
                 cx,
@@ -148,7 +147,7 @@ pub(super) fn check<'tcx>(
                 format!("unwrap_or_else({closure_args} panic!({sugg}))"),
                 applicability,
             );
-        });
+        }
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index fafc9709770..33657254965 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -8,6 +8,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::Binder;
 use rustc_span::{sym, Span};
 
@@ -36,6 +37,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
         && let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id)
         && match_def_path(cx, def_id, &BOOL_THEN)
         && !is_from_proc_macro(cx, expr)
+        // Count the number of derefs needed to get to the bool because we need those in the suggestion
+        && let needed_derefs = cx.typeck_results().expr_adjustments(recv)
+            .iter()
+            .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
+            .count()
         && let Some(param_snippet) = snippet_opt(cx, param.span)
         && let Some(filter) = snippet_opt(cx, recv.span)
         && let Some(map) = snippet_opt(cx, then_body.span)
@@ -46,7 +52,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
             call_span,
             "usage of `bool::then` in `filter_map`",
             "use `filter` then `map` instead",
-            format!("filter(|&{param_snippet}| {filter}).map(|{param_snippet}| {map})"),
+            format!(
+                "filter(|&{param_snippet}| {derefs}{filter}).map(|{param_snippet}| {map})",
+                derefs="*".repeat(needed_derefs)
+            ),
             Applicability::MachineApplicable,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 81223fa8d95..e7fcef9e9de 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -74,9 +74,11 @@ mod option_map_unwrap_or;
 mod or_fun_call;
 mod or_then_unwrap;
 mod path_buf_push_overwrite;
+mod path_ends_with_ext;
 mod range_zip_with_len;
 mod read_line_without_trim;
 mod readonly_write_lock;
+mod redundant_as_str;
 mod repeat_once;
 mod search_is_some;
 mod seek_from_current;
@@ -120,9 +122,10 @@ use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
 use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
 use if_chain::if_chain;
+pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, TraitRef, Ty};
@@ -3563,11 +3566,77 @@ declare_clippy_lint! {
     "calls to `.take()` or `.skip()` that are out of bounds"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Looks for calls to `Path::ends_with` calls where the argument looks like a file extension.
+    ///
+    /// By default, Clippy has a short list of known filenames that start with a dot
+    /// but aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default.
+    /// The `allowed-dotfiles` configuration can be used to allow additional
+    /// file extensions that Clippy should not lint.
+    ///
+    /// ### Why is this bad?
+    /// This doesn't actually compare file extensions. Rather, `ends_with` compares the given argument
+    /// to the last **component** of the path and checks if it matches exactly.
+    ///
+    /// ### Known issues
+    /// File extensions are often at most three characters long, so this only lints in those cases
+    /// in an attempt to avoid false positives.
+    /// Any extension names longer than that are assumed to likely be real path components and are
+    /// therefore ignored.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use std::path::Path;
+    /// fn is_markdown(path: &Path) -> bool {
+    ///     path.ends_with(".md")
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::path::Path;
+    /// fn is_markdown(path: &Path) -> bool {
+    ///     path.extension().is_some_and(|ext| ext == "md")
+    /// }
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub PATH_ENDS_WITH_EXT,
+    suspicious,
+    "attempting to compare file extensions using `Path::ends_with`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `as_str()` on a `String`` chained with a method available on the `String` itself.
+    ///
+    /// ### Why is this bad?
+    /// The `as_str()` conversion is pointless and can be removed for simplicity and cleanliness.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # #![allow(unused)]
+    /// let owned_string = "This is a string".to_owned();
+    /// owned_string.as_str().as_bytes();
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust
+    /// # #![allow(unused)]
+    /// let owned_string = "This is a string".to_owned();
+    /// owned_string.as_bytes();
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub REDUNDANT_AS_STR,
+    complexity,
+    "`as_str` used to call a method on `str` that is also available on `String`"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Msrv,
     allow_expect_in_tests: bool,
     allow_unwrap_in_tests: bool,
+    allowed_dotfiles: FxHashSet<String>,
 }
 
 impl Methods {
@@ -3577,12 +3646,14 @@ impl Methods {
         msrv: Msrv,
         allow_expect_in_tests: bool,
         allow_unwrap_in_tests: bool,
+        allowed_dotfiles: FxHashSet<String>,
     ) -> Self {
         Self {
             avoid_breaking_exported_api,
             msrv,
             allow_expect_in_tests,
             allow_unwrap_in_tests,
+            allowed_dotfiles,
         }
     }
 }
@@ -3703,6 +3774,8 @@ impl_lint_pass!(Methods => [
     FILTER_MAP_BOOL_THEN,
     READONLY_WRITE_LOCK,
     ITER_OUT_OF_BOUNDS,
+    PATH_ENDS_WITH_EXT,
+    REDUNDANT_AS_STR,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -3852,18 +3925,20 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
         if_chain! {
             if let TraitItemKind::Fn(ref sig, _) = item.kind;
             if sig.decl.implicit_self.has_implicit_self();
-            if let Some(first_arg_ty) = sig.decl.inputs.iter().next();
-
+            if let Some(first_arg_hir_ty) = sig.decl.inputs.first();
+            if let Some(&first_arg_ty) = cx.tcx.fn_sig(item.owner_id)
+                .instantiate_identity()
+                .inputs()
+                .skip_binder()
+                .first();
             then {
-                let first_arg_span = first_arg_ty.span;
-                let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
                 let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty();
                 wrong_self_convention::check(
                     cx,
                     item.ident.name.as_str(),
                     self_ty,
                     first_arg_ty,
-                    first_arg_span,
+                    first_arg_hir_ty.span,
                     false,
                     true,
                 );
@@ -3929,6 +4004,7 @@ impl Methods {
                 ("as_deref" | "as_deref_mut", []) => {
                     needless_option_as_deref::check(cx, expr, recv, name);
                 },
+                ("as_bytes" | "is_empty", []) => if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) { redundant_as_str::check(cx, expr, recv, as_str_span, span); },
                 ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
                 ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
                 ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
@@ -3978,6 +4054,7 @@ impl Methods {
                     if let ExprKind::MethodCall(.., span) = expr.kind {
                         case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg);
                     }
+                    path_ends_with_ext::check(cx, recv, arg, expr, &self.msrv, &self.allowed_dotfiles);
                 },
                 ("expect", [_]) => {
                     match method_call(recv) {
diff --git a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
new file mode 100644
index 00000000000..3347c8c1620
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
@@ -0,0 +1,53 @@
+use super::PATH_ENDS_WITH_EXT;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs;
+use clippy_utils::msrvs::Msrv;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_ast::{LitKind, StrStyle};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+use std::fmt::Write;
+
+pub const DEFAULT_ALLOWED_DOTFILES: &[&str] = &[
+    "git", "svn", "gem", "npm", "vim", "env", "rnd", "ssh", "vnc", "smb", "nvm", "bin",
+];
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    recv: &Expr<'_>,
+    path: &Expr<'_>,
+    expr: &Expr<'_>,
+    msrv: &Msrv,
+    allowed_dotfiles: &FxHashSet<String>,
+) {
+    if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv).peel_refs(), sym::Path)
+        && !path.span.from_expansion()
+        && let ExprKind::Lit(lit) = path.kind
+        && let LitKind::Str(path, StrStyle::Cooked) = lit.node
+        && let Some(path) = path.as_str().strip_prefix('.')
+        && (1..=3).contains(&path.len())
+        && !allowed_dotfiles.contains(path)
+        && path.chars().all(char::is_alphanumeric)
+    {
+        let mut sugg = snippet(cx, recv.span, "..").into_owned();
+        if msrv.meets(msrvs::OPTION_IS_SOME_AND) {
+            let _ = write!(sugg, r#".extension().is_some_and(|ext| ext == "{path}")"#);
+        } else {
+            let _ = write!(sugg, r#".extension().map_or(false, |ext| ext == "{path}")"#);
+        };
+
+        span_lint_and_sugg(
+            cx,
+            PATH_ENDS_WITH_EXT,
+            expr.span,
+            "this looks like a failed attempt at checking for the file extension",
+            "try",
+            sugg,
+            Applicability::MaybeIncorrect
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs b/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs
new file mode 100644
index 00000000000..98cd6afc2b7
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs
@@ -0,0 +1,34 @@
+use super::REDUNDANT_AS_STR;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_middle::query::Key;
+use rustc_span::Span;
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    _expr: &Expr<'_>,
+    recv: &Expr<'_>,
+    as_str_span: Span,
+    other_method_span: Span,
+) {
+    if cx
+        .tcx
+        .lang_items()
+        .string()
+        .is_some_and(|id| Some(id) == cx.typeck_results().expr_ty(recv).ty_adt_id())
+    {
+        let mut applicability = Applicability::MachineApplicable;
+        span_lint_and_sugg(
+            cx,
+            REDUNDANT_AS_STR,
+            as_str_span.to(other_method_span),
+            "this `as_str` is redundant and can be removed as the method immediately following exists on `String` too",
+            "try",
+            snippet_with_applicability(cx, other_method_span, "..", &mut applicability).into_owned(),
+            applicability,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 5c5ee262052..50d6f3b7e55 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -401,7 +401,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                     = get_callee_generic_args_and_args(cx, parent_expr)
                 {
                     // FIXME: the `instantiate_identity()` below seems incorrect, since we eventually
-                    // call `tcx.try_subst_and_normalize_erasing_regions` further down
+                    // call `tcx.try_instantiate_and_normalize_erasing_regions` further down
                     // (i.e., we are explicitly not in the identity context).
                     let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
                     if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
@@ -452,7 +452,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
 
                         let output_ty = fn_sig.output();
                         if output_ty.contains(*param_ty) {
-                            if let Ok(new_ty)  = cx.tcx.try_subst_and_normalize_erasing_regions(
+                            if let Ok(new_ty)  = cx.tcx.try_instantiate_and_normalize_erasing_regions(
                                 new_subst, cx.param_env, EarlyBinder::bind(output_ty)) {
                                 expr = parent_expr;
                                 ty = new_ty;
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index 303f0125690..9c8b47fb303 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -1,24 +1,22 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::source::{snippet, snippet_opt, snippet_with_context};
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::source::{snippet, snippet_with_context};
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{
+    any_parent_is_automatically_derived, fulfill_or_allowed, get_parent_expr, is_lint_allowed, iter_input_pats,
+    last_path_segment, SpanlessEq,
+};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
+use rustc_hir::def::Res;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    self as hir, def, BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, Stmt,
-    StmtKind, TyKind,
+    BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
 };
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::def_id::LocalDefId;
-use rustc_span::hygiene::DesugaringKind;
-use rustc_span::source_map::{ExpnKind, Span};
-
-use clippy_utils::sugg::Sugg;
-use clippy_utils::{
-    get_parent_expr, in_constant, is_integer_literal, is_lint_allowed, is_no_std_crate, iter_input_pats,
-    last_path_segment, SpanlessEq,
-};
+use rustc_span::source_map::Span;
 
 use crate::ref_patterns::REF_PATTERNS;
 
@@ -56,6 +54,7 @@ declare_clippy_lint! {
     style,
     "an entire binding declared as `ref`, in a function argument or a `let` statement"
 }
+
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for the use of bindings with a single leading
@@ -103,51 +102,13 @@ declare_clippy_lint! {
     "using a short circuit boolean condition as a statement"
 }
 
-declare_clippy_lint! {
-    /// ### What it does
-    /// Catch casts from `0` to some pointer type
-    ///
-    /// ### Why is this bad?
-    /// This generally means `null` and is better expressed as
-    /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
-    ///
-    /// ### Example
-    /// ```rust
-    /// let a = 0 as *const u32;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```rust
-    /// let a = std::ptr::null::<u32>();
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub ZERO_PTR,
-    style,
-    "using `0 as *{const, mut} T`"
-}
-
-pub struct LintPass {
-    std_or_core: &'static str,
-}
-impl Default for LintPass {
-    fn default() -> Self {
-        Self { std_or_core: "std" }
-    }
-}
-impl_lint_pass!(LintPass => [
+declare_lint_pass!(LintPass => [
     TOPLEVEL_REF_ARG,
     USED_UNDERSCORE_BINDING,
     SHORT_CIRCUIT_STATEMENT,
-    ZERO_PTR,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for LintPass {
-    fn check_crate(&mut self, cx: &LateContext<'_>) {
-        if is_no_std_crate(cx) {
-            self.std_or_core = "core";
-        }
-    }
-
     fn check_fn(
         &mut self,
         cx: &LateContext<'tcx>,
@@ -253,50 +214,56 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if let ExprKind::Cast(e, ty) = expr.kind {
-            self.check_cast(cx, expr.span, e, ty);
-            return;
-        }
-        if in_attributes_expansion(expr) || expr.span.is_desugaring(DesugaringKind::Await) {
-            // Don't lint things expanded by #[derive(...)], etc or `await` desugaring
+        if in_external_macro(cx.sess(), expr.span)
+            || expr.span.desugaring_kind().is_some()
+            || any_parent_is_automatically_derived(cx.tcx, expr.hir_id)
+        {
             return;
         }
-        let sym;
-        let binding = match expr.kind {
-            ExprKind::Path(ref qpath) if !matches!(qpath, hir::QPath::LangItem(..)) => {
-                let binding = last_path_segment(qpath).ident.as_str();
-                if binding.starts_with('_') &&
-                    !binding.starts_with("__") &&
-                    binding != "_result" && // FIXME: #944
-                    is_used(cx, expr) &&
-                    // don't lint if the declaration is in a macro
-                    non_macro_local(cx, cx.qpath_res(qpath, expr.hir_id))
+        let (definition_hir_id, ident) = match expr.kind {
+            ExprKind::Path(ref qpath) => {
+                if let QPath::Resolved(None, path) = qpath
+                    && let Res::Local(id) = path.res
+                    && is_used(cx, expr)
                 {
-                    Some(binding)
+                    (id, last_path_segment(qpath).ident)
                 } else {
-                    None
+                    return;
                 }
             },
-            ExprKind::Field(_, ident) => {
-                sym = ident.name;
-                let name = sym.as_str();
-                if name.starts_with('_') && !name.starts_with("__") {
-                    Some(name)
+            ExprKind::Field(recv, ident) => {
+                if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def()
+                    && let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name)
+                    && let Some(local_did) = field.did.as_local()
+                    && let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(local_did)
+                    && !cx.tcx.type_of(field.did).skip_binder().is_phantom_data()
+                {
+                    (hir_id, ident)
                 } else {
-                    None
+                    return;
                 }
             },
-            _ => None,
+            _ => return,
         };
-        if let Some(binding) = binding {
-            span_lint(
+
+        let name = ident.name.as_str();
+        if name.starts_with('_')
+            && !name.starts_with("__")
+            && let definition_span = cx.tcx.hir().span(definition_hir_id)
+            && !definition_span.from_expansion()
+            && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id])
+        {
+            span_lint_and_then(
                 cx,
                 USED_UNDERSCORE_BINDING,
                 expr.span,
                 &format!(
-                    "used binding `{binding}` which is prefixed with an underscore. A leading \
+                    "used binding `{name}` which is prefixed with an underscore. A leading \
                      underscore signals that a binding will not be used"
                 ),
+                |diag| {
+                    diag.span_note(definition_span, format!("`{name}` is defined here"));
+                }
             );
         }
     }
@@ -311,50 +278,3 @@ fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         _ => is_used(cx, parent),
     })
 }
-
-/// Tests whether an expression is in a macro expansion (e.g., something
-/// generated by `#[derive(...)]` or the like).
-fn in_attributes_expansion(expr: &Expr<'_>) -> bool {
-    use rustc_span::hygiene::MacroKind;
-    if expr.span.from_expansion() {
-        let data = expr.span.ctxt().outer_expn_data();
-        matches!(data.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, _))
-    } else {
-        false
-    }
-}
-
-/// Tests whether `res` is a variable defined outside a macro.
-fn non_macro_local(cx: &LateContext<'_>, res: def::Res) -> bool {
-    if let def::Res::Local(id) = res {
-        !cx.tcx.hir().span(id).from_expansion()
-    } else {
-        false
-    }
-}
-
-impl LintPass {
-    fn check_cast(&self, cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
-        if_chain! {
-            if let TyKind::Ptr(ref mut_ty) = ty.kind;
-            if is_integer_literal(e, 0);
-            if !in_constant(cx, e.hir_id);
-            then {
-                let (msg, sugg_fn) = match mut_ty.mutbl {
-                    Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
-                    Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
-                };
-
-                let (sugg, appl) = if let TyKind::Infer = mut_ty.ty.kind {
-                    (format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MachineApplicable)
-                } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
-                    (format!("{}::{sugg_fn}::<{mut_ty_snip}>()", self.std_or_core), Applicability::MachineApplicable)
-                } else {
-                    // `MaybeIncorrect` as type inference may not work with the suggested code
-                    (format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MaybeIncorrect)
-                };
-                span_lint_and_sugg(cx, ZERO_PTR, span, msg, "try", sugg, appl);
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 3b7eccad79d..f598a65d2e4 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -7,7 +7,6 @@ use rustc_hir as hir;
 use rustc_hir::def_id::CRATE_DEF_ID;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Constness, FnDecl, GenericParamKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -124,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
             FnKind::Method(_, sig, ..) => {
                 if trait_ref_of_method(cx, def_id).is_some()
                     || already_const(sig.header)
-                    || method_accepts_droppable(cx, sig.decl.inputs)
+                    || method_accepts_droppable(cx, def_id)
                 {
                     return;
                 }
@@ -165,12 +164,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
 
 /// Returns true if any of the method parameters is a type that implements `Drop`. The method
 /// can't be made const then, because `drop` can't be const-evaluated.
-fn method_accepts_droppable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool {
+fn method_accepts_droppable(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
+    let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+
     // If any of the params are droppable, return true
-    param_tys.iter().any(|hir_ty| {
-        let ty_ty = hir_ty_to_ty(cx.tcx, hir_ty);
-        has_drop(cx, ty_ty)
-    })
+    sig.inputs().iter().any(|&ty| has_drop(cx, ty))
 }
 
 // We don't have to lint on something that's already `const`
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
new file mode 100644
index 00000000000..d55c77a92b1
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -0,0 +1,410 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::snippet_with_context;
+use clippy_utils::ty::is_copy;
+use clippy_utils::{expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy, ExprUseNode};
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::{Body, Expr, ExprKind, Mutability, Path, QPath};
+use rustc_index::bit_set::BitSet;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::mir::{Rvalue, StatementKind};
+use rustc_middle::ty::{
+    self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, List, ParamTy, ProjectionPredicate, Ty,
+};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::symbol::sym;
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
+use rustc_trait_selection::traits::{Obligation, ObligationCause};
+use std::collections::VecDeque;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for borrow operations (`&`) that used as a generic argument to a
+    /// function when the borrowed value could be used.
+    ///
+    /// ### Why is this bad?
+    /// Suggests that the receiver of the expression borrows
+    /// the expression.
+    ///
+    /// ### Known problems
+    /// The lint cannot tell when the implementation of a trait
+    /// for `&T` and `T` do different things. Removing a borrow
+    /// in such a case can change the semantics of the code.
+    ///
+    /// ### Example
+    /// ```rust
+    /// fn f(_: impl AsRef<str>) {}
+    ///
+    /// let x = "foo";
+    /// f(&x);
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust
+    /// fn f(_: impl AsRef<str>) {}
+    ///
+    /// let x = "foo";
+    /// f(x);
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub NEEDLESS_BORROWS_FOR_GENERIC_ARGS,
+    style,
+    "taking a reference that is going to be automatically dereferenced"
+}
+
+pub struct NeedlessBorrowsForGenericArgs<'tcx> {
+    /// Stack of (body owner, `PossibleBorrowerMap`) pairs. Used by
+    /// `needless_borrow_impl_arg_position` to determine when a borrowed expression can instead
+    /// be moved.
+    possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+
+    // `IntoIterator` for arrays requires Rust 1.53.
+    msrv: Msrv,
+}
+impl_lint_pass!(NeedlessBorrowsForGenericArgs<'_> => [NEEDLESS_BORROWS_FOR_GENERIC_ARGS]);
+
+impl NeedlessBorrowsForGenericArgs<'_> {
+    #[must_use]
+    pub fn new(msrv: Msrv) -> Self {
+        Self {
+            possible_borrowers: Vec::new(),
+            msrv,
+        }
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if matches!(expr.kind, ExprKind::AddrOf(..))
+            && !expr.span.from_expansion()
+            && let Some(use_cx) = expr_use_ctxt(cx, expr)
+            && !use_cx.is_ty_unified
+            && let Some(DefinedTy::Mir(ty)) = use_cx.node.defined_ty(cx)
+            && let ty::Param(ty) = *ty.value.skip_binder().kind()
+            && let Some((hir_id, fn_id, i)) = match use_cx.node {
+                ExprUseNode::MethodArg(_, _, 0) => None,
+                ExprUseNode::MethodArg(hir_id, None, i) => {
+                    cx.typeck_results().type_dependent_def_id(hir_id).map(|id| (hir_id, id, i))
+                },
+                ExprUseNode::FnArg(&Expr { kind: ExprKind::Path(ref p), hir_id, .. }, i)
+                if !path_has_args(p) => match cx.typeck_results().qpath_res(p, hir_id) {
+                    Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => {
+                        Some((hir_id, id, i))
+                    },
+                    _ => None,
+                },
+                _ => None,
+            } && let count = needless_borrow_count(
+                cx,
+                &mut self.possible_borrowers,
+                fn_id,
+                cx.typeck_results().node_args(hir_id),
+                i,
+                ty,
+                expr,
+                &self.msrv,
+            ) && count != 0
+        {
+            span_lint_and_then(
+                cx,
+                NEEDLESS_BORROWS_FOR_GENERIC_ARGS,
+                expr.span,
+                "the borrowed expression implements the required traits",
+                |diag| {
+                    let mut app = Applicability::MachineApplicable;
+                    let snip_span = peel_n_hir_expr_refs(expr, count).0.span;
+                    let snip = snippet_with_context(cx, snip_span, expr.span.ctxt(), "..", &mut app).0;
+                    diag.span_suggestion(expr.span, "change this to", snip.into_owned(), app);
+                }
+            );
+        }
+    }
+
+    fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
+        if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
+            local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
+        }) {
+            self.possible_borrowers.pop();
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
+
+fn path_has_args(p: &QPath<'_>) -> bool {
+    match *p {
+        QPath::Resolved(_, Path { segments: [.., s], .. }) | QPath::TypeRelative(_, s) => s.args.is_some(),
+        _ => false,
+    }
+}
+
+/// Checks for the number of borrow expressions which can be removed from the given expression
+/// where the expression is used as an argument to a function expecting a generic type.
+///
+/// The following constraints will be checked:
+/// * The borrowed expression meets all the generic type's constraints.
+/// * The generic type appears only once in the functions signature.
+/// * The borrowed value will not be moved if it is used later in the function.
+#[expect(clippy::too_many_arguments)]
+fn needless_borrow_count<'tcx>(
+    cx: &LateContext<'tcx>,
+    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+    fn_id: DefId,
+    callee_args: &'tcx List<GenericArg<'tcx>>,
+    arg_index: usize,
+    param_ty: ParamTy,
+    mut expr: &Expr<'tcx>,
+    msrv: &Msrv,
+) -> usize {
+    let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
+    let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
+
+    let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
+    let predicates = cx.tcx.param_env(fn_id).caller_bounds();
+    let projection_predicates = predicates
+        .iter()
+        .filter_map(|predicate| {
+            if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
+                Some(projection_predicate)
+            } else {
+                None
+            }
+        })
+        .collect::<Vec<_>>();
+
+    let mut trait_with_ref_mut_self_method = false;
+
+    // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.
+    if predicates
+        .iter()
+        .filter_map(|predicate| {
+            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+                && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
+            {
+                Some(trait_predicate.trait_ref.def_id)
+            } else {
+                None
+            }
+        })
+        .inspect(|trait_def_id| {
+            trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);
+        })
+        .all(|trait_def_id| {
+            Some(trait_def_id) == destruct_trait_def_id
+                || Some(trait_def_id) == sized_trait_def_id
+                || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
+        })
+    {
+        return 0;
+    }
+
+    // See:
+    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
+    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
+    if projection_predicates
+        .iter()
+        .any(|projection_predicate| is_mixed_projection_predicate(cx, fn_id, projection_predicate))
+    {
+        return 0;
+    }
+
+    // `args_with_referent_ty` can be constructed outside of `check_referent` because the same
+    // elements are modified each time `check_referent` is called.
+    let mut args_with_referent_ty = callee_args.to_vec();
+
+    let mut check_reference_and_referent = |reference, referent| {
+        let referent_ty = cx.typeck_results().expr_ty(referent);
+
+        if !is_copy(cx, referent_ty)
+            && (referent_ty.has_significant_drop(cx.tcx, cx.param_env)
+                || !referent_used_exactly_once(cx, possible_borrowers, reference))
+        {
+            return false;
+        }
+
+        // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+        if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
+            return false;
+        }
+
+        if !replace_types(
+            cx,
+            param_ty,
+            referent_ty,
+            fn_sig,
+            arg_index,
+            &projection_predicates,
+            &mut args_with_referent_ty,
+        ) {
+            return false;
+        }
+
+        predicates.iter().all(|predicate| {
+            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+                && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
+                && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
+                && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack()
+                && ty.is_array()
+                && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
+            {
+                return false;
+            }
+
+            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
+            let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
+            let infcx = cx.tcx.infer_ctxt().build();
+            infcx.predicate_must_hold_modulo_regions(&obligation)
+        })
+    };
+
+    let mut count = 0;
+    while let ExprKind::AddrOf(_, _, referent) = expr.kind {
+        if !check_reference_and_referent(expr, referent) {
+            break;
+        }
+        expr = referent;
+        count += 1;
+    }
+    count
+}
+
+fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
+    cx.tcx
+        .associated_items(trait_def_id)
+        .in_definition_order()
+        .any(|assoc_item| {
+            if assoc_item.fn_has_self_parameter {
+                let self_ty = cx
+                    .tcx
+                    .fn_sig(assoc_item.def_id)
+                    .instantiate_identity()
+                    .skip_binder()
+                    .inputs()[0];
+                matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
+            } else {
+                false
+            }
+        })
+}
+
+fn is_mixed_projection_predicate<'tcx>(
+    cx: &LateContext<'tcx>,
+    callee_def_id: DefId,
+    projection_predicate: &ProjectionPredicate<'tcx>,
+) -> bool {
+    let generics = cx.tcx.generics_of(callee_def_id);
+    // The predicate requires the projected type to equal a type parameter from the parent context.
+    if let Some(term_ty) = projection_predicate.term.ty()
+        && let ty::Param(term_param_ty) = term_ty.kind()
+        && (term_param_ty.index as usize) < generics.parent_count
+    {
+        // The inner-most self type is a type parameter from the current function.
+        let mut projection_ty = projection_predicate.projection_ty;
+        loop {
+            match projection_ty.self_ty().kind() {
+                ty::Alias(ty::Projection, inner_projection_ty) => {
+                    projection_ty = *inner_projection_ty;
+                }
+                ty::Param(param_ty) => {
+                    return (param_ty.index as usize) >= generics.parent_count;
+                }
+                _ => {
+                    return false;
+                }
+            }
+        }
+    } else {
+        false
+    }
+}
+
+fn referent_used_exactly_once<'tcx>(
+    cx: &LateContext<'tcx>,
+    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+    reference: &Expr<'tcx>,
+) -> bool {
+    if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)
+        && let Some(local) = expr_local(cx.tcx, reference)
+        && let [location] = *local_assignments(mir, local).as_slice()
+        && let block_data = &mir.basic_blocks[location.block]
+        && let Some(statement) = block_data.statements.get(location.statement_index)
+        && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
+        && !place.is_indirect_first_projection()
+    {
+        let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
+        if possible_borrowers
+            .last()
+            .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id)
+        {
+            possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));
+        }
+        let possible_borrower = &mut possible_borrowers.last_mut().unwrap().1;
+        // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
+        // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
+        // itself. See the comment in that method for an explanation as to why.
+        possible_borrower.bounded_borrowers(&[local], &[local, place.local], place.local, location)
+            && used_exactly_once(mir, place.local).unwrap_or(false)
+    } else {
+        false
+    }
+}
+
+// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
+// projected type that is a type parameter. Returns `false` if replacing the types would have an
+// effect on the function signature beyond substituting `new_ty` for `param_ty`.
+// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
+fn replace_types<'tcx>(
+    cx: &LateContext<'tcx>,
+    param_ty: ParamTy,
+    new_ty: Ty<'tcx>,
+    fn_sig: FnSig<'tcx>,
+    arg_index: usize,
+    projection_predicates: &[ProjectionPredicate<'tcx>],
+    args: &mut [ty::GenericArg<'tcx>],
+) -> bool {
+    let mut replaced = BitSet::new_empty(args.len());
+
+    let mut deque = VecDeque::with_capacity(args.len());
+    deque.push_back((param_ty, new_ty));
+
+    while let Some((param_ty, new_ty)) = deque.pop_front() {
+        // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
+        if !fn_sig
+            .inputs_and_output
+            .iter()
+            .enumerate()
+            .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))
+        {
+            return false;
+        }
+
+        args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
+
+        // The `replaced.insert(...)` check provides some protection against infinite loops.
+        if replaced.insert(param_ty.index) {
+            for projection_predicate in projection_predicates {
+                if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
+                    && let Some(term_ty) = projection_predicate.term.ty()
+                    && let ty::Param(term_param_ty) = term_ty.kind()
+                {
+                    let projection = cx.tcx.mk_ty_from_kind(ty::Alias(
+                        ty::Projection,
+                        projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty),
+                    ));
+
+                    if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
+                        && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
+                    {
+                        deque.push_back((*term_param_ty, projected_ty));
+                    }
+                }
+            }
+        }
+    }
+
+    true
+}
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 7b00eabf97b..57652e5ff54 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -1,6 +1,7 @@
 use super::needless_pass_by_value::requires_exact_signature;
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet;
+use clippy_utils::visitors::for_each_expr_with_closures;
 use clippy_utils::{get_parent_node, inherits_cfg, is_from_proc_macro, is_self};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::Applicability;
@@ -9,7 +10,7 @@ use rustc_hir::{
     Body, Closure, Expr, ExprKind, FnDecl, HirId, HirIdMap, HirIdSet, Impl, ItemKind, Mutability, Node, PatKind, QPath,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
-use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::map::associated_body;
 use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -21,6 +22,8 @@ use rustc_span::symbol::kw;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
+use core::ops::ControlFlow;
+
 declare_clippy_lint! {
     /// ### What it does
     /// Check if a `&mut` function argument is actually used mutably.
@@ -95,6 +98,30 @@ fn should_skip<'tcx>(
     is_from_proc_macro(cx, &input)
 }
 
+fn check_closures<'tcx>(
+    ctx: &mut MutablyUsedVariablesCtxt<'tcx>,
+    cx: &LateContext<'tcx>,
+    infcx: &InferCtxt<'tcx>,
+    checked_closures: &mut FxHashSet<LocalDefId>,
+    closures: FxHashSet<LocalDefId>,
+) {
+    let hir = cx.tcx.hir();
+    for closure in closures {
+        if !checked_closures.insert(closure) {
+            continue;
+        }
+        ctx.prev_bind = None;
+        ctx.prev_move_to_closure.clear();
+        if let Some(body) = hir
+            .find_by_def_id(closure)
+            .and_then(associated_body)
+            .map(|(_, body_id)| hir.body(body_id))
+        {
+            euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body);
+        }
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
     fn check_fn(
         &mut self,
@@ -161,25 +188,22 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
             euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
             if is_async {
                 let mut checked_closures = FxHashSet::default();
+
+                // We retrieve all the closures declared in the async function because they will
+                // not be found by `euv::Delegate`.
+                let mut closures: FxHashSet<LocalDefId> = FxHashSet::default();
+                for_each_expr_with_closures(cx, body, |expr| {
+                    if let ExprKind::Closure(closure) = expr.kind {
+                        closures.insert(closure.def_id);
+                    }
+                    ControlFlow::<()>::Continue(())
+                });
+                check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures);
+
                 while !ctx.async_closures.is_empty() {
-                    let closures = ctx.async_closures.clone();
+                    let async_closures = ctx.async_closures.clone();
                     ctx.async_closures.clear();
-                    let hir = cx.tcx.hir();
-                    for closure in closures {
-                        if !checked_closures.insert(closure) {
-                            continue;
-                        }
-                        ctx.prev_bind = None;
-                        ctx.prev_move_to_closure.clear();
-                        if let Some(body) = hir
-                            .find_by_def_id(closure)
-                            .and_then(associated_body)
-                            .map(|(_, body_id)| hir.body(body_id))
-                        {
-                            euv::ExprUseVisitor::new(&mut ctx, &infcx, closure, cx.param_env, cx.typeck_results())
-                                .consume_body(body);
-                        }
-                    }
+                    check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures);
                 }
             }
             ctx
@@ -244,6 +268,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
 struct MutablyUsedVariablesCtxt<'tcx> {
     mutably_used_vars: HirIdSet,
     prev_bind: Option<HirId>,
+    /// In async functions, the inner AST is composed of multiple layers until we reach the code
+    /// defined by the user. Because of that, some variables are marked as mutably borrowed even
+    /// though they're not. This field lists the `HirId` that should not be considered as mutable
+    /// use of a variable.
     prev_move_to_closure: HirIdSet,
     aliases: HirIdMap<HirId>,
     async_closures: FxHashSet<LocalDefId>,
@@ -308,7 +336,12 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
     fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId, borrow: ty::BorrowKind) {
         self.prev_bind = None;
         if let euv::Place {
-            base: euv::PlaceBase::Local(vid),
+            base:
+                euv::PlaceBase::Local(vid)
+                | euv::PlaceBase::Upvar(UpvarId {
+                    var_path: UpvarPath { hir_id: vid },
+                    ..
+                }),
             base_ty,
             ..
         } = &cmt.place
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 5f2a324b05f..aee184252fb 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -5,10 +5,8 @@ use clippy_utils::{get_parent_node, is_lint_allowed, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, FnRetTy, ItemKind, Node, PatKind, Stmt, StmtKind,
-    UnsafeSource,
+    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, ItemKind, Node, PatKind, Stmt, StmtKind, UnsafeSource,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -99,14 +97,13 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
                 |diag| {
                     for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
                         if let Node::Item(item) = parent.1
-                            && let ItemKind::Fn(sig, ..) = item.kind
-                            && let FnRetTy::Return(ret_ty) = sig.decl.output
+                            && let ItemKind::Fn(..) = item.kind
                             && let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
                             && let [.., final_stmt] = block.stmts
                             && final_stmt.hir_id == stmt.hir_id
                         {
                             let expr_ty = cx.typeck_results().expr_ty(expr);
-                            let mut ret_ty = hir_ty_to_ty(cx.tcx, ret_ty);
+                            let mut ret_ty = cx.tcx.fn_sig(item.owner_id).instantiate_identity().output().skip_binder();
 
                             // Remove `impl Future<Output = T>` to get `T`
                             if cx.tcx.ty_is_opaque_future(ret_ty) &&
@@ -115,7 +112,7 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
                                 ret_ty = true_ret_ty;
                             }
 
-                            if ret_ty == expr_ty {
+                            if !ret_ty.is_unit() && ret_ty == expr_ty {
                                 diag.span_suggestion(
                                     stmt.span.shrink_to_lo(),
                                     "did you mean to return it?",
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 4b24f059afd..20b4b4f03ed 100644
--- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -4,7 +4,7 @@ use clippy_utils::ty::implements_trait;
 use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, match_def_path, path_res, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, ItemKind, LangItem, Node, UnOp};
+use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::EarlyBinder;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -122,9 +122,6 @@ impl LateLintPass<'_> for NonCanonicalImpls {
         if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) {
             return;
         }
-        let ItemKind::Impl(_) = item.kind else {
-            return;
-        };
         let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else {
             return;
         };
@@ -180,17 +177,8 @@ impl LateLintPass<'_> for NonCanonicalImpls {
 
         if cx.tcx.is_diagnostic_item(sym::PartialOrd, trait_impl.def_id)
             && impl_item.ident.name == sym::partial_cmp
-            && let Some(ord_def_id) = cx
-                .tcx
-                .diagnostic_items(trait_impl.def_id.krate)
-                .name_to_id
-                .get(&sym::Ord)
-            && implements_trait(
-                    cx,
-                    trait_impl.self_ty(),
-                    *ord_def_id,
-                    &[],
-                )
+            && let Some(ord_def_id) = cx.tcx.get_diagnostic_item(sym::Ord)
+            && implements_trait(cx, trait_impl.self_ty(), ord_def_id, &[])
         {
             // If the `cmp` call likely needs to be fully qualified in the suggestion
             // (like `std::cmp::Ord::cmp`). It's unfortunate we must put this here but we can't
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 88466333787..2b4e3260c56 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -13,7 +13,6 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{
     BodyId, Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass, Lint};
 use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
 use rustc_middle::ty::adjustment::Adjust;
@@ -297,8 +296,8 @@ declare_lint_pass!(NonCopyConst => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTER
 
 impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
     fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) {
-        if let ItemKind::Const(hir_ty, _generics, body_id) = it.kind {
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+        if let ItemKind::Const(.., body_id) = it.kind {
+            let ty = cx.tcx.type_of(it.owner_id).instantiate_identity();
             if !ignored_macro(cx, it) && is_unfrozen(cx, ty) && is_value_unfrozen_poly(cx, body_id, ty) {
                 lint(cx, Source::Item { item: it.span });
             }
@@ -306,8 +305,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) {
-        if let TraitItemKind::Const(hir_ty, body_id_opt) = &trait_item.kind {
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+        if let TraitItemKind::Const(_, body_id_opt) = &trait_item.kind {
+            let ty = cx.tcx.type_of(trait_item.owner_id).instantiate_identity();
 
             // Normalize assoc types because ones originated from generic params
             // bounded other traits could have their bound.
@@ -333,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
-        if let ImplItemKind::Const(hir_ty, body_id) = &impl_item.kind {
+        if let ImplItemKind::Const(_, body_id) = &impl_item.kind {
             let item_def_id = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
             let item = cx.tcx.hir().expect_item(item_def_id);
 
@@ -366,7 +365,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                             // we should use here as a frozen variant is a potential to be frozen
                             // similar to unknown layouts.
                             // e.g. `layout_of(...).is_err() || has_frozen_variant(...);`
-                        let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+                        let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
                         let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
                         if is_unfrozen(cx, normalized);
                         if is_value_unfrozen_poly(cx, *body_id, normalized);
@@ -381,7 +380,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                     }
                 },
                 ItemKind::Impl(Impl { of_trait: None, .. }) => {
-                    let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+                    let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
                     // Normalize assoc types originated from generic params.
                     let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
 
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index bf031ac8454..7dabdcd58ec 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -16,7 +16,6 @@ use rustc_hir::{
     ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind,
     TyKind, Unsafety,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{Obligation, ObligationCause};
 use rustc_lint::{LateContext, LateLintPass};
@@ -172,13 +171,8 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
             for arg in check_fn_args(
                 cx,
-                cx.tcx
-                    .fn_sig(item.owner_id)
-                    .instantiate_identity()
-                    .skip_binder()
-                    .inputs(),
+                cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder(),
                 sig.decl.inputs,
-                &sig.decl.output,
                 &[],
             )
             .filter(|arg| arg.mutability() == Mutability::Not)
@@ -237,7 +231,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
         let decl = sig.decl;
         let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder();
-        let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params)
+        let lint_args: Vec<_> = check_fn_args(cx, sig, decl.inputs, body.params)
             .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)
             .collect();
         let results = check_ptr_arg_usage(cx, body, &lint_args);
@@ -443,12 +437,13 @@ impl<'tcx> DerefTy<'tcx> {
 #[expect(clippy::too_many_lines)]
 fn check_fn_args<'cx, 'tcx: 'cx>(
     cx: &'cx LateContext<'tcx>,
-    tys: &'tcx [Ty<'tcx>],
+    fn_sig: ty::FnSig<'tcx>,
     hir_tys: &'tcx [hir::Ty<'tcx>],
-    ret_ty: &'tcx FnRetTy<'tcx>,
     params: &'tcx [Param<'tcx>],
 ) -> impl Iterator<Item = PtrArg<'tcx>> + 'cx {
-    tys.iter()
+    fn_sig
+        .inputs()
+        .iter()
         .zip(hir_tys.iter())
         .enumerate()
         .filter_map(move |(i, (ty, hir_ty))| {
@@ -494,9 +489,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                                 })
                             {
                                 if !lifetime.is_anonymous()
-                                    && let FnRetTy::Return(ret_ty) = ret_ty
-                                    && let ret_ty = hir_ty_to_ty(cx.tcx, ret_ty)
-                                    && ret_ty
+                                    && fn_sig.output()
                                         .walk()
                                         .filter_map(|arg| {
                                             arg.as_region().and_then(|lifetime| {
diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs
index e8018462d75..2895595e039 100644
--- a/src/tools/clippy/clippy_lints/src/raw_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs
@@ -93,7 +93,7 @@ impl EarlyLintPass for RawStrings {
                             diag.span_suggestion(
                                 start,
                                 "use a string literal instead",
-                                format!("\"{}\"", str),
+                                format!("\"{str}\""),
                                 Applicability::MachineApplicable,
                             );
                         } else {
@@ -105,8 +105,9 @@ impl EarlyLintPass for RawStrings {
                         }
                     },
                 );
-
-                return;
+                if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
+                    return;
+                }
             }
 
             let req = {
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
index 4944381da24..b26365e34ab 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
@@ -28,35 +28,43 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t
         return false;
     }
 
-    match arg.kind {
+    let casts_peeled = peel_casts(arg);
+    match casts_peeled.kind {
         // Catching:
         // transmute over constants that resolve to `null`.
-        ExprKind::Path(ref _qpath) if matches!(constant(cx, cx.typeck_results(), arg), Some(Constant::RawPtr(0))) => {
+        ExprKind::Path(ref _qpath)
+            if matches!(
+                constant(cx, cx.typeck_results(), casts_peeled),
+                Some(Constant::RawPtr(0))
+            ) =>
+        {
             lint_expr(cx, expr);
             true
         },
-
-        // Catching:
-        // `std::mem::transmute(0 as *const i32)`
-        ExprKind::Cast(inner_expr, _cast_ty) if is_integer_literal(inner_expr, 0) => {
-            lint_expr(cx, expr);
-            true
-        },
-
         // Catching:
         // `std::mem::transmute(std::ptr::null::<i32>())`
         ExprKind::Call(func1, []) if is_path_diagnostic_item(cx, func1, sym::ptr_null) => {
             lint_expr(cx, expr);
             true
         },
-
         _ => {
             // FIXME:
             // Also catch transmutations of variables which are known nulls.
             // To do this, MIR const propagation seems to be the better tool.
             // Whenever MIR const prop routines are more developed, this will
             // become available. As of this writing (25/03/19) it is not yet.
+            if is_integer_literal(casts_peeled, 0) {
+                lint_expr(cx, expr);
+                return true;
+            }
             false
         },
     }
 }
+
+fn peel_casts<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
+    match &expr.kind {
+        ExprKind::Cast(inner_expr, _) => peel_casts(inner_expr),
+        _ => expr,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 79f9d45d597..71a4b3fba1b 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -315,7 +315,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
     fn check_fn(
         &mut self,
         cx: &LateContext<'_>,
-        _: FnKind<'_>,
+        fn_kind: FnKind<'_>,
         decl: &FnDecl<'_>,
         _: &Body<'_>,
         _: Span,
@@ -340,6 +340,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
             CheckTyContext {
                 is_in_trait_impl,
                 is_exported,
+                in_body: matches!(fn_kind, FnKind::Closure),
                 ..CheckTyContext::default()
             },
         );
@@ -427,7 +428,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
                 cx,
                 ty,
                 CheckTyContext {
-                    is_local: true,
+                    in_body: true,
                     ..CheckTyContext::default()
                 },
             );
@@ -481,7 +482,7 @@ impl Types {
         }
 
         match hir_ty.kind {
-            TyKind::Path(ref qpath) if !context.is_local => {
+            TyKind::Path(ref qpath) if !context.in_body => {
                 let hir_id = hir_ty.hir_id;
                 let res = cx.qpath_res(qpath, hir_id);
                 if let Some(def_id) = res.opt_def_id() {
@@ -581,8 +582,8 @@ impl Types {
 #[derive(Clone, Copy, Default)]
 struct CheckTyContext {
     is_in_trait_impl: bool,
-    /// `true` for types on local variables.
-    is_local: bool,
+    /// `true` for types on local variables and in closure signatures.
+    in_body: bool,
     /// `true` for types that are part of the public API.
     is_exported: bool,
     is_nested_call: bool,
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index 704d7abd7e5..e7915953d85 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -7,7 +7,7 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Local, MatchSource, Node, PatKind, QPath, TyKind};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_middle::lint::{in_external_macro, is_from_async_await};
 use rustc_middle::ty;
 
 use super::LET_UNIT_VALUE;
@@ -16,6 +16,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
     if let Some(init) = local.init
         && !local.pat.span.from_expansion()
         && !in_external_macro(cx.sess(), local.span)
+        && !is_from_async_await(local.span)
         && cx.typeck_results().pat_ty(local.pat).is_unit()
     {
         if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer))
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
new file mode 100644
index 00000000000..5aa057580e9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
@@ -0,0 +1,93 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::get_type_diagnostic_name;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Suggest removing the use of a may (or map_err) method when an Option or Result is being construted.
+    ///
+    /// ### Why is this bad?
+    /// It introduces unnecessary complexity. In this case the function can be used directly and
+    /// construct the Option or Result from the output.
+    ///
+    /// ### Example
+    /// ```rust
+    /// Some(4).map(i32::swap_bytes);
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// Some(i32::swap_bytes(4));
+    /// ```
+    #[clippy::version = "1.73.0"]
+    pub UNNECESSARY_MAP_ON_CONSTRUCTOR,
+    complexity,
+    "using `map`/`map_err` on `Option` or `Result` constructors"
+}
+declare_lint_pass!(UnnecessaryMapOnConstructor => [UNNECESSARY_MAP_ON_CONSTRUCTOR]);
+
+impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+        if expr.span.from_expansion() {
+            return;
+        }
+        if let hir::ExprKind::MethodCall(path, recv, args, ..) = expr.kind
+            && let Some(sym::Option | sym::Result) = get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(recv)){
+            let (constructor_path, constructor_item) =
+                if let hir::ExprKind::Call(constructor, constructor_args) = recv.kind
+                    && let hir::ExprKind::Path(constructor_path) = constructor.kind
+                    && let Some(arg) = constructor_args.get(0)
+                {
+                    if constructor.span.from_expansion() || arg.span.from_expansion() {
+                        return;
+                    }
+                    (constructor_path, arg)
+                } else {
+                    return;
+                };
+            let constructor_symbol = match constructor_path {
+                hir::QPath::Resolved(_, path) => {
+                    if let Some(path_segment) = path.segments.last() {
+                        path_segment.ident.name
+                    } else {
+                        return;
+                    }
+                },
+                hir::QPath::TypeRelative(_, path) => path.ident.name,
+                hir::QPath::LangItem(_, _, _) => return,
+            };
+            match constructor_symbol {
+                sym::Some | sym::Ok if path.ident.name == rustc_span::sym::map => (),
+                sym::Err if path.ident.name == sym!(map_err) => (),
+                _ => return,
+            }
+
+            if let Some(map_arg) = args.get(0)
+                && let hir::ExprKind::Path(fun) = map_arg.kind
+            {
+                if map_arg.span.from_expansion() {
+                    return;
+                }
+                let mut applicability = Applicability::MachineApplicable;
+                let fun_snippet = snippet_with_applicability(cx, fun.span(), "_", &mut applicability);
+                let constructor_snippet =
+                    snippet_with_applicability(cx, constructor_path.span(), "_", &mut applicability);
+                let constructor_arg_snippet =
+                    snippet_with_applicability(cx, constructor_item.span, "_", &mut applicability);
+                span_lint_and_sugg(
+                    cx,
+                    UNNECESSARY_MAP_ON_CONSTRUCTOR,
+                    expr.span,
+                    &format!("unnecessary {} on constructor {constructor_snippet}(_)", path.ident.name),
+                    "try",
+                    format!("{constructor_snippet}({fun_snippet}({constructor_arg_snippet}))"),
+                    applicability,
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 5ac4f0aa46c..f32e7edad6c 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -8,10 +8,14 @@ use rustc_errors::Applicability;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, MatchSource, Node, PatKind};
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::traits::Obligation;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
+use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{sym, Span};
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -61,22 +65,69 @@ impl MethodOrFunction {
     }
 }
 
-/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did`
-fn into_iter_bound(cx: &LateContext<'_>, fn_did: DefId, into_iter_did: DefId, param_index: u32) -> Option<Span> {
-    cx.tcx
-        .predicates_of(fn_did)
-        .predicates
-        .iter()
-        .find_map(|&(ref pred, span)| {
-            if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder()
-                && tr.def_id() == into_iter_did
-                && tr.self_ty().is_param(param_index)
-            {
-                Some(span)
-            } else {
-                None
+/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did`,
+/// iff all of the bounds also hold for the type of the `.into_iter()` receiver.
+/// ```ignore
+/// pub fn foo<I>(i: I)
+/// where I: IntoIterator<Item=i32> + ExactSizeIterator
+///                                   ^^^^^^^^^^^^^^^^^ this extra bound stops us from suggesting to remove `.into_iter()` ...
+/// {
+///     assert_eq!(i.len(), 3);
+/// }
+///
+/// pub fn bar() {
+///     foo([1, 2, 3].into_iter());
+///                  ^^^^^^^^^^^^ ... here, because `[i32; 3]` is not `ExactSizeIterator`
+/// }
+/// ```
+fn into_iter_bound<'tcx>(
+    cx: &LateContext<'tcx>,
+    fn_did: DefId,
+    into_iter_did: DefId,
+    into_iter_receiver: Ty<'tcx>,
+    param_index: u32,
+    node_args: GenericArgsRef<'tcx>,
+) -> Option<Span> {
+    let param_env = cx.tcx.param_env(fn_did);
+    let mut into_iter_span = None;
+
+    for (pred, span) in cx.tcx.explicit_predicates_of(fn_did).predicates {
+        if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder() {
+            if tr.self_ty().is_param(param_index) {
+                if tr.def_id() == into_iter_did {
+                    into_iter_span = Some(*span);
+                } else {
+                    let tr = cx.tcx.erase_regions(tr);
+                    if tr.has_escaping_bound_vars() {
+                        return None;
+                    }
+
+                    // Substitute generics in the predicate and replace the IntoIterator type parameter with the
+                    // `.into_iter()` receiver to see if the bound also holds for that type.
+                    let args = cx.tcx.mk_args_from_iter(node_args.iter().enumerate().map(|(i, arg)| {
+                        if i == param_index as usize {
+                            GenericArg::from(into_iter_receiver)
+                        } else {
+                            arg
+                        }
+                    }));
+
+                    let predicate = EarlyBinder::bind(tr).instantiate(cx.tcx, args);
+                    let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), param_env, predicate);
+                    if !cx
+                        .tcx
+                        .infer_ctxt()
+                        .build()
+                        .predicate_must_hold_modulo_regions(&obligation)
+                    {
+                        return None;
+                    }
+                }
             }
-        })
+        }
+    }
+
+    into_iter_span
 }
 
 /// Extracts the receiver of a `.into_iter()` method call.
@@ -160,22 +211,41 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                                     // `fn_sig` does not ICE. (see #11065)
                                     && cx.tcx.opt_def_kind(did).is_some_and(DefKind::is_fn_like) =>
                             {
-                                    Some((did, args, MethodOrFunction::Function))
+                                Some((
+                                    did,
+                                    args,
+                                    cx.typeck_results().node_args(recv.hir_id),
+                                    MethodOrFunction::Function
+                                ))
                             }
                             ExprKind::MethodCall(.., args, _) => {
                                 cx.typeck_results().type_dependent_def_id(parent.hir_id)
-                                    .map(|did| (did, args, MethodOrFunction::Method))
+                                    .map(|did| {
+                                        return (
+                                            did,
+                                            args,
+                                            cx.typeck_results().node_args(parent.hir_id),
+                                            MethodOrFunction::Method
+                                        );
+                                    })
                             }
                             _ => None,
                         };
 
-                        if let Some((parent_fn_did, args, kind)) = parent_fn
+                        if let Some((parent_fn_did, args, node_args, kind)) = parent_fn
                             && let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
                             && let sig = cx.tcx.fn_sig(parent_fn_did).skip_binder().skip_binder()
                             && let Some(arg_pos) = args.iter().position(|x| x.hir_id == e.hir_id)
                             && let Some(&into_iter_param) = sig.inputs().get(kind.param_pos(arg_pos))
                             && let ty::Param(param) = into_iter_param.kind()
-                            && let Some(span) = into_iter_bound(cx, parent_fn_did, into_iter_did, param.index)
+                            && let Some(span) = into_iter_bound(
+                                cx,
+                                parent_fn_did,
+                                into_iter_did,
+                                cx.typeck_results().expr_ty(into_iter_recv),
+                                param.index,
+                                node_args
+                            )
                             && self.expn_depth == 0
                         {
                             // Get the "innermost" `.into_iter()` call, e.g. given this expression:
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 26889475522..75c3c7a958a 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -542,11 +542,11 @@ define_Conf! {
     /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS.
     ///
     /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
-    (accept_comment_above_statement: bool = false),
+    (accept_comment_above_statement: bool = true),
     /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS.
     ///
     /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
-    (accept_comment_above_attributes: bool = false),
+    (accept_comment_above_attributes: bool = true),
     /// Lint: UNNECESSARY_RAW_STRING_HASHES.
     ///
     /// Whether to allow `r#""#` when `r""` can be used
@@ -561,6 +561,11 @@ define_Conf! {
     /// Which crates to allow absolute paths from
     (absolute_paths_allowed_crates: rustc_data_structures::fx::FxHashSet<String> =
         rustc_data_structures::fx::FxHashSet::default()),
+    /// Lint: PATH_ENDS_WITH_EXT.
+    ///
+    /// Additional dotfiles (files or directories starting with a dot) to allow
+    (allowed_dotfiles: rustc_data_structures::fx::FxHashSet<String> =
+        rustc_data_structures::fx::FxHashSet::default()),
     /// Lint: EXPLICIT_ITER_LOOP
     ///
     /// Whether to recommend using implicit into iter for reborrowed values.
diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
index 6d3493523e6..94a9a7c241b 100644
--- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
@@ -1,12 +1,15 @@
-use clippy_utils::macros::collect_ast_format_args;
+use clippy_utils::macros::AST_FORMAT_ARGS;
 use clippy_utils::source::snippet_opt;
 use itertools::Itertools;
-use rustc_ast::{Expr, ExprKind, FormatArgs};
+use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{EarlyContext, EarlyLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::hygiene;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{hygiene, Span};
 use std::iter::once;
+use std::mem;
+use std::rc::Rc;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -17,7 +20,12 @@ declare_clippy_lint! {
     "collects `format_args` AST nodes for use in later lints"
 }
 
-declare_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]);
+#[derive(Default)]
+pub struct FormatArgsCollector {
+    format_args: FxHashMap<Span, Rc<FormatArgs>>,
+}
+
+impl_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]);
 
 impl EarlyLintPass for FormatArgsCollector {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
@@ -26,9 +34,17 @@ impl EarlyLintPass for FormatArgsCollector {
                 return;
             }
 
-            collect_ast_format_args(expr.span, args);
+            self.format_args
+                .insert(expr.span.with_parent(None), Rc::new((**args).clone()));
         }
     }
+
+    fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &Crate) {
+        AST_FORMAT_ARGS.with(|ast_format_args| {
+            let result = ast_format_args.set(mem::take(&mut self.format_args));
+            debug_assert!(result.is_ok());
+        });
+    }
 }
 
 /// Detects if the format string or an argument has its span set by a proc macro to something inside
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
index da8654d9388..82f9d4e41e8 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
@@ -10,7 +10,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::interpret::ConstValue;
+use rustc_middle::mir::ConstValue;
 use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::Symbol;
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 4ed985f54d0..25077223885 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -5,10 +5,9 @@ use if_chain::if_chain;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::Item;
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::{self, FloatTy};
+use rustc_middle::ty::FloatTy;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::Symbol;
 
@@ -34,25 +33,20 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
         let mod_name = &cx.tcx.item_name(local_def_id.to_def_id());
         if_chain! {
             if mod_name.as_str() == "paths";
-            if let hir::ItemKind::Const(ty, _, body_id) = item.kind;
-            let ty = hir_ty_to_ty(cx.tcx, ty);
-            if let ty::Array(el_ty, _) = &ty.kind();
-            if let ty::Ref(_, el_ty, _) = &el_ty.kind();
-            if el_ty.is_str();
+            if let hir::ItemKind::Const(.., body_id) = item.kind;
             let body = cx.tcx.hir().body(body_id);
             let typeck_results = cx.tcx.typeck_body(body_id);
             if let Some(Constant::Vec(path)) = constant_simple(cx, typeck_results, body.value);
-            let path: Vec<&str> = path
+            if let Some(path) = path
                 .iter()
                 .map(|x| {
                     if let Constant::Str(s) = x {
-                        s.as_str()
+                        Some(s.as_str())
                     } else {
-                        // We checked the type of the constant above
-                        unreachable!()
+                        None
                     }
                 })
-                .collect();
+                .collect::<Option<Vec<&str>>>();
             if !check_path(cx, &path[..]);
             then {
                 span_lint(cx, INVALID_PATHS, item.span, "invalid path");
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index f49c3fadb07..c38a3e81b0f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -31,7 +31,7 @@ use serde::{Serialize, Serializer};
 use std::collections::{BTreeSet, BinaryHeap};
 use std::fmt;
 use std::fmt::Write as _;
-use std::fs::{self, OpenOptions};
+use std::fs::{self, File};
 use std::io::prelude::*;
 use std::path::{Path, PathBuf};
 use std::process::Command;
@@ -229,25 +229,10 @@ impl Drop for MetadataCollector {
         collect_renames(&mut lints);
 
         // Outputting json
-        if Path::new(JSON_OUTPUT_FILE).exists() {
-            fs::remove_file(JSON_OUTPUT_FILE).unwrap();
-        }
-        let mut file = OpenOptions::new()
-            .write(true)
-            .create(true)
-            .open(JSON_OUTPUT_FILE)
-            .unwrap();
-        writeln!(file, "{}", serde_json::to_string_pretty(&lints).unwrap()).unwrap();
+        fs::write(JSON_OUTPUT_FILE, serde_json::to_string_pretty(&lints).unwrap()).unwrap();
 
         // Outputting markdown
-        if Path::new(MARKDOWN_OUTPUT_FILE).exists() {
-            fs::remove_file(MARKDOWN_OUTPUT_FILE).unwrap();
-        }
-        let mut file = OpenOptions::new()
-            .write(true)
-            .create(true)
-            .open(MARKDOWN_OUTPUT_FILE)
-            .unwrap();
+        let mut file = File::create(MARKDOWN_OUTPUT_FILE).unwrap();
         writeln!(
             file,
             "<!--
@@ -261,17 +246,15 @@ Please use that command to update the file and do not edit it by hand.
         .unwrap();
 
         // Write configuration links to CHANGELOG.md
-        let mut changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap();
-        let mut changelog_file = OpenOptions::new().read(true).write(true).open(CHANGELOG_PATH).unwrap();
-
-        if let Some(position) = changelog.find("<!-- begin autogenerated links to configuration documentation -->") {
-            // I know this is kinda wasteful, we just don't have regex on `clippy_lints` so... this is the best
-            // we can do AFAIK.
-            changelog = changelog[..position].to_string();
-        }
+        let changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap();
+        let mut changelog_file = File::create(CHANGELOG_PATH).unwrap();
+        let position = changelog
+            .find("<!-- begin autogenerated links to configuration documentation -->")
+            .unwrap();
         writeln!(
             changelog_file,
-            "{changelog}<!-- begin autogenerated links to configuration documentation -->\n{}\n<!-- end autogenerated links to configuration documentation -->",
+            "{}<!-- begin autogenerated links to configuration documentation -->\n{}\n<!-- end autogenerated links to configuration documentation -->",
+            &changelog[..position],
             self.configs_to_markdown(ClippyConfiguration::to_markdown_link)
         )
         .unwrap();
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
index bf835f89cfc..86b77a77f17 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
@@ -5,9 +5,8 @@ use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::{self, GenericArgKind};
+use rustc_middle::ty::{self, EarlyBinder, GenericArgKind};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
 declare_clippy_lint! {
@@ -25,16 +24,14 @@ impl LateLintPass<'_> for MsrvAttrImpl {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
         if_chain! {
             if let hir::ItemKind::Impl(hir::Impl {
-                of_trait: Some(lint_pass_trait_ref),
-                self_ty,
+                of_trait: Some(_),
                 items,
                 ..
             }) = &item.kind;
-            if let Some(lint_pass_trait_def_id) = lint_pass_trait_ref.trait_def_id();
-            let is_late_pass = match_def_path(cx, lint_pass_trait_def_id, &paths::LATE_LINT_PASS);
-            if is_late_pass || match_def_path(cx, lint_pass_trait_def_id, &paths::EARLY_LINT_PASS);
-            let self_ty = hir_ty_to_ty(cx.tcx, self_ty);
-            if let ty::Adt(self_ty_def, _) = self_ty.kind();
+            if let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::instantiate_identity);
+            let is_late_pass = match_def_path(cx, trait_ref.def_id, &paths::LATE_LINT_PASS);
+            if is_late_pass || match_def_path(cx, trait_ref.def_id, &paths::EARLY_LINT_PASS);
+            if let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind();
             if self_ty_def.is_struct();
             if self_ty_def.all_fields().any(|f| {
                 cx.tcx
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 4a5b6fa5c18..a3acb8f1762 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -10,7 +10,8 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::interpret::{Allocation, ConstValue, GlobalAlloc};
+use rustc_middle::mir::interpret::{Allocation, GlobalAlloc};
+use rustc_middle::mir::ConstValue;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::Symbol;
@@ -232,7 +233,8 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
                 cx.tcx.type_of(def_id).instantiate_identity(),
             ),
             Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? {
-                ConstValue::Indirect { alloc, offset } if offset.bytes() == 0 => {
+                ConstValue::Indirect { alloc_id, offset } if offset.bytes() == 0 => {
+                    let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory();
                     read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).instantiate_identity())
                 },
                 _ => None,
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index a9957b18a53..da083fb14aa 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -304,7 +304,7 @@ impl<'tcx> LateLintPass<'tcx> for Write {
             _ => return,
         }
 
-        find_format_args(cx, expr, macro_call.expn, |format_args| {
+        if let Some(format_args) = find_format_args(cx, expr, macro_call.expn) {
             // ignore `writeln!(w)` and `write!(v, some_macro!())`
             if format_args.span.from_expansion() {
                 return;
@@ -312,15 +312,15 @@ impl<'tcx> LateLintPass<'tcx> for Write {
 
             match diag_name {
                 sym::print_macro | sym::eprint_macro | sym::write_macro => {
-                    check_newline(cx, format_args, &macro_call, name);
+                    check_newline(cx, &format_args, &macro_call, name);
                 },
                 sym::println_macro | sym::eprintln_macro | sym::writeln_macro => {
-                    check_empty_string(cx, format_args, &macro_call, name);
+                    check_empty_string(cx, &format_args, &macro_call, name);
                 },
                 _ => {},
             }
 
-            check_literal(cx, format_args, name);
+            check_literal(cx, &format_args, name);
 
             if !self.in_debug_impl {
                 for piece in &format_args.template {
@@ -334,7 +334,7 @@ impl<'tcx> LateLintPass<'tcx> for Write {
                     }
                 }
             }
-        });
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 6b1a738aaa9..d596eed4b7c 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -671,10 +671,11 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
             ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))),
             _ => None,
         },
-        mir::Const::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) => {
+        mir::Const::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) =>
+        {
             let data = cv.try_get_slice_bytes_for_diagnostics(lcx.tcx)?;
             String::from_utf8(data.to_owned()).ok().map(Constant::Str)
-        }
+        },
         mir::Const::Val(ConstValue::Indirect { alloc_id, offset: _ }, _) => {
             let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory();
             match result.ty().kind() {
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index be1c46319c2..13da79fba7e 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -288,7 +288,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
 /// Checks if the given `QPath` belongs to a type alias.
 pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
     match *qpath {
-        QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, ..)),
+        QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)),
         QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) },
         _ => false,
     }
@@ -1785,6 +1785,33 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc
     None
 }
 
+/// Returns `true` if the lint is `#[allow]`ed or `#[expect]`ed at any of the `ids`, fulfilling all
+/// of the expectations in `ids`
+///
+/// This should only be used when the lint would otherwise be emitted, for a way to check if a lint
+/// is allowed early to skip work see [`is_lint_allowed`]
+///
+/// To emit at a lint at a different context than the one current see
+/// [`span_lint_hir`](diagnostics::span_lint_hir) or
+/// [`span_lint_hir_and_then`](diagnostics::span_lint_hir_and_then)
+pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl IntoIterator<Item = HirId>) -> bool {
+    let mut suppress_lint = false;
+
+    for id in ids {
+        let (level, _) = cx.tcx.lint_level_at_node(lint, id);
+        if let Some(expectation) = level.get_expectation_id() {
+            cx.fulfill_expectation(expectation);
+        }
+
+        match level {
+            Level::Allow | Level::Expect(_) => suppress_lint = true,
+            Level::Warn | Level::ForceWarn(_) | Level::Deny | Level::Forbid => {},
+        }
+    }
+
+    suppress_lint
+}
+
 /// Returns `true` if the lint is allowed in the current context. This is useful for
 /// skipping long running code when it's unnecessary
 ///
@@ -1958,7 +1985,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
 /// Checks if the given function kind is an async function.
 pub fn is_async_fn(kind: FnKind<'_>) -> bool {
     match kind {
-        FnKind::ItemFn(_, _, header) => header.asyncness .is_async(),
+        FnKind::ItemFn(_, _, header) => header.asyncness.is_async(),
         FnKind::Method(_, sig) => sig.header.asyncness.is_async(),
         FnKind::Closure => false,
     }
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 173f9841d44..82508bcdb85 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -10,8 +10,9 @@ use rustc_lint::LateContext;
 use rustc_span::def_id::DefId;
 use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
 use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol};
-use std::cell::RefCell;
+use std::cell::OnceCell;
 use std::ops::ControlFlow;
+use std::rc::Rc;
 use std::sync::atomic::{AtomicBool, Ordering};
 
 const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
@@ -374,28 +375,21 @@ thread_local! {
     /// A thread local is used because [`FormatArgs`] is `!Send` and `!Sync`, we are making an
     /// assumption that the early pass that populates the map and the later late passes will all be
     /// running on the same thread.
-    static AST_FORMAT_ARGS: RefCell<FxHashMap<Span, FormatArgs>> = {
+    #[doc(hidden)]
+    pub static AST_FORMAT_ARGS: OnceCell<FxHashMap<Span, Rc<FormatArgs>>> = {
         static CALLED: AtomicBool = AtomicBool::new(false);
         debug_assert!(
             !CALLED.swap(true, Ordering::SeqCst),
             "incorrect assumption: `AST_FORMAT_ARGS` should only be accessed by a single thread",
         );
 
-        RefCell::default()
+        OnceCell::new()
     };
 }
 
-/// Record [`rustc_ast::FormatArgs`] for use in late lint passes, this should only be called by
-/// `FormatArgsCollector`
-pub fn collect_ast_format_args(span: Span, format_args: &FormatArgs) {
-    AST_FORMAT_ARGS.with(|ast_format_args| {
-        ast_format_args.borrow_mut().insert(span, format_args.clone());
-    });
-}
-
-/// Calls `callback` with an AST [`FormatArgs`] node if a `format_args` expansion is found as a
-/// descendant of `expn_id`
-pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId, callback: impl FnOnce(&FormatArgs)) {
+/// Returns an AST [`FormatArgs`] node if a `format_args` expansion is found as a descendant of
+/// `expn_id`
+pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId) -> Option<Rc<FormatArgs>> {
     let format_args_expr = for_each_expr(start, |expr| {
         let ctxt = expr.span.ctxt();
         if ctxt.outer_expn().is_descendant_of(expn_id) {
@@ -410,13 +404,14 @@ pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId,
         } else {
             ControlFlow::Continue(Descend::No)
         }
-    });
+    })?;
 
-    if let Some(expr) = format_args_expr {
-        AST_FORMAT_ARGS.with(|ast_format_args| {
-            ast_format_args.borrow().get(&expr.span).map(callback);
-        });
-    }
+    AST_FORMAT_ARGS.with(|ast_format_args| {
+        ast_format_args
+            .get()?
+            .get(&format_args_expr.span.with_parent(None))
+            .map(Rc::clone)
+    })
 }
 
 /// Attempt to find the [`rustc_hir::Expr`] that corresponds to the [`FormatArgument`]'s value, if
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 131f3c0aa39..f04467dc19d 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -1,7 +1,8 @@
 use rustc_hir::{Expr, HirId};
+use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{
-    traversal, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
+    traversal, BasicBlock, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
 };
 use rustc_middle::ty::TyCtxt;
 
@@ -79,8 +80,32 @@ impl<'a, 'tcx> Visitor<'tcx> for V<'a> {
     }
 }
 
+/// Checks if the block is part of a cycle
+pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {
+    let mut seen = BitSet::new_empty(body.basic_blocks.len());
+    let mut to_visit = Vec::with_capacity(body.basic_blocks.len() / 2);
+
+    seen.insert(block);
+    let mut next = block;
+    loop {
+        for succ in body.basic_blocks[next].terminator().successors() {
+            if seen.insert(succ) {
+                to_visit.push(succ);
+            } else if succ == block {
+                return true;
+            }
+        }
+
+        if let Some(x) = to_visit.pop() {
+            next = x;
+        } else {
+            return false;
+        }
+    }
+}
+
 /// Convenience wrapper around `visit_local_usage`.
-pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> {
+pub fn used_exactly_once(mir: &Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> {
     visit_local_usage(
         &[local],
         mir,
@@ -91,11 +116,14 @@ pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle:
     )
     .map(|mut vec| {
         let LocalUsage { local_use_locs, .. } = vec.remove(0);
-        local_use_locs
+        let mut locations = local_use_locs
             .into_iter()
-            .filter(|location| !is_local_assignment(mir, local, *location))
-            .count()
-            == 1
+            .filter(|&location| !is_local_assignment(mir, local, location));
+        if let Some(location) = locations.next() {
+            locations.next().is_none() && !block_in_cycle(mir, location.block)
+        } else {
+            false
+        }
     })
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 9e25d97f5a6..604dc76912e 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -13,7 +13,8 @@ use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
-use rustc_middle::mir::{ConstValue, interpret::Scalar};
+use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::ConstValue;
 use rustc_middle::traits::EvaluationResult;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index 4b06b12fb94..75064672326 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -207,9 +207,8 @@ fn path_segment_certainty(
             // Checking `res_generics_def_id(..)` before calling `generics_of` avoids an ICE.
             if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
                 let generics = cx.tcx.generics_of(def_id);
-                let count = generics.params.len() - generics.host_effect_index.is_some() as usize;
-                let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0
-                {
+                let count = generics.params.len() - usize::from(generics.host_effect_index.is_some());
+                let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0 {
                     Certainty::Certain(None)
                 } else {
                     Certainty::Uncertain
@@ -220,7 +219,7 @@ fn path_segment_certainty(
                 // See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value.
                 let certainty = lhs.join_clearing_def_ids(rhs);
                 if resolves_to_type {
-                    if let DefKind::TyAlias { .. } = cx.tcx.def_kind(def_id) {
+                    if let DefKind::TyAlias = cx.tcx.def_kind(def_id) {
                         adt_def_id(cx.tcx.type_of(def_id).instantiate_identity())
                             .map_or(certainty, |def_id| certainty.with_def_id(def_id))
                     } else {
@@ -300,10 +299,11 @@ fn type_is_inferrable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> b
 
     // Check that all type parameters appear in the functions input types.
     (0..(generics.parent_count + generics.params.len()) as u32).all(|index| {
-        Some(index as usize) == generics.host_effect_index || fn_sig
-            .inputs()
-            .iter()
-            .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
+        Some(index as usize) == generics.host_effect_index
+            || fn_sig
+                .inputs()
+                .iter()
+                .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
     })
 }
 
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 9f5116eb73b..5ce22b65f00 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2023-09-07"
+channel = "nightly-2023-09-25"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 9fcc269dbf8..f340cf5938a 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -18,7 +18,6 @@ use test_utils::IS_RUSTC_TEST_SUITE;
 // in the depinfo file (otherwise cargo thinks they are unused)
 extern crate clippy_lints;
 extern crate clippy_utils;
-extern crate derive_new;
 extern crate futures;
 extern crate if_chain;
 extern crate itertools;
@@ -33,7 +32,6 @@ mod test_utils;
 static TEST_DEPENDENCIES: &[&str] = &[
     "clippy_lints",
     "clippy_utils",
-    "derive_new",
     "futures",
     "if_chain",
     "itertools",
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml
new file mode 100644
index 00000000000..74fc5d249d0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml
@@ -0,0 +1 @@
+literal-representation-threshold = 0xFFFFFF
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed
new file mode 100644
index 00000000000..750f3be84c0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed
@@ -0,0 +1,6 @@
+#![warn(clippy::decimal_literal_representation)]
+fn main() {
+    let _ = 8388608;
+    let _ = 0x00FF_FFFF;
+    //~^ ERROR: integer literal has a better hexadecimal representation
+}
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs
new file mode 100644
index 00000000000..26b3354d159
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs
@@ -0,0 +1,6 @@
+#![warn(clippy::decimal_literal_representation)]
+fn main() {
+    let _ = 8388608;
+    let _ = 16777215;
+    //~^ ERROR: integer literal has a better hexadecimal representation
+}
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr
new file mode 100644
index 00000000000..6f817a3fdde
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr
@@ -0,0 +1,11 @@
+error: integer literal has a better hexadecimal representation
+  --> $DIR/decimal_literal_representation.rs:4:13
+   |
+LL |     let _ = 16777215;
+   |             ^^^^^^^^ help: consider: `0x00FF_FFFF`
+   |
+   = note: `-D clippy::decimal-literal-representation` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::decimal_literal_representation)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml
new file mode 100644
index 00000000000..26cb2d77bfd
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml
@@ -0,0 +1 @@
+allowed-scripts = ["Cyrillic"]
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs
new file mode 100644
index 00000000000..9df1ec6fab0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs
@@ -0,0 +1,6 @@
+#![warn(clippy::disallowed_script_idents)]
+fn main() {
+    let счётчик = 10;
+    let カウンタ = 10;
+    //~^ ERROR: identifier `カウンタ` has a Unicode script that is not allowed by configuration
+}
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr
new file mode 100644
index 00000000000..31bb5ee3514
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr
@@ -0,0 +1,11 @@
+error: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana
+  --> $DIR/disallowed_script_idents.rs:4:9
+   |
+LL |     let カウンタ = 10;
+   |         ^^^^^^^^
+   |
+   = note: `-D clippy::disallowed-script-idents` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::disallowed_script_idents)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml
new file mode 100644
index 00000000000..0ad7a979948
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml
@@ -0,0 +1 @@
+enum-variant-name-threshold = 5
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs
new file mode 100644
index 00000000000..8f4e178ccfe
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs
@@ -0,0 +1,16 @@
+enum Foo {
+    AFoo,
+    BFoo,
+    CFoo,
+    DFoo,
+}
+enum Foo2 {
+    //~^ ERROR: all variants have the same postfix
+    AFoo,
+    BFoo,
+    CFoo,
+    DFoo,
+    EFoo,
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr
new file mode 100644
index 00000000000..11039b1db48
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr
@@ -0,0 +1,18 @@
+error: all variants have the same postfix: `Foo`
+  --> $DIR/enum_variant_names.rs:7:1
+   |
+LL | / enum Foo2 {
+LL | |
+LL | |     AFoo,
+LL | |     BFoo,
+...  |
+LL | |     EFoo,
+LL | | }
+   | |_^
+   |
+   = help: remove the postfixes and use full paths to the variants instead of glob imports
+   = note: `-D clippy::enum-variant-names` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml
new file mode 100644
index 00000000000..64a8017fe02
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml
@@ -0,0 +1 @@
+enum-variant-size-threshold = 500
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed
new file mode 100644
index 00000000000..9ae760ae41a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed
@@ -0,0 +1,11 @@
+enum Fine {
+    A(()),
+    B([u8; 500]),
+}
+enum Bad {
+    //~^ ERROR: large size difference between variants
+    A(()),
+    B(Box<[u8; 501]>),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs
new file mode 100644
index 00000000000..cf7f432bf0b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs
@@ -0,0 +1,11 @@
+enum Fine {
+    A(()),
+    B([u8; 500]),
+}
+enum Bad {
+    //~^ ERROR: large size difference between variants
+    A(()),
+    B([u8; 501]),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
new file mode 100644
index 00000000000..4d9bc9d48e4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
@@ -0,0 +1,21 @@
+error: large size difference between variants
+  --> $DIR/enum_variant_size.rs:5:1
+   |
+LL | / enum Bad {
+LL | |
+LL | |     A(()),
+   | |     ----- the second-largest variant contains at least 0 bytes
+LL | |     B([u8; 501]),
+   | |     ------------ the largest variant contains at least 501 bytes
+LL | | }
+   | |_^ the entire enum is at least 502 bytes
+   |
+   = note: `-D clippy::large-enum-variant` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
+help: consider boxing the large fields to reduce the total size of the enum
+   |
+LL |     B(Box<[u8; 501]>),
+   |       ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml
new file mode 100644
index 00000000000..f85aade6ae8
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml
@@ -0,0 +1 @@
+enum-variant-name-threshold = 0
diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs
new file mode 100644
index 00000000000..6918d7528c1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs
@@ -0,0 +1,3 @@
+enum Actions {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml
new file mode 100644
index 00000000000..15d175ef147
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml
@@ -0,0 +1 @@
+enforce-iter-loop-reborrow = true
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed
new file mode 100644
index 00000000000..468da22a926
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::explicit_iter_loop)]
+
+fn main() {
+    let mut vec = vec![1, 2, 3];
+    let rmvec = &mut vec;
+    for _ in &*rmvec {}
+    //~^ ERROR: it is more concise to loop over references to containers
+    for _ in &mut *rmvec {}
+    //~^ ERROR: it is more concise to loop over references to containers
+}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs
new file mode 100644
index 00000000000..a934648608c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::explicit_iter_loop)]
+
+fn main() {
+    let mut vec = vec![1, 2, 3];
+    let rmvec = &mut vec;
+    for _ in rmvec.iter() {}
+    //~^ ERROR: it is more concise to loop over references to containers
+    for _ in rmvec.iter_mut() {}
+    //~^ ERROR: it is more concise to loop over references to containers
+}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr
new file mode 100644
index 00000000000..587d4f9b3f0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr
@@ -0,0 +1,17 @@
+error: it is more concise to loop over references to containers instead of using explicit iteration methods
+  --> $DIR/explicit_iter_loop.rs:6:14
+   |
+LL |     for _ in rmvec.iter() {}
+   |              ^^^^^^^^^^^^ help: to write this more concisely, try: `&*rmvec`
+   |
+   = note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::explicit_iter_loop)]`
+
+error: it is more concise to loop over references to containers instead of using explicit iteration methods
+  --> $DIR/explicit_iter_loop.rs:8:14
+   |
+LL |     for _ in rmvec.iter_mut() {}
+   |              ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *rmvec`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml b/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml
new file mode 100644
index 00000000000..584335dc28f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml
@@ -0,0 +1 @@
+stack-size-threshold = 1000
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs
new file mode 100644
index 00000000000..39798ffea49
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs
@@ -0,0 +1,17 @@
+#![warn(clippy::large_stack_frames)]
+
+// We use this helper function instead of writing [0; 4294967297] directly to represent a
+// case that large_stack_arrays can't catch
+fn create_array<const N: usize>() -> [u8; N] {
+    [0; N]
+}
+
+fn f() {
+    let _x = create_array::<1000>();
+}
+fn f2() {
+    //~^ ERROR: this function allocates a large amount of stack space
+    let _x = create_array::<1001>();
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr
new file mode 100644
index 00000000000..67ee57ab672
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr
@@ -0,0 +1,15 @@
+error: this function allocates a large amount of stack space
+  --> $DIR/large_stack_frames.rs:12:1
+   |
+LL | / fn f2() {
+LL | |
+LL | |     let _x = create_array::<1001>();
+LL | | }
+   | |_^
+   |
+   = note: allocating large amounts of stack space can overflow the stack
+   = note: `-D clippy::large-stack-frames` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml
new file mode 100644
index 00000000000..45bcbce1e3c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml
@@ -0,0 +1 @@
+pass-by-value-size-limit = 512
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed
new file mode 100644
index 00000000000..3c87c79cf2f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::large_types_passed_by_value)]
+
+fn f(_v: [u8; 512]) {}
+fn f2(_v: &[u8; 513]) {}
+//~^ ERROR: this argument (513 byte) is passed by value
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs
new file mode 100644
index 00000000000..0572373a611
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::large_types_passed_by_value)]
+
+fn f(_v: [u8; 512]) {}
+fn f2(_v: [u8; 513]) {}
+//~^ ERROR: this argument (513 byte) is passed by value
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr
new file mode 100644
index 00000000000..6678a2b4721
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr
@@ -0,0 +1,11 @@
+error: this argument (513 byte) is passed by value, but might be more efficient if passed by reference (limit: 512 byte)
+  --> $DIR/large_types_passed_by_value.rs:4:11
+   |
+LL | fn f2(_v: [u8; 513]) {}
+   |           ^^^^^^^^^ help: consider passing by reference instead: `&[u8; 513]`
+   |
+   = note: `-D clippy::large-types-passed-by-value` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::large_types_passed_by_value)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml b/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml
new file mode 100644
index 00000000000..cdae1da011b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml
@@ -0,0 +1 @@
+matches-for-let-else = "AllTypes"
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed
new file mode 100644
index 00000000000..972f6aa4030
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::manual_let_else)]
+
+enum Foo {
+    A(u8),
+    B,
+}
+
+fn main() {
+    let Foo::A(x) = Foo::A(1) else { return };
+}
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs
new file mode 100644
index 00000000000..fdaba4ad2a6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs
@@ -0,0 +1,14 @@
+#![warn(clippy::manual_let_else)]
+
+enum Foo {
+    A(u8),
+    B,
+}
+
+fn main() {
+    let x = match Foo::A(1) {
+        //~^ ERROR: this could be rewritten as `let...else`
+        Foo::A(x) => x,
+        Foo::B => return,
+    };
+}
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr
new file mode 100644
index 00000000000..5c2c86c3731
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr
@@ -0,0 +1,15 @@
+error: this could be rewritten as `let...else`
+  --> $DIR/manual_let_else.rs:9:5
+   |
+LL | /     let x = match Foo::A(1) {
+LL | |
+LL | |         Foo::A(x) => x,
+LL | |         Foo::B => return,
+LL | |     };
+   | |______^ help: consider writing: `let Foo::A(x) = Foo::A(1) else { return };`
+   |
+   = note: `-D clippy::manual-let-else` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml
new file mode 100644
index 00000000000..40d7dfd938c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml
@@ -0,0 +1 @@
+allowed-dotfiles = ["dot"]
diff --git a/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs
new file mode 100644
index 00000000000..a34b15f4ac9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::path_ends_with_ext)]
+
+use std::path::Path;
+
+fn f(p: &Path) {
+    p.ends_with(".dot");
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml b/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml
new file mode 100644
index 00000000000..df505ed9672
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml
@@ -0,0 +1 @@
+large-error-threshold = 512
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs
new file mode 100644
index 00000000000..dea4d61a96b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::result_large_err)]
+
+fn f() -> Result<(), [u8; 511]> {
+    todo!()
+}
+fn f2() -> Result<(), [u8; 512]> {
+    //~^ ERROR: the `Err`-variant returned from this function is very large
+    todo!()
+}
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr
new file mode 100644
index 00000000000..b0936319d1b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr
@@ -0,0 +1,12 @@
+error: the `Err`-variant returned from this function is very large
+  --> $DIR/result_large_err.rs:6:12
+   |
+LL | fn f2() -> Result<(), [u8; 512]> {
+   |            ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
+   |
+   = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
+   = note: `-D clippy::result-large-err` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::result_large_err)]`
+
+error: aborting due to previous error
+
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 b97bb144468..4bed5c149f5 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
@@ -10,6 +10,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
+           allowed-dotfiles
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
@@ -82,6 +83,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
+           allowed-dotfiles
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs
new file mode 100644
index 00000000000..2f023612206
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs
@@ -0,0 +1,5 @@
+fn f(x: Box<[u8; 500]>) {}
+//~^ ERROR: local variable doesn't need to be boxed here
+fn f2(x: Box<[u8; 501]>) {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr
new file mode 100644
index 00000000000..2859a29f1b2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr
@@ -0,0 +1,11 @@
+error: local variable doesn't need to be boxed here
+  --> $DIR/boxed_local.rs:1:6
+   |
+LL | fn f(x: Box<[u8; 500]>) {}
+   |      ^
+   |
+   = note: `-D clippy::boxed-local` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml b/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml
new file mode 100644
index 00000000000..a9c42fca468
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml
@@ -0,0 +1 @@
+too-large-for-stack = 500
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed
new file mode 100644
index 00000000000..ebe92d9b599
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed
@@ -0,0 +1,9 @@
+#![warn(clippy::useless_vec)]
+
+fn main() {
+    let x = [0u8; 500];
+    //~^ ERROR: useless use of `vec!`
+    x.contains(&1);
+    let y = vec![0u8; 501];
+    y.contains(&1);
+}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs
new file mode 100644
index 00000000000..e2886a8ccd1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::useless_vec)]
+
+fn main() {
+    let x = vec![0u8; 500];
+    //~^ ERROR: useless use of `vec!`
+    x.contains(&1);
+    let y = vec![0u8; 501];
+    y.contains(&1);
+}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr
new file mode 100644
index 00000000000..923cded5eef
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr
@@ -0,0 +1,11 @@
+error: useless use of `vec!`
+  --> $DIR/useless_vec.rs:4:13
+   |
+LL |     let x = vec![0u8; 500];
+   |             ^^^^^^^^^^^^^^ help: you can use an array directly: `[0u8; 500]`
+   |
+   = note: `-D clippy::useless-vec` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml b/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml
new file mode 100644
index 00000000000..15906305c89
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml
@@ -0,0 +1 @@
+too-many-arguments-threshold = 10
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs
new file mode 100644
index 00000000000..7b2d6897d3c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::too_many_arguments)]
+
+fn not_too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8) {}
+fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {}
+//~^ ERROR: this function has too many arguments
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr
new file mode 100644
index 00000000000..a52e1fcb9e3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr
@@ -0,0 +1,11 @@
+error: this function has too many arguments (11/10)
+  --> $DIR/too_many_arguments.rs:4:1
+   |
+LL | fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::too-many-arguments` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml b/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml
new file mode 100644
index 00000000000..bf2ffdd0e30
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml
@@ -0,0 +1 @@
+type-complexity-threshold = 500
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs
new file mode 100644
index 00000000000..b95f5134347
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs
@@ -0,0 +1,7 @@
+// 480
+fn f(_: (u8, (u8, (u8, (u8, (u8, (u8,))))))) {}
+// 550
+fn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}
+//~^ ERROR: very complex type used
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr
new file mode 100644
index 00000000000..8ca637f7222
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr
@@ -0,0 +1,11 @@
+error: very complex type used. Consider factoring parts into `type` definitions
+  --> $DIR/type_complexity.rs:4:10
+   |
+LL | fn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::type-complexity` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml
new file mode 100644
index 00000000000..2f91866aa93
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml
@@ -0,0 +1 @@
+max-trait-bounds = 5
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs
new file mode 100644
index 00000000000..2454c10382d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs
@@ -0,0 +1,18 @@
+#![warn(clippy::type_repetition_in_bounds)]
+
+fn f<T>()
+where
+    T: Copy + Clone + Sync + Send + ?Sized + Unpin,
+    T: PartialEq,
+{
+}
+
+fn f2<T>()
+where
+    T: Copy + Clone + Sync + Send + ?Sized,
+    T: Unpin + PartialEq,
+    //~^ ERROR: this type has already been used as a bound predicate
+{
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr
new file mode 100644
index 00000000000..2ae2984975f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr
@@ -0,0 +1,12 @@
+error: this type has already been used as a bound predicate
+  --> $DIR/main.rs:13:5
+   |
+LL |     T: Unpin + PartialEq,
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider combining the bounds: `T: Copy + Clone + Sync + Send + ?Sized + Unpin + PartialEq`
+   = note: `-D clippy::type-repetition-in-bounds` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::type_repetition_in_bounds)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
deleted file mode 100644
index e6dbb3d3784..00000000000
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-accept-comment-above-statement = true
-accept-comment-above-attributes = true
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml
new file mode 100644
index 00000000000..3b205d536f2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml
@@ -0,0 +1,2 @@
+# default configuration has `accept-comment-above-statement` and
+# `accept-comment-above-attributes` true
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml
new file mode 100644
index 00000000000..57ecb902d65
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml
@@ -0,0 +1,3 @@
+# test with these options disabled
+accept-comment-above-statement = false
+accept-comment-above-attributes = false
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index 183c07fe786..15edf2a7dae 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:263:19
+  --> $DIR/undocumented_unsafe_blocks.rs:266:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     /* Safety: */ unsafe {}
    = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:267:5
+  --> $DIR/undocumented_unsafe_blocks.rs:270:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:271:14
+  --> $DIR/undocumented_unsafe_blocks.rs:274:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:271:29
+  --> $DIR/undocumented_unsafe_blocks.rs:274:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:271:48
+  --> $DIR/undocumented_unsafe_blocks.rs:274:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:275:18
+  --> $DIR/undocumented_unsafe_blocks.rs:278:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:275:37
+  --> $DIR/undocumented_unsafe_blocks.rs:278:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:279:14
+  --> $DIR/undocumented_unsafe_blocks.rs:282:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     let _ = *unsafe { &42 };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:284:19
+  --> $DIR/undocumented_unsafe_blocks.rs:287:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     let _ = match unsafe {} {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:290:14
+  --> $DIR/undocumented_unsafe_blocks.rs:293:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     let _ = &unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:294:14
+  --> $DIR/undocumented_unsafe_blocks.rs:297:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |     let _ = [unsafe {}; 5];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:298:13
+  --> $DIR/undocumented_unsafe_blocks.rs:301:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     let _ = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:308:8
+  --> $DIR/undocumented_unsafe_blocks.rs:311:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:314:13
+  --> $DIR/undocumented_unsafe_blocks.rs:317:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     t!();
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:322:5
+  --> $DIR/undocumented_unsafe_blocks.rs:325:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |     unsafe {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:326:5
+  --> $DIR/undocumented_unsafe_blocks.rs:329:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -133,7 +133,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:336:5
+  --> $DIR/undocumented_unsafe_blocks.rs:339:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -141,7 +141,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:340:20
+  --> $DIR/undocumented_unsafe_blocks.rs:343:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:347:5
+  --> $DIR/undocumented_unsafe_blocks.rs:350:5
    |
 LL |     unsafe impl A for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL |     unsafe impl A for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:354:9
+  --> $DIR/undocumented_unsafe_blocks.rs:357:9
    |
 LL |         unsafe impl B for (u32) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         unsafe impl B for (u32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:375:13
+  --> $DIR/undocumented_unsafe_blocks.rs:378:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,7 +177,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:400:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:408:5
+  --> $DIR/undocumented_unsafe_blocks.rs:411:5
    |
 LL |     unsafe impl T for (i32) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -197,7 +197,7 @@ LL |     unsafe impl T for (i32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:400:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     no_safety_comment!(u32);
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:414:5
+  --> $DIR/undocumented_unsafe_blocks.rs:417:5
    |
 LL |     unsafe impl T for (bool) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL |     unsafe impl T for (bool) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:460:5
+  --> $DIR/undocumented_unsafe_blocks.rs:463:5
    |
 LL |     unsafe impl NoComment for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -225,7 +225,7 @@ LL |     unsafe impl NoComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:464:19
+  --> $DIR/undocumented_unsafe_blocks.rs:467:19
    |
 LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:468:5
+  --> $DIR/undocumented_unsafe_blocks.rs:471:5
    |
 LL |     unsafe impl TrailingComment for () {} // SAFETY:
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,13 +241,13 @@ LL |     unsafe impl TrailingComment for () {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: constant item has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:472:5
+  --> $DIR/undocumented_unsafe_blocks.rs:475:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:471:5
+  --> $DIR/undocumented_unsafe_blocks.rs:474:5
    |
 LL |     // SAFETY:
    |     ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     // SAFETY:
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:473:5
+  --> $DIR/undocumented_unsafe_blocks.rs:476:5
    |
 LL |     unsafe impl Interference for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     unsafe impl Interference for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:480:5
+  --> $DIR/undocumented_unsafe_blocks.rs:483:5
    |
 LL |     unsafe impl ImplInFn for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     unsafe impl ImplInFn for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:489:1
+  --> $DIR/undocumented_unsafe_blocks.rs:492:1
    |
 LL | unsafe impl CrateRoot for () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: statement has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:502:5
+  --> $DIR/undocumented_unsafe_blocks.rs:505:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -291,13 +291,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:501:5
+  --> $DIR/undocumented_unsafe_blocks.rs:504:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:503:12
+  --> $DIR/undocumented_unsafe_blocks.rs:506:12
    |
 LL |         if unsafe { true } {
    |            ^^^^^^^^^^^^^^^
@@ -305,7 +305,7 @@ LL |         if unsafe { true } {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:506:23
+  --> $DIR/undocumented_unsafe_blocks.rs:509:23
    |
 LL |             let bar = unsafe {};
    |                       ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index 77f6aea2e0d..cc9530f79b6 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:262:19
+  --> $DIR/undocumented_unsafe_blocks.rs:266:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     /* Safety: */ unsafe {}
    = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:266:5
+  --> $DIR/undocumented_unsafe_blocks.rs:270:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:14
+  --> $DIR/undocumented_unsafe_blocks.rs:274:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:29
+  --> $DIR/undocumented_unsafe_blocks.rs:274:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:48
+  --> $DIR/undocumented_unsafe_blocks.rs:274:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:274:18
+  --> $DIR/undocumented_unsafe_blocks.rs:278:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:274:37
+  --> $DIR/undocumented_unsafe_blocks.rs:278:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:278:14
+  --> $DIR/undocumented_unsafe_blocks.rs:282:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     let _ = *unsafe { &42 };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:283:19
+  --> $DIR/undocumented_unsafe_blocks.rs:287:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     let _ = match unsafe {} {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:289:14
+  --> $DIR/undocumented_unsafe_blocks.rs:293:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     let _ = &unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:293:14
+  --> $DIR/undocumented_unsafe_blocks.rs:297:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |     let _ = [unsafe {}; 5];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:297:13
+  --> $DIR/undocumented_unsafe_blocks.rs:301:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     let _ = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:307:8
+  --> $DIR/undocumented_unsafe_blocks.rs:311:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:313:13
+  --> $DIR/undocumented_unsafe_blocks.rs:317:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     t!();
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:321:5
+  --> $DIR/undocumented_unsafe_blocks.rs:325:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |     unsafe {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:325:5
+  --> $DIR/undocumented_unsafe_blocks.rs:329:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -133,7 +133,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:335:5
+  --> $DIR/undocumented_unsafe_blocks.rs:339:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -141,7 +141,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:339:20
+  --> $DIR/undocumented_unsafe_blocks.rs:343:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:346:5
+  --> $DIR/undocumented_unsafe_blocks.rs:350:5
    |
 LL |     unsafe impl A for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL |     unsafe impl A for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:353:9
+  --> $DIR/undocumented_unsafe_blocks.rs:357:9
    |
 LL |         unsafe impl B for (u32) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         unsafe impl B for (u32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:374:13
+  --> $DIR/undocumented_unsafe_blocks.rs:378:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,7 +177,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:399:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:407:5
+  --> $DIR/undocumented_unsafe_blocks.rs:411:5
    |
 LL |     unsafe impl T for (i32) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -197,7 +197,7 @@ LL |     unsafe impl T for (i32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:399:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     no_safety_comment!(u32);
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:413:5
+  --> $DIR/undocumented_unsafe_blocks.rs:417:5
    |
 LL |     unsafe impl T for (bool) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL |     unsafe impl T for (bool) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:459:5
+  --> $DIR/undocumented_unsafe_blocks.rs:463:5
    |
 LL |     unsafe impl NoComment for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -225,7 +225,7 @@ LL |     unsafe impl NoComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:463:19
+  --> $DIR/undocumented_unsafe_blocks.rs:467:19
    |
 LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:467:5
+  --> $DIR/undocumented_unsafe_blocks.rs:471:5
    |
 LL |     unsafe impl TrailingComment for () {} // SAFETY:
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,13 +241,13 @@ LL |     unsafe impl TrailingComment for () {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: constant item has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:471:5
+  --> $DIR/undocumented_unsafe_blocks.rs:475:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:470:5
+  --> $DIR/undocumented_unsafe_blocks.rs:474:5
    |
 LL |     // SAFETY:
    |     ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     // SAFETY:
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:472:5
+  --> $DIR/undocumented_unsafe_blocks.rs:476:5
    |
 LL |     unsafe impl Interference for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     unsafe impl Interference for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:479:5
+  --> $DIR/undocumented_unsafe_blocks.rs:483:5
    |
 LL |     unsafe impl ImplInFn for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     unsafe impl ImplInFn for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:488:1
+  --> $DIR/undocumented_unsafe_blocks.rs:492:1
    |
 LL | unsafe impl CrateRoot for () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:498:9
+  --> $DIR/undocumented_unsafe_blocks.rs:502:9
    |
 LL |         unsafe {};
    |         ^^^^^^^^^
@@ -287,7 +287,7 @@ LL |         unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: statement has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:501:5
+  --> $DIR/undocumented_unsafe_blocks.rs:505:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -299,13 +299,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:500:5
+  --> $DIR/undocumented_unsafe_blocks.rs:504:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:502:12
+  --> $DIR/undocumented_unsafe_blocks.rs:506:12
    |
 LL |         if unsafe { true } {
    |            ^^^^^^^^^^^^^^^
@@ -313,7 +313,7 @@ LL |         if unsafe { true } {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:505:23
+  --> $DIR/undocumented_unsafe_blocks.rs:509:23
    |
 LL |             let bar = unsafe {};
    |                       ^^^^^^^^^
@@ -321,7 +321,7 @@ LL |             let bar = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:523:9
+  --> $DIR/undocumented_unsafe_blocks.rs:527:9
    |
 LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -329,7 +329,7 @@ LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:527:9
+  --> $DIR/undocumented_unsafe_blocks.rs:531:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -337,12 +337,60 @@ LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line()
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:531:9
+  --> $DIR/undocumented_unsafe_blocks.rs:535:9
+   |
+LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:541:5
+   |
+LL |     unsafe {}
+   |     ^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:545:5
+   |
+LL |     unsafe {
+   |     ^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:552:9
+   |
+LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:557:9
+   |
+LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:563:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 39 previous errors
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:568:5
+   |
+LL |     unsafe {}
+   |     ^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 45 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index b28e1b7d180..a2781398760 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -1,4 +1,7 @@
 //@aux-build:../../ui/auxiliary/proc_macro_unsafe.rs
+//@revisions: default disabled
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/default
+//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled
 
 #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
 #![allow(deref_nullptr, clippy::let_unit_value, clippy::missing_safety_doc)]
@@ -491,7 +494,7 @@ unsafe impl CrateRoot for () {}
 // SAFETY: ok
 unsafe impl CrateRoot for (i32) {}
 
-fn issue_9142() {
+fn nested_block_separation_issue_9142() {
     // SAFETY: ok
     let _ =
         // we need this comment to avoid rustfmt putting
@@ -518,49 +521,50 @@ pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -
     2
 }
 
-fn issue_10832() {
-    // Safety: A safety comment
+fn separate_line_from_let_issue_10832() {
+    // SAFETY: fail ONLY if `accept-comment-above-statement = false`
     let _some_variable_with_a_very_long_name_to_break_the_line =
         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-statement = false`
     const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Yet another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-statement = false`
     static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 }
 
-fn issue_8679<T: Copy>() {
-    // SAFETY:
+fn above_expr_attribute_issue_8679<T: Copy>() {
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
     unsafe {}
 
-    // SAFETY:
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[expect(unsafe_code, reason = "totally safe")]
     unsafe {
         *std::ptr::null::<T>()
     };
 
-    // Safety: A safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
     let _some_variable_with_a_very_long_name_to_break_the_line =
         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
     const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Yet another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
-    static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
+    #[allow(non_upper_case_globals)]
+    static _some_static_with_a_very_long_name_to_break_the_line: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 
     // SAFETY:
     #[allow(unsafe_code)]
-    // This also works I guess
+    // This shouldn't work either
     unsafe {}
 }
 
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml
new file mode 100644
index 00000000000..7c3ffc2908f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml
@@ -0,0 +1 @@
+unnecessary-box-size = 64
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed
new file mode 100644
index 00000000000..413bc0bf1e3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed
@@ -0,0 +1,11 @@
+#![warn(clippy::unnecessary_box_returns)]
+
+fn f() -> [u8; 64] {
+    //~^ ERROR: boxed return of the sized type `[u8; 64]`
+    todo!()
+}
+fn f2() -> Box<[u8; 65]> {
+    todo!()
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs
new file mode 100644
index 00000000000..b44fbb55448
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::unnecessary_box_returns)]
+
+fn f() -> Box<[u8; 64]> {
+    //~^ ERROR: boxed return of the sized type `[u8; 64]`
+    todo!()
+}
+fn f2() -> Box<[u8; 65]> {
+    todo!()
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr
new file mode 100644
index 00000000000..df9aa37ac10
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr
@@ -0,0 +1,12 @@
+error: boxed return of the sized type `[u8; 64]`
+  --> $DIR/unnecessary_box_returns.rs:3:11
+   |
+LL | fn f() -> Box<[u8; 64]> {
+   |           ^^^^^^^^^^^^^ help: try: `[u8; 64]`
+   |
+   = help: changing this also requires a change to the return expressions in this function
+   = note: `-D clippy::unnecessary-box-returns` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml
new file mode 100644
index 00000000000..55a202eefb9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml
@@ -0,0 +1 @@
+verbose-bit-mask-threshold = 31
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed
new file mode 100644
index 00000000000..437692a4d78
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::verbose_bit_mask)]
+fn main() {
+    let v: i32 = 0;
+    let _ = v & 0b11111 == 0;
+    let _ = v.trailing_zeros() >= 6;
+    //~^ ERROR: bit mask could be simplified
+}
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs
new file mode 100644
index 00000000000..ce102708055
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::verbose_bit_mask)]
+fn main() {
+    let v: i32 = 0;
+    let _ = v & 0b11111 == 0;
+    let _ = v & 0b111111 == 0;
+    //~^ ERROR: bit mask could be simplified
+}
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr
new file mode 100644
index 00000000000..7377921b42a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr
@@ -0,0 +1,11 @@
+error: bit mask could be simplified with a call to `trailing_zeros`
+  --> $DIR/verbose_bit_mask.rs:5:13
+   |
+LL |     let _ = v & 0b111111 == 0;
+   |             ^^^^^^^^^^^^^^^^^ help: try: `v.trailing_zeros() >= 6`
+   |
+   = note: `-D clippy::verbose-bit-mask` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
new file mode 100644
index 00000000000..875aaeef6c9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
@@ -0,0 +1 @@
+warn-on-all-wildcard-imports = true
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
new file mode 100644
index 00000000000..1752f48856c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
@@ -0,0 +1,11 @@
+#![warn(clippy::wildcard_imports)]
+
+mod prelude {
+    pub const FOO: u8 = 1;
+}
+use prelude::FOO;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+    let _ = FOO;
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
new file mode 100644
index 00000000000..331c2c59c22
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::wildcard_imports)]
+
+mod prelude {
+    pub const FOO: u8 = 1;
+}
+use prelude::*;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+    let _ = FOO;
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
new file mode 100644
index 00000000000..13ec3a229ce
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
@@ -0,0 +1,11 @@
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:6:5
+   |
+LL | use prelude::*;
+   |     ^^^^^^^^^^ help: try: `prelude::FOO`
+   |
+   = note: `-D clippy::wildcard-imports` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index d0a092093f3..1ca18170f8a 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -361,3 +361,7 @@ fn avoid_subtract_overflow(q: u32) {
     //~^ ERROR: casting `u32` to `u8` may truncate the value
     c as usize;
 }
+
+fn issue11426() {
+    (&42u8 >> 0xa9008fb6c9d81e42_0e25730562a601c8_u128) as usize;
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
index 6547107f500..5e7e545e764 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
@@ -49,3 +49,14 @@ mod cast_lossless_in_impl {
 enum Test {
     A = u32::MAX as i64 + 1,
 }
+
+fn issue11458() {
+    macro_rules! sign_cast {
+        ($var: ident, $src: ty, $dest: ty) => {
+            <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())
+        };
+    }
+    let x = 10_u128;
+    let _ = i32::from(sign_cast!(x, u8, i8));
+    let _ = i32::from(sign_cast!(x, u8, i8) + 1);
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.rs b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
index 79af9a83ca2..0d69ddbd586 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
@@ -49,3 +49,14 @@ mod cast_lossless_in_impl {
 enum Test {
     A = u32::MAX as i64 + 1,
 }
+
+fn issue11458() {
+    macro_rules! sign_cast {
+        ($var: ident, $src: ty, $dest: ty) => {
+            <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())
+        };
+    }
+    let x = 10_u128;
+    let _ = sign_cast!(x, u8, i8) as i32;
+    let _ = (sign_cast!(x, u8, i8) + 1) as i32;
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
index da75cb195eb..f9f111a7c20 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
@@ -115,5 +115,17 @@ error: casting `u8` to `u16` may become silently lossy if you later change the t
 LL |     let _ = (1u8 + 1u8) as u16;
    |             ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
 
-error: aborting due to 19 previous errors
+error: casting `i8` to `i32` may become silently lossy if you later change the type
+  --> $DIR/cast_lossless_integer.rs:60:13
+   |
+LL |     let _ = sign_cast!(x, u8, i8) as i32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8))`
+
+error: casting `i8` to `i32` may become silently lossy if you later change the type
+  --> $DIR/cast_lossless_integer.rs:61:13
+   |
+LL |     let _ = (sign_cast!(x, u8, i8) + 1) as i32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8) + 1)`
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index f1cac8c5fbc..32c7499bf73 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -7,7 +7,8 @@
     clippy::option_map_unit_fn,
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::unnecessary_map_on_constructor
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index c7a470b5be6..25b7431ba8c 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -7,7 +7,8 @@
     clippy::option_map_unit_fn,
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::unnecessary_map_on_constructor
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index 7c7f1797462..951e4ac749c 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -1,5 +1,5 @@
 error: redundant closure
-  --> $DIR/eta.rs:28:27
+  --> $DIR/eta.rs:29:27
    |
 LL |     let a = Some(1u8).map(|a| foo(a));
    |                           ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
@@ -8,31 +8,31 @@ LL |     let a = Some(1u8).map(|a| foo(a));
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
 
 error: redundant closure
-  --> $DIR/eta.rs:32:40
+  --> $DIR/eta.rs:33:40
    |
 LL |     let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
    |                                        ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
 
 error: redundant closure
-  --> $DIR/eta.rs:33:35
+  --> $DIR/eta.rs:34:35
    |
 LL |     let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
    |                                   ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
 
 error: redundant closure
-  --> $DIR/eta.rs:34:26
+  --> $DIR/eta.rs:35:26
    |
 LL |     all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
    |                          ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
 
 error: redundant closure
-  --> $DIR/eta.rs:41:27
+  --> $DIR/eta.rs:42:27
    |
 LL |     let e = Some(1u8).map(|a| generic(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
 
 error: redundant closure
-  --> $DIR/eta.rs:93:51
+  --> $DIR/eta.rs:94:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    |                                                   ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
@@ -41,127 +41,127 @@ LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]`
 
 error: redundant closure
-  --> $DIR/eta.rs:94:51
+  --> $DIR/eta.rs:95:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
    |                                                   ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
 
 error: redundant closure
-  --> $DIR/eta.rs:96:42
+  --> $DIR/eta.rs:97:42
    |
 LL |     let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
    |                                          ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
 
 error: redundant closure
-  --> $DIR/eta.rs:100:29
+  --> $DIR/eta.rs:101:29
    |
 LL |     let e = Some("str").map(|s| s.to_string());
    |                             ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
 
 error: redundant closure
-  --> $DIR/eta.rs:101:27
+  --> $DIR/eta.rs:102:27
    |
 LL |     let e = Some('a').map(|s| s.to_uppercase());
    |                           ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
 
 error: redundant closure
-  --> $DIR/eta.rs:103:65
+  --> $DIR/eta.rs:104:65
    |
 LL |     let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
    |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
 
 error: redundant closure
-  --> $DIR/eta.rs:166:22
+  --> $DIR/eta.rs:167:22
    |
 LL |     requires_fn_once(|| x());
    |                      ^^^^^^ help: replace the closure with the function itself: `x`
 
 error: redundant closure
-  --> $DIR/eta.rs:173:27
+  --> $DIR/eta.rs:174:27
    |
 LL |     let a = Some(1u8).map(|a| foo_ptr(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
 
 error: redundant closure
-  --> $DIR/eta.rs:178:27
+  --> $DIR/eta.rs:179:27
    |
 LL |     let a = Some(1u8).map(|a| closure(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
 
 error: redundant closure
-  --> $DIR/eta.rs:210:28
+  --> $DIR/eta.rs:211:28
    |
 LL |     x.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:211:28
+  --> $DIR/eta.rs:212:28
    |
 LL |     y.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:212:28
+  --> $DIR/eta.rs:213:28
    |
 LL |     z.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:219:21
+  --> $DIR/eta.rs:220:21
    |
 LL |         Some(1).map(|n| closure(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
 
 error: redundant closure
-  --> $DIR/eta.rs:223:21
+  --> $DIR/eta.rs:224:21
    |
 LL |         Some(1).map(|n| in_loop(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
 
 error: redundant closure
-  --> $DIR/eta.rs:316:18
+  --> $DIR/eta.rs:317:18
    |
 LL |     takes_fn_mut(|| f());
    |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> $DIR/eta.rs:319:19
+  --> $DIR/eta.rs:320:19
    |
 LL |     takes_fn_once(|| f());
    |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> $DIR/eta.rs:323:26
+  --> $DIR/eta.rs:324:26
    |
 LL |     move || takes_fn_mut(|| f_used_once())
    |                          ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
 
 error: redundant closure
-  --> $DIR/eta.rs:335:19
+  --> $DIR/eta.rs:336:19
    |
 LL |     array_opt.map(|a| a.as_slice());
    |                   ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
 
 error: redundant closure
-  --> $DIR/eta.rs:338:19
+  --> $DIR/eta.rs:339:19
    |
 LL |     slice_opt.map(|s| s.len());
    |                   ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
 
 error: redundant closure
-  --> $DIR/eta.rs:341:17
+  --> $DIR/eta.rs:342:17
    |
 LL |     ptr_opt.map(|p| p.is_null());
    |                 ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
 
 error: redundant closure
-  --> $DIR/eta.rs:345:17
+  --> $DIR/eta.rs:346:17
    |
 LL |     dyn_opt.map(|d| d.method_on_dyn());
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
 
 error: redundant closure
-  --> $DIR/eta.rs:388:19
+  --> $DIR/eta.rs:389:19
    |
 LL |     let _ = f(&0, |x, y| f2(x, y));
    |                   ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
index a4943344a11..c9bebabdf17 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
@@ -113,4 +113,19 @@ with_span!(
     }
 );
 
+mod issue11302 {
+    use std::fmt::Debug;
+    use std::marker::PhantomData;
+
+    #[derive(Debug)]
+    struct Wrapper<T>(PhantomData<T>);
+
+    fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)
+    where
+        Wrapper<T>: Debug,
+    {
+        v.push(Box::new(Wrapper(PhantomData)));
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
index 6d85b1ce9d4..1bc0047adf0 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
@@ -113,4 +113,19 @@ with_span!(
     }
 );
 
+mod issue11302 {
+    use std::fmt::Debug;
+    use std::marker::PhantomData;
+
+    #[derive(Debug)]
+    struct Wrapper<T>(PhantomData<T>);
+
+    fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)
+    where
+        Wrapper<T>: Debug,
+    {
+        v.push(Box::new(Wrapper(PhantomData)));
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
index 6de870a9289..6a1b81fdbcb 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
@@ -55,3 +55,27 @@ fn main() {
 fn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {
     iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()
 }
+
+fn issue11503() {
+    let bools: &[bool] = &[true, false, false, true];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| *b).map(|(i, b)| i).collect();
+
+    // Need to insert multiple derefs if there is more than one layer of references
+    let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ***b).map(|(i, b)| i).collect();
+
+    // Should also suggest derefs when going through a mutable reference
+    let bools: &[&mut bool] = &[&mut true];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| **b).map(|(i, b)| i).collect();
+
+    // Should also suggest derefs when going through a custom deref
+    struct DerefToBool;
+    impl std::ops::Deref for DerefToBool {
+        type Target = bool;
+        fn deref(&self) -> &Self::Target {
+            &true
+        }
+    }
+    let bools: &[&&DerefToBool] = &[&&DerefToBool];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ****b).map(|(i, b)| i).collect();
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.rs b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
index 4108177e3a0..a41e88f8805 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.rs
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
@@ -55,3 +55,27 @@ fn main() {
 fn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {
     iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()
 }
+
+fn issue11503() {
+    let bools: &[bool] = &[true, false, false, true];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+    // Need to insert multiple derefs if there is more than one layer of references
+    let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+    // Should also suggest derefs when going through a mutable reference
+    let bools: &[&mut bool] = &[&mut true];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+    // Should also suggest derefs when going through a custom deref
+    struct DerefToBool;
+    impl std::ops::Deref for DerefToBool {
+        type Target = bool;
+        fn deref(&self) -> &Self::Target {
+            &true
+        }
+    }
+    let bools: &[&&DerefToBool] = &[&&DerefToBool];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
index 86ef6edf8ee..fab6987913a 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
@@ -37,5 +37,29 @@ error: usage of `bool::then` in `filter_map`
 LL |     v.clone().iter().filter_map(|i| (i == &NonCopy).then(|| i));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i == &NonCopy)).map(|i| i)`
 
-error: aborting due to 6 previous errors
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:61:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| *b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:65:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ***b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:69:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| **b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:80:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ****b).map(|(i, b)| i)`
+
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.rs b/src/tools/clippy/tests/ui/len_without_is_empty.rs
index ac6c3e06365..d623601110e 100644
--- a/src/tools/clippy/tests/ui/len_without_is_empty.rs
+++ b/src/tools/clippy/tests/ui/len_without_is_empty.rs
@@ -436,4 +436,27 @@ impl DifferingErrors {
     }
 }
 
+// Issue #11165
+pub struct Aliased1;
+pub type Alias1 = Aliased1;
+
+impl Alias1 {
+    pub fn len(&self) -> usize {
+        todo!()
+    }
+
+    pub fn is_empty(&self) -> bool {
+        todo!()
+    }
+}
+
+pub struct Aliased2;
+pub type Alias2 = Aliased2;
+impl Alias2 {
+    pub fn len(&self) -> usize {
+        //~^ ERROR: type `Alias2` has a public `len` method, but no `is_empty` method
+        todo!()
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.stderr b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
index 4815ce6a04b..8e51c28b330 100644
--- a/src/tools/clippy/tests/ui/len_without_is_empty.stderr
+++ b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
@@ -141,5 +141,11 @@ error: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `
 LL |     pub async fn len(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 15 previous errors
+error: type `Alias2` has a public `len` method, but no `is_empty` method
+  --> $DIR/len_without_is_empty.rs:456:5
+   |
+LL |     pub fn len(&self) -> usize {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed
index 57374bd5fcd..f98ce9d50a9 100644
--- a/src/tools/clippy/tests/ui/let_unit.fixed
+++ b/src/tools/clippy/tests/ui/let_unit.fixed
@@ -177,3 +177,5 @@ fn attributes() {
 async fn issue10433() {
     let _pending: () = std::future::pending().await;
 }
+
+pub async fn issue11502(a: ()) {}
diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs
index 09077c60d50..6d942ca8908 100644
--- a/src/tools/clippy/tests/ui/let_unit.rs
+++ b/src/tools/clippy/tests/ui/let_unit.rs
@@ -177,3 +177,5 @@ fn attributes() {
 async fn issue10433() {
     let _pending: () = std::future::pending().await;
 }
+
+pub async fn issue11502(a: ()) {}
diff --git a/src/tools/clippy/tests/ui/manual_map_option.fixed b/src/tools/clippy/tests/ui/manual_map_option.fixed
index f6a964da418..16cee3fd382 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.fixed
+++ b/src/tools/clippy/tests/ui/manual_map_option.fixed
@@ -5,6 +5,7 @@
     clippy::unit_arg,
     clippy::match_ref_pats,
     clippy::redundant_pattern_matching,
+    clippy::unnecessary_map_on_constructor,
     for_loops_over_fallibles,
     dead_code
 )]
diff --git a/src/tools/clippy/tests/ui/manual_map_option.rs b/src/tools/clippy/tests/ui/manual_map_option.rs
index df9dc256d30..4655acf1406 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.rs
+++ b/src/tools/clippy/tests/ui/manual_map_option.rs
@@ -5,6 +5,7 @@
     clippy::unit_arg,
     clippy::match_ref_pats,
     clippy::redundant_pattern_matching,
+    clippy::unnecessary_map_on_constructor,
     for_loops_over_fallibles,
     dead_code
 )]
diff --git a/src/tools/clippy/tests/ui/manual_map_option.stderr b/src/tools/clippy/tests/ui/manual_map_option.stderr
index ff6ed974d4a..3754a982cb9 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.stderr
+++ b/src/tools/clippy/tests/ui/manual_map_option.stderr
@@ -1,5 +1,5 @@
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:13:5
+  --> $DIR/manual_map_option.rs:14:5
    |
 LL | /     match Some(0) {
 LL | |         Some(_) => Some(2),
@@ -11,7 +11,7 @@ LL | |     };
    = help: to override `-D warnings` add `#[allow(clippy::manual_map)]`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:18:5
+  --> $DIR/manual_map_option.rs:19:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => Some(x + 1),
@@ -20,7 +20,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| x + 1)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:23:5
+  --> $DIR/manual_map_option.rs:24:5
    |
 LL | /     match Some("") {
 LL | |         Some(x) => Some(x.is_empty()),
@@ -29,7 +29,7 @@ LL | |     };
    | |_____^ help: try: `Some("").map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:28:5
+  --> $DIR/manual_map_option.rs:29:5
    |
 LL | /     if let Some(x) = Some(0) {
 LL | |         Some(!x)
@@ -39,7 +39,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| !x)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:35:5
+  --> $DIR/manual_map_option.rs:36:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => { Some(std::convert::identity(x)) }
@@ -48,7 +48,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(std::convert::identity)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:40:5
+  --> $DIR/manual_map_option.rs:41:5
    |
 LL | /     match Some(&String::new()) {
 LL | |         Some(x) => Some(str::len(x)),
@@ -57,7 +57,7 @@ LL | |     };
    | |_____^ help: try: `Some(&String::new()).map(|x| str::len(x))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:50:5
+  --> $DIR/manual_map_option.rs:51:5
    |
 LL | /     match &Some([0, 1]) {
 LL | |         Some(x) => Some(x[0]),
@@ -66,7 +66,7 @@ LL | |     };
    | |_____^ help: try: `Some([0, 1]).as_ref().map(|x| x[0])`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:55:5
+  --> $DIR/manual_map_option.rs:56:5
    |
 LL | /     match &Some(0) {
 LL | |         &Some(x) => Some(x * 2),
@@ -75,7 +75,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| x * 2)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:60:5
+  --> $DIR/manual_map_option.rs:61:5
    |
 LL | /     match Some(String::new()) {
 LL | |         Some(ref x) => Some(x.is_empty()),
@@ -84,7 +84,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:65:5
+  --> $DIR/manual_map_option.rs:66:5
    |
 LL | /     match &&Some(String::new()) {
 LL | |         Some(x) => Some(x.len()),
@@ -93,7 +93,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:70:5
+  --> $DIR/manual_map_option.rs:71:5
    |
 LL | /     match &&Some(0) {
 LL | |         &&Some(x) => Some(x + x),
@@ -102,7 +102,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| x + x)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:83:9
+  --> $DIR/manual_map_option.rs:84:9
    |
 LL | /         match &mut Some(String::new()) {
 LL | |             Some(x) => Some(x.push_str("")),
@@ -111,7 +111,7 @@ LL | |         };
    | |_________^ help: try: `Some(String::new()).as_mut().map(|x| x.push_str(""))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:89:5
+  --> $DIR/manual_map_option.rs:90:5
    |
 LL | /     match &mut Some(String::new()) {
 LL | |         Some(ref x) => Some(x.len()),
@@ -120,7 +120,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:94:5
+  --> $DIR/manual_map_option.rs:95:5
    |
 LL | /     match &mut &Some(String::new()) {
 LL | |         Some(x) => Some(x.is_empty()),
@@ -129,7 +129,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:99:5
+  --> $DIR/manual_map_option.rs:100:5
    |
 LL | /     match Some((0, 1, 2)) {
 LL | |         Some((x, y, z)) => Some(x + y + z),
@@ -138,7 +138,7 @@ LL | |     };
    | |_____^ help: try: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:104:5
+  --> $DIR/manual_map_option.rs:105:5
    |
 LL | /     match Some([1, 2, 3]) {
 LL | |         Some([first, ..]) => Some(first),
@@ -147,7 +147,7 @@ LL | |     };
    | |_____^ help: try: `Some([1, 2, 3]).map(|[first, ..]| first)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:109:5
+  --> $DIR/manual_map_option.rs:110:5
    |
 LL | /     match &Some((String::new(), "test")) {
 LL | |         Some((x, y)) => Some((y, x)),
@@ -156,7 +156,7 @@ LL | |     };
    | |_____^ help: try: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:167:5
+  --> $DIR/manual_map_option.rs:168:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => Some(vec![x]),
@@ -165,7 +165,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| vec![x])`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:172:5
+  --> $DIR/manual_map_option.rs:173:5
    |
 LL | /     match option_env!("") {
 LL | |         Some(x) => Some(String::from(x)),
@@ -174,7 +174,7 @@ LL | |     };
    | |_____^ help: try: `option_env!("").map(String::from)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:192:12
+  --> $DIR/manual_map_option.rs:193:12
    |
 LL |       } else if let Some(x) = Some(0) {
    |  ____________^
@@ -185,7 +185,7 @@ LL | |     };
    | |_____^ help: try: `{ Some(0).map(|x| x + 1) }`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:200:12
+  --> $DIR/manual_map_option.rs:201:12
    |
 LL |       } else if let Some(x) = Some(0) {
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index 0a52b25229d..c2c5f765abf 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -131,21 +131,6 @@ fn main() {
             0
         }
     }
-
-    let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
-    let _ = std::path::Path::new(".").join(".");
-    deref_target_is_x(X);
-    multiple_constraints([[""]]);
-    multiple_constraints_normalizes_to_same(X, X);
-    let _ = Some("").unwrap_or("");
-    let _ = std::fs::write("x", "".to_string());
-
-    only_sized(&""); // Don't lint. `Sized` is only bound
-    let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
-    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
-    ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
-    refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
-    multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
 }
 
 #[allow(clippy::needless_borrowed_reference)]
@@ -201,103 +186,6 @@ mod issue9160 {
     }
 }
 
-#[derive(Clone, Copy)]
-struct X;
-
-impl std::ops::Deref for X {
-    type Target = X;
-    fn deref(&self) -> &Self::Target {
-        self
-    }
-}
-
-fn deref_target_is_x<T>(_: T)
-where
-    T: std::ops::Deref<Target = X>,
-{
-}
-
-fn multiple_constraints<T, U, V, X, Y>(_: T)
-where
-    T: IntoIterator<Item = U> + IntoIterator<Item = X>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-    X: IntoIterator<Item = Y>,
-    Y: AsRef<std::ffi::OsStr>,
-{
-}
-
-fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
-where
-    T: std::ops::Deref<Target = U>,
-    U: std::ops::Deref<Target = V>,
-{
-}
-
-fn only_sized<T>(_: T) {}
-
-fn ref_as_ref_path<T: 'static>(_: &'static T)
-where
-    &'static T: AsRef<std::path::Path>,
-{
-}
-
-trait RefsOnly {
-    type Referent;
-}
-
-impl<T> RefsOnly for &T {
-    type Referent = T;
-}
-
-fn refs_only<T, U>(_: T)
-where
-    T: RefsOnly<Referent = U>,
-{
-}
-
-fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
-where
-    T: IntoIterator<Item = U>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-{
-}
-
-// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-mod copyable_iterator {
-    #[derive(Clone, Copy)]
-    struct Iter;
-    impl Iterator for Iter {
-        type Item = ();
-        fn next(&mut self) -> Option<Self::Item> {
-            None
-        }
-    }
-    fn takes_iter(_: impl Iterator) {}
-    fn dont_warn(mut x: Iter) {
-        takes_iter(&mut x);
-    }
-    #[allow(unused_mut)]
-    fn warn(mut x: &mut Iter) {
-        takes_iter(x)
-    }
-}
-
-#[clippy::msrv = "1.52.0"]
-mod under_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    }
-}
-
-#[clippy::msrv = "1.53.0"]
-mod meets_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
-    }
-}
-
 fn issue9383() {
     // Should not lint because unions need explicit deref when accessing field
     use std::mem::ManuallyDrop;
@@ -326,184 +214,6 @@ fn issue9383() {
     }
 }
 
-fn closure_test() {
-    let env = "env".to_owned();
-    let arg = "arg".to_owned();
-    let f = |arg| {
-        let loc = "loc".to_owned();
-        let _ = std::fs::write("x", &env); // Don't lint. In environment
-        let _ = std::fs::write("x", arg);
-        let _ = std::fs::write("x", loc);
-    };
-    let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
-    f(arg);
-}
-
-mod significant_drop {
-    #[derive(Debug)]
-    struct X;
-
-    #[derive(Debug)]
-    struct Y;
-
-    impl Drop for Y {
-        fn drop(&mut self) {}
-    }
-
-    fn foo(x: X, y: Y) {
-        debug(x);
-        debug(&y); // Don't lint. Has significant drop
-    }
-
-    fn debug(_: impl std::fmt::Debug) {}
-}
-
-mod used_exactly_once {
-    fn foo(x: String) {
-        use_x(x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-}
-
-mod used_more_than_once {
-    fn foo(x: String) {
-        use_x(&x);
-        use_x_again(&x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-    fn use_x_again(_: impl AsRef<str>) {}
-}
-
-// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
-mod issue_9111 {
-    struct A;
-
-    impl Extend<u8> for A {
-        fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    impl<'a> Extend<&'a u8> for A {
-        fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    fn main() {
-        let mut a = A;
-        a.extend(&[]); // vs a.extend([]);
-    }
-}
-
-mod issue_9710 {
-    fn main() {
-        let string = String::new();
-        for _i in 0..10 {
-            f(&string);
-        }
-    }
-
-    fn f<T: AsRef<str>>(_: T) {}
-}
-
-mod issue_9739 {
-    fn foo<D: std::fmt::Display>(_it: impl IntoIterator<Item = D>) {}
-
-    fn main() {
-        foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9739_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<D: std::fmt::Display>(&self, _it: impl IntoIterator<Item = D>) {}
-    }
-
-    fn main() {
-        S.foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9782 {
-    fn foo<T: AsRef<[u8]>>(t: T) {
-        println!("{}", std::mem::size_of::<T>());
-        let _t: &[u8] = t.as_ref();
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        // 100
-        foo::<[u8; 100]>(a);
-        foo(a);
-
-        // 16
-        foo::<&[u8]>(&a);
-        foo(a.as_slice());
-
-        // 8
-        foo::<&[u8; 100]>(&a);
-        foo(a);
-    }
-}
-
-mod issue_9782_type_relative_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S::foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_9782_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(&self, t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S.foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_10535 {
-    static SOME_STATIC: String = String::new();
-
-    static UNIT: () = compute(&SOME_STATIC);
-
-    pub const fn compute<T>(_: T)
-    where
-        T: Copy,
-    {
-    }
-}
-
 mod issue_10253 {
     struct S;
     trait X {
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 34a95d18463..0cd6e41b8a4 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -131,21 +131,6 @@ fn main() {
             0
         }
     }
-
-    let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    let _ = std::path::Path::new(".").join(&&".");
-    deref_target_is_x(&X);
-    multiple_constraints(&[[""]]);
-    multiple_constraints_normalizes_to_same(&X, X);
-    let _ = Some("").unwrap_or(&"");
-    let _ = std::fs::write("x", &"".to_string());
-
-    only_sized(&""); // Don't lint. `Sized` is only bound
-    let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
-    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
-    ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
-    refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
-    multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
 }
 
 #[allow(clippy::needless_borrowed_reference)]
@@ -201,103 +186,6 @@ mod issue9160 {
     }
 }
 
-#[derive(Clone, Copy)]
-struct X;
-
-impl std::ops::Deref for X {
-    type Target = X;
-    fn deref(&self) -> &Self::Target {
-        self
-    }
-}
-
-fn deref_target_is_x<T>(_: T)
-where
-    T: std::ops::Deref<Target = X>,
-{
-}
-
-fn multiple_constraints<T, U, V, X, Y>(_: T)
-where
-    T: IntoIterator<Item = U> + IntoIterator<Item = X>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-    X: IntoIterator<Item = Y>,
-    Y: AsRef<std::ffi::OsStr>,
-{
-}
-
-fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
-where
-    T: std::ops::Deref<Target = U>,
-    U: std::ops::Deref<Target = V>,
-{
-}
-
-fn only_sized<T>(_: T) {}
-
-fn ref_as_ref_path<T: 'static>(_: &'static T)
-where
-    &'static T: AsRef<std::path::Path>,
-{
-}
-
-trait RefsOnly {
-    type Referent;
-}
-
-impl<T> RefsOnly for &T {
-    type Referent = T;
-}
-
-fn refs_only<T, U>(_: T)
-where
-    T: RefsOnly<Referent = U>,
-{
-}
-
-fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
-where
-    T: IntoIterator<Item = U>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-{
-}
-
-// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-mod copyable_iterator {
-    #[derive(Clone, Copy)]
-    struct Iter;
-    impl Iterator for Iter {
-        type Item = ();
-        fn next(&mut self) -> Option<Self::Item> {
-            None
-        }
-    }
-    fn takes_iter(_: impl Iterator) {}
-    fn dont_warn(mut x: Iter) {
-        takes_iter(&mut x);
-    }
-    #[allow(unused_mut)]
-    fn warn(mut x: &mut Iter) {
-        takes_iter(&mut x)
-    }
-}
-
-#[clippy::msrv = "1.52.0"]
-mod under_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    }
-}
-
-#[clippy::msrv = "1.53.0"]
-mod meets_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    }
-}
-
 fn issue9383() {
     // Should not lint because unions need explicit deref when accessing field
     use std::mem::ManuallyDrop;
@@ -326,184 +214,6 @@ fn issue9383() {
     }
 }
 
-fn closure_test() {
-    let env = "env".to_owned();
-    let arg = "arg".to_owned();
-    let f = |arg| {
-        let loc = "loc".to_owned();
-        let _ = std::fs::write("x", &env); // Don't lint. In environment
-        let _ = std::fs::write("x", &arg);
-        let _ = std::fs::write("x", &loc);
-    };
-    let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
-    f(arg);
-}
-
-mod significant_drop {
-    #[derive(Debug)]
-    struct X;
-
-    #[derive(Debug)]
-    struct Y;
-
-    impl Drop for Y {
-        fn drop(&mut self) {}
-    }
-
-    fn foo(x: X, y: Y) {
-        debug(&x);
-        debug(&y); // Don't lint. Has significant drop
-    }
-
-    fn debug(_: impl std::fmt::Debug) {}
-}
-
-mod used_exactly_once {
-    fn foo(x: String) {
-        use_x(&x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-}
-
-mod used_more_than_once {
-    fn foo(x: String) {
-        use_x(&x);
-        use_x_again(&x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-    fn use_x_again(_: impl AsRef<str>) {}
-}
-
-// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
-mod issue_9111 {
-    struct A;
-
-    impl Extend<u8> for A {
-        fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    impl<'a> Extend<&'a u8> for A {
-        fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    fn main() {
-        let mut a = A;
-        a.extend(&[]); // vs a.extend([]);
-    }
-}
-
-mod issue_9710 {
-    fn main() {
-        let string = String::new();
-        for _i in 0..10 {
-            f(&string);
-        }
-    }
-
-    fn f<T: AsRef<str>>(_: T) {}
-}
-
-mod issue_9739 {
-    fn foo<D: std::fmt::Display>(_it: impl IntoIterator<Item = D>) {}
-
-    fn main() {
-        foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9739_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<D: std::fmt::Display>(&self, _it: impl IntoIterator<Item = D>) {}
-    }
-
-    fn main() {
-        S.foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9782 {
-    fn foo<T: AsRef<[u8]>>(t: T) {
-        println!("{}", std::mem::size_of::<T>());
-        let _t: &[u8] = t.as_ref();
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        // 100
-        foo::<[u8; 100]>(a);
-        foo(a);
-
-        // 16
-        foo::<&[u8]>(&a);
-        foo(a.as_slice());
-
-        // 8
-        foo::<&[u8; 100]>(&a);
-        foo(&a);
-    }
-}
-
-mod issue_9782_type_relative_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S::foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_9782_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(&self, t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S.foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_10535 {
-    static SOME_STATIC: String = String::new();
-
-    static UNIT: () = compute(&SOME_STATIC);
-
-    pub const fn compute<T>(_: T)
-    where
-        T: Copy,
-    {
-    }
-}
-
 mod issue_10253 {
     struct S;
     trait X {
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index 8e27014d53c..e91b78b0a15 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -121,101 +121,17 @@ error: this expression creates a reference which is immediately dereferenced by
 LL |     (&&5).foo();
    |     ^^^^^ help: change this to: `(&5)`
 
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:135:51
-   |
-LL |     let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-   |                                                   ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:136:44
-   |
-LL |     let _ = std::path::Path::new(".").join(&&".");
-   |                                            ^^^^^ help: change this to: `"."`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:137:23
-   |
-LL |     deref_target_is_x(&X);
-   |                       ^^ help: change this to: `X`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:138:26
-   |
-LL |     multiple_constraints(&[[""]]);
-   |                          ^^^^^^^ help: change this to: `[[""]]`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:139:45
-   |
-LL |     multiple_constraints_normalizes_to_same(&X, X);
-   |                                             ^^ help: change this to: `X`
-
-error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:140:32
-   |
-LL |     let _ = Some("").unwrap_or(&"");
-   |                                ^^^ help: change this to: `""`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:141:33
-   |
-LL |     let _ = std::fs::write("x", &"".to_string());
-   |                                 ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()`
-
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:190:13
+  --> $DIR/needless_borrow.rs:175:13
    |
 LL |             (&self.f)()
    |             ^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:199:13
+  --> $DIR/needless_borrow.rs:184:13
    |
 LL |             (&mut self.f)()
    |             ^^^^^^^^^^^^^ help: change this to: `(self.f)`
 
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:283:20
-   |
-LL |         takes_iter(&mut x)
-   |                    ^^^^^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:297:55
-   |
-LL |         let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-   |                                                       ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:335:37
-   |
-LL |         let _ = std::fs::write("x", &arg);
-   |                                     ^^^^ help: change this to: `arg`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:336:37
-   |
-LL |         let _ = std::fs::write("x", &loc);
-   |                                     ^^^^ help: change this to: `loc`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:354:15
-   |
-LL |         debug(&x);
-   |               ^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:363:15
-   |
-LL |         use_x(&x);
-   |               ^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:457:13
-   |
-LL |         foo(&a);
-   |             ^^ help: change this to: `a`
-
-error: aborting due to 36 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
new file mode 100644
index 00000000000..2a335516f51
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
@@ -0,0 +1,287 @@
+#![warn(clippy::needless_borrows_for_generic_args)]
+#![allow(
+    clippy::unnecessary_to_owned,
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_borrow
+)]
+
+use core::ops::Deref;
+use std::any::Any;
+use std::ffi::OsStr;
+use std::fmt::{Debug, Display};
+use std::path::Path;
+use std::process::Command;
+
+fn main() {
+    let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap();
+    let _ = Path::new(".").join(".");
+    let _ = Any::type_id(&""); // Don't lint. `Any` is only bound
+    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+    let _ = Some("").unwrap_or(&"");
+    let _ = std::fs::write("x", "".to_string());
+
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}
+
+        deref_target_is_x(X);
+    }
+    {
+        fn multiple_constraints<T, U, V, X, Y>(_: T)
+        where
+            T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+            X: IntoIterator<Item = Y>,
+            Y: AsRef<OsStr>,
+        {
+        }
+
+        multiple_constraints([[""]]);
+    }
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+        where
+            T: Deref<Target = U>,
+            U: Deref<Target = V>,
+        {
+        }
+
+        multiple_constraints_normalizes_to_same(X, X);
+    }
+    {
+        fn only_sized<T>(_: T) {}
+        only_sized(&""); // Don't lint. `Sized` is only bound
+    }
+    {
+        fn ref_as_ref_path<T: 'static>(_: &'static T)
+        where
+            &'static T: AsRef<Path>,
+        {
+        }
+
+        ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+    }
+    {
+        trait RefsOnly {
+            type Referent;
+        }
+
+        impl<T> RefsOnly for &T {
+            type Referent = T;
+        }
+
+        fn refs_only<T, U>(_: T)
+        where
+            T: RefsOnly<Referent = U>,
+        {
+        }
+
+        refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+    }
+    {
+        fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+        where
+            T: IntoIterator<Item = U>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+        {
+        }
+        multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
+    }
+    // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+    {
+        #[derive(Clone, Copy)]
+        struct Iter;
+        impl Iterator for Iter {
+            type Item = ();
+            fn next(&mut self) -> Option<Self::Item> {
+                None
+            }
+        }
+        fn takes_iter(_: impl Iterator) {}
+        fn dont_warn(mut x: Iter) {
+            takes_iter(&mut x);
+        }
+        #[allow(unused_mut)]
+        fn warn(mut x: &mut Iter) {
+            takes_iter(x)
+        }
+    }
+    #[clippy::msrv = "1.52.0"]
+    {
+        let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    };
+    #[clippy::msrv = "1.53.0"]
+    {
+        let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap();
+    };
+    {
+        let env = "env".to_owned();
+        let arg = "arg".to_owned();
+        let f = |arg| {
+            let loc = "loc".to_owned();
+            let _ = std::fs::write("x", &env); // Don't lint. In environment
+            let _ = std::fs::write("x", arg);
+            let _ = std::fs::write("x", loc);
+        };
+        let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
+        f(arg);
+    }
+    {
+        #[derive(Debug)]
+        struct X;
+
+        impl Drop for X {
+            fn drop(&mut self) {}
+        }
+
+        fn f(_: impl Debug) {}
+
+        let x = X;
+        f(&x); // Don't lint. Has significant drop
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(x);
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+        fn f2(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(&x);
+        f2(&x);
+    }
+    // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
+    // issue 9111
+    {
+        struct A;
+
+        impl Extend<u8> for A {
+            fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        impl<'a> Extend<&'a u8> for A {
+            fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        let mut a = A;
+        a.extend(&[]); // vs a.extend([]);
+    }
+    // issue 9710
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        for _ in 0..10 {
+            f(&x);
+        }
+    }
+    // issue 9739
+    {
+        fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}
+        foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}
+        }
+
+        S.foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    // issue 9782
+    {
+        fn foo<T: AsRef<[u8]>>(t: T) {
+            println!("{}", std::mem::size_of::<T>());
+            let _t: &[u8] = t.as_ref();
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+
+        // 100
+        foo::<[u8; 100]>(a);
+        foo(a);
+
+        // 16
+        foo::<&[u8]>(&a);
+        foo(a.as_slice());
+
+        // 8
+        foo::<&[u8; 100]>(&a);
+        foo(a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S::foo::<&[u8; 100]>(&a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(&self, t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S.foo::<&[u8; 100]>(&a);
+    }
+    // issue 10535
+    {
+        static SOME_STATIC: String = String::new();
+
+        static UNIT: () = compute(&SOME_STATIC);
+
+        pub const fn compute<T>(_: T)
+        where
+            T: Copy,
+        {
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
new file mode 100644
index 00000000000..f0567f486ac
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
@@ -0,0 +1,287 @@
+#![warn(clippy::needless_borrows_for_generic_args)]
+#![allow(
+    clippy::unnecessary_to_owned,
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_borrow
+)]
+
+use core::ops::Deref;
+use std::any::Any;
+use std::ffi::OsStr;
+use std::fmt::{Debug, Display};
+use std::path::Path;
+use std::process::Command;
+
+fn main() {
+    let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    let _ = Path::new(".").join(&&".");
+    let _ = Any::type_id(&""); // Don't lint. `Any` is only bound
+    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+    let _ = Some("").unwrap_or(&"");
+    let _ = std::fs::write("x", &"".to_string());
+
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}
+
+        deref_target_is_x(&X);
+    }
+    {
+        fn multiple_constraints<T, U, V, X, Y>(_: T)
+        where
+            T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+            X: IntoIterator<Item = Y>,
+            Y: AsRef<OsStr>,
+        {
+        }
+
+        multiple_constraints(&[[""]]);
+    }
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+        where
+            T: Deref<Target = U>,
+            U: Deref<Target = V>,
+        {
+        }
+
+        multiple_constraints_normalizes_to_same(&X, X);
+    }
+    {
+        fn only_sized<T>(_: T) {}
+        only_sized(&""); // Don't lint. `Sized` is only bound
+    }
+    {
+        fn ref_as_ref_path<T: 'static>(_: &'static T)
+        where
+            &'static T: AsRef<Path>,
+        {
+        }
+
+        ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+    }
+    {
+        trait RefsOnly {
+            type Referent;
+        }
+
+        impl<T> RefsOnly for &T {
+            type Referent = T;
+        }
+
+        fn refs_only<T, U>(_: T)
+        where
+            T: RefsOnly<Referent = U>,
+        {
+        }
+
+        refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+    }
+    {
+        fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+        where
+            T: IntoIterator<Item = U>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+        {
+        }
+        multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
+    }
+    // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+    {
+        #[derive(Clone, Copy)]
+        struct Iter;
+        impl Iterator for Iter {
+            type Item = ();
+            fn next(&mut self) -> Option<Self::Item> {
+                None
+            }
+        }
+        fn takes_iter(_: impl Iterator) {}
+        fn dont_warn(mut x: Iter) {
+            takes_iter(&mut x);
+        }
+        #[allow(unused_mut)]
+        fn warn(mut x: &mut Iter) {
+            takes_iter(&mut x)
+        }
+    }
+    #[clippy::msrv = "1.52.0"]
+    {
+        let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    };
+    #[clippy::msrv = "1.53.0"]
+    {
+        let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    };
+    {
+        let env = "env".to_owned();
+        let arg = "arg".to_owned();
+        let f = |arg| {
+            let loc = "loc".to_owned();
+            let _ = std::fs::write("x", &env); // Don't lint. In environment
+            let _ = std::fs::write("x", &arg);
+            let _ = std::fs::write("x", &loc);
+        };
+        let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
+        f(arg);
+    }
+    {
+        #[derive(Debug)]
+        struct X;
+
+        impl Drop for X {
+            fn drop(&mut self) {}
+        }
+
+        fn f(_: impl Debug) {}
+
+        let x = X;
+        f(&x); // Don't lint. Has significant drop
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(&x);
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+        fn f2(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(&x);
+        f2(&x);
+    }
+    // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
+    // issue 9111
+    {
+        struct A;
+
+        impl Extend<u8> for A {
+            fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        impl<'a> Extend<&'a u8> for A {
+            fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        let mut a = A;
+        a.extend(&[]); // vs a.extend([]);
+    }
+    // issue 9710
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        for _ in 0..10 {
+            f(&x);
+        }
+    }
+    // issue 9739
+    {
+        fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}
+        foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}
+        }
+
+        S.foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    // issue 9782
+    {
+        fn foo<T: AsRef<[u8]>>(t: T) {
+            println!("{}", std::mem::size_of::<T>());
+            let _t: &[u8] = t.as_ref();
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+
+        // 100
+        foo::<[u8; 100]>(a);
+        foo(a);
+
+        // 16
+        foo::<&[u8]>(&a);
+        foo(a.as_slice());
+
+        // 8
+        foo::<&[u8; 100]>(&a);
+        foo(&a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S::foo::<&[u8; 100]>(&a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(&self, t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S.foo::<&[u8; 100]>(&a);
+    }
+    // issue 10535
+    {
+        static SOME_STATIC: String = String::new();
+
+        static UNIT: () = compute(&SOME_STATIC);
+
+        pub const fn compute<T>(_: T)
+        where
+            T: Copy,
+        {
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr
new file mode 100644
index 00000000000..e2cde2c59a6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr
@@ -0,0 +1,77 @@
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:16:37
+   |
+LL |     let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+   |                                     ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+   |
+   = note: `-D clippy::needless-borrows-for-generic-args` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_borrows_for_generic_args)]`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:17:33
+   |
+LL |     let _ = Path::new(".").join(&&".");
+   |                                 ^^^^^ help: change this to: `"."`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:21:33
+   |
+LL |     let _ = std::fs::write("x", &"".to_string());
+   |                                 ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:36:27
+   |
+LL |         deref_target_is_x(&X);
+   |                           ^^ help: change this to: `X`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:49:30
+   |
+LL |         multiple_constraints(&[[""]]);
+   |                              ^^^^^^^ help: change this to: `[[""]]`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:69:49
+   |
+LL |         multiple_constraints_normalizes_to_same(&X, X);
+   |                                                 ^^ help: change this to: `X`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:127:24
+   |
+LL |             takes_iter(&mut x)
+   |                        ^^^^^^ help: change this to: `x`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:136:41
+   |
+LL |         let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+   |                                         ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:144:41
+   |
+LL |             let _ = std::fs::write("x", &arg);
+   |                                         ^^^^ help: change this to: `arg`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:145:41
+   |
+LL |             let _ = std::fs::write("x", &loc);
+   |                                         ^^^^ help: change this to: `loc`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:167:11
+   |
+LL |         f(&x);
+   |           ^^ help: change this to: `x`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:247:13
+   |
+LL |         foo(&a);
+   |             ^^ help: change this to: `a`
+
+error: aborting due to 12 previous errors
+
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
index e1e5e8fd220..9cddcb3df23 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::if_same_then_else, clippy::no_effect)]
+#![allow(clippy::if_same_then_else, clippy::no_effect, clippy::redundant_closure_call)]
 #![feature(lint_reasons)]
 //@no-rustfix
 use std::ptr::NonNull;
@@ -230,6 +230,44 @@ async fn async_vec(b: &mut Vec<bool>) {
 async fn async_vec2(b: &mut Vec<bool>) {
     b.push(true);
 }
+fn non_mut(n: &str) {}
+//Should warn
+pub async fn call_in_closure1(n: &mut str) {
+    (|| non_mut(n))()
+}
+fn str_mut(str: &mut String) -> bool {
+    str.pop().is_some()
+}
+//Should not warn
+pub async fn call_in_closure2(str: &mut String) {
+    (|| str_mut(str))();
+}
+
+// Should not warn.
+pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
+    || {
+        *n += 1;
+    }
+}
+
+// Should warn.
+pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    || *n + 1
+}
+
+// Should not warn.
+pub async fn closure3(n: &mut usize) {
+    (|| *n += 1)();
+}
+
+// Should warn.
+pub async fn closure4(n: &mut usize) {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    (|| {
+        let _x = *n + 1;
+    })();
+}
 
 fn main() {
     let mut u = 0;
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
index df3df045776..0c7fbd5df6d 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
@@ -107,5 +107,37 @@ error: this argument is a mutable reference, but not used mutably
 LL | async fn inner_async3(x: &mut i32, y: &mut u32) {
    |                          ^^^^^^^^ help: consider changing to: `&i32`
 
-error: aborting due to 17 previous errors
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:235:34
+   |
+LL | pub async fn call_in_closure1(n: &mut str) {
+   |                                  ^^^^^^^^ help: consider changing to: `&str`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:247:25
+   |
+LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
+   |                         ^^^^^^^^^^ help: consider changing to: `&usize`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:254:20
+   |
+LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
+   |                    ^^^^^^^^^^ help: consider changing to: `&usize`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:265:26
+   |
+LL | pub async fn closure4(n: &mut usize) {
+   |                          ^^^^^^^^^^ help: consider changing to: `&usize`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
index e980adeeff4..c99c2f46532 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
@@ -21,4 +21,7 @@ fn main() {
         multiline
         string
     ";
+
+    r"rust";
+    r"hello world";
 }
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
index 6113c5f25ae..dcc2af69f4e 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
@@ -21,4 +21,7 @@ fn main() {
         multiline
         string
     "#;
+
+    r###"rust"###;
+    r#"hello world"#;
 }
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
index 5a8e3d04543..4399c6555c2 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
@@ -163,5 +163,29 @@ LL |         string
 LL ~     ";
    |
 
-error: aborting due to 13 previous errors
+error: unnecessary hashes around raw string literal
+  --> $DIR/needless_raw_string_hashes.rs:25:5
+   |
+LL |     r###"rust"###;
+   |     ^^^^^^^^^^^^^
+   |
+help: remove all the hashes around the literal
+   |
+LL -     r###"rust"###;
+LL +     r"rust";
+   |
+
+error: unnecessary hashes around raw string literal
+  --> $DIR/needless_raw_string_hashes.rs:26:5
+   |
+LL |     r#"hello world"#;
+   |     ^^^^^^^^^^^^^^^^
+   |
+help: remove all the hashes around the literal
+   |
+LL -     r#"hello world"#;
+LL +     r"hello world";
+   |
+
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/no_effect_return.rs b/src/tools/clippy/tests/ui/no_effect_return.rs
index f6585aa30a6..e46c0d73518 100644
--- a/src/tools/clippy/tests/ui/no_effect_return.rs
+++ b/src/tools/clippy/tests/ui/no_effect_return.rs
@@ -76,6 +76,7 @@ fn h() -> Vec<u16> {
 
 fn i() -> () {
     {
+        // does not suggest on function with explicit unit return type
         ();
         //~^ ERROR: statement with no effect
     }
diff --git a/src/tools/clippy/tests/ui/no_effect_return.stderr b/src/tools/clippy/tests/ui/no_effect_return.stderr
index b036e634204..aed079f09b9 100644
--- a/src/tools/clippy/tests/ui/no_effect_return.stderr
+++ b/src/tools/clippy/tests/ui/no_effect_return.stderr
@@ -54,15 +54,13 @@ LL |         ControlFlow::Break::<()>(());
    |         help: did you mean to return it?: `return`
 
 error: statement with no effect
-  --> $DIR/no_effect_return.rs:79:9
+  --> $DIR/no_effect_return.rs:80:9
    |
 LL |         ();
-   |         -^^
-   |         |
-   |         help: did you mean to return it?: `return`
+   |         ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect_return.rs:88:9
+  --> $DIR/no_effect_return.rs:89:9
    |
 LL |         ();
    |         ^^^
diff --git a/src/tools/clippy/tests/ui/option_filter_map.fixed b/src/tools/clippy/tests/ui/option_filter_map.fixed
index d4c04ff907b..ee004c0e194 100644
--- a/src/tools/clippy/tests/ui/option_filter_map.fixed
+++ b/src/tools/clippy/tests/ui/option_filter_map.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::option_filter_map)]
-#![allow(clippy::map_flatten)]
+#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]
 
 fn main() {
     let _ = Some(Some(1)).flatten();
diff --git a/src/tools/clippy/tests/ui/option_filter_map.rs b/src/tools/clippy/tests/ui/option_filter_map.rs
index 99fb4723cab..eae2fa176a8 100644
--- a/src/tools/clippy/tests/ui/option_filter_map.rs
+++ b/src/tools/clippy/tests/ui/option_filter_map.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::option_filter_map)]
-#![allow(clippy::map_flatten)]
+#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]
 
 fn main() {
     let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap);
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.fixed b/src/tools/clippy/tests/ui/path_ends_with_ext.fixed
new file mode 100644
index 00000000000..49767e242ce
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.fixed
@@ -0,0 +1,36 @@
+#![warn(clippy::path_ends_with_ext)]
+use std::path::Path;
+
+macro_rules! arg {
+    () => {
+        ".md"
+    };
+}
+
+fn test(path: &Path) {
+    path.extension().is_some_and(|ext| ext == "md");
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+
+    // some "extensions" are allowed by default
+    path.ends_with(".git");
+
+    // most legitimate "dotfiles" are longer than 3 chars, so we allow them as well
+    path.ends_with(".bashrc");
+
+    // argument from expn shouldn't trigger
+    path.ends_with(arg!());
+
+    path.ends_with("..");
+    path.ends_with("./a");
+    path.ends_with(".");
+    path.ends_with("");
+}
+
+// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that
+#[clippy::msrv = "1.69"]
+fn under_msv(path: &Path) -> bool {
+    path.extension().map_or(false, |ext| ext == "md")
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.rs b/src/tools/clippy/tests/ui/path_ends_with_ext.rs
new file mode 100644
index 00000000000..2dfd046218a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.rs
@@ -0,0 +1,36 @@
+#![warn(clippy::path_ends_with_ext)]
+use std::path::Path;
+
+macro_rules! arg {
+    () => {
+        ".md"
+    };
+}
+
+fn test(path: &Path) {
+    path.ends_with(".md");
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+
+    // some "extensions" are allowed by default
+    path.ends_with(".git");
+
+    // most legitimate "dotfiles" are longer than 3 chars, so we allow them as well
+    path.ends_with(".bashrc");
+
+    // argument from expn shouldn't trigger
+    path.ends_with(arg!());
+
+    path.ends_with("..");
+    path.ends_with("./a");
+    path.ends_with(".");
+    path.ends_with("");
+}
+
+// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that
+#[clippy::msrv = "1.69"]
+fn under_msv(path: &Path) -> bool {
+    path.ends_with(".md")
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.stderr b/src/tools/clippy/tests/ui/path_ends_with_ext.stderr
new file mode 100644
index 00000000000..a73ab4d08e9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.stderr
@@ -0,0 +1,17 @@
+error: this looks like a failed attempt at checking for the file extension
+  --> $DIR/path_ends_with_ext.rs:11:5
+   |
+LL |     path.ends_with(".md");
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().is_some_and(|ext| ext == "md")`
+   |
+   = note: `-D clippy::path-ends-with-ext` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::path_ends_with_ext)]`
+
+error: this looks like a failed attempt at checking for the file extension
+  --> $DIR/path_ends_with_ext.rs:32:5
+   |
+LL |     path.ends_with(".md")
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().map_or(false, |ext| ext == "md")`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.rs b/src/tools/clippy/tests/ui/redundant_allocation.rs
index b3257c04f82..e70f8e71fae 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation.rs
@@ -159,4 +159,9 @@ mod box_fat_ptr {
     //~| NOTE: `Box<Box<DynSized>>` is already on the heap, `Rc<Box<Box<DynSized>>>` makes
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn type_in_closure() {
+    let _ = |_: &mut Box<Box<dyn ToString>>| {};
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.fixed b/src/tools/clippy/tests/ui/redundant_as_str.fixed
new file mode 100644
index 00000000000..a38523a7c79
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.fixed
@@ -0,0 +1,24 @@
+#![warn(clippy::redundant_as_str)]
+
+fn main() {
+    let string = "Hello, world!".to_owned();
+
+    // These methods are redundant and the `as_str` can be removed
+    let _redundant = string.as_bytes();
+    let _redundant = string.is_empty();
+
+    // These methods don't use `as_str` when they are redundant
+    let _no_as_str = string.as_bytes();
+    let _no_as_str = string.is_empty();
+
+    // These methods are not redundant, and are equivelant to
+    // doing dereferencing the string and applying the method
+    let _not_redundant = string.as_str().escape_unicode();
+    let _not_redundant = string.as_str().trim();
+    let _not_redundant = string.as_str().split_whitespace();
+
+    // These methods don't use `as_str` and are applied on a `str` directly
+    let borrowed_str = "Hello, world!";
+    let _is_str = borrowed_str.as_bytes();
+    let _is_str = borrowed_str.is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.rs b/src/tools/clippy/tests/ui/redundant_as_str.rs
new file mode 100644
index 00000000000..33adb609996
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.rs
@@ -0,0 +1,24 @@
+#![warn(clippy::redundant_as_str)]
+
+fn main() {
+    let string = "Hello, world!".to_owned();
+
+    // These methods are redundant and the `as_str` can be removed
+    let _redundant = string.as_str().as_bytes();
+    let _redundant = string.as_str().is_empty();
+
+    // These methods don't use `as_str` when they are redundant
+    let _no_as_str = string.as_bytes();
+    let _no_as_str = string.is_empty();
+
+    // These methods are not redundant, and are equivelant to
+    // doing dereferencing the string and applying the method
+    let _not_redundant = string.as_str().escape_unicode();
+    let _not_redundant = string.as_str().trim();
+    let _not_redundant = string.as_str().split_whitespace();
+
+    // These methods don't use `as_str` and are applied on a `str` directly
+    let borrowed_str = "Hello, world!";
+    let _is_str = borrowed_str.as_bytes();
+    let _is_str = borrowed_str.is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.stderr b/src/tools/clippy/tests/ui/redundant_as_str.stderr
new file mode 100644
index 00000000000..0ea42a94a81
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.stderr
@@ -0,0 +1,17 @@
+error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too
+  --> $DIR/redundant_as_str.rs:7:29
+   |
+LL |     let _redundant = string.as_str().as_bytes();
+   |                             ^^^^^^^^^^^^^^^^^ help: try: `as_bytes`
+   |
+   = note: `-D clippy::redundant-as-str` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::redundant_as_str)]`
+
+error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too
+  --> $DIR/redundant_as_str.rs:8:29
+   |
+LL |     let _redundant = string.as_str().is_empty();
+   |                             ^^^^^^^^^^^^^^^^^ help: try: `is_empty`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed
index bbe3b38e547..c578e786426 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.fixed
+++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed
@@ -1,8 +1,9 @@
+//@aux-build:proc_macros.rs
 #![warn(clippy::redundant_field_names)]
 #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]
 
 #[macro_use]
-extern crate derive_new;
+extern crate proc_macros;
 
 use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
 
@@ -18,7 +19,6 @@ struct Person {
     foo: u8,
 }
 
-#[derive(new)]
 pub struct S {
     v: String,
 }
@@ -57,6 +57,13 @@ fn main() {
     let _ = Range { start, end };
     let _ = RangeInclusive::new(start, end);
     let _ = RangeToInclusive { end };
+
+    external! {
+        let v = String::new();
+        let _ = S {
+            v: v
+        };
+    }
 }
 
 fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.rs b/src/tools/clippy/tests/ui/redundant_field_names.rs
index 9afa191ce7c..d8c2286d5ad 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.rs
+++ b/src/tools/clippy/tests/ui/redundant_field_names.rs
@@ -1,8 +1,9 @@
+//@aux-build:proc_macros.rs
 #![warn(clippy::redundant_field_names)]
 #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]
 
 #[macro_use]
-extern crate derive_new;
+extern crate proc_macros;
 
 use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
 
@@ -18,7 +19,6 @@ struct Person {
     foo: u8,
 }
 
-#[derive(new)]
 pub struct S {
     v: String,
 }
@@ -57,6 +57,13 @@ fn main() {
     let _ = Range { start: start, end: end };
     let _ = RangeInclusive::new(start, end);
     let _ = RangeToInclusive { end: end };
+
+    external! {
+        let v = String::new();
+        let _ = S {
+            v: v
+        };
+    }
 }
 
 fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.stderr b/src/tools/clippy/tests/ui/redundant_field_names.stderr
index 5fee60b8ea4..6eb1cc75319 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.stderr
+++ b/src/tools/clippy/tests/ui/redundant_field_names.stderr
@@ -44,7 +44,7 @@ LL |     let _ = RangeToInclusive { end: end };
    |                                ^^^^^^^^ help: replace it with: `end`
 
 error: redundant field names in struct initialization
-  --> $DIR/redundant_field_names.rs:81:25
+  --> $DIR/redundant_field_names.rs:88:25
    |
 LL |     let _ = RangeFrom { start: start };
    |                         ^^^^^^^^^^^^ help: replace it with: `start`
diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed
index 9a1ec3a4d36..f23116a7e1c 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.fixed
+++ b/src/tools/clippy/tests/ui/redundant_guards.fixed
@@ -43,6 +43,7 @@ fn main() {
         },
         Some(Some(1)) => ..,
         Some(Some(2)) => ..,
+        Some(Some(2)) => ..,
         // Don't lint, since x is used in the body
         Some(x) if let Some(1) = x => {
             x;
@@ -56,11 +57,13 @@ fn main() {
         Some(x) if matches!(y, 1 if true) => ..,
         Some(x) if let 1 = y => ..,
         Some(x) if y == 2 => ..,
+        Some(x) if 2 == y => ..,
         _ => todo!(),
     };
     let a = A(1);
     match a {
         _ if a.0 == 1 => {},
+        _ if 1 == a.0 => {},
         _ => todo!(),
     }
     let b = B { e: Some(A(0)) };
@@ -119,6 +122,7 @@ fn h(v: Option<u32>) {
 fn f(s: Option<std::ffi::OsString>) {
     match s {
         Some(x) if x == "a" => {},
+        Some(x) if "a" == x => {},
         _ => {},
     }
 }
@@ -140,6 +144,52 @@ static CONST_S: S = S { a: 1 };
 fn g(opt_s: Option<S>) {
     match opt_s {
         Some(x) if x == CONST_S => {},
+        Some(x) if CONST_S == x => {},
         _ => {},
     }
 }
+
+mod issue11465 {
+    enum A {
+        Foo([u8; 3]),
+    }
+
+    struct B {
+        b: String,
+        c: i32,
+    }
+
+    fn issue11465() {
+        let c = Some(1);
+        match c {
+            Some(1) => {},
+            Some(1) => {},
+            Some(2) => {},
+            Some(3) => {},
+            _ => {},
+        };
+
+        let enum_a = A::Foo([98, 97, 114]);
+        match enum_a {
+            A::Foo(ref arr) if arr == b"foo" => {},
+            A::Foo(ref arr) if b"foo" == arr => {},
+            A::Foo(ref arr) if let b"bar" = arr => {},
+            A::Foo(ref arr) if matches!(arr, b"baz") => {},
+            _ => {},
+        };
+
+        let struct_b = B {
+            b: "bar".to_string(),
+            c: 42,
+        };
+        match struct_b {
+            B { ref b, .. } if b == "bar" => {},
+            B { ref b, .. } if "bar" == b => {},
+            B { c: 1, .. } => {},
+            B { c: 1, .. } => {},
+            B { c: 1, .. } => {},
+            B { c: 1, .. } => {},
+            _ => {},
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs
index e2e0ee816c5..c0206b4cec7 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.rs
+++ b/src/tools/clippy/tests/ui/redundant_guards.rs
@@ -43,6 +43,7 @@ fn main() {
         },
         Some(x) if let Some(1) = x => ..,
         Some(x) if x == Some(2) => ..,
+        Some(x) if Some(2) == x => ..,
         // Don't lint, since x is used in the body
         Some(x) if let Some(1) = x => {
             x;
@@ -56,11 +57,13 @@ fn main() {
         Some(x) if matches!(y, 1 if true) => ..,
         Some(x) if let 1 = y => ..,
         Some(x) if y == 2 => ..,
+        Some(x) if 2 == y => ..,
         _ => todo!(),
     };
     let a = A(1);
     match a {
         _ if a.0 == 1 => {},
+        _ if 1 == a.0 => {},
         _ => todo!(),
     }
     let b = B { e: Some(A(0)) };
@@ -119,6 +122,7 @@ fn h(v: Option<u32>) {
 fn f(s: Option<std::ffi::OsString>) {
     match s {
         Some(x) if x == "a" => {},
+        Some(x) if "a" == x => {},
         _ => {},
     }
 }
@@ -140,6 +144,52 @@ static CONST_S: S = S { a: 1 };
 fn g(opt_s: Option<S>) {
     match opt_s {
         Some(x) if x == CONST_S => {},
+        Some(x) if CONST_S == x => {},
         _ => {},
     }
 }
+
+mod issue11465 {
+    enum A {
+        Foo([u8; 3]),
+    }
+
+    struct B {
+        b: String,
+        c: i32,
+    }
+
+    fn issue11465() {
+        let c = Some(1);
+        match c {
+            Some(ref x) if x == &1 => {},
+            Some(ref x) if &1 == x => {},
+            Some(ref x) if let &2 = x => {},
+            Some(ref x) if matches!(x, &3) => {},
+            _ => {},
+        };
+
+        let enum_a = A::Foo([98, 97, 114]);
+        match enum_a {
+            A::Foo(ref arr) if arr == b"foo" => {},
+            A::Foo(ref arr) if b"foo" == arr => {},
+            A::Foo(ref arr) if let b"bar" = arr => {},
+            A::Foo(ref arr) if matches!(arr, b"baz") => {},
+            _ => {},
+        };
+
+        let struct_b = B {
+            b: "bar".to_string(),
+            c: 42,
+        };
+        match struct_b {
+            B { ref b, .. } if b == "bar" => {},
+            B { ref b, .. } if "bar" == b => {},
+            B { ref c, .. } if c == &1 => {},
+            B { ref c, .. } if &1 == c => {},
+            B { ref c, .. } if let &1 = c => {},
+            B { ref c, .. } if matches!(c, &1) => {},
+            _ => {},
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr
index 0a45a6d7619..b8d7834e358 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.stderr
+++ b/src/tools/clippy/tests/ui/redundant_guards.stderr
@@ -60,7 +60,19 @@ LL +         Some(Some(2)) => ..,
    |
 
 error: redundant guard
-  --> $DIR/redundant_guards.rs:68:20
+  --> $DIR/redundant_guards.rs:46:20
+   |
+LL |         Some(x) if Some(2) == x => ..,
+   |                    ^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -         Some(x) if Some(2) == x => ..,
+LL +         Some(Some(2)) => ..,
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:71:20
    |
 LL |         B { e } if matches!(e, Some(A(2))) => ..,
    |                    ^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +84,7 @@ LL +         B { e: Some(A(2)) } => ..,
    |
 
 error: redundant guard
-  --> $DIR/redundant_guards.rs:105:20
+  --> $DIR/redundant_guards.rs:108:20
    |
 LL |         E::A(y) if y == "not from an or pattern" => {},
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +96,7 @@ LL +         E::A("not from an or pattern") => {},
    |
 
 error: redundant guard
-  --> $DIR/redundant_guards.rs:112:14
+  --> $DIR/redundant_guards.rs:115:14
    |
 LL |         x if matches!(x, Some(0)) => ..,
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -95,5 +107,101 @@ LL -         x if matches!(x, Some(0)) => ..,
 LL +         Some(0) => ..,
    |
 
-error: aborting due to 8 previous errors
+error: redundant guard
+  --> $DIR/redundant_guards.rs:165:28
+   |
+LL |             Some(ref x) if x == &1 => {},
+   |                            ^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if x == &1 => {},
+LL +             Some(1) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:166:28
+   |
+LL |             Some(ref x) if &1 == x => {},
+   |                            ^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if &1 == x => {},
+LL +             Some(1) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:167:28
+   |
+LL |             Some(ref x) if let &2 = x => {},
+   |                            ^^^^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if let &2 = x => {},
+LL +             Some(2) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:168:28
+   |
+LL |             Some(ref x) if matches!(x, &3) => {},
+   |                            ^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if matches!(x, &3) => {},
+LL +             Some(3) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:188:32
+   |
+LL |             B { ref c, .. } if c == &1 => {},
+   |                                ^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if c == &1 => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:189:32
+   |
+LL |             B { ref c, .. } if &1 == c => {},
+   |                                ^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if &1 == c => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:190:32
+   |
+LL |             B { ref c, .. } if let &1 = c => {},
+   |                                ^^^^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if let &1 = c => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:191:32
+   |
+LL |             B { ref c, .. } if matches!(c, &1) => {},
+   |                                ^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if matches!(c, &1) => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs
index 5259d9ce04b..094d9574ae9 100644
--- a/src/tools/clippy/tests/ui/regex.rs
+++ b/src/tools/clippy/tests/ui/regex.rs
@@ -2,7 +2,8 @@
     unused,
     clippy::needless_raw_strings,
     clippy::needless_raw_string_hashes,
-    clippy::needless_borrow
+    clippy::needless_borrow,
+    clippy::needless_borrows_for_generic_args
 )]
 #![warn(clippy::invalid_regex, clippy::trivial_regex)]
 
diff --git a/src/tools/clippy/tests/ui/regex.stderr b/src/tools/clippy/tests/ui/regex.stderr
index 91f90157e68..6d98d691d6f 100644
--- a/src/tools/clippy/tests/ui/regex.stderr
+++ b/src/tools/clippy/tests/ui/regex.stderr
@@ -1,5 +1,5 @@
 error: trivial regex
-  --> $DIR/regex.rs:18:45
+  --> $DIR/regex.rs:19:45
    |
 LL |     let pipe_in_wrong_position = Regex::new("|");
    |                                             ^^^
@@ -9,7 +9,7 @@ LL |     let pipe_in_wrong_position = Regex::new("|");
    = help: to override `-D warnings` add `#[allow(clippy::trivial_regex)]`
 
 error: trivial regex
-  --> $DIR/regex.rs:20:60
+  --> $DIR/regex.rs:21:60
    |
 LL |     let pipe_in_wrong_position_builder = RegexBuilder::new("|");
    |                                                            ^^^
@@ -17,7 +17,7 @@ LL |     let pipe_in_wrong_position_builder = RegexBuilder::new("|");
    = help: the regex is unlikely to be useful as it is
 
 error: regex syntax error: invalid character class range, the start must be <= the end
-  --> $DIR/regex.rs:22:42
+  --> $DIR/regex.rs:23:42
    |
 LL |     let wrong_char_ranice = Regex::new("[z-a]");
    |                                          ^^^
@@ -26,7 +26,7 @@ LL |     let wrong_char_ranice = Regex::new("[z-a]");
    = help: to override `-D warnings` add `#[allow(clippy::invalid_regex)]`
 
 error: regex syntax error: invalid character class range, the start must be <= the end
-  --> $DIR/regex.rs:25:37
+  --> $DIR/regex.rs:26:37
    |
 LL |     let some_unicode = Regex::new("[é-è]");
    |                                     ^^^
@@ -35,13 +35,13 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:28:33
+  --> $DIR/regex.rs:29:33
    |
 LL |     let some_regex = Regex::new(OPENING_PAREN);
    |                                 ^^^^^^^^^^^^^
 
 error: trivial regex
-  --> $DIR/regex.rs:30:53
+  --> $DIR/regex.rs:31:53
    |
 LL |     let binary_pipe_in_wrong_position = BRegex::new("|");
    |                                                     ^^^
@@ -52,7 +52,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:32:41
+  --> $DIR/regex.rs:33:41
    |
 LL |     let some_binary_regex = BRegex::new(OPENING_PAREN);
    |                                         ^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:33:56
+  --> $DIR/regex.rs:34:56
    |
 LL |     let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN);
    |                                                        ^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:45:37
+  --> $DIR/regex.rs:46:37
    |
 LL |     let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]);
    |                                     ^^^^^^^^^^^^^
@@ -79,7 +79,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:46:39
+  --> $DIR/regex.rs:47:39
    |
 LL |     let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]);
    |                                       ^^^^^^^^^^^^^
@@ -88,7 +88,7 @@ error: regex parse error:
            \b\c
              ^^
        error: unrecognized escape sequence
-  --> $DIR/regex.rs:53:42
+  --> $DIR/regex.rs:54:42
    |
 LL |     let escaped_string_span = Regex::new("\\b\\c");
    |                                          ^^^^^^^^
@@ -96,19 +96,19 @@ LL |     let escaped_string_span = Regex::new("\\b\\c");
    = help: consider using a raw string literal: `r".."`
 
 error: regex syntax error: duplicate flag
-  --> $DIR/regex.rs:55:34
+  --> $DIR/regex.rs:56:34
    |
 LL |     let aux_span = Regex::new("(?ixi)");
    |                                  ^ ^
 
 error: regex syntax error: pattern can match invalid UTF-8
-  --> $DIR/regex.rs:61:53
+  --> $DIR/regex.rs:62:53
    |
 LL |     let invalid_utf8_should_lint = Regex::new("(?-u).");
    |                                                     ^
 
 error: trivial regex
-  --> $DIR/regex.rs:66:33
+  --> $DIR/regex.rs:67:33
    |
 LL |     let trivial_eq = Regex::new("^foobar$");
    |                                 ^^^^^^^^^^
@@ -116,7 +116,7 @@ LL |     let trivial_eq = Regex::new("^foobar$");
    = help: consider using `==` on `str`s
 
 error: trivial regex
-  --> $DIR/regex.rs:69:48
+  --> $DIR/regex.rs:70:48
    |
 LL |     let trivial_eq_builder = RegexBuilder::new("^foobar$");
    |                                                ^^^^^^^^^^
@@ -124,7 +124,7 @@ LL |     let trivial_eq_builder = RegexBuilder::new("^foobar$");
    = help: consider using `==` on `str`s
 
 error: trivial regex
-  --> $DIR/regex.rs:72:42
+  --> $DIR/regex.rs:73:42
    |
 LL |     let trivial_starts_with = Regex::new("^foobar");
    |                                          ^^^^^^^^^
@@ -132,7 +132,7 @@ LL |     let trivial_starts_with = Regex::new("^foobar");
    = help: consider using `str::starts_with`
 
 error: trivial regex
-  --> $DIR/regex.rs:75:40
+  --> $DIR/regex.rs:76:40
    |
 LL |     let trivial_ends_with = Regex::new("foobar$");
    |                                        ^^^^^^^^^
@@ -140,7 +140,7 @@ LL |     let trivial_ends_with = Regex::new("foobar$");
    = help: consider using `str::ends_with`
 
 error: trivial regex
-  --> $DIR/regex.rs:78:39
+  --> $DIR/regex.rs:79:39
    |
 LL |     let trivial_contains = Regex::new("foobar");
    |                                       ^^^^^^^^
@@ -148,7 +148,7 @@ LL |     let trivial_contains = Regex::new("foobar");
    = help: consider using `str::contains`
 
 error: trivial regex
-  --> $DIR/regex.rs:81:39
+  --> $DIR/regex.rs:82:39
    |
 LL |     let trivial_contains = Regex::new(NOT_A_REAL_REGEX);
    |                                       ^^^^^^^^^^^^^^^^
@@ -156,7 +156,7 @@ LL |     let trivial_contains = Regex::new(NOT_A_REAL_REGEX);
    = help: consider using `str::contains`
 
 error: trivial regex
-  --> $DIR/regex.rs:84:40
+  --> $DIR/regex.rs:85:40
    |
 LL |     let trivial_backslash = Regex::new("a\\.b");
    |                                        ^^^^^^^
@@ -164,7 +164,7 @@ LL |     let trivial_backslash = Regex::new("a\\.b");
    = help: consider using `str::contains`
 
 error: trivial regex
-  --> $DIR/regex.rs:88:36
+  --> $DIR/regex.rs:89:36
    |
 LL |     let trivial_empty = Regex::new("");
    |                                    ^^
@@ -172,7 +172,7 @@ LL |     let trivial_empty = Regex::new("");
    = help: the regex is unlikely to be useful as it is
 
 error: trivial regex
-  --> $DIR/regex.rs:91:36
+  --> $DIR/regex.rs:92:36
    |
 LL |     let trivial_empty = Regex::new("^");
    |                                    ^^^
@@ -180,7 +180,7 @@ LL |     let trivial_empty = Regex::new("^");
    = help: the regex is unlikely to be useful as it is
 
 error: trivial regex
-  --> $DIR/regex.rs:94:36
+  --> $DIR/regex.rs:95:36
    |
 LL |     let trivial_empty = Regex::new("^$");
    |                                    ^^^^
@@ -188,7 +188,7 @@ LL |     let trivial_empty = Regex::new("^$");
    = help: consider using `str::is_empty`
 
 error: trivial regex
-  --> $DIR/regex.rs:97:44
+  --> $DIR/regex.rs:98:44
    |
 LL |     let binary_trivial_empty = BRegex::new("^$");
    |                                            ^^^^
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
index a4dfc8f293d..62798b6d3d6 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::result_map_unit_fn)]
 #![feature(never_type)]
-#![allow(unused)]
+#![allow(unused, clippy::unnecessary_map_on_constructor)]
 //@no-rustfix
 struct HasResult {
     field: Result<usize, usize>,
diff --git a/src/tools/clippy/tests/ui/transmute_null_to_fn.rs b/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
index 7d780c803ff..b07851e864f 100644
--- a/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
+++ b/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
@@ -25,6 +25,17 @@ fn transmute_const() {
     }
 }
 
+fn issue_11485() {
+    unsafe {
+        let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
+        //~^ ERROR: transmuting a known null pointer into a function pointer
+        let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+        //~^ ERROR: transmuting a known null pointer into a function pointer
+        let _: fn() = std::mem::transmute(ZPTR as *const u8);
+        //~^ ERROR: transmuting a known null pointer into a function pointer
+    }
+}
+
 fn main() {
     one_liners();
     transmute_const();
diff --git a/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr b/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
index ab0ac0dd480..9073080cbf3 100644
--- a/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
+++ b/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
@@ -24,5 +24,29 @@ LL |         let _: fn() = std::mem::transmute(ZPTR);
    |
    = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
 
-error: aborting due to 3 previous errors
+error: transmuting a known null pointer into a function pointer
+  --> $DIR/transmute_null_to_fn.rs:30:23
+   |
+LL |         let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+   |
+   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: transmuting a known null pointer into a function pointer
+  --> $DIR/transmute_null_to_fn.rs:32:23
+   |
+LL |         let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+   |
+   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: transmuting a known null pointer into a function pointer
+  --> $DIR/transmute_null_to_fn.rs:34:23
+   |
+LL |         let _: fn() = std::mem::transmute(ZPTR as *const u8);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+   |
+   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
deleted file mode 100644
index f4e7f1943ae..00000000000
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
+++ /dev/null
@@ -1,534 +0,0 @@
-//@aux-build:proc_macro_unsafe.rs
-
-#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
-#![allow(clippy::let_unit_value, clippy::missing_safety_doc)]
-
-extern crate proc_macro_unsafe;
-
-// Valid comments
-
-fn nested_local() {
-    let _ = {
-        let _ = {
-            // SAFETY:
-            let _ = unsafe {};
-        };
-    };
-}
-
-fn deep_nest() {
-    let _ = {
-        let _ = {
-            // SAFETY:
-            let _ = unsafe {};
-
-            // Safety:
-            unsafe {};
-
-            let _ = {
-                let _ = {
-                    let _ = {
-                        let _ = {
-                            let _ = {
-                                // Safety:
-                                let _ = unsafe {};
-
-                                // SAFETY:
-                                unsafe {};
-                            };
-                        };
-                    };
-
-                    // Safety:
-                    unsafe {};
-                };
-            };
-        };
-
-        // Safety:
-        unsafe {};
-    };
-
-    // SAFETY:
-    unsafe {};
-}
-
-fn local_tuple_expression() {
-    // Safety:
-    let _ = (42, unsafe {});
-}
-
-fn line_comment() {
-    // Safety:
-    unsafe {}
-}
-
-fn line_comment_newlines() {
-    // SAFETY:
-
-    unsafe {}
-}
-
-fn line_comment_empty() {
-    // Safety:
-    //
-    //
-    //
-    unsafe {}
-}
-
-fn line_comment_with_extras() {
-    // This is a description
-    // Safety:
-    unsafe {}
-}
-
-fn block_comment() {
-    /* Safety: */
-    unsafe {}
-}
-
-fn block_comment_newlines() {
-    /* SAFETY: */
-
-    unsafe {}
-}
-
-fn block_comment_with_extras() {
-    /* This is a description
-     * SAFETY:
-     */
-    unsafe {}
-}
-
-fn block_comment_terminator_same_line() {
-    /* This is a description
-     * Safety: */
-    unsafe {}
-}
-
-fn buried_safety() {
-    // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
-    // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
-    // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
-    // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
-    // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
-    // laborum. Safety:
-    // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi
-    // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio
-    // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl
-    // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.
-    unsafe {}
-}
-
-fn safety_with_prepended_text() {
-    // This is a test. safety:
-    unsafe {}
-}
-
-fn local_line_comment() {
-    // Safety:
-    let _ = unsafe {};
-}
-
-fn local_block_comment() {
-    /* SAFETY: */
-    let _ = unsafe {};
-}
-
-fn comment_array() {
-    // Safety:
-    let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-}
-
-fn comment_tuple() {
-    // sAFETY:
-    let _ = (42, unsafe {}, "test", unsafe {});
-}
-
-fn comment_unary() {
-    // SAFETY:
-    let _ = *unsafe { &42 };
-}
-
-#[allow(clippy::match_single_binding)]
-fn comment_match() {
-    // SAFETY:
-    let _ = match unsafe {} {
-        _ => {},
-    };
-}
-
-fn comment_addr_of() {
-    // Safety:
-    let _ = &unsafe {};
-}
-
-fn comment_repeat() {
-    // Safety:
-    let _ = [unsafe {}; 5];
-}
-
-fn comment_macro_call() {
-    macro_rules! t {
-        ($b:expr) => {
-            $b
-        };
-    }
-
-    t!(
-        // SAFETY:
-        unsafe {}
-    );
-}
-
-fn comment_macro_def() {
-    macro_rules! t {
-        () => {
-            // Safety:
-            unsafe {}
-        };
-    }
-
-    t!();
-}
-
-fn non_ascii_comment() {
-    // ॐ᧻໒ SaFeTy: ௵∰
-    unsafe {};
-}
-
-fn local_commented_block() {
-    let _ =
-        // safety:
-        unsafe {};
-}
-
-fn local_nest() {
-    // safety:
-    let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})];
-}
-
-fn in_fn_call(x: *const u32) {
-    fn f(x: u32) {}
-
-    // Safety: reason
-    f(unsafe { *x });
-}
-
-fn multi_in_fn_call(x: *const u32) {
-    fn f(x: u32, y: u32) {}
-
-    // Safety: reason
-    f(unsafe { *x }, unsafe { *x });
-}
-
-fn in_multiline_fn_call(x: *const u32) {
-    fn f(x: u32, y: u32) {}
-
-    f(
-        // Safety: reason
-        unsafe { *x },
-        0,
-    );
-}
-
-fn in_macro_call(x: *const u32) {
-    // Safety: reason
-    println!("{}", unsafe { *x });
-}
-
-fn in_multiline_macro_call(x: *const u32) {
-    println!(
-        "{}",
-        // Safety: reason
-        unsafe { *x },
-    );
-}
-
-fn from_proc_macro() {
-    proc_macro_unsafe::unsafe_block!(token);
-}
-
-fn in_closure(x: *const u32) {
-    // Safety: reason
-    let _ = || unsafe { *x };
-}
-
-// Invalid comments
-
-#[rustfmt::skip]
-fn inline_block_comment() {
-    /* Safety: */ unsafe {}
-}
-
-fn no_comment() {
-    unsafe {}
-}
-
-fn no_comment_array() {
-    let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-}
-
-fn no_comment_tuple() {
-    let _ = (42, unsafe {}, "test", unsafe {});
-}
-
-fn no_comment_unary() {
-    let _ = *unsafe { &42 };
-}
-
-#[allow(clippy::match_single_binding)]
-fn no_comment_match() {
-    let _ = match unsafe {} {
-        _ => {},
-    };
-}
-
-fn no_comment_addr_of() {
-    let _ = &unsafe {};
-}
-
-fn no_comment_repeat() {
-    let _ = [unsafe {}; 5];
-}
-
-fn local_no_comment() {
-    let _ = unsafe {};
-}
-
-fn no_comment_macro_call() {
-    macro_rules! t {
-        ($b:expr) => {
-            $b
-        };
-    }
-
-    t!(unsafe {});
-}
-
-fn no_comment_macro_def() {
-    macro_rules! t {
-        () => {
-            unsafe {}
-        };
-    }
-
-    t!();
-}
-
-fn trailing_comment() {
-    unsafe {} // SAFETY:
-}
-
-fn internal_comment() {
-    unsafe {
-        // SAFETY:
-    }
-}
-
-fn interference() {
-    // SAFETY
-
-    let _ = 42;
-
-    unsafe {};
-}
-
-pub fn print_binary_tree() {
-    println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
-}
-
-mod unsafe_impl_smoke_test {
-    unsafe trait A {}
-
-    // error: no safety comment
-    unsafe impl A for () {}
-
-    // Safety: ok
-    unsafe impl A for (i32) {}
-
-    mod sub_mod {
-        // error:
-        unsafe impl B for (u32) {}
-        unsafe trait B {}
-    }
-
-    #[rustfmt::skip]
-    mod sub_mod2 {
-        //
-        // SAFETY: ok
-        //
-
-        unsafe impl B for (u32) {}
-        unsafe trait B {}
-    }
-}
-
-mod unsafe_impl_from_macro {
-    unsafe trait T {}
-
-    // error
-    macro_rules! no_safety_comment {
-        ($t:ty) => {
-            unsafe impl T for $t {}
-        };
-    }
-
-    // ok
-    no_safety_comment!(());
-
-    // ok
-    macro_rules! with_safety_comment {
-        ($t:ty) => {
-            // SAFETY:
-            unsafe impl T for $t {}
-        };
-    }
-
-    // ok
-    with_safety_comment!((i32));
-}
-
-mod unsafe_impl_macro_and_not_macro {
-    unsafe trait T {}
-
-    // error
-    macro_rules! no_safety_comment {
-        ($t:ty) => {
-            unsafe impl T for $t {}
-        };
-    }
-
-    // ok
-    no_safety_comment!(());
-
-    // error
-    unsafe impl T for (i32) {}
-
-    // ok
-    no_safety_comment!(u32);
-
-    // error
-    unsafe impl T for (bool) {}
-}
-
-#[rustfmt::skip]
-mod unsafe_impl_valid_comment {
-    unsafe trait SaFety {}
-    // SaFety:
-    unsafe impl SaFety for () {}
-
-    unsafe trait MultiLineComment {}
-    // The following impl is safe
-    // ...
-    // Safety: reason
-    unsafe impl MultiLineComment for () {}
-
-    unsafe trait NoAscii {}
-    // 安全 SAFETY: 以下のコードは安全です
-    unsafe impl NoAscii for () {}
-
-    unsafe trait InlineAndPrecedingComment {}
-    // SAFETY:
-    /* comment */ unsafe impl InlineAndPrecedingComment for () {}
-
-    unsafe trait BuriedSafety {}
-    // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
-    // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
-    // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
-    // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
-    // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
-    // laborum. Safety:
-    // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi
-    // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio
-    // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl
-    // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.
-    unsafe impl BuriedSafety for () {}
-
-    unsafe trait MultiLineBlockComment {}
-    /* This is a description
-     * Safety: */
-    unsafe impl MultiLineBlockComment for () {}
-}
-
-#[rustfmt::skip]
-mod unsafe_impl_invalid_comment {
-    unsafe trait NoComment {}
-
-    unsafe impl NoComment for () {}
-
-    unsafe trait InlineComment {}
-
-    /* SAFETY: */ unsafe impl InlineComment for () {}
-
-    unsafe trait TrailingComment {}
-
-    unsafe impl TrailingComment for () {} // SAFETY:
-
-    unsafe trait Interference {}
-    // SAFETY:
-    const BIG_NUMBER: i32 = 1000000;
-    unsafe impl Interference for () {}
-}
-
-unsafe trait ImplInFn {}
-
-fn impl_in_fn() {
-    // error
-    unsafe impl ImplInFn for () {}
-
-    // SAFETY: ok
-    unsafe impl ImplInFn for (i32) {}
-}
-
-unsafe trait CrateRoot {}
-
-// error
-unsafe impl CrateRoot for () {}
-
-// SAFETY: ok
-unsafe impl CrateRoot for (i32) {}
-
-fn issue_9142() {
-    // SAFETY: ok
-    let _ =
-        // we need this comment to avoid rustfmt putting
-        // it all on one line
-        unsafe {};
-
-    // SAFETY: this is more than one level away, so it should warn
-    let _ = {
-        if unsafe { true } {
-            todo!();
-        } else {
-            let bar = unsafe {};
-            todo!();
-            bar
-        }
-    };
-}
-
-pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 {
-    1
-}
-
-pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 {
-    2
-}
-
-fn issue_10832() {
-    // Safety: A safety comment. But it will warn anyways
-    let _some_variable_with_a_very_long_name_to_break_the_line =
-        unsafe { a_function_with_a_very_long_name_to_break_the_line() };
-
-    // Safety: Another safety comment. But it will warn anyways
-    const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
-        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
-
-    // Safety: Yet another safety comment. But it will warn anyways
-    static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
-        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
-}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed
new file mode 100644
index 00000000000..d0ba7ed749e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed
@@ -0,0 +1,56 @@
+#![allow(unused)]
+#![warn(clippy::unnecessary_map_on_constructor)]
+
+use std::ffi::OsStr;
+
+fn fun(t: i32) -> i32 {
+    t
+}
+
+fn notfun(e: SimpleError) -> SimpleError {
+    e
+}
+macro_rules! expands_to_fun {
+    () => {
+        fun
+    };
+}
+
+#[derive(Copy, Clone)]
+struct SimpleError {}
+
+type SimpleResult = std::result::Result<i32, SimpleError>;
+
+fn main() {
+    let x: i32 = 4;
+
+    let err = SimpleError {};
+    let a = Some(x);
+    let b: SimpleResult = Ok(x);
+    let c: SimpleResult = Err(err);
+
+    let a = Some(fun(x));
+    let b: SimpleResult = Ok(fun(x));
+    let c: SimpleResult = Err(notfun(err));
+
+    let a = Option::Some(fun(x));
+    let b: SimpleResult = SimpleResult::Ok(fun(x));
+    let c: SimpleResult = SimpleResult::Err(notfun(err));
+    let b: std::result::Result<i32, SimpleError> = Ok(fun(x));
+    let c: std::result::Result<i32, SimpleError> = Err(notfun(err));
+
+    let a = Some(fun(x));
+    let b: SimpleResult = Ok(fun(x));
+    let c: SimpleResult = Err(notfun(err));
+
+    // Should not trigger warning
+    a.map(fun);
+    b.map(fun);
+    c.map_err(notfun);
+
+    b.map_err(notfun); // Ok(_).map_err
+    c.map(fun); // Err(_).map()
+
+    option_env!("PATH").map(OsStr::new);
+    Some(x).map(expands_to_fun!());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs
new file mode 100644
index 00000000000..e89e7aad4c4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs
@@ -0,0 +1,56 @@
+#![allow(unused)]
+#![warn(clippy::unnecessary_map_on_constructor)]
+
+use std::ffi::OsStr;
+
+fn fun(t: i32) -> i32 {
+    t
+}
+
+fn notfun(e: SimpleError) -> SimpleError {
+    e
+}
+macro_rules! expands_to_fun {
+    () => {
+        fun
+    };
+}
+
+#[derive(Copy, Clone)]
+struct SimpleError {}
+
+type SimpleResult = std::result::Result<i32, SimpleError>;
+
+fn main() {
+    let x: i32 = 4;
+
+    let err = SimpleError {};
+    let a = Some(x);
+    let b: SimpleResult = Ok(x);
+    let c: SimpleResult = Err(err);
+
+    let a = Some(x).map(fun);
+    let b: SimpleResult = Ok(x).map(fun);
+    let c: SimpleResult = Err(err).map_err(notfun);
+
+    let a = Option::Some(x).map(fun);
+    let b: SimpleResult = SimpleResult::Ok(x).map(fun);
+    let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);
+    let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);
+    let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);
+
+    let a = Some(fun(x));
+    let b: SimpleResult = Ok(fun(x));
+    let c: SimpleResult = Err(notfun(err));
+
+    // Should not trigger warning
+    a.map(fun);
+    b.map(fun);
+    c.map_err(notfun);
+
+    b.map_err(notfun); // Ok(_).map_err
+    c.map(fun); // Err(_).map()
+
+    option_env!("PATH").map(OsStr::new);
+    Some(x).map(expands_to_fun!());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr
new file mode 100644
index 00000000000..d522b68d872
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr
@@ -0,0 +1,53 @@
+error: unnecessary map on constructor Some(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:32:13
+   |
+LL |     let a = Some(x).map(fun);
+   |             ^^^^^^^^^^^^^^^^ help: try: `Some(fun(x))`
+   |
+   = note: `-D clippy::unnecessary-map-on-constructor` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_on_constructor)]`
+
+error: unnecessary map on constructor Ok(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:33:27
+   |
+LL |     let b: SimpleResult = Ok(x).map(fun);
+   |                           ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`
+
+error: unnecessary map_err on constructor Err(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:34:27
+   |
+LL |     let c: SimpleResult = Err(err).map_err(notfun);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`
+
+error: unnecessary map on constructor Option::Some(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:36:13
+   |
+LL |     let a = Option::Some(x).map(fun);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option::Some(fun(x))`
+
+error: unnecessary map on constructor SimpleResult::Ok(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:37:27
+   |
+LL |     let b: SimpleResult = SimpleResult::Ok(x).map(fun);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Ok(fun(x))`
+
+error: unnecessary map_err on constructor SimpleResult::Err(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:38:27
+   |
+LL |     let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Err(notfun(err))`
+
+error: unnecessary map on constructor Ok(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:39:52
+   |
+LL |     let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);
+   |                                                    ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`
+
+error: unnecessary map_err on constructor Err(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:40:52
+   |
+LL |     let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index 7b662ca92d2..67faabc53cb 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -1,4 +1,4 @@
-#![allow(clippy::needless_borrow, clippy::ptr_arg)]
+#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
 #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index d79778a6a2e..99f9136427d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::needless_borrow, clippy::ptr_arg)]
+#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
 #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.rs b/src/tools/clippy/tests/ui/used_underscore_binding.rs
index c672eff1c27..a8f404b1400 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.rs
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.rs
@@ -1,6 +1,5 @@
 //@aux-build:proc_macro_derive.rs
-#![feature(rustc_private)]
-#![warn(clippy::all)]
+#![feature(rustc_private, lint_reasons)]
 #![warn(clippy::used_underscore_binding)]
 #![allow(clippy::disallowed_names, clippy::eq_op, clippy::uninlined_format_args)]
 
@@ -107,6 +106,31 @@ async fn await_desugaring() {
     .await
 }
 
+struct PhantomField<T> {
+    _marker: std::marker::PhantomData<T>,
+}
+
+impl<T> std::fmt::Debug for PhantomField<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("PhantomField").field("_marker", &self._marker).finish()
+    }
+}
+
+struct AllowedField {
+    #[allow(clippy::used_underscore_binding)]
+    _allowed: usize,
+}
+
+struct ExpectedField {
+    #[expect(clippy::used_underscore_binding)]
+    _expected: usize,
+}
+
+fn lint_levels(allowed: AllowedField, expected: ExpectedField) {
+    let _ = allowed._allowed;
+    let _ = expected._expected;
+}
+
 fn main() {
     let foo = 0u32;
     // tests of unused_underscore lint
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.stderr b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
index 289519b172e..78d8279810c 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.stderr
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
@@ -1,41 +1,76 @@
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:24:5
+  --> $DIR/used_underscore_binding.rs:23:5
    |
 LL |     _foo + 1
    |     ^^^^
    |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:22:22
+   |
+LL | fn prefix_underscore(_foo: u32) -> u32 {
+   |                      ^^^^
    = note: `-D clippy::used-underscore-binding` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::used_underscore_binding)]`
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:29:20
+  --> $DIR/used_underscore_binding.rs:28:20
    |
 LL |     println!("{}", _foo);
    |                    ^^^^
+   |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:27:24
+   |
+LL | fn in_macro_or_desugar(_foo: u32) {
+   |                        ^^^^
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:30:16
+  --> $DIR/used_underscore_binding.rs:29:16
    |
 LL |     assert_eq!(_foo, _foo);
    |                ^^^^
+   |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:27:24
+   |
+LL | fn in_macro_or_desugar(_foo: u32) {
+   |                        ^^^^
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:30:22
+  --> $DIR/used_underscore_binding.rs:29:22
    |
 LL |     assert_eq!(_foo, _foo);
    |                      ^^^^
+   |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:27:24
+   |
+LL | fn in_macro_or_desugar(_foo: u32) {
+   |                        ^^^^
 
 error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:43:5
+  --> $DIR/used_underscore_binding.rs:42:5
    |
 LL |     s._underscore_field += 1;
    |     ^^^^^^^^^^^^^^^^^^^
+   |
+note: `_underscore_field` is defined here
+  --> $DIR/used_underscore_binding.rs:36:5
+   |
+LL |     _underscore_field: u32,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:104:16
+  --> $DIR/used_underscore_binding.rs:103:16
    |
 LL |         uses_i(_i);
    |                ^^
+   |
+note: `_i` is defined here
+  --> $DIR/used_underscore_binding.rs:102:13
+   |
+LL |         let _i = 5;
+   |             ^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed
index 52591959905..ed8387b7eb2 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.fixed
+++ b/src/tools/clippy/tests/ui/useless_conversion.fixed
@@ -151,6 +151,8 @@ fn main() {
     let _ = s3;
     let s4: Foo<'a'> = Foo;
     let _ = vec![s4, s4, s4].into_iter();
+
+    issue11300::bar();
 }
 
 #[allow(dead_code)]
@@ -196,6 +198,95 @@ fn explicit_into_iter_fn_arg() {
     b(macro_generated!());
 }
 
+mod issue11300 {
+    pub fn foo<I>(i: I)
+    where
+        I: IntoIterator<Item = i32> + ExactSizeIterator,
+    {
+        assert_eq!(i.len(), 3);
+    }
+
+    trait Helper<T: ?Sized> {}
+    impl Helper<i32> for [i32; 3] {}
+    impl Helper<i32> for std::array::IntoIter<i32, 3> {}
+    impl Helper<()> for std::array::IntoIter<i32, 3> {}
+
+    fn foo2<X: ?Sized, I>(_: I)
+    where
+        I: IntoIterator<Item = i32> + Helper<X>,
+    {
+    }
+
+    trait Helper2<T> {}
+    impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}
+    impl Helper2<[i32; 3]> for i32 {}
+    fn foo3<I>(_: I)
+    where
+        I: IntoIterator<Item = i32>,
+        i32: Helper2<I>,
+    {
+    }
+
+    pub fn bar() {
+        // This should not trigger the lint:
+        // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be
+        // removed and is not useless.
+        foo([1, 2, 3].into_iter());
+
+        // This should trigger the lint, receiver type [i32; 3] also implements `Helper`
+        foo2::<i32, _>([1, 2, 3]);
+
+        // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,
+        // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).
+        foo2::<(), _>([1, 2, 3].into_iter());
+
+        // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,
+        // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unncessary.
+        foo3([1, 2, 3]);
+    }
+
+    fn ice() {
+        struct S1;
+        impl S1 {
+            pub fn foo<I: IntoIterator>(&self, _: I) {}
+        }
+
+        S1.foo([1, 2]);
+
+        // ICE that occured in itertools
+        trait Itertools {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized;
+        }
+        impl<I: Iterator> Itertools for I {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized,
+            {
+            }
+        }
+        let v0: Vec<i32> = vec![0, 2, 4];
+        let v1: Vec<i32> = vec![1, 3, 5, 7];
+        v0.into_iter().interleave_shortest(v1);
+
+        trait TraitWithLifetime<'a> {}
+        impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}
+
+        struct Helper;
+        impl<'a> Helper {
+            fn with_lt<I>(&self, _: I)
+            where
+                I: IntoIterator + TraitWithLifetime<'a>,
+            {
+            }
+        }
+        Helper.with_lt([&1, &2].into_iter());
+    }
+}
+
 #[derive(Copy, Clone)]
 struct Foo<const C: char>;
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs
index befb2f9a5c3..991a7762fc6 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.rs
+++ b/src/tools/clippy/tests/ui/useless_conversion.rs
@@ -151,6 +151,8 @@ fn main() {
     let _ = Foo::<'a'>::from(s3);
     let s4: Foo<'a'> = Foo;
     let _ = vec![s4, s4, s4].into_iter().into_iter();
+
+    issue11300::bar();
 }
 
 #[allow(dead_code)]
@@ -196,6 +198,95 @@ fn explicit_into_iter_fn_arg() {
     b(macro_generated!());
 }
 
+mod issue11300 {
+    pub fn foo<I>(i: I)
+    where
+        I: IntoIterator<Item = i32> + ExactSizeIterator,
+    {
+        assert_eq!(i.len(), 3);
+    }
+
+    trait Helper<T: ?Sized> {}
+    impl Helper<i32> for [i32; 3] {}
+    impl Helper<i32> for std::array::IntoIter<i32, 3> {}
+    impl Helper<()> for std::array::IntoIter<i32, 3> {}
+
+    fn foo2<X: ?Sized, I>(_: I)
+    where
+        I: IntoIterator<Item = i32> + Helper<X>,
+    {
+    }
+
+    trait Helper2<T> {}
+    impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}
+    impl Helper2<[i32; 3]> for i32 {}
+    fn foo3<I>(_: I)
+    where
+        I: IntoIterator<Item = i32>,
+        i32: Helper2<I>,
+    {
+    }
+
+    pub fn bar() {
+        // This should not trigger the lint:
+        // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be
+        // removed and is not useless.
+        foo([1, 2, 3].into_iter());
+
+        // This should trigger the lint, receiver type [i32; 3] also implements `Helper`
+        foo2::<i32, _>([1, 2, 3].into_iter());
+
+        // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,
+        // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).
+        foo2::<(), _>([1, 2, 3].into_iter());
+
+        // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,
+        // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unncessary.
+        foo3([1, 2, 3].into_iter());
+    }
+
+    fn ice() {
+        struct S1;
+        impl S1 {
+            pub fn foo<I: IntoIterator>(&self, _: I) {}
+        }
+
+        S1.foo([1, 2].into_iter());
+
+        // ICE that occured in itertools
+        trait Itertools {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized;
+        }
+        impl<I: Iterator> Itertools for I {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized,
+            {
+            }
+        }
+        let v0: Vec<i32> = vec![0, 2, 4];
+        let v1: Vec<i32> = vec![1, 3, 5, 7];
+        v0.into_iter().interleave_shortest(v1.into_iter());
+
+        trait TraitWithLifetime<'a> {}
+        impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}
+
+        struct Helper;
+        impl<'a> Helper {
+            fn with_lt<I>(&self, _: I)
+            where
+                I: IntoIterator + TraitWithLifetime<'a>,
+            {
+            }
+        }
+        Helper.with_lt([&1, &2].into_iter());
+    }
+}
+
 #[derive(Copy, Clone)]
 struct Foo<const C: char>;
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr
index 28e7bb61098..c1f8b6b4aa9 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion.stderr
@@ -119,64 +119,112 @@ LL |     let _ = vec![s4, s4, s4].into_iter().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()`
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:183:7
+  --> $DIR/useless_conversion.rs:185:7
    |
 LL |     b(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:173:13
+  --> $DIR/useless_conversion.rs:175:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:184:7
+  --> $DIR/useless_conversion.rs:186:7
    |
 LL |     c(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:174:18
+  --> $DIR/useless_conversion.rs:176:18
    |
 LL |     fn c(_: impl IntoIterator<Item = i32>) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:185:7
+  --> $DIR/useless_conversion.rs:187:7
    |
 LL |     d(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:177:12
+  --> $DIR/useless_conversion.rs:179:12
    |
 LL |         T: IntoIterator<Item = i32>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:188:7
+  --> $DIR/useless_conversion.rs:190:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:173:13
+  --> $DIR/useless_conversion.rs:175:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:189:7
+  --> $DIR/useless_conversion.rs:191:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter().into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:173:13
+  --> $DIR/useless_conversion.rs:175:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 24 previous errors
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:237:24
+   |
+LL |         foo2::<i32, _>([1, 2, 3].into_iter());
+   |                        ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:216:12
+   |
+LL |         I: IntoIterator<Item = i32> + Helper<X>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:245:14
+   |
+LL |         foo3([1, 2, 3].into_iter());
+   |              ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:225:12
+   |
+LL |         I: IntoIterator<Item = i32>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:254:16
+   |
+LL |         S1.foo([1, 2].into_iter());
+   |                ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:251:27
+   |
+LL |             pub fn foo<I: IntoIterator>(&self, _: I) {}
+   |                           ^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:273:44
+   |
+LL |         v0.into_iter().interleave_shortest(v1.into_iter());
+   |                                            ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:260:20
+   |
+LL |                 J: IntoIterator,
+   |                    ^^^^^^^^^^^^
+
+error: aborting due to 28 previous errors
 
diff --git a/src/tools/clippy/tests/ui/vec_box_sized.fixed b/src/tools/clippy/tests/ui/vec_box_sized.fixed
index 4a5ef83856a..4363d2224af 100644
--- a/src/tools/clippy/tests/ui/vec_box_sized.fixed
+++ b/src/tools/clippy/tests/ui/vec_box_sized.fixed
@@ -49,4 +49,9 @@ mod inner_mod {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn in_closure() {
+    let _ = |_: Vec<Box<dyn ToString>>| {};
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/vec_box_sized.rs b/src/tools/clippy/tests/ui/vec_box_sized.rs
index ea020405a30..f4e27fe4bd5 100644
--- a/src/tools/clippy/tests/ui/vec_box_sized.rs
+++ b/src/tools/clippy/tests/ui/vec_box_sized.rs
@@ -49,4 +49,9 @@ mod inner_mod {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn in_closure() {
+    let _ = |_: Vec<Box<dyn ToString>>| {};
+}
+
 fn main() {}
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 843ffe2c4c3..7d3ef4197a7 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -18,6 +18,7 @@ const LICENSES: &[&str] = &[
     "Apache-2.0/MIT",
     "ISC",
     "MIT / Apache-2.0",
+    "MIT OR Apache-2.0 OR LGPL-2.1-or-later",              // r-efi, r-efi-alloc
     "MIT OR Apache-2.0 OR Zlib",                           // tinyvec_macros
     "MIT OR Apache-2.0",
     "MIT OR Zlib OR Apache-2.0",                           // miniz_oxide
@@ -57,14 +58,14 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
     // tidy-alphabetical-start
     ("bitmaps", "MPL-2.0+"),
     ("bytesize", "Apache-2.0"),
+    ("byteyarn", "Apache-2.0"),
     ("ciborium", "Apache-2.0"),
     ("ciborium-io", "Apache-2.0"),
     ("ciborium-ll", "Apache-2.0"),
     ("dunce", "CC0-1.0 OR MIT-0 OR Apache-2.0"),
+    ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"),
     ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"),
     ("im-rc", "MPL-2.0+"),
-    ("imara-diff", "Apache-2.0"),
-    ("instant", "BSD-3-Clause"),
     ("normalize-line-endings", "Apache-2.0"),
     ("openssl", "Apache-2.0"),
     ("ryu", "Apache-2.0 OR BSL-1.0"),
@@ -179,7 +180,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "instant",
     "intl-memoizer",
     "intl_pluralrules",
-    "io-lifetimes",
     "is-terminal",
     "itertools",
     "itoa",
@@ -217,6 +217,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "pulldown-cmark",
     "punycode",
     "quote",
+    "r-efi",
+    "r-efi-alloc",
     "rand",
     "rand_chacha",
     "rand_core",
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 3a4d9c53d7b..5f6b63a67fd 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -56,6 +56,7 @@ const EXCEPTION_PATHS: &[&str] = &[
     "library/std/src/path.rs",
     "library/std/src/sys_common", // Should only contain abstractions over platforms
     "library/std/src/net/test.rs", // Utility helpers for tests
+    "library/std/src/io/error.rs", // Repr unpacked needed for UEFI
 ];
 
 pub fn check(path: &Path, bad: &mut bool) {
diff --git a/tests/assembly/closure-inherit-target-feature.rs b/tests/assembly/closure-inherit-target-feature.rs
new file mode 100644
index 00000000000..65728a15516
--- /dev/null
+++ b/tests/assembly/closure-inherit-target-feature.rs
@@ -0,0 +1,58 @@
+// only-x86_64
+// assembly-output: emit-asm
+// make sure the feature is not enabled at compile-time
+// compile-flags: -C opt-level=3 -C target-feature=-sse4.1 -C llvm-args=-x86-asm-syntax=intel
+
+#![feature(target_feature_11)]
+#![crate_type = "rlib"]
+
+use std::arch::x86_64::{__m128, _mm_blend_ps};
+
+#[no_mangle]
+pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128) -> __m128 {
+    let f = {
+        // check that _mm_blend_ps is not being inlined into the closure
+        // CHECK-LABEL: {{sse41_blend_nofeature.*closure.*:}}
+        // CHECK-NOT: blendps
+        // CHECK: {{call .*_mm_blend_ps.*}}
+        // CHECK-NOT: blendps
+        // CHECK: ret
+        #[inline(never)] |x, y| _mm_blend_ps(x, y, 0b0101)
+    };
+    f(x, y)
+}
+
+#[target_feature(enable = "sse4.1")]
+pub fn sse41_blend_noinline(x: __m128, y: __m128) -> __m128 {
+    let f = {
+        // check that _mm_blend_ps is being inlined into the closure
+        // CHECK-LABEL: {{sse41_blend_noinline.*closure.*:}}
+        // CHECK-NOT: _mm_blend_ps
+        // CHECK: blendps
+        // CHECK-NOT: _mm_blend_ps
+        // CHECK: ret
+        #[inline(never)] |x, y| unsafe {
+            _mm_blend_ps(x, y, 0b0101)
+        }
+    };
+    f(x, y)
+}
+
+#[no_mangle]
+#[target_feature(enable = "sse4.1")]
+pub fn sse41_blend_doinline(x: __m128, y: __m128) -> __m128 {
+    // check that the closure and _mm_blend_ps are being inlined into the function
+    // CHECK-LABEL: sse41_blend_doinline:
+    // CHECK-NOT: {{sse41_blend_doinline.*closure.*}}
+    // CHECK-NOT: _mm_blend_ps
+    // CHECK: blendps
+    // CHECK-NOT: {{sse41_blend_doinline.*closure.*}}
+    // CHECK-NOT: _mm_blend_ps
+    // CHECK: ret
+    let f = {
+        #[inline] |x, y| unsafe {
+            _mm_blend_ps(x, y, 0b0101)
+        }
+    };
+    f(x, y)
+}
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff
new file mode 100644
index 00000000000..b9b46f16a8b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff
@@ -0,0 +1,119 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
++ }
++ 
++ alloc11 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc10 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc7 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff
new file mode 100644
index 00000000000..93b18f23e61
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff
@@ -0,0 +1,123 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
++ }
++ 
++ alloc11 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc10 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc7 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff
new file mode 100644
index 00000000000..3d3af62856b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff
@@ -0,0 +1,119 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
++ }
++ 
++ alloc11 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc10 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc7 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff
new file mode 100644
index 00000000000..1933f9bafb3
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff
@@ -0,0 +1,123 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
++ }
++ 
++ alloc11 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc10 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc7 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
new file mode 100644
index 00000000000..7862c23da80
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -0,0 +1,111 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  }
+  
+  alloc11 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc10 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc7 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
new file mode 100644
index 00000000000..bd4150ebb45
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -0,0 +1,115 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  }
+  
+  alloc11 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc10 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc7 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
new file mode 100644
index 00000000000..312fc7b7a82
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -0,0 +1,111 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  }
+  
+  alloc11 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc10 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc7 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
new file mode 100644
index 00000000000..3227d8b8435
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -0,0 +1,115 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  }
+  
+  alloc11 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc10 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc7 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs
new file mode 100644
index 00000000000..dfeccd3eb94
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs
@@ -0,0 +1,17 @@
+// unit-test: DataflowConstProp
+// compile-flags: -Zmir-enable-passes=+ConstProp,+Inline
+// ignore-debug assertions change the output MIR
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+struct A {
+    foo: Box<[bool]>,
+}
+
+// EMIT_MIR default_boxed_slice.main.ConstProp.diff
+// EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff
+fn main() {
+    // ConstProp will create a constant of type `Box<[bool]>`.
+    // Verify that `DataflowConstProp` does not ICE trying to dereference it directly.
+    let a: A = A { foo: Box::default() };
+}
diff --git a/tests/rustdoc-ui/issue-102467.rs b/tests/rustdoc-ui/issue-102467.rs
new file mode 100644
index 00000000000..bff876e41d6
--- /dev/null
+++ b/tests/rustdoc-ui/issue-102467.rs
@@ -0,0 +1,15 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/102467>.
+// It ensures that the expected error is displayed.
+
+#![feature(associated_const_equality)]
+
+trait T {
+    type A: S<C<X = 0i32> = 34>;
+    //~^ ERROR associated type bindings are not allowed here
+}
+
+trait S {
+    const C: i32;
+}
+
+fn main() {}
diff --git a/tests/rustdoc-ui/issue-102467.stderr b/tests/rustdoc-ui/issue-102467.stderr
new file mode 100644
index 00000000000..a337293f7a0
--- /dev/null
+++ b/tests/rustdoc-ui/issue-102467.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-102467.rs:7:17
+   |
+LL |     type A: S<C<X = 0i32> = 34>;
+   |                 ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/tests/rustdoc/inline_cross/async-fn.rs b/tests/rustdoc/inline_cross/async-fn.rs
new file mode 100644
index 00000000000..95e175aabd0
--- /dev/null
+++ b/tests/rustdoc/inline_cross/async-fn.rs
@@ -0,0 +1,19 @@
+// Regression test for issue #115760.
+// Check that we render the correct return type of free and
+// associated async functions reexported from external crates.
+
+// aux-crate:async_fn=async-fn.rs
+// edition: 2021
+#![crate_name = "user"]
+
+// @has user/fn.load.html
+// @has - '//pre[@class="rust item-decl"]' "pub async fn load() -> i32"
+pub use async_fn::load;
+
+// @has user/trait.Load.html
+// @has - '//*[@id="tymethod.run"]' 'async fn run(&self) -> i32'
+pub use async_fn::Load;
+
+// @has user/struct.Loader.html
+// @has - '//*[@id="method.run"]' 'async fn run(&self) -> i32'
+pub use async_fn::Loader;
diff --git a/tests/rustdoc/inline_cross/auxiliary/async-fn.rs b/tests/rustdoc/inline_cross/auxiliary/async-fn.rs
new file mode 100644
index 00000000000..767564ed145
--- /dev/null
+++ b/tests/rustdoc/inline_cross/auxiliary/async-fn.rs
@@ -0,0 +1,18 @@
+#![feature(async_fn_in_trait)]
+// edition: 2021
+
+pub async fn load() -> i32 {
+    0
+}
+
+pub trait Load {
+    async fn run(&self) -> i32;
+}
+
+pub struct Loader;
+
+impl Load for Loader {
+    async fn run(&self) -> i32 {
+        1
+    }
+}
diff --git a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
index 19433c9682b..42cfc3dc319 100644
--- a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
@@ -33,9 +33,3 @@ pub struct Foo;
 impl Foo {
     pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a) {}
 }
-
-pub struct Bar;
-
-impl Bar {
-    pub async fn async_foo(&self) {}
-}
diff --git a/tests/rustdoc/inline_cross/impl_trait.rs b/tests/rustdoc/inline_cross/impl_trait.rs
index b6a1552bc00..5c802c51486 100644
--- a/tests/rustdoc/inline_cross/impl_trait.rs
+++ b/tests/rustdoc/inline_cross/impl_trait.rs
@@ -33,15 +33,7 @@ pub use impl_trait_aux::func4;
 // @!has - '//pre[@class="rust item-decl"]' 'where'
 pub use impl_trait_aux::func5;
 
-// @has impl_trait/fn.async_fn.html
-// @has - '//pre[@class="rust item-decl"]' "pub async fn async_fn()"
-pub use impl_trait_aux::async_fn;
-
 // @has impl_trait/struct.Foo.html
 // @has - '//*[@id="method.method"]//h4[@class="code-header"]' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8, Global>> + 'a)"
 // @!has - '//*[@id="method.method"]//h4[@class="code-header"]' 'where'
 pub use impl_trait_aux::Foo;
-
-// @has impl_trait/struct.Bar.html
-// @has - '//*[@id="method.async_foo"]' "pub async fn async_foo("
-pub use impl_trait_aux::Bar;
diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs
index 23a9e2a064c..3ec1519fb13 100644
--- a/tests/ui-fulldeps/stable-mir/compilation-result.rs
+++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs
@@ -11,9 +11,10 @@
 
 extern crate rustc_middle;
 extern crate rustc_smir;
+extern crate stable_mir;
 
 use rustc_middle::ty::TyCtxt;
-use rustc_smir::{rustc_internal, stable_mir};
+use rustc_smir::rustc_internal;
 use std::io::Write;
 use std::ops::ControlFlow;
 
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index a11720c4b55..ce4ee3c2463 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -13,13 +13,13 @@
 extern crate rustc_hir;
 extern crate rustc_middle;
 extern crate rustc_smir;
+extern crate stable_mir;
 
 use rustc_hir::def::DefKind;
 use rustc_middle::ty::TyCtxt;
-use rustc_smir::{
-    rustc_internal,
-    stable_mir::{self, fold::Foldable},
-};
+use rustc_smir::rustc_internal;
+
+use stable_mir::fold::Foldable;
 use std::assert_matches::assert_matches;
 use std::io::Write;
 use std::ops::ControlFlow;
@@ -27,7 +27,7 @@ use std::ops::ControlFlow;
 const CRATE_NAME: &str = "input";
 
 /// This function uses the Stable MIR APIs to get information about the test crate.
-fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
+fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
     // Get the local crate using stable_mir API.
     let local = stable_mir::local_crate();
     assert_eq!(&local.name, CRATE_NAME);
@@ -36,12 +36,12 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
 
     // Find items in the local crate.
     let items = stable_mir::all_local_items();
-    assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some());
+    assert!(get_item(&items, (DefKind::Fn, "foo::bar")).is_some());
 
     // Find the `std` crate.
     assert!(stable_mir::find_crate("std").is_some());
 
-    let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap();
+    let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap();
     let body = bar.body();
     assert_eq!(body.locals.len(), 2);
     assert_eq!(body.blocks.len(), 1);
@@ -56,7 +56,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap();
+    let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
     let body = foo_bar.body();
     assert_eq!(body.locals.len(), 7);
     assert_eq!(body.blocks.len(), 4);
@@ -66,7 +66,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let types = get_item(tcx, &items, (DefKind::Fn, "types")).unwrap();
+    let types = get_item(&items, (DefKind::Fn, "types")).unwrap();
     let body = types.body();
     assert_eq!(body.locals.len(), 6);
     assert_matches!(
@@ -96,7 +96,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         ))
     );
 
-    let drop = get_item(tcx, &items, (DefKind::Fn, "drop")).unwrap();
+    let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap();
     let body = drop.body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
@@ -105,7 +105,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let assert = get_item(tcx, &items, (DefKind::Fn, "assert")).unwrap();
+    let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap();
     let body = assert.body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
@@ -114,7 +114,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let monomorphic = get_item(tcx, &items, (DefKind::Fn, "monomorphic")).unwrap();
+    let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap();
     for block in monomorphic.body().blocks {
         match &block.terminator {
             stable_mir::mir::Terminator::Call { func, .. } => match func {
@@ -154,7 +154,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         }
     }
 
-    let foo_const = get_item(tcx, &items, (DefKind::Const, "FOO")).unwrap();
+    let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap();
     // Ensure we don't panic trying to get the body of a constant.
     foo_const.body();
 
@@ -163,13 +163,11 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
 
 // Use internal API to find a function in a crate.
 fn get_item<'a>(
-    tcx: TyCtxt,
     items: &'a stable_mir::CrateItems,
     item: (DefKind, &str),
 ) -> Option<&'a stable_mir::CrateItem> {
     items.iter().find(|crate_item| {
-        let def_id = rustc_internal::item_def_id(crate_item);
-        tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1
+        crate_item.kind().to_string() == format!("{:?}", item.0) && crate_item.name() == item.1
     })
 }
 
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
index 5c59f217be6..99769692342 100644
--- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
+++ b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
@@ -1,6 +1,5 @@
-// FIXME(inherent_associated_types): This should be `check-pass`
-// known-bug: #108491
 // compile-flags: --crate-type=lib
+// check-pass
 
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
@@ -8,11 +7,6 @@
 // Bounds on the self type play a major role in the resolution of inherent associated types (*).
 // As a result of that, if a type alias contains any then its bounds have to be respected and the
 // lint `type_alias_bounds` should not fire.
-//
-// FIXME(inherent_associated_types): In the current implementation that is. We might move the
-// selection phase of IATs from hir_typeck to trait_selection resulting in us not requiring the
-// ParamEnv that early allowing us to ignore bounds on type aliases again.
-// Triage this before stabilization.
 
 #![deny(type_alias_bounds)]
 
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr
deleted file mode 100644
index 5e18543fc90..00000000000
--- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr
+++ /dev/null
@@ -1,55 +0,0 @@
-error[E0391]: cycle detected when expanding type alias `Alias`
-  --> $DIR/type-alias-bounds-are-enforced.rs:19:1
-   |
-LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing the variances of `Source`...
-  --> $DIR/type-alias-bounds-are-enforced.rs:21:1
-   |
-LL | pub struct Source<T>(T);
-   | ^^^^^^^^^^^^^^^^^^^^
-   = note: ...which requires computing the variances for items in this crate...
-   = note: ...which again requires expanding type alias `Alias`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/type-alias-bounds-are-enforced.rs:5:1
-   |
-LL | / #![feature(inherent_associated_types)]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | // Bounds on the self type play a major role in the resolution of inherent associated types (*).
-...  |
-LL | |     pub type Assoc = ();
-LL | | }
-   | |_^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error[E0391]: cycle detected when expanding type alias `Alias`
-  --> $DIR/type-alias-bounds-are-enforced.rs:19:1
-   |
-LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing the variances of `Source`...
-  --> $DIR/type-alias-bounds-are-enforced.rs:21:1
-   |
-LL | pub struct Source<T>(T);
-   | ^^^^^^^^^^^^^^^^^^^^
-   = note: ...which requires computing the variances for items in this crate...
-   = note: ...which again requires expanding type alias `Alias`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/type-alias-bounds-are-enforced.rs:5:1
-   |
-LL | / #![feature(inherent_associated_types)]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | // Bounds on the self type play a major role in the resolution of inherent associated types (*).
-...  |
-LL | |     pub type Assoc = ();
-LL | | }
-   | |_^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/async-await/const-async-fn-in-main.rs b/tests/ui/async-await/const-async-fn-in-main.rs
new file mode 100644
index 00000000000..5d1aa4d83f3
--- /dev/null
+++ b/tests/ui/async-await/const-async-fn-in-main.rs
@@ -0,0 +1,7 @@
+// edition:2021
+// Check what happens when a const async fn is in the main function (#102796)
+
+fn main() {
+    const async fn a() {}
+//~^ ERROR functions cannot be both `const` and `async`
+}
diff --git a/tests/ui/async-await/const-async-fn-in-main.stderr b/tests/ui/async-await/const-async-fn-in-main.stderr
new file mode 100644
index 00000000000..10b15170922
--- /dev/null
+++ b/tests/ui/async-await/const-async-fn-in-main.stderr
@@ -0,0 +1,11 @@
+error: functions cannot be both `const` and `async`
+  --> $DIR/const-async-fn-in-main.rs:5:5
+   |
+LL |     const async fn a() {}
+   |     ^^^^^-^^^^^----------
+   |     |     |
+   |     |     `async` because of this
+   |     `const` because of this
+
+error: aborting due to previous error
+
diff --git a/tests/ui/closures/issue-112547.rs b/tests/ui/closures/issue-112547.rs
new file mode 100644
index 00000000000..8ecb2abccd4
--- /dev/null
+++ b/tests/ui/closures/issue-112547.rs
@@ -0,0 +1,15 @@
+#![feature(non_lifetime_binders)]
+        //~^ WARNING the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+
+pub fn bar()
+where
+    for<const N: usize = {
+    (||1usize)()
+}> V: IntoIterator
+//~^ ERROR cannot find type `V` in this scope [E0412]
+{
+}
+
+fn main() {
+    bar();
+}
diff --git a/tests/ui/closures/issue-112547.stderr b/tests/ui/closures/issue-112547.stderr
new file mode 100644
index 00000000000..d86b05dc6a7
--- /dev/null
+++ b/tests/ui/closures/issue-112547.stderr
@@ -0,0 +1,23 @@
+error[E0412]: cannot find type `V` in this scope
+  --> $DIR/issue-112547.rs:8:4
+   |
+LL | }> V: IntoIterator
+   |    ^ not found in this scope
+   |
+help: you might be missing a type parameter
+   |
+LL | pub fn bar<V>()
+   |           +++
+
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-112547.rs:1:12
+   |
+LL | #![feature(non_lifetime_binders)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/codegen/issue-79865-llvm-miscompile.rs b/tests/ui/codegen/issue-79865-llvm-miscompile.rs
new file mode 100644
index 00000000000..b77f09f8e9a
--- /dev/null
+++ b/tests/ui/codegen/issue-79865-llvm-miscompile.rs
@@ -0,0 +1,38 @@
+// run-pass
+// only-x86_64
+// compile-flags: -C opt-level=3
+
+// Regression test for issue #79865.
+// The assertion will fail when compiled with Rust 1.56..=1.59
+// due to a LLVM miscompilation.
+
+use std::arch::x86_64::*;
+
+fn main() {
+    if is_x86_feature_detected!("avx") {
+        let res: [f64; 4] = unsafe { std::mem::transmute::<_, _>(first()) };
+        assert_eq!(res, [22.0, 44.0, 66.0, 88.0]);
+    }
+}
+
+#[target_feature(enable = "avx")]
+unsafe fn first() -> __m256d {
+    second()
+}
+
+unsafe fn second() -> __m256d {
+    let v0 = _mm256_setr_pd(1.0, 2.0, 3.0, 4.0);
+    let v1 = _mm256_setr_pd(10.0, 20.0, 30.0, 40.0);
+
+    // needs to be called twice to hit the miscompilation
+    let (add, _) = add_sub(v0, v1);
+    let (add, _) = add_sub(add, add);
+    add
+}
+
+#[inline(never)] // needed to hit the miscompilation
+unsafe fn add_sub(v1: __m256d, v0: __m256d) -> (__m256d, __m256d) {
+    let add = _mm256_add_pd(v0, v1);
+    let sub = _mm256_sub_pd(v0, v1);
+    (add, sub)
+}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
index 08f7c5cb542..7174d1ec4f2 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
@@ -10,10 +10,12 @@ struct CantParam(ImplementsConstParamTy);
 impl std::marker::ConstParamTy for CantParam {}
 //~^ error: the type `CantParam` does not `#[derive(Eq)]`
 //~| error: the type `CantParam` does not `#[derive(PartialEq)]`
+//~| the trait bound `CantParam: Eq` is not satisfied
 
 #[derive(std::marker::ConstParamTy)]
 //~^ error: the type `CantParamDerive` does not `#[derive(Eq)]`
 //~| error: the type `CantParamDerive` does not `#[derive(PartialEq)]`
+//~| the trait bound `CantParamDerive: Eq` is not satisfied
 struct CantParamDerive(ImplementsConstParamTy);
 
 fn check<T: std::marker::ConstParamTy>() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
index 43c5b96dc7c..2cf7cc07dbe 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
@@ -1,3 +1,17 @@
+error[E0277]: the trait bound `CantParam: Eq` is not satisfied
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
+   |
+LL | impl std::marker::ConstParamTy for CantParam {}
+   |                                    ^^^^^^^^^ the trait `Eq` is not implemented for `CantParam`
+   |
+note: required by a bound in `ConstParamTy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+help: consider annotating `CantParam` with `#[derive(Eq)]`
+   |
+LL + #[derive(Eq)]
+LL | struct CantParam(ImplementsConstParamTy);
+   |
+
 error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]`
   --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
    |
@@ -16,8 +30,23 @@ LL | impl std::marker::ConstParamTy for CantParam {}
 note: required by a bound in `ConstParamTy`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
 
+error[E0277]: the trait bound `CantParamDerive: Eq` is not satisfied
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10
+   |
+LL | #[derive(std::marker::ConstParamTy)]
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive`
+   |
+note: required by a bound in `ConstParamTy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+   = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider annotating `CantParamDerive` with `#[derive(Eq)]`
+   |
+LL + #[derive(Eq)]
+LL | struct CantParamDerive(ImplementsConstParamTy);
+   |
+
 error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]`
-  --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10
    |
 LL | #[derive(std::marker::ConstParamTy)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParamDerive`
@@ -27,7 +56,7 @@ note: required by a bound in `ConstParamTy`
    = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]`
-  --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10
    |
 LL | #[derive(std::marker::ConstParamTy)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive`
@@ -36,6 +65,6 @@ note: required by a bound in `ConstParamTy`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
    = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.rs b/tests/ui/consts/const_in_pattern/issue-65466.rs
index 2b421f4c705..d45c32e170a 100644
--- a/tests/ui/consts/const_in_pattern/issue-65466.rs
+++ b/tests/ui/consts/const_in_pattern/issue-65466.rs
@@ -15,7 +15,8 @@ const C: &[O<B>] = &[O::None];
 fn main() {
     let x = O::None;
     match &[x][..] {
-        C => (),
+        C => (), //~WARN: the type must implement `PartialEq`
+        //~| previously accepted
         _ => (),
     }
 }
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.stderr b/tests/ui/consts/const_in_pattern/issue-65466.stderr
new file mode 100644
index 00000000000..9c80cb3a849
--- /dev/null
+++ b/tests/ui/consts/const_in_pattern/issue-65466.stderr
@@ -0,0 +1,23 @@
+warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-65466.rs:18:9
+   |
+LL |         C => (),
+   |         ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
+warning: 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-65466.rs:18:9
+   |
+LL |         C => (),
+   |         ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
diff --git a/tests/ui/error-codes/E0094.rs b/tests/ui/error-codes/E0094.rs
index a2ec932c124..97ebcff99dc 100644
--- a/tests/ui/error-codes/E0094.rs
+++ b/tests/ui/error-codes/E0094.rs
@@ -1,4 +1,4 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 extern "rust-intrinsic" {
     #[rustc_safe_intrinsic]
diff --git a/tests/ui/extern/extern-with-type-bounds.rs b/tests/ui/extern/extern-with-type-bounds.rs
index a72aa4171a1..99e9801fd40 100644
--- a/tests/ui/extern/extern-with-type-bounds.rs
+++ b/tests/ui/extern/extern-with-type-bounds.rs
@@ -1,4 +1,4 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 extern "rust-intrinsic" {
     // Real example from libcore
diff --git a/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
new file mode 100644
index 00000000000..e62662f2f07
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
@@ -0,0 +1,13 @@
+// compile-flags: --crate-type=lib
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![deny(refining_impl_trait)]
+
+pub trait Tr<T> {
+    fn foo() -> impl for<'a> Tr<&'a Self>;
+}
+
+impl<T> Tr<T> for () {
+    fn foo() -> impl for<'a> Tr<&'a Self> {}
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs
new file mode 100644
index 00000000000..5e14a7f8e72
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs
@@ -0,0 +1,26 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Extend {
+    fn extend<'a: 'a>(_: &'a str) -> (impl Sized + 'a, &'static str);
+}
+
+impl Extend for () {
+    fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+    //~^ ERROR in type `&'static &'a ()`, reference has a longer lifetime than the data it references
+    where
+        'a: 'static,
+    {
+        (None, s)
+    }
+}
+
+// This indirection is not necessary for reproduction,
+// but it makes this test future-proof against #114936.
+fn extend<T: Extend>(s: &str) -> &'static str {
+    <T as Extend>::extend(s).1
+}
+
+fn main() {
+    let use_after_free = extend::<()>(&String::from("temporary"));
+    println!("{}", use_after_free);
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr
new file mode 100644
index 00000000000..1d947310e12
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr
@@ -0,0 +1,16 @@
+error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
+  --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:38
+   |
+LL |     fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the pointer is valid for the static lifetime
+note: but the referenced data is only valid for the lifetime `'a` as defined here
+  --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:15
+   |
+LL |     fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+   |               ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs
new file mode 100644
index 00000000000..c1885af4e5e
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs
@@ -0,0 +1,23 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Extend {
+    fn extend(_: &str) -> (impl Sized + '_, &'static str);
+}
+
+impl Extend for () {
+    fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+        //~^ ERROR in type `&'static &()`, reference has a longer lifetime than the data it references
+        (None, s)
+    }
+}
+
+// This indirection is not necessary for reproduction,
+// but it makes this test future-proof against #114936.
+fn extend<T: Extend>(s: &str) -> &'static str {
+    <T as Extend>::extend(s).1
+}
+
+fn main() {
+    let use_after_free = extend::<()>(&String::from("temporary"));
+    println!("{}", use_after_free);
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
new file mode 100644
index 00000000000..7b63e72acbf
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
@@ -0,0 +1,16 @@
+error[E0491]: in type `&'static &()`, reference has a longer lifetime than the data it references
+  --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:27
+   |
+LL |     fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the pointer is valid for the static lifetime
+note: but the referenced data is only valid for the anonymous lifetime defined here
+  --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:18
+   |
+LL |     fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+   |                  ^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs b/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs
new file mode 100644
index 00000000000..3e3bc09a62a
--- /dev/null
+++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs
@@ -0,0 +1,27 @@
+// edition: 2021
+
+use std::future::Future;
+
+async fn bop() {
+    fold(run(), |mut foo| async move {
+        &mut foo.bar;
+    })
+}
+
+fn fold<Fut, F, U>(_: Foo<U>, f: F)
+where
+    F: FnMut(Foo<U>) -> Fut,
+{
+    loop {}
+}
+
+struct Foo<F> {
+    bar: Vec<F>,
+}
+
+fn run() -> Foo<impl Future<Output = ()>> {
+    //~^ ERROR type annotations needed
+    loop {}
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr
new file mode 100644
index 00000000000..ee4343b110f
--- /dev/null
+++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/opaque-cast-field-access-in-future.rs:22:17
+   |
+LL | fn run() -> Foo<impl Future<Output = ()>> {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs b/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
new file mode 100644
index 00000000000..ffaa4d771d9
--- /dev/null
+++ b/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
@@ -0,0 +1,6 @@
+#[rustc_safe_intrinsic]
+//~^ ERROR the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
+//~| ERROR attribute should be applied to intrinsic functions
+fn safe() {}
+
+fn main() {}
diff --git a/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr b/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr
new file mode 100644
index 00000000000..8aeb56598ec
--- /dev/null
+++ b/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr
@@ -0,0 +1,20 @@
+error[E0658]: the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
+  --> $DIR/feature-gate-safe-intrinsic.rs:1:1
+   |
+LL | #[rustc_safe_intrinsic]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error: attribute should be applied to intrinsic functions
+  --> $DIR/feature-gate-safe-intrinsic.rs:1:1
+   |
+LL | #[rustc_safe_intrinsic]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | fn safe() {}
+   | ------------ not an intrinsic function
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs
index 30b8a21269a..6f9df64417e 100644
--- a/tests/ui/intrinsics/intrinsic-alignment.rs
+++ b/tests/ui/intrinsics/intrinsic-alignment.rs
@@ -1,7 +1,7 @@
 // run-pass
 // ignore-wasm32-bare seems not important to test here
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 mod rusti {
     extern "rust-intrinsic" {
diff --git a/tests/ui/issues/issue-27042.stderr b/tests/ui/issues/issue-27042.stderr
index 59ef28481d0..01532de999e 100644
--- a/tests/ui/issues/issue-27042.stderr
+++ b/tests/ui/issues/issue-27042.stderr
@@ -11,11 +11,18 @@ LL | |         while true { break }; // but here we cite the whole loop
 error[E0308]: mismatched types
   --> $DIR/issue-27042.rs:6:16
    |
+LL |     let _: i32 =
+   |         - expected because of this assignment
+LL |         'a: // in this case, the citation is just the `break`:
 LL |         loop { break };
-   |                ^^^^^
-   |                |
-   |                expected `i32`, found `()`
-   |                help: give it a value of the expected type: `break 42`
+   |         ----   ^^^^^ expected `i32`, found `()`
+   |         |
+   |         this loop is expected to be of type `i32`
+   |
+help: give it a value of the expected type
+   |
+LL |         loop { break 42 };
+   |                      ++
 
 error[E0308]: mismatched types
   --> $DIR/issue-27042.rs:8:9
diff --git a/tests/ui/loops/loop-break-value.rs b/tests/ui/loops/loop-break-value.rs
index f334f9d464a..c35200520cb 100644
--- a/tests/ui/loops/loop-break-value.rs
+++ b/tests/ui/loops/loop-break-value.rs
@@ -95,6 +95,66 @@ fn main() {
         break LOOP;
         //~^ ERROR cannot find value `LOOP` in this scope
     }
+
+    let _ = 'a: loop {
+        loop {
+            break; // This doesn't affect the expected break type of the 'a loop
+            loop {
+                loop {
+                    break 'a 1;
+                }
+            }
+        }
+        break; //~ ERROR mismatched types
+    };
+
+    let _ = 'a: loop {
+        loop {
+            break; // This doesn't affect the expected break type of the 'a loop
+            loop {
+                loop {
+                    break 'a 1;
+                }
+            }
+        }
+        break 'a; //~ ERROR mismatched types
+    };
+
+    loop {
+        break;
+        let _ = loop {
+            break 2;
+            loop {
+                break;
+            }
+        };
+        break 2; //~ ERROR mismatched types
+    }
+
+    'a: loop {
+        break;
+        let _ = 'a: loop {
+            //~^ WARNING label name `'a` shadows a label name that is already in scope
+            break 2;
+            loop {
+                break 'a; //~ ERROR mismatched types
+            }
+        };
+        break 2; //~ ERROR mismatched types
+    }
+
+    'a: loop {
+        break;
+        let _ = 'a: loop {
+            //~^ WARNING label name `'a` shadows a label name that is already in scope
+            break 'a 2;
+            loop {
+                break 'a; //~ ERROR mismatched types
+            }
+        };
+        break 2; //~ ERROR mismatched types
+    };
+
     loop { // point at the return type
         break 2; //~ ERROR mismatched types
     }
diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr
index 76d12b7c1b3..6c83bc7575c 100644
--- a/tests/ui/loops/loop-break-value.stderr
+++ b/tests/ui/loops/loop-break-value.stderr
@@ -1,3 +1,21 @@
+warning: label name `'a` shadows a label name that is already in scope
+  --> $DIR/loop-break-value.rs:136:17
+   |
+LL |     'a: loop {
+   |     -- first declared here
+LL |         break;
+LL |         let _ = 'a: loop {
+   |                 ^^ label `'a` already in scope
+
+warning: label name `'a` shadows a label name that is already in scope
+  --> $DIR/loop-break-value.rs:148:17
+   |
+LL |     'a: loop {
+   |     -- first declared here
+LL |         break;
+LL |         let _ = 'a: loop {
+   |                 ^^ label `'a` already in scope
+
 error[E0425]: cannot find value `LOOP` in this scope
   --> $DIR/loop-break-value.rs:95:15
    |
@@ -134,7 +152,10 @@ error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:4:31
    |
 LL |     let val: ! = loop { break break; };
-   |                               ^^^^^ expected `!`, found `()`
+   |         ---      ----         ^^^^^ expected `!`, found `()`
+   |         |        |
+   |         |        this loop is expected to be of type `!`
+   |         expected because of this assignment
    |
    = note:   expected type `!`
            found unit type `()`
@@ -142,6 +163,9 @@ LL |     let val: ! = loop { break break; };
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:11:19
    |
+LL |             break "asdf";
+   |             ------------ expected because of this `break`
+LL |         } else {
 LL |             break 123;
    |                   ^^^ expected `&str`, found integer
 
@@ -169,6 +193,8 @@ LL |             break 'outer_loop "nope";
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:73:26
    |
+LL |                 break;
+   |                 ----- expected because of this `break`
 LL |                 break 'c 123;
    |                          ^^^ expected `()`, found integer
 
@@ -176,7 +202,11 @@ error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:80:15
    |
 LL |         break (break, break);
-   |               ^^^^^^^^^^^^^^ expected `()`, found `(!, !)`
+   |               ^-----^^-----^
+   |               ||      |
+   |               ||      expected because of this `break`
+   |               |expected because of this `break`
+   |               expected `()`, found `(!, !)`
    |
    = note: expected unit type `()`
                   found tuple `(!, !)`
@@ -184,20 +214,109 @@ LL |         break (break, break);
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:85:15
    |
+LL |         break;
+   |         ----- expected because of this `break`
 LL |         break 2;
    |               ^ expected `()`, found integer
 
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:90:9
    |
+LL |         break 2;
+   |         ------- expected because of this `break`
 LL |         break;
-   |         ^^^^^
-   |         |
-   |         expected integer, found `()`
-   |         help: give it a value of the expected type: `break value`
+   |         ^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         break value;
+   |               +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:108:9
+   |
+LL |                     break 'a 1;
+   |                     ---------- expected because of this `break`
+...
+LL |         break;
+   |         ^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         break value;
+   |               +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:120:9
+   |
+LL |                     break 'a 1;
+   |                     ---------- expected because of this `break`
+...
+LL |         break 'a;
+   |         ^^^^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         break 'a value;
+   |                  +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:131:15
+   |
+LL |         break;
+   |         ----- expected because of this `break`
+...
+LL |         break 2;
+   |               ^ expected `()`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:140:17
+   |
+LL |             break 2;
+   |             ------- expected because of this `break`
+LL |             loop {
+LL |                 break 'a;
+   |                 ^^^^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |                 break 'a value;
+   |                          +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:143:15
+   |
+LL |         break;
+   |         ----- expected because of this `break`
+...
+LL |         break 2;
+   |               ^ expected `()`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:152:17
+   |
+LL |             break 'a 2;
+   |             ---------- expected because of this `break`
+LL |             loop {
+LL |                 break 'a;
+   |                 ^^^^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |                 break 'a value;
+   |                          +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:155:15
+   |
+LL |         break;
+   |         ----- expected because of this `break`
+...
+LL |         break 2;
+   |               ^ expected `()`, found integer
 
 error[E0308]: mismatched types
-  --> $DIR/loop-break-value.rs:99:15
+  --> $DIR/loop-break-value.rs:159:15
    |
 LL | fn main() {
    |           - expected `()` because of this return type
@@ -207,7 +326,7 @@ LL |     loop { // point at the return type
 LL |         break 2;
    |               ^ expected `()`, found integer
 
-error: aborting due to 18 previous errors; 1 warning emitted
+error: aborting due to 25 previous errors; 3 warnings emitted
 
 Some errors have detailed explanations: E0308, E0425, E0571.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/loops/loop-labeled-break-value.stderr b/tests/ui/loops/loop-labeled-break-value.stderr
index aa04d330f25..694d6c306f6 100644
--- a/tests/ui/loops/loop-labeled-break-value.stderr
+++ b/tests/ui/loops/loop-labeled-break-value.stderr
@@ -2,28 +2,43 @@ error[E0308]: mismatched types
   --> $DIR/loop-labeled-break-value.rs:3:29
    |
 LL |         let _: i32 = loop { break };
-   |                             ^^^^^
-   |                             |
-   |                             expected `i32`, found `()`
-   |                             help: give it a value of the expected type: `break 42`
+   |             -        ----   ^^^^^ expected `i32`, found `()`
+   |             |        |
+   |             |        this loop is expected to be of type `i32`
+   |             expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |         let _: i32 = loop { break 42 };
+   |                                   ++
 
 error[E0308]: mismatched types
   --> $DIR/loop-labeled-break-value.rs:6:37
    |
 LL |         let _: i32 = 'inner: loop { break 'inner };
-   |                                     ^^^^^^^^^^^^
-   |                                     |
-   |                                     expected `i32`, found `()`
-   |                                     help: give it a value of the expected type: `break 'inner 42`
+   |             -                ----   ^^^^^^^^^^^^ expected `i32`, found `()`
+   |             |                |
+   |             |                this loop is expected to be of type `i32`
+   |             expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |         let _: i32 = 'inner: loop { break 'inner 42 };
+   |                                                  ++
 
 error[E0308]: mismatched types
   --> $DIR/loop-labeled-break-value.rs:9:45
    |
 LL |         let _: i32 = 'inner2: loop { loop { break 'inner2 } };
-   |                                             ^^^^^^^^^^^^^
-   |                                             |
-   |                                             expected `i32`, found `()`
-   |                                             help: give it a value of the expected type: `break 'inner2 42`
+   |             -                 ----          ^^^^^^^^^^^^^ expected `i32`, found `()`
+   |             |                 |
+   |             |                 this loop is expected to be of type `i32`
+   |             expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |         let _: i32 = 'inner2: loop { loop { break 'inner2 42 } };
+   |                                                           ++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/loops/loop-properly-diverging-2.stderr b/tests/ui/loops/loop-properly-diverging-2.stderr
index 5030a2935b9..1d1ae60cda1 100644
--- a/tests/ui/loops/loop-properly-diverging-2.stderr
+++ b/tests/ui/loops/loop-properly-diverging-2.stderr
@@ -2,10 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/loop-properly-diverging-2.rs:2:23
    |
 LL |   let x: i32 = loop { break };
-   |                       ^^^^^
-   |                       |
-   |                       expected `i32`, found `()`
-   |                       help: give it a value of the expected type: `break 42`
+   |       -        ----   ^^^^^ expected `i32`, found `()`
+   |       |        |
+   |       |        this loop is expected to be of type `i32`
+   |       expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |   let x: i32 = loop { break 42 };
+   |                             ++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/match/issue-72896.rs b/tests/ui/match/issue-72896-non-partial-eq-const.rs
index 3a8b8203731..a3095f0be83 100644
--- a/tests/ui/match/issue-72896.rs
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.rs
@@ -17,7 +17,8 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
 
 fn main() {
     match CONST_SET {
-        CONST_SET => { /* ok */ }
+        CONST_SET => { /* ok */ } //~WARN: must implement `PartialEq`
+        //~| previously accepted
         _ => panic!("match fell through?"),
     }
 }
diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.stderr b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
new file mode 100644
index 00000000000..a7fc0cfc054
--- /dev/null
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
@@ -0,0 +1,23 @@
+warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-72896-non-partial-eq-const.rs:20:9
+   |
+LL |         CONST_SET => { /* ok */ }
+   |         ^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
+warning: 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-72896-non-partial-eq-const.rs:20:9
+   |
+LL |         CONST_SET => { /* ok */ }
+   |         ^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr
index 99dfce86903..59292ed68a3 100644
--- a/tests/ui/never_type/issue-52443.stderr
+++ b/tests/ui/never_type/issue-52443.stderr
@@ -33,10 +33,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-52443.rs:4:17
    |
 LL |     [(); loop { break }];
-   |                 ^^^^^
-   |                 |
-   |                 expected `usize`, found `()`
-   |                 help: give it a value of the expected type: `break 42`
+   |                 ^^^^^ expected `usize`, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |     [(); loop { break 42 }];
+   |                       ++
 
 error[E0015]: cannot convert `RangeFrom<usize>` into an iterator in constants
   --> $DIR/issue-52443.rs:9:21
diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
index 1e3a5328d3d..b3cb7813e19 100644
--- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -6,7 +6,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) i32)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) i32)),
                (),
            ]
 
diff --git a/tests/ui/nll/closure-requirements/escape-argument.stderr b/tests/ui/nll/closure-requirements/escape-argument.stderr
index bc4ba93f884..4f0156728ac 100644
--- a/tests/ui/nll/closure-requirements/escape-argument.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument.stderr
@@ -6,7 +6,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32)),
                (),
            ]
 
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index f8383cc42a2..ccf56bf6f37 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -6,7 +6,7 @@ LL |         |_outlives1, _outlives2, _outlives3, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?3 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?3 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?4
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index 113173d8f76..a16433c9d37 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index ba15199ab5a..9e0f16c0fc7 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -6,7 +6,7 @@ LL |     foo(cell, |cell_a, cell_x| {
    |
    = note: defining type: case1::{closure#0} with closure args [
                i32,
-               for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>)),
                (),
            ]
 
@@ -36,7 +36,7 @@ LL |     foo(cell, |cell_a, cell_x| {
    |
    = note: defining type: case2::{closure#0} with closure args [
                i32,
-               for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>)),
                (),
            ]
    = note: number of external vids: 2
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index f2bf83c6c59..e4989e32155 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?2
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 2734326ed64..be35e62d070 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr
index 5ab321eb666..8880dd816a1 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index 595fd5ff565..47774b63f81 100644
--- a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -6,7 +6,7 @@ LL |         |_outlives1, _outlives2, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 62b0e3eed85..3404bb12827 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?2
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 6f2044d621e..e40648912e3 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 7635f2ede0a..18fb7195d02 100644
--- a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -6,7 +6,7 @@ LL |     expect_sig(|a, b| b); // ought to return `a`
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) i32,
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) i32,
                (),
            ]
 
diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 660211fe21a..f58d49d8461 100644
--- a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -6,7 +6,7 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
    |
    = note: defining type: generic::<T>::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) T)),
                (),
            ]
    = note: number of external vids: 2
@@ -28,7 +28,7 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
    |
    = note: defining type: generic_fail::<T>::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) T)),
                (),
            ]
    = note: late-bound region is '?2
diff --git a/tests/ui/proc-macro/auxiliary/print-tokens.rs b/tests/ui/proc-macro/auxiliary/print-tokens.rs
new file mode 100644
index 00000000000..3a5767edb15
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/print-tokens.rs
@@ -0,0 +1,16 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn print_tokens(input: TokenStream) -> TokenStream {
+    println!("{:#?}", input);
+    for token in input {
+        println!("{token}");
+    }
+    TokenStream::new()
+}
diff --git a/tests/ui/proc-macro/literal-to-string.rs b/tests/ui/proc-macro/literal-to-string.rs
new file mode 100644
index 00000000000..494d17cbeea
--- /dev/null
+++ b/tests/ui/proc-macro/literal-to-string.rs
@@ -0,0 +1,26 @@
+// check-pass
+// edition: 2021
+#![feature(c_str_literals)]
+
+// aux-build: print-tokens.rs
+extern crate print_tokens;
+
+fn main() {
+    print_tokens::print_tokens! {
+        1
+        17u8
+        42.
+        3.14f32
+        b'a'
+        b'\xFF'
+        'c'
+        '\x32'
+        "\"str\""
+        r#""raw" str"#
+        r###"very ##"raw"## str"###
+        b"\"byte\" str"
+        br#""raw" "byte" str"#
+        c"\"c\" str"
+        cr#""raw" "c" str"#
+    }
+}
diff --git a/tests/ui/proc-macro/literal-to-string.stdout b/tests/ui/proc-macro/literal-to-string.stdout
new file mode 100644
index 00000000000..7b27fcf798b
--- /dev/null
+++ b/tests/ui/proc-macro/literal-to-string.stdout
@@ -0,0 +1,107 @@
+TokenStream [
+    Literal {
+        kind: Integer,
+        symbol: "1",
+        suffix: None,
+        span: #0 bytes(172..173),
+    },
+    Literal {
+        kind: Integer,
+        symbol: "17",
+        suffix: Some("u8"),
+        span: #0 bytes(182..186),
+    },
+    Literal {
+        kind: Float,
+        symbol: "42.",
+        suffix: None,
+        span: #0 bytes(195..198),
+    },
+    Literal {
+        kind: Float,
+        symbol: "3.14",
+        suffix: Some("f32"),
+        span: #0 bytes(207..214),
+    },
+    Literal {
+        kind: Byte,
+        symbol: "a",
+        suffix: None,
+        span: #0 bytes(223..227),
+    },
+    Literal {
+        kind: Byte,
+        symbol: "\xFF",
+        suffix: None,
+        span: #0 bytes(236..243),
+    },
+    Literal {
+        kind: Char,
+        symbol: "c",
+        suffix: None,
+        span: #0 bytes(252..255),
+    },
+    Literal {
+        kind: Char,
+        symbol: "\x32",
+        suffix: None,
+        span: #0 bytes(264..270),
+    },
+    Literal {
+        kind: Str,
+        symbol: "\\"str\\"",
+        suffix: None,
+        span: #0 bytes(279..288),
+    },
+    Literal {
+        kind: StrRaw(1),
+        symbol: "\"raw\" str",
+        suffix: None,
+        span: #0 bytes(297..311),
+    },
+    Literal {
+        kind: StrRaw(3),
+        symbol: "very ##\"raw\"## str",
+        suffix: None,
+        span: #0 bytes(320..347),
+    },
+    Literal {
+        kind: ByteStr,
+        symbol: "\\"byte\\" str",
+        suffix: None,
+        span: #0 bytes(356..371),
+    },
+    Literal {
+        kind: ByteStrRaw(1),
+        symbol: "\"raw\" \"byte\" str",
+        suffix: None,
+        span: #0 bytes(380..402),
+    },
+    Literal {
+        kind: CStr,
+        symbol: "\\"c\\" str",
+        suffix: None,
+        span: #0 bytes(411..423),
+    },
+    Literal {
+        kind: CStrRaw(1),
+        symbol: "\"raw\" \"c\" str",
+        suffix: None,
+        span: #0 bytes(432..451),
+    },
+]
+1
+17u8
+42.
+3.14f32
+b'a'
+b'\xFF'
+'c'
+'\x32'
+"\"str\""
+r#""raw" str"#
+r###"very ##"raw"## str"###
+b"\"byte\" str"
+br#""raw" "byte" str"#
+c"\"c\" str"
+cr#""raw" "c" str"#
diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs
index 2acfde4be46..d4fea2b192b 100644
--- a/tests/ui/repr/16-bit-repr-c-enum.rs
+++ b/tests/ui/repr/16-bit-repr-c-enum.rs
@@ -5,7 +5,7 @@
 // [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib
 // [msp430] needs-llvm-components: msp430
 // [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib
-#![feature(no_core, lang_items, intrinsics, staged_api)]
+#![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)]
 #![no_core]
 #![crate_type = "lib"]
 #![stable(feature = "", since = "")]
diff --git a/tests/ui/structs-enums/rec-align-u32.rs b/tests/ui/structs-enums/rec-align-u32.rs
index ee704198d19..b3c323d2a29 100644
--- a/tests/ui/structs-enums/rec-align-u32.rs
+++ b/tests/ui/structs-enums/rec-align-u32.rs
@@ -3,7 +3,7 @@
 #![allow(unused_unsafe)]
 // Issue #2303
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 use std::mem;
 
diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs-enums/rec-align-u64.rs
index c3b201fb1c6..de008bcc01d 100644
--- a/tests/ui/structs-enums/rec-align-u64.rs
+++ b/tests/ui/structs-enums/rec-align-u64.rs
@@ -5,7 +5,7 @@
 
 // Issue #2303
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 use std::mem;
 
diff --git a/tests/ui/type/type-error-break-tail.stderr b/tests/ui/type/type-error-break-tail.stderr
index 16dc6475c6f..9a02bc28752 100644
--- a/tests/ui/type/type-error-break-tail.stderr
+++ b/tests/ui/type/type-error-break-tail.stderr
@@ -2,13 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/type-error-break-tail.rs:3:20
    |
 LL | fn loop_ending() -> i32 {
-   |                     --- expected `i32` because of return type
+   |                     --- expected `i32` because of this return type
 LL |     loop {
+   |     ---- this loop is expected to be of type `i32`
 LL |         if false { break; }
-   |                    ^^^^^
-   |                    |
-   |                    expected `i32`, found `()`
-   |                    help: give it a value of the expected type: `break 42`
+   |                    ^^^^^ expected `i32`, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         if false { break 42; }
+   |                          ++
 
 error: aborting due to previous error
 
diff --git a/triagebot.toml b/triagebot.toml
index dbced481993..648997ad6f0 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -542,6 +542,10 @@ cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
 message = "This PR changes Stable MIR"
 cc = ["@oli-obk", "@celinval", "@spastorino"]
 
+[mentions."compiler/stable_mir"]
+message = "This PR changes Stable MIR"
+cc = ["@oli-obk", "@celinval", "@spastorino"]
+
 [mentions."compiler/rustc_target/src/spec"]
 message = """
 These commits modify **compiler targets**.