about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-03-08 07:09:40 +0000
committerbors <bors@rust-lang.org>2024-03-08 07:09:40 +0000
commit4db028f44995266895ae9e75b0a0726cc690ef7c (patch)
tree9da59f255a8a2d5451877c60b9b4d48ab5328542
parent305d2b0f5c7e8081ab21f78e2d53ed8f84aebecd (diff)
parentfcd2efeb1180162091ce8f79087b2cbd56ea0b76 (diff)
downloadrust-4db028f44995266895ae9e75b0a0726cc690ef7c.tar.gz
rust-4db028f44995266895ae9e75b0a0726cc690ef7c.zip
Auto merge of #3365 - rust-lang:rustup-2024-03-08, r=RalfJung
Automatic Rustup
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs57
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs2
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs54
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs11
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs7
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs12
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs16
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs6
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs2
-rw-r--r--compiler/rustc_driver_impl/src/pretty.rs4
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/object_safety.rs80
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs19
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs52
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs12
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/unsafety.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs39
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check.rs22
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs16
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs6
-rw-r--r--compiler/rustc_index/src/vec.rs19
-rw-r--r--compiler/rustc_infer/src/infer/higher_ranked/README.md8
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs143
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs (renamed from compiler/rustc_infer/src/infer/opaque_types.rs)0
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/table.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs5
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/leak_check.rs8
-rw-r--r--compiler/rustc_infer/src/infer/region_constraints/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs4
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/fudge.rs (renamed from compiler/rustc_infer/src/infer/fudge.rs)6
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/mod.rs102
-rw-r--r--compiler/rustc_infer/src/infer/snapshot/undo_log.rs (renamed from compiler/rustc_infer/src/infer/undo_log.rs)0
-rw-r--r--compiler/rustc_infer/src/traits/project.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs23
-rw-r--r--compiler/rustc_interface/src/queries.rs12
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs6
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs3
-rw-r--r--compiler/rustc_llvm/Cargo.toml7
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp14
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp42
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp54
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp9
-rw-r--r--compiler/rustc_metadata/src/locator.rs22
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs3
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs2
-rw-r--r--compiler/rustc_middle/src/query/erase.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs15
-rw-r--r--compiler/rustc_middle/src/ty/context.rs76
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs20
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs81
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs34
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs21
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs4
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs4
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs16
-rw-r--r--compiler/rustc_passes/src/debugger_visualizer.rs2
-rw-r--r--compiler/rustc_passes/src/hir_id_validator.rs36
-rw-r--r--compiler/rustc_passes/src/lang_items.rs2
-rw-r--r--compiler/rustc_passes/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs56
-rw-r--r--compiler/rustc_resolve/src/check_unused.rs146
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs18
-rw-r--r--compiler/rustc_resolve/src/imports.rs2
-rw-r--r--compiler/rustc_resolve/src/late.rs19
-rw-r--r--compiler/rustc_resolve/src/lib.rs67
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs21
-rw-r--r--compiler/rustc_target/src/target_features.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs94
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs95
-rw-r--r--compiler/rustc_traits/src/codegen.rs9
-rw-r--r--compiler/rustc_ty_utils/src/assoc.rs47
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs5
-rw-r--r--config.example.toml4
-rw-r--r--library/alloc/src/raw_vec.rs2
-rw-r--r--library/core/src/arch.rs8
-rw-r--r--library/core/src/array/mod.rs1
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/core/src/macros/mod.rs2
-rw-r--r--library/core/src/ptr/alignment.rs2
-rw-r--r--library/core/src/slice/cmp.rs4
-rw-r--r--library/core/src/slice/mod.rs2
-rw-r--r--library/core/src/sync/exclusive.rs2
-rw-r--r--library/std/src/ffi/os_str.rs8
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/os/unix/mod.rs16
-rw-r--r--library/std/src/os/unix/net/mod.rs29
-rw-r--r--library/std/src/os/unix/net/stream.rs33
-rw-r--r--library/std/src/os/unix/net/ucred.rs (renamed from library/std/src/os/unix/ucred.rs)14
-rw-r--r--library/std/src/os/unix/net/ucred/tests.rs (renamed from library/std/src/os/unix/ucred/tests.rs)0
-rw-r--r--library/std/src/sys/pal/hermit/time.rs2
-rw-r--r--library/std/src/sys/pal/windows/thread.rs7
-rw-r--r--library/std/src/thread/tests.rs14
-rw-r--r--library/std/src/time.rs10
-rw-r--r--library/test/src/formatters/terse.rs2
-rw-r--r--library/test/src/types.rs2
-rw-r--r--src/bootstrap/bootstrap.py4
-rwxr-xr-xsrc/bootstrap/configure.py1
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs11
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs9
-rw-r--r--src/bootstrap/src/core/build_steps/format.rs2
-rw-r--r--src/bootstrap/src/core/config/config.rs4
-rw-r--r--src/bootstrap/src/core/download.rs8
-rw-r--r--src/bootstrap/src/lib.rs2
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/doc/rust.css4
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md7
-rw-r--r--src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md69
-rw-r--r--src/doc/unstable-book/src/language-features/diagnostic-namespace.md84
-rw-r--r--src/tools/build_helper/src/git.rs17
m---------src/tools/cargo0
-rwxr-xr-xsrc/tools/clippy/.github/driver.sh4
-rw-r--r--src/tools/clippy/.github/workflows/clippy.yml11
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml32
-rw-r--r--src/tools/clippy/CHANGELOG.md112
-rw-r--r--src/tools/clippy/book/src/development/trait_checking.md50
-rw-r--r--src/tools/clippy/book/src/development/type_checking.md16
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md826
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs6
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_config/src/metadata.rs4
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs322
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs1210
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs87
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs52
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/inline_always.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs51
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs588
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs49
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs54
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs73
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/utils.rs87
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/markdown.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/let_underscore.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/identity_op.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs205
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs67
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/vec_box.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/main.rs9
-rw-r--r--src/tools/clippy/tests/compile-test.rs1
-rw-r--r--src/tools/clippy/tests/missing-test-files.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.stderr7
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.rs15
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr74
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr94
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs7
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.fixed222
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.rs222
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.stderr107
-rw-r--r--src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs2
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed26
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs26
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr14
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed5
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.stderr13
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_9473.fixed9
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_9473.rs9
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_9473.stderr15
-rw-r--r--src/tools/clippy/tests/ui/else_if_without_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/else_if_without_else.stderr4
-rw-r--r--src/tools/clippy/tests/ui/empty_docs.rs2
-rw-r--r--src/tools/clippy/tests/ui/empty_docs.stderr18
-rw-r--r--src/tools/clippy/tests/ui/entry.fixed11
-rw-r--r--src/tools/clippy/tests/ui/entry.rs11
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.fixed2
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.rs2
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.rs1
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.stderr44
-rw-r--r--src/tools/clippy/tests/ui/identity_op.fixed2
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs2
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.rs2
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr32
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_untyped.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.rs10
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.stderr68
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs58
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr52
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.stderr76
-rw-r--r--src/tools/clippy/tests/ui/many_single_char_names.rs2
-rw-r--r--src/tools/clippy/tests/ui/many_single_char_names.stderr10
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs2
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr12
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.rs39
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.stderr30
-rw-r--r--src/tools/clippy/tests/ui/mut_mut.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_mut.stderr18
-rw-r--r--src/tools/clippy/tests/ui/no_effect_replace.rs2
-rw-r--r--src/tools/clippy/tests/ui/no_effect_replace.stderr16
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.rs1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr8
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.rs6
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.stderr58
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed2
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.rs2
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr26
-rw-r--r--src/tools/clippy/tests/ui/option_option.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_option.stderr26
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.fixed1
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.rs1
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.stderr66
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed10
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs10
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed17
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs17
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.fixed15
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.rs15
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.stderr15
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.fixed2
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.rs2
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.stderr2
-rw-r--r--src/tools/clippy/tests/ui/single_match.fixed2
-rw-r--r--src/tools/clippy/tests/ui/single_match.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_match.stderr36
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.fixed2
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr18
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.fixed11
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.rs9
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.stderr36
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.rs2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr52
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed14
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs14
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr14
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed7
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs7
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.rs2
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.stderr30
-rw-r--r--src/tools/clippy/tests/ui/unknown_attribute.rs2
-rw-r--r--src/tools/clippy/tests/ui/unknown_attribute.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.fixed6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.stderr8
-rw-r--r--src/tools/compiletest/src/common.rs9
-rw-r--r--src/tools/compiletest/src/header.rs1
-rw-r--r--src/tools/compiletest/src/header/needs.rs5
-rw-r--r--src/tools/compiletest/src/header/tests.rs20
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/concurrency/thread.rs2
-rw-r--r--src/tools/miri/src/eval.rs4
-rw-r--r--src/tools/miri/src/helpers.rs4
-rw-r--r--src/tools/miri/src/machine.rs6
-rw-r--r--src/tools/miri/src/shims/backtrace.rs21
-rw-r--r--src/tools/miri/src/shims/ffi_support.rs4
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs10
-rw-r--r--src/tools/miri/src/shims/intrinsics/atomic.rs14
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs6
-rw-r--r--src/tools/miri/src/shims/intrinsics/simd.rs22
-rw-r--r--src/tools/miri/src/shims/panic.rs4
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs4
-rw-r--r--src/tools/miri/src/shims/unix/linux/sync.rs4
-rw-r--r--src/tools/miri/src/shims/unix/macos/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs4
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs2
-rw-r--r--src/tools/miri/src/shims/windows/sync.rs12
-rw-r--r--src/tools/miri/src/shims/x86/aesni.rs4
-rw-r--r--src/tools/miri/src/shims/x86/avx.rs10
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs38
-rw-r--r--src/tools/miri/src/shims/x86/sse.rs4
-rw-r--r--src/tools/miri/src/shims/x86/sse2.rs24
-rw-r--r--src/tools/miri/src/shims/x86/sse3.rs2
-rw-r--r--src/tools/miri/src/shims/x86/sse41.rs10
-rw-r--r--src/tools/miri/src/shims/x86/ssse3.rs12
-rw-r--r--src/tools/miri/tests/compiletest.rs4
-rw-r--r--src/tools/miri/tests/pass/shims/fs.rs4
-rw-r--r--src/tools/opt-dist/src/utils/artifact_size.rs2
-rw-r--r--src/tools/tidy/src/ui_tests.rs6
-rw-r--r--tests/assembly/targets/targets-pe.rs3
-rw-r--r--tests/codegen/cffi/c-variadic.rs2
-rw-r--r--tests/codegen/dst-offset.rs84
-rw-r--r--tests/codegen/zst-offset.rs6
-rw-r--r--tests/rustdoc-ui/not-wf-ambiguous-normalization.rs2
-rw-r--r--tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr8
-rw-r--r--tests/ui/abi/compatibility.rs2
-rw-r--r--tests/ui/abi/extern/extern-call-deep2.rs2
-rw-r--r--tests/ui/abi/extern/extern-call-scrub.rs2
-rw-r--r--tests/ui/abi/foreign/foreign-call-no-runtime.rs2
-rw-r--r--tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr7
-rw-r--r--tests/ui/associated-types/hr-associated-type-projection-1.rs2
-rw-r--r--tests/ui/associated-types/hr-associated-type-projection-1.stderr8
-rw-r--r--tests/ui/associated-types/issue-38821.stderr38
-rw-r--r--tests/ui/box/unit/unique-send-2.rs2
-rw-r--r--tests/ui/check-cfg/mix.stderr2
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr4
-rw-r--r--tests/ui/codegen/init-large-type.rs3
-rw-r--r--tests/ui/codegen/issue-28950.rs2
-rw-r--r--tests/ui/coherence/coherence-orphan.stderr22
-rw-r--r--tests/ui/const-generics/issues/issue-68366.full.stderr26
-rw-r--r--tests/ui/const-generics/issues/issue-68366.min.stderr17
-rw-r--r--tests/ui/const-generics/issues/issue-68366.rs2
-rw-r--r--tests/ui/coroutine/smoke.rs2
-rw-r--r--tests/ui/crate-loading/missing-std.stderr4
-rw-r--r--tests/ui/cross-crate/cci_capture_clause.rs2
-rw-r--r--tests/ui/diagnostic_namespace/existing_proc_macros.rs1
-rw-r--r--tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs13
-rw-r--r--tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr37
-rw-r--r--tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs1
-rw-r--r--tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr4
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/auxiliary/other.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr74
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr54
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.rs7
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.stderr13
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr14
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr12
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr6
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs2
-rw-r--r--tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr14
-rw-r--r--tests/ui/diagnostic_namespace/requires_path.rs2
-rw-r--r--tests/ui/diagnostic_namespace/requires_path.stderr2
-rw-r--r--tests/ui/duplicate/duplicate-type-parameter.rs1
-rw-r--r--tests/ui/duplicate/duplicate-type-parameter.stderr11
-rw-r--r--tests/ui/error-codes/E0374.stderr16
-rw-r--r--tests/ui/error-codes/E0375.stderr18
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-87735.stderr89
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88526.stderr18
-rw-r--r--tests/ui/hashmap/hashmap-memory.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs18
-rw-r--r--tests/ui/impl-trait/issues/issue-87340.rs2
-rw-r--r--tests/ui/impl-trait/issues/issue-87340.stderr17
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr16
-rw-r--r--tests/ui/impl-unused-tps.stderr44
-rw-r--r--tests/ui/imports/auxiliary/aux-issue-121915.rs1
-rw-r--r--tests/ui/imports/redundant-import-issue-121915-2015.rs11
-rw-r--r--tests/ui/imports/redundant-import-issue-121915-2015.stderr17
-rw-r--r--tests/ui/imports/redundant-import-issue-121915.rs9
-rw-r--r--tests/ui/imports/redundant-import-issue-121915.stderr14
-rw-r--r--tests/ui/imports/suggest-remove-issue-121315.rs40
-rw-r--r--tests/ui/imports/suggest-remove-issue-121315.stderr56
-rw-r--r--tests/ui/issues/issue-16560.rs2
-rw-r--r--tests/ui/issues/issue-21291.rs2
-rw-r--r--tests/ui/issues/issue-22864-2.rs2
-rw-r--r--tests/ui/issues/issue-29861.rs1
-rw-r--r--tests/ui/issues/issue-29861.stderr16
-rw-r--r--tests/ui/issues/issue-33941.rs1
-rw-r--r--tests/ui/issues/issue-33941.stderr12
-rw-r--r--tests/ui/issues/issue-37131.stderr4
-rw-r--r--tests/ui/issues/issue-49851/compiler-builtins-error.rs2
-rw-r--r--tests/ui/issues/issue-49851/compiler-builtins-error.stderr12
-rw-r--r--tests/ui/issues/issue-59020.rs2
-rw-r--r--tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs2
-rw-r--r--tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr13
-rw-r--r--tests/ui/linkage-attr/common-linkage-non-zero-init.stderr2
-rw-r--r--tests/ui/lint/non_local_definitions.rs1
-rw-r--r--tests/ui/lint/non_local_definitions.stderr106
-rw-r--r--tests/ui/logging-only-prints-once.rs2
-rw-r--r--tests/ui/lto/lto-still-runs-thread-dtors.rs2
-rw-r--r--tests/ui/macros/macro-with-braces-in-expr-position.rs2
-rw-r--r--tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr24
-rw-r--r--tests/ui/moves/moves-based-on-type-capture-clause.rs2
-rw-r--r--tests/ui/panics/default-backtrace-ice.stderr2
-rw-r--r--tests/ui/panics/panic-handler-chain.rs3
-rw-r--r--tests/ui/panics/panic-task-name-none.rs2
-rw-r--r--tests/ui/panics/panic-task-name-owned.rs2
-rw-r--r--tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr18
-rw-r--r--tests/ui/parser/impls-nested-within-anon-consts-semantic.rs35
-rw-r--r--tests/ui/parser/impls-nested-within-fns-semantic-0.rs15
-rw-r--r--tests/ui/parser/impls-nested-within-fns-semantic-1.rs22
-rw-r--r--tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs7
-rw-r--r--tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr12
-rw-r--r--tests/ui/proc-macro/nested-macro-rules.rs2
-rw-r--r--tests/ui/proc-macro/nested-macro-rules.stderr8
-rw-r--r--tests/ui/proc-macro/nested-macro-rules.stdout4
-rw-r--r--tests/ui/process-termination/process-termination-blocking-io.rs2
-rw-r--r--tests/ui/process-termination/process-termination-simple.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr16
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs2
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr27
-rw-r--r--tests/ui/structs-enums/ivec-tag.rs2
-rw-r--r--tests/ui/test-attrs/test-filter-multiple.rs2
-rw-r--r--tests/ui/test-attrs/test-type.rs2
-rw-r--r--tests/ui/thread-local/tls.rs2
-rw-r--r--tests/ui/threads-sendsync/child-outlives-parent.rs2
-rw-r--r--tests/ui/threads-sendsync/clone-with-exterior.rs2
-rw-r--r--tests/ui/threads-sendsync/comm.rs4
-rw-r--r--tests/ui/threads-sendsync/eprint-on-tls-drop.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-24313.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-29488.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-43733-2.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-43733.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-4446.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-4448.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-8827.rs2
-rw-r--r--tests/ui/threads-sendsync/issue-9396.rs2
-rw-r--r--tests/ui/threads-sendsync/mpsc_stress.rs2
-rw-r--r--tests/ui/threads-sendsync/send-resource.rs2
-rw-r--r--tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs2
-rw-r--r--tests/ui/threads-sendsync/spawn-fn.rs2
-rw-r--r--tests/ui/threads-sendsync/spawn-types.rs2
-rw-r--r--tests/ui/threads-sendsync/spawn.rs2
-rw-r--r--tests/ui/threads-sendsync/spawn2.rs2
-rw-r--r--tests/ui/threads-sendsync/spawning-with-debug.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-0.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-1.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-10.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-11.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-12.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-13.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-14.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-15.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-17.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-3.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-7.rs2
-rw-r--r--tests/ui/threads-sendsync/task-comm-9.rs2
-rw-r--r--tests/ui/threads-sendsync/task-life-0.rs2
-rw-r--r--tests/ui/threads-sendsync/task-spawn-barefn.rs2
-rw-r--r--tests/ui/threads-sendsync/task-spawn-move-and-copy.rs2
-rw-r--r--tests/ui/threads-sendsync/task-stderr.rs2
-rw-r--r--tests/ui/threads-sendsync/tcp-stress.rs2
-rw-r--r--tests/ui/threads-sendsync/test-tasks-invalid-value.rs2
-rw-r--r--tests/ui/threads-sendsync/threads.rs2
-rw-r--r--tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs2
-rw-r--r--tests/ui/threads-sendsync/tls-init-on-init.rs2
-rw-r--r--tests/ui/threads-sendsync/tls-try-with.rs2
-rw-r--r--tests/ui/threads-sendsync/unwind-resource.rs2
-rw-r--r--tests/ui/threads-sendsync/yield.rs2
-rw-r--r--tests/ui/threads-sendsync/yield1.rs2
-rw-r--r--tests/ui/trait-bounds/super-assoc-mismatch.rs60
-rw-r--r--tests/ui/trait-bounds/super-assoc-mismatch.stderr105
-rw-r--r--tests/ui/traits/alias/only-require-assocs-from-supertraits.rs16
-rw-r--r--tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs1
-rw-r--r--tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr20
-rw-r--r--tests/ui/traits/bound/in-arc.rs2
-rw-r--r--tests/ui/traits/issue-105231.rs2
-rw-r--r--tests/ui/traits/issue-105231.stderr27
-rw-r--r--tests/ui/traits/issue-50480.stderr16
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr24
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.stderr12
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr17
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74244.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74244.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761-2.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761-2.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-74761.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr14
-rw-r--r--tests/ui/type-alias-impl-trait/variance.rs11
-rw-r--r--tests/ui/type-alias-impl-trait/variance.stderr110
-rw-r--r--tests/ui/typeck/issue-13853-5.rs1
-rw-r--r--tests/ui/typeck/issue-13853-5.stderr20
-rw-r--r--tests/ui/variance/variance-associated-consts.rs1
-rw-r--r--tests/ui/variance/variance-associated-consts.stderr10
-rw-r--r--tests/ui/variance/variance-regions-direct.rs1
-rw-r--r--tests/ui/variance/variance-regions-direct.stderr13
-rw-r--r--tests/ui/variance/variance-regions-indirect.rs4
-rw-r--r--tests/ui/variance/variance-regions-indirect.stderr43
-rw-r--r--tests/ui/variance/variance-trait-bounds.rs3
-rw-r--r--tests/ui/variance/variance-trait-bounds.stderr34
517 files changed, 7061 insertions, 4174 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 635146492b0..853acd1abd6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -469,9 +469,9 @@ version = "0.1.0"
 
 [[package]]
 name = "cc"
-version = "1.0.79"
+version = "1.0.90"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
 
 [[package]]
 name = "cfg-if"
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 37ee9a5140a..03ad75ca8b4 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -427,7 +427,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
     tcx.ensure_with_value().early_lint_checks(());
     tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
     tcx.ensure_with_value().get_lang_items(());
-    let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal();
+    let (mut resolver, krate) = tcx.resolver_for_lowering().steal();
 
     let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
     let mut owners = IndexVec::from_fn_n(
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 5321ba8a7cb..2bef4c91224 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -929,35 +929,38 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         only_trait: only_trait.then_some(()),
                     };
 
-                self.visibility_not_permitted(
-                    &item.vis,
-                    errors::VisibilityNotPermittedNote::IndividualImplItems,
-                );
-                if let &Unsafe::Yes(span) = unsafety {
-                    self.dcx().emit_err(errors::InherentImplCannotUnsafe {
-                        span: self_ty.span,
-                        annotation_span: span,
-                        annotation: "unsafe",
-                        self_ty: self_ty.span,
-                    });
-                }
-                if let &ImplPolarity::Negative(span) = polarity {
-                    self.dcx().emit_err(error(span, "negative", false));
-                }
-                if let &Defaultness::Default(def_span) = defaultness {
-                    self.dcx().emit_err(error(def_span, "`default`", true));
-                }
-                if let &Const::Yes(span) = constness {
-                    self.dcx().emit_err(error(span, "`const`", true));
-                }
+                self.with_in_trait_impl(None, |this| {
+                    this.visibility_not_permitted(
+                        &item.vis,
+                        errors::VisibilityNotPermittedNote::IndividualImplItems,
+                    );
+                    if let &Unsafe::Yes(span) = unsafety {
+                        this.dcx().emit_err(errors::InherentImplCannotUnsafe {
+                            span: self_ty.span,
+                            annotation_span: span,
+                            annotation: "unsafe",
+                            self_ty: self_ty.span,
+                        });
+                    }
+                    if let &ImplPolarity::Negative(span) = polarity {
+                        this.dcx().emit_err(error(span, "negative", false));
+                    }
+                    if let &Defaultness::Default(def_span) = defaultness {
+                        this.dcx().emit_err(error(def_span, "`default`", true));
+                    }
+                    if let &Const::Yes(span) = constness {
+                        this.dcx().emit_err(error(span, "`const`", true));
+                    }
 
-                self.visit_vis(&item.vis);
-                self.visit_ident(item.ident);
-                self.with_tilde_const(Some(DisallowTildeConstContext::Impl(item.span)), |this| {
-                    this.visit_generics(generics)
+                    this.visit_vis(&item.vis);
+                    this.visit_ident(item.ident);
+                    this.with_tilde_const(
+                        Some(DisallowTildeConstContext::Impl(item.span)),
+                        |this| this.visit_generics(generics),
+                    );
+                    this.visit_ty(self_ty);
+                    walk_list!(this, visit_assoc_item, items, AssocCtxt::Impl);
                 });
-                self.visit_ty(self_ty);
-                walk_list!(self, visit_assoc_item, items, AssocCtxt::Impl);
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again.
             }
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index d9e3f028697..2e14238f950 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -206,14 +206,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                 );
             }
         }
-        if !attr.is_doc_comment()
-            && let [seg, _] = attr.get_normal_item().path.segments.as_slice()
-            && seg.ident.name == sym::diagnostic
-            && !self.features.diagnostic_namespace
-        {
-            let msg = "`#[diagnostic]` attribute name space is experimental";
-            gate!(self, diagnostic_namespace, seg.ident.span, msg);
-        }
 
         // Emit errors for non-staged-api crates.
         if !self.features.staged_api {
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index ca43ac4b0e7..0619000364b 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -55,6 +55,7 @@ fn llvm_machine_type(cpu: &str) -> LLVMMachineType {
         "x86_64" => LLVMMachineType::AMD64,
         "x86" => LLVMMachineType::I386,
         "aarch64" => LLVMMachineType::ARM64,
+        "arm64ec" => LLVMMachineType::ARM64EC,
         "arm" => LLVMMachineType::ARM,
         _ => panic!("unsupported cpu type {cpu}"),
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 952f41fbd90..3a34ef0874e 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -56,6 +56,7 @@ pub enum LLVMMachineType {
     AMD64 = 0x8664,
     I386 = 0x14c,
     ARM64 = 0xaa64,
+    ARM64EC = 0xa641,
     ARM = 0x01c0,
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 75a189aa87c..78d47f36f91 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -201,7 +201,13 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
 // which might lead to failures if the oldest tested / supported LLVM version
 // doesn't yet support the relevant intrinsics
 pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
-    let arch = if sess.target.arch == "x86_64" { "x86" } else { &*sess.target.arch };
+    let arch = if sess.target.arch == "x86_64" {
+        "x86"
+    } else if sess.target.arch == "arm64ec" {
+        "aarch64"
+    } else {
+        &*sess.target.arch
+    };
     match (arch, s) {
         ("x86", "sse4.2") => {
             LLVMFeature::with_dependency("sse4.2", TargetFeatureFoldStrength::EnableOnly("crc32"))
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index b406a04af74..220bb77d3fd 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -288,7 +288,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
         // Generic x86
         "x86" => emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(4).unwrap(), true),
         // Windows AArch64
-        "aarch64" if target.is_like_windows => {
+        "aarch64" | "arm64ec" if target.is_like_windows => {
             emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), false)
         }
         // macOS / iOS AArch64
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 9359df5de6a..81ca42e1ad8 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
 # tidy-alphabetical-start
 ar_archive_writer = "0.1.5"
 bitflags = "2.4.1"
-cc = "1.0.69"
+cc = "1.0.90"
 itertools = "0.11"
 jobserver = "0.1.28"
 pathdiff = "0.2.0"
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 158b8fb8727..ab1bc0b6cd2 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -8,7 +8,7 @@ use std::path::Path;
 use object::write::{self, StandardSegment, Symbol, SymbolSection};
 use object::{
     elf, pe, xcoff, Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection,
-    ObjectSymbol, SectionFlags, SectionKind, SymbolFlags, SymbolKind, SymbolScope,
+    ObjectSymbol, SectionFlags, SectionKind, SubArchitecture, SymbolFlags, SymbolKind, SymbolScope,
 };
 
 use rustc_data_structures::memmap::Mmap;
@@ -182,37 +182,40 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
         Endian::Little => Endianness::Little,
         Endian::Big => Endianness::Big,
     };
-    let architecture = match &sess.target.arch[..] {
-        "arm" => Architecture::Arm,
-        "aarch64" => {
+    let (architecture, sub_architecture) = match &sess.target.arch[..] {
+        "arm" => (Architecture::Arm, None),
+        "aarch64" => (
             if sess.target.pointer_width == 32 {
                 Architecture::Aarch64_Ilp32
             } else {
                 Architecture::Aarch64
-            }
-        }
-        "x86" => Architecture::I386,
-        "s390x" => Architecture::S390x,
-        "mips" | "mips32r6" => Architecture::Mips,
-        "mips64" | "mips64r6" => Architecture::Mips64,
-        "x86_64" => {
+            },
+            None,
+        ),
+        "x86" => (Architecture::I386, None),
+        "s390x" => (Architecture::S390x, None),
+        "mips" | "mips32r6" => (Architecture::Mips, None),
+        "mips64" | "mips64r6" => (Architecture::Mips64, None),
+        "x86_64" => (
             if sess.target.pointer_width == 32 {
                 Architecture::X86_64_X32
             } else {
                 Architecture::X86_64
-            }
-        }
-        "powerpc" => Architecture::PowerPc,
-        "powerpc64" => Architecture::PowerPc64,
-        "riscv32" => Architecture::Riscv32,
-        "riscv64" => Architecture::Riscv64,
-        "sparc64" => Architecture::Sparc64,
-        "avr" => Architecture::Avr,
-        "msp430" => Architecture::Msp430,
-        "hexagon" => Architecture::Hexagon,
-        "bpf" => Architecture::Bpf,
-        "loongarch64" => Architecture::LoongArch64,
-        "csky" => Architecture::Csky,
+            },
+            None,
+        ),
+        "powerpc" => (Architecture::PowerPc, None),
+        "powerpc64" => (Architecture::PowerPc64, None),
+        "riscv32" => (Architecture::Riscv32, None),
+        "riscv64" => (Architecture::Riscv64, None),
+        "sparc64" => (Architecture::Sparc64, None),
+        "avr" => (Architecture::Avr, None),
+        "msp430" => (Architecture::Msp430, None),
+        "hexagon" => (Architecture::Hexagon, None),
+        "bpf" => (Architecture::Bpf, None),
+        "loongarch64" => (Architecture::LoongArch64, None),
+        "csky" => (Architecture::Csky, None),
+        "arm64ec" => (Architecture::Aarch64, Some(SubArchitecture::Arm64EC)),
         // Unsupported architecture.
         _ => return None,
     };
@@ -227,6 +230,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
     };
 
     let mut file = write::Object::new(binary_format, architecture, endianness);
+    file.set_sub_architecture(sub_architecture);
     if sess.target.is_like_osx {
         if macho_is_arm64e(&sess.target) {
             file.set_macho_cpu_subtype(object::macho::CPU_SUBTYPE_ARM64E);
@@ -335,7 +339,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
                 "ilp32s" | "lp64s" => e_flags |= elf::EF_LARCH_ABI_SOFT_FLOAT,
                 "ilp32f" | "lp64f" => e_flags |= elf::EF_LARCH_ABI_SINGLE_FLOAT,
                 "ilp32d" | "lp64d" => e_flags |= elf::EF_LARCH_ABI_DOUBLE_FLOAT,
-                _ => bug!("unknown RISC-V ABI name"),
+                _ => bug!("unknown LoongArch ABI name"),
             }
 
             e_flags
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index bff7e43b8e4..72648e5ade4 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -567,9 +567,10 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
         return undecorated;
     }
 
-    let x86 = match &target.arch[..] {
-        "x86" => true,
-        "x86_64" => false,
+    let prefix = match &target.arch[..] {
+        "x86" => Some('_'),
+        "x86_64" => None,
+        "arm64ec" => Some('#'),
         // Only x86/64 use symbol decorations.
         _ => return undecorated,
     };
@@ -606,8 +607,8 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
         Conv::X86Stdcall => ("_", "@"),
         Conv::X86VectorCall => ("", "@@"),
         _ => {
-            if x86 {
-                undecorated.insert(0, '_');
+            if let Some(prefix) = prefix {
+                undecorated.insert(0, prefix);
             }
             return undecorated;
         }
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index f7afd22a48c..2161bf61daa 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -907,7 +907,11 @@ impl CrateInfo {
                     lang_items::required(tcx, l).then_some(name)
                 })
                 .collect();
-            let prefix = if target.is_like_windows && target.arch == "x86" { "_" } else { "" };
+            let prefix = match (target.is_like_windows, target.arch.as_ref()) {
+                (true, "x86") => "_",
+                (true, "arm64ec") => "#",
+                _ => "",
+            };
 
             // This loop only adds new items to values of the hash map, so the order in which we
             // iterate over the values is not important.
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 725d3bf4431..1ec6c351e25 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -104,10 +104,6 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         let mut simple = || {
             let llval = if offset.bytes() == 0 {
                 self.llval
-            } else if field.is_zst() {
-                // FIXME(erikdesjardins): it should be fine to use inbounds for ZSTs too;
-                // keeping this logic for now to preserve previous behavior.
-                bx.ptradd(self.llval, bx.const_usize(offset.bytes()))
             } else {
                 bx.inbounds_ptradd(self.llval, bx.const_usize(offset.bytes()))
             };
@@ -168,8 +164,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         debug!("struct_field_ptr: DST field offset: {:?}", offset);
 
         // Adjust pointer.
-        // FIXME(erikdesjardins): should be able to use inbounds here too.
-        let ptr = bx.ptradd(self.llval, offset);
+        let ptr = bx.inbounds_ptradd(self.llval, offset);
 
         PlaceRef { llval: ptr, llextra: self.llextra, layout: field, align: effective_field_align }
     }
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 946ffc05cc1..864241fbd4a 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -24,7 +24,7 @@ use crate::errors::{LongRunning, LongRunningWarn};
 use crate::fluent_generated as fluent;
 use crate::interpret::{
     self, compile_time_machine, AllocId, AllocRange, ConstAllocation, CtfeProvenance, FnArg, FnVal,
-    Frame, ImmTy, InterpCx, InterpResult, OpTy, PlaceTy, Pointer, PointerArithmetic, Scalar,
+    Frame, ImmTy, InterpCx, InterpResult, MPlaceTy, OpTy, Pointer, PointerArithmetic, Scalar,
 };
 
 use super::error::*;
@@ -219,7 +219,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
         &mut self,
         instance: ty::Instance<'tcx>,
         args: &[FnArg<'tcx>],
-        dest: &PlaceTy<'tcx>,
+        dest: &MPlaceTy<'tcx>,
         ret: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
         let def_id = instance.def_id();
@@ -280,7 +280,7 @@ impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> {
         &mut self,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
-        dest: &PlaceTy<'tcx>,
+        dest: &MPlaceTy<'tcx>,
         ret: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx, ControlFlow<()>> {
         assert_eq!(args.len(), 2);
@@ -410,7 +410,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
         orig_instance: ty::Instance<'tcx>,
         _abi: CallAbi,
         args: &[FnArg<'tcx>],
-        dest: &PlaceTy<'tcx>,
+        dest: &MPlaceTy<'tcx>,
         ret: Option<mir::BasicBlock>,
         _unwind: mir::UnwindAction, // unwinding is not supported in consts
     ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@@ -455,7 +455,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx>],
-        dest: &PlaceTy<'tcx, Self::Provenance>,
+        dest: &MPlaceTy<'tcx, Self::Provenance>,
         target: Option<mir::BasicBlock>,
         _unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index cb308ab53ec..a484fbd892c 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -108,7 +108,7 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = CtfeProvenance, Extra = ()> {
 
     /// The location where the result of the current stack frame should be written to,
     /// and its layout in the caller.
-    pub return_place: PlaceTy<'tcx, Prov>,
+    pub return_place: MPlaceTy<'tcx, Prov>,
 
     /// The list of locals for this stack frame, stored in order as
     /// `[return_ptr, arguments..., variables..., temporaries...]`.
@@ -771,7 +771,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &mut self,
         instance: ty::Instance<'tcx>,
         body: &'mir mir::Body<'tcx>,
-        return_place: &PlaceTy<'tcx, M::Provenance>,
+        return_place: &MPlaceTy<'tcx, M::Provenance>,
         return_to_block: StackPopCleanup,
     ) -> InterpResult<'tcx> {
         trace!("body: {:#?}", body);
@@ -912,7 +912,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             } else {
                 self.copy_op_allow_transmute(&op, &dest)
             };
-            trace!("return value: {:?}", self.dump_place(&dest));
+            trace!("return value: {:?}", self.dump_place(&dest.into()));
             // We delay actually short-circuiting on this error until *after* the stack frame is
             // popped, since we want this error to be attributed to the caller, whose type defines
             // this transmute.
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 1cb991b38f7..b68bfb4211d 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -21,7 +21,7 @@ use rustc_span::symbol::{sym, Symbol};
 use rustc_target::abi::Size;
 
 use super::{
-    util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, Machine, OpTy, PlaceTy,
+    util::ensure_monomorphic_enough, CheckInAllocMsg, ImmTy, InterpCx, MPlaceTy, Machine, OpTy,
     Pointer,
 };
 
@@ -104,7 +104,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &mut self,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, M::Provenance>],
-        dest: &PlaceTy<'tcx, M::Provenance>,
+        dest: &MPlaceTy<'tcx, M::Provenance>,
         ret: Option<mir::BasicBlock>,
     ) -> InterpResult<'tcx, bool> {
         let instance_args = instance.args;
@@ -377,7 +377,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let index = u64::from(self.read_scalar(&args[1])?.to_u32()?);
                 let elem = &args[2];
                 let (input, input_len) = self.operand_to_simd(&args[0])?;
-                let (dest, dest_len) = self.place_to_simd(dest)?;
+                let (dest, dest_len) = self.mplace_to_simd(dest)?;
                 assert_eq!(input_len, dest_len, "Return vector length must match input length");
                 // Bounds are not checked by typeck so we have to do it ourselves.
                 if index >= input_len {
@@ -430,7 +430,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             _ => return Ok(false),
         }
 
-        trace!("{:?}", self.dump_place(dest));
+        trace!("{:?}", self.dump_place(&dest.clone().into()));
         self.go_to_block(ret);
         Ok(true)
     }
@@ -488,7 +488,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         &mut self,
         a: &ImmTy<'tcx, M::Provenance>,
         b: &ImmTy<'tcx, M::Provenance>,
-        dest: &PlaceTy<'tcx, M::Provenance>,
+        dest: &MPlaceTy<'tcx, M::Provenance>,
     ) -> InterpResult<'tcx> {
         assert_eq!(a.layout.ty, b.layout.ty);
         assert!(matches!(a.layout.ty.kind(), ty::Int(..) | ty::Uint(..)));
@@ -506,7 +506,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             )
         }
         // `Rem` says this is all right, so we can let `Div` do its job.
-        self.binop_ignore_overflow(BinOp::Div, a, b, dest)
+        self.binop_ignore_overflow(BinOp::Div, a, b, &dest.clone().into())
     }
 
     pub fn saturating_arith(
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index 0106ec425bc..ee5de44a651 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -196,7 +196,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
         instance: ty::Instance<'tcx>,
         abi: CallAbi,
         args: &[FnArg<'tcx, Self::Provenance>],
-        destination: &PlaceTy<'tcx, Self::Provenance>,
+        destination: &MPlaceTy<'tcx, Self::Provenance>,
         target: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>>;
@@ -208,7 +208,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
         fn_val: Self::ExtraFnVal,
         abi: CallAbi,
         args: &[FnArg<'tcx, Self::Provenance>],
-        destination: &PlaceTy<'tcx, Self::Provenance>,
+        destination: &MPlaceTy<'tcx, Self::Provenance>,
         target: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx>;
@@ -219,7 +219,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
         ecx: &mut InterpCx<'mir, 'tcx, Self>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Self::Provenance>],
-        destination: &PlaceTy<'tcx, Self::Provenance>,
+        destination: &MPlaceTy<'tcx, Self::Provenance>,
         target: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx>;
@@ -584,7 +584,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
         fn_val: !,
         _abi: CallAbi,
         _args: &[FnArg<$tcx>],
-        _destination: &PlaceTy<$tcx, Self::Provenance>,
+        _destination: &MPlaceTy<$tcx, Self::Provenance>,
         _target: Option<mir::BasicBlock>,
         _unwind: mir::UnwindAction,
     ) -> InterpResult<$tcx> {
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 672008edfd3..60f7710c11d 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -194,6 +194,12 @@ pub(super) enum Place<Prov: Provenance = CtfeProvenance> {
     Local { frame: usize, local: mir::Local, offset: Option<Size> },
 }
 
+/// An evaluated place, together with its type.
+///
+/// This may reference a stack frame by its index, so `PlaceTy` should generally not be kept around
+/// for longer than a single operation. Popping and then pushing a stack frame can make `PlaceTy`
+/// point to the wrong destination. If the interpreter has multiple stacks, stack switching will
+/// also invalidate a `PlaceTy`.
 #[derive(Clone)]
 pub struct PlaceTy<'tcx, Prov: Provenance = CtfeProvenance> {
     place: Place<Prov>, // Keep this private; it helps enforce invariants.
@@ -495,16 +501,6 @@ where
         Ok((mplace, len))
     }
 
-    /// Converts a repr(simd) place into a place where `place_index` accesses the SIMD elements.
-    /// Also returns the number of elements.
-    pub fn place_to_simd(
-        &mut self,
-        place: &PlaceTy<'tcx, M::Provenance>,
-    ) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::Provenance>, u64)> {
-        let mplace = self.force_allocation(place)?;
-        self.mplace_to_simd(&mplace)
-    }
-
     pub fn local_to_place(
         &self,
         frame: usize,
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index d29e69d753e..55f85573f38 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -153,7 +153,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     ),
                 };
 
-                let destination = self.eval_place(destination)?;
+                let destination = self.force_allocation(&self.eval_place(destination)?)?;
                 self.eval_fn_call(
                     fn_val,
                     (fn_sig.abi, fn_abi),
@@ -497,7 +497,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         (caller_abi, caller_fn_abi): (Abi, &FnAbi<'tcx, Ty<'tcx>>),
         args: &[FnArg<'tcx, M::Provenance>],
         with_caller_location: bool,
-        destination: &PlaceTy<'tcx, M::Provenance>,
+        destination: &MPlaceTy<'tcx, M::Provenance>,
         target: Option<mir::BasicBlock>,
         mut unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
@@ -726,7 +726,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                         });
                     }
                     // Protect return place for in-place return value passing.
-                    M::protect_in_place_function_argument(self, destination)?;
+                    M::protect_in_place_function_argument(self, &destination.clone().into())?;
 
                     // Don't forget to mark "initially live" locals as live.
                     self.storage_live_for_always_live_locals()?;
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index cd296c9662a..e06d1d245b2 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -418,7 +418,7 @@ fn run_compiler(
             }
 
             // Make sure name resolution and macro expansion is run.
-            queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering(()));
+            queries.global_ctxt()?.enter(|tcx| tcx.resolver_for_lowering());
 
             if callbacks.after_expansion(compiler, queries) == Compilation::Stop {
                 return early_exit();
diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs
index 768d98ce01e..c9bbe45b212 100644
--- a/compiler/rustc_driver_impl/src/pretty.rs
+++ b/compiler/rustc_driver_impl/src/pretty.rs
@@ -229,7 +229,7 @@ impl<'tcx> PrintExtra<'tcx> {
     {
         match self {
             PrintExtra::AfterParsing { krate, .. } => f(krate),
-            PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering(()).borrow().1),
+            PrintExtra::NeedsAstMap { tcx } => f(&tcx.resolver_for_lowering().borrow().1),
         }
     }
 
@@ -281,7 +281,7 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
         }
         AstTreeExpanded => {
             debug!("pretty-printing expanded AST");
-            format!("{:#?}", ex.tcx().resolver_for_lowering(()).borrow().1)
+            format!("{:#?}", ex.tcx().resolver_for_lowering().borrow().1)
         }
         Hir(s) => {
             debug!("pretty printing HIR {:?}", s);
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 1b2993dabdb..7e5197f16f9 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -146,6 +146,8 @@ declare_features! (
     (accepted, derive_default_enum, "1.62.0", Some(86985)),
     /// Allows the use of destructuring assignments.
     (accepted, destructuring_assignment, "1.59.0", Some(71126)),
+    /// Allows using the `#[diagnostic]` attribute tool namespace
+    (accepted, diagnostic_namespace, "CURRENT_RUSTC_VERSION", Some(111996)),
     /// Allows `#[doc(alias = "...")]`.
     (accepted, doc_alias, "1.48.0", Some(50146)),
     /// Allows `..` in tuple (struct) patterns.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 17c4d81474e..9f4bead21dc 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -436,8 +436,6 @@ declare_features! (
     (unstable, deprecated_safe, "1.61.0", Some(94978)),
     /// Allows having using `suggestion` in the `#[deprecated]` attribute.
     (unstable, deprecated_suggestion, "1.61.0", Some(94785)),
-    /// Allows using the `#[diagnostic]` attribute tool namespace
-    (unstable, diagnostic_namespace, "1.73.0", Some(111996)),
     /// Controls errors in trait implementations.
     (unstable, do_not_recommend, "1.67.0", Some(51992)),
     /// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index b8cf72c2c73..325342d653d 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -1612,10 +1612,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         .any(|impl_def_id| {
                             let impl_header = tcx.impl_trait_header(impl_def_id);
                             impl_header.is_some_and(|header| {
-                                let header = header.instantiate(
+                                let trait_ref = header.trait_ref.instantiate(
                                     tcx,
                                     infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
                                 );
+
                                 let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
                                 // FIXME: Don't bother dealing with non-lifetime binders here...
                                 if value.has_escaping_bound_vars() {
@@ -1624,7 +1625,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                                 infcx
                                     .can_eq(
                                         ty::ParamEnv::empty(),
-                                        header.trait_ref.self_ty(),
+                                        trait_ref.self_ty(),
                                         value,
                                     ) && header.polarity != ty::ImplPolarity::Negative
                             })
@@ -1677,9 +1678,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     .filter(|header| {
                         // Consider only accessible traits
                         tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
-                            && header.skip_binder().polarity != ty::ImplPolarity::Negative
+                            && header.polarity != ty::ImplPolarity::Negative
                     })
-                    .map(|header| header.instantiate_identity().trait_ref.self_ty())
+                    .map(|header| header.trait_ref.instantiate_identity().self_ty())
                     // We don't care about blanket impls.
                     .filter(|self_ty| !self_ty.has_non_region_param())
                     .map(|self_ty| tcx.erase_regions(self_ty).to_string())
diff --git a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
index 7705445ffaa..b9543c7a29b 100644
--- a/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/object_safety.rs
@@ -45,10 +45,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 dummy_self,
                 &mut bounds,
                 false,
-                // FIXME: This should be `true`, but we don't really handle
-                // associated type bounds or type aliases in objects in a way
-                // that makes this meaningful, I think.
-                OnlySelfBounds(false),
+                // True so we don't populate `bounds` with associated type bounds, even
+                // though they're disallowed from object types.
+                OnlySelfBounds(true),
             ) {
                 potential_assoc_types.extend(cur_potential_assoc_types);
             }
@@ -83,9 +82,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let expanded_traits =
             traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b)));
 
-        let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits
-            .filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self)
-            .partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
+        let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
+            expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
         if regular_traits.len() > 1 {
             let first_trait = &regular_traits[0];
             let additional_trait = &regular_traits[1];
@@ -158,7 +156,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         for (base_trait_ref, span) in regular_traits_refs_spans {
             let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
-            for pred in traits::elaborate(tcx, [base_pred]) {
+            for pred in traits::elaborate(tcx, [base_pred]).filter_only_self() {
                 debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred);
 
                 let bound_predicate = pred.kind();
@@ -312,45 +310,39 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             })
         });
 
-        let existential_projections = projection_bounds
-            .iter()
-            // We filter out traits that don't have `Self` as their self type above,
-            // we need to do the same for projections.
-            .filter(|(bound, _)| bound.skip_binder().self_ty() == dummy_self)
-            .map(|(bound, _)| {
-                bound.map_bound(|mut b| {
-                    assert_eq!(b.projection_ty.self_ty(), dummy_self);
+        let existential_projections = projection_bounds.iter().map(|(bound, _)| {
+            bound.map_bound(|mut b| {
+                assert_eq!(b.projection_ty.self_ty(), dummy_self);
 
-                    // Like for trait refs, verify that `dummy_self` did not leak inside default type
-                    // parameters.
-                    let references_self = b.projection_ty.args.iter().skip(1).any(|arg| {
-                        if arg.walk().any(|arg| arg == dummy_self.into()) {
-                            return true;
-                        }
-                        false
-                    });
-                    if references_self {
-                        let guar = tcx.dcx().span_delayed_bug(
-                            span,
-                            "trait object projection bounds reference `Self`",
-                        );
-                        let args: Vec<_> = b
-                            .projection_ty
-                            .args
-                            .iter()
-                            .map(|arg| {
-                                if arg.walk().any(|arg| arg == dummy_self.into()) {
-                                    return Ty::new_error(tcx, guar).into();
-                                }
-                                arg
-                            })
-                            .collect();
-                        b.projection_ty.args = tcx.mk_args(&args);
+                // Like for trait refs, verify that `dummy_self` did not leak inside default type
+                // parameters.
+                let references_self = b.projection_ty.args.iter().skip(1).any(|arg| {
+                    if arg.walk().any(|arg| arg == dummy_self.into()) {
+                        return true;
                     }
+                    false
+                });
+                if references_self {
+                    let guar = tcx
+                        .dcx()
+                        .span_delayed_bug(span, "trait object projection bounds reference `Self`");
+                    let args: Vec<_> = b
+                        .projection_ty
+                        .args
+                        .iter()
+                        .map(|arg| {
+                            if arg.walk().any(|arg| arg == dummy_self.into()) {
+                                return Ty::new_error(tcx, guar).into();
+                            }
+                            arg
+                        })
+                        .collect();
+                    b.projection_ty.args = tcx.mk_args(&args);
+                }
 
-                    ty::ExistentialProjection::erase_self_ty(tcx, b)
-                })
-            });
+                ty::ExistentialProjection::erase_self_ty(tcx, b)
+            })
+        });
 
         let regular_trait_predicates = existential_trait_refs
             .map(|trait_ref| trait_ref.map_bound(ty::ExistentialPredicate::Trait));
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 845bbdca96a..748571c12b3 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -530,11 +530,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         }
         DefKind::Impl { of_trait } => {
             if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
-                check_impl_items_against_trait(
-                    tcx,
-                    def_id,
-                    impl_trait_header.instantiate_identity(),
-                );
+                check_impl_items_against_trait(tcx, def_id, impl_trait_header);
                 check_on_unimplemented(tcx, def_id);
             }
         }
@@ -725,10 +721,11 @@ fn check_impl_items_against_trait<'tcx>(
     impl_id: LocalDefId,
     impl_trait_header: ty::ImplTraitHeader<'tcx>,
 ) {
+    let trait_ref = impl_trait_header.trait_ref.instantiate_identity();
     // If the trait reference itself is erroneous (so the compilation is going
     // to fail), skip checking the items here -- the `impl_item` table in `tcx`
     // isn't populated for such impls.
-    if impl_trait_header.references_error() {
+    if trait_ref.references_error() {
         return;
     }
 
@@ -752,7 +749,7 @@ fn check_impl_items_against_trait<'tcx>(
         }
     }
 
-    let trait_def = tcx.trait_def(impl_trait_header.trait_ref.def_id);
+    let trait_def = tcx.trait_def(trait_ref.def_id);
 
     for &impl_item in impl_item_refs {
         let ty_impl_item = tcx.associated_item(impl_item);
@@ -771,10 +768,10 @@ fn check_impl_items_against_trait<'tcx>(
                 ));
             }
             ty::AssocKind::Fn => {
-                compare_impl_method(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
+                compare_impl_method(tcx, ty_impl_item, ty_trait_item, trait_ref);
             }
             ty::AssocKind::Type => {
-                compare_impl_ty(tcx, ty_impl_item, ty_trait_item, impl_trait_header.trait_ref);
+                compare_impl_ty(tcx, ty_impl_item, ty_trait_item, trait_ref);
             }
         }
 
@@ -794,7 +791,7 @@ fn check_impl_items_against_trait<'tcx>(
         let mut must_implement_one_of: Option<&[Ident]> =
             trait_def.must_implement_one_of.as_deref();
 
-        for &trait_item_id in tcx.associated_item_def_ids(impl_trait_header.trait_ref.def_id) {
+        for &trait_item_id in tcx.associated_item_def_ids(trait_ref.def_id) {
             let leaf_def = ancestors.leaf_def(tcx, trait_item_id);
 
             let is_implemented = leaf_def
@@ -872,7 +869,7 @@ fn check_impl_items_against_trait<'tcx>(
 
         if let Some(missing_items) = must_implement_one_of {
             let attr_span = tcx
-                .get_attr(impl_trait_header.trait_ref.def_id, sym::rustc_must_implement_one_of)
+                .get_attr(trait_ref.def_id, sym::rustc_must_implement_one_of)
                 .map(|attr| attr.span);
 
             missing_items_must_implement_one_of_err(
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index bec7b7bd974..ae7ea271c56 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -247,7 +247,9 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
         hir::ItemKind::Impl(impl_) => {
             let header = tcx.impl_trait_header(def_id);
             let is_auto = header
-                .is_some_and(|header| tcx.trait_is_auto(header.skip_binder().trait_ref.def_id));
+                .is_some_and(|header| tcx.trait_is_auto(header.trait_ref.skip_binder().def_id));
+
+            crate::impl_wf_check::check_impl_wf(tcx, def_id)?;
             let mut res = Ok(());
             if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
                 let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
@@ -259,7 +261,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
                     .emit());
             }
             // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
-            match header.map(|h| h.skip_binder().polarity) {
+            match header.map(|h| h.polarity) {
                 // `None` means this is an inherent impl
                 Some(ty::ImplPolarity::Positive) | None => {
                     res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
@@ -296,31 +298,31 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
         hir::ItemKind::Const(ty, ..) => {
             check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
         }
-        hir::ItemKind::Struct(_, ast_generics) => {
+        hir::ItemKind::Struct(_, hir_generics) => {
             let res = check_type_defn(tcx, item, false);
-            check_variances_for_type_defn(tcx, item, ast_generics);
+            check_variances_for_type_defn(tcx, item, hir_generics);
             res
         }
-        hir::ItemKind::Union(_, ast_generics) => {
+        hir::ItemKind::Union(_, hir_generics) => {
             let res = check_type_defn(tcx, item, true);
-            check_variances_for_type_defn(tcx, item, ast_generics);
+            check_variances_for_type_defn(tcx, item, hir_generics);
             res
         }
-        hir::ItemKind::Enum(_, ast_generics) => {
+        hir::ItemKind::Enum(_, hir_generics) => {
             let res = check_type_defn(tcx, item, true);
-            check_variances_for_type_defn(tcx, item, ast_generics);
+            check_variances_for_type_defn(tcx, item, hir_generics);
             res
         }
         hir::ItemKind::Trait(..) => check_trait(tcx, item),
         hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
         // `ForeignItem`s are handled separately.
         hir::ItemKind::ForeignMod { .. } => Ok(()),
-        hir::ItemKind::TyAlias(hir_ty, ast_generics) => {
+        hir::ItemKind::TyAlias(hir_ty, hir_generics) => {
             if tcx.type_alias_is_lazy(item.owner_id) {
                 // Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
                 // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
                 let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
-                check_variances_for_type_defn(tcx, item, ast_generics);
+                check_variances_for_type_defn(tcx, item, hir_generics);
                 res
             } else {
                 Ok(())
@@ -1275,16 +1277,16 @@ fn check_item_type(
     })
 }
 
-#[instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
+#[instrument(level = "debug", skip(tcx, hir_self_ty, hir_trait_ref))]
 fn check_impl<'tcx>(
     tcx: TyCtxt<'tcx>,
     item: &'tcx hir::Item<'tcx>,
-    ast_self_ty: &hir::Ty<'_>,
-    ast_trait_ref: &Option<hir::TraitRef<'_>>,
+    hir_self_ty: &hir::Ty<'_>,
+    hir_trait_ref: &Option<hir::TraitRef<'_>>,
 ) -> Result<(), ErrorGuaranteed> {
     enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
-        match ast_trait_ref {
-            Some(ast_trait_ref) => {
+        match hir_trait_ref {
+            Some(hir_trait_ref) => {
                 // `#[rustc_reservation_impl]` impls are not real impls and
                 // therefore don't need to be WF (the trait's `Self: Trait` predicate
                 // won't hold).
@@ -1292,8 +1294,9 @@ fn check_impl<'tcx>(
                 // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
                 // other `Foo` impls are incoherent.
                 tcx.ensure().coherent_trait(trait_ref.def_id)?;
+                let trait_span = hir_trait_ref.path.span;
                 let trait_ref = wfcx.normalize(
-                    ast_trait_ref.path.span,
+                    trait_span,
                     Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
                     trait_ref,
                 );
@@ -1304,14 +1307,23 @@ fn check_impl<'tcx>(
                     wfcx.param_env,
                     wfcx.body_def_id,
                     trait_pred,
-                    ast_trait_ref.path.span,
+                    trait_span,
                     item,
                 );
                 for obligation in &mut obligations {
+                    if obligation.cause.span != trait_span {
+                        // We already have a better span.
+                        continue;
+                    }
                     if let Some(pred) = obligation.predicate.to_opt_poly_trait_pred()
-                        && pred.self_ty().skip_binder() == trait_ref.self_ty()
+                        && pred.skip_binder().self_ty() == trait_ref.self_ty()
+                    {
+                        obligation.cause.span = hir_self_ty.span;
+                    }
+                    if let Some(pred) = obligation.predicate.to_opt_poly_projection_pred()
+                        && pred.skip_binder().self_ty() == trait_ref.self_ty()
                     {
-                        obligation.cause.span = ast_self_ty.span;
+                        obligation.cause.span = hir_self_ty.span;
                     }
                 }
                 debug!(?obligations);
@@ -1325,7 +1337,7 @@ fn check_impl<'tcx>(
                     self_ty,
                 );
                 wfcx.register_wf_obligation(
-                    ast_self_ty.span,
+                    hir_self_ty.span,
                     Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
                     self_ty.into(),
                 );
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 6c3a9b747ef..8d8b13d6cb3 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -25,7 +25,7 @@ use rustc_trait_selection::traits::ObligationCtxt;
 use rustc_trait_selection::traits::{self, ObligationCause};
 use std::collections::BTreeMap;
 
-pub fn check_trait<'tcx>(
+pub(super) fn check_trait<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_def_id: DefId,
     impl_def_id: LocalDefId,
@@ -66,10 +66,9 @@ impl<'tcx> Checker<'tcx> {
 
 fn visit_implementation_of_drop(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
     let tcx = checker.tcx;
-    let header = checker.impl_header;
     let impl_did = checker.impl_def_id;
     // Destructors only work on local ADT types.
-    match header.trait_ref.self_ty().kind() {
+    match checker.impl_header.trait_ref.instantiate_identity().self_ty().kind() {
         ty::Adt(def, _) if def.did().is_local() => return Ok(()),
         ty::Error(_) => return Ok(()),
         _ => {}
@@ -86,7 +85,7 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
     let impl_did = checker.impl_def_id;
     debug!("visit_implementation_of_copy: impl_did={:?}", impl_did);
 
-    let self_type = impl_header.trait_ref.self_ty();
+    let self_type = impl_header.trait_ref.instantiate_identity().self_ty();
     debug!("visit_implementation_of_copy: self_type={:?} (bound)", self_type);
 
     let param_env = tcx.param_env(impl_did);
@@ -120,7 +119,7 @@ fn visit_implementation_of_const_param_ty(checker: &Checker<'_>) -> Result<(), E
     let tcx = checker.tcx;
     let header = checker.impl_header;
     let impl_did = checker.impl_def_id;
-    let self_type = header.trait_ref.self_ty();
+    let self_type = header.trait_ref.instantiate_identity().self_ty();
     assert!(!self_type.has_escaping_bound_vars());
 
     let param_env = tcx.param_env(impl_did);
@@ -157,9 +156,8 @@ fn visit_implementation_of_coerce_unsized(checker: &Checker<'_>) -> Result<(), E
 
 fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<(), ErrorGuaranteed> {
     let tcx = checker.tcx;
-    let header = checker.impl_header;
     let impl_did = checker.impl_def_id;
-    let trait_ref = header.trait_ref;
+    let trait_ref = checker.impl_header.trait_ref.instantiate_identity();
     debug!("visit_implementation_of_dispatch_from_dyn: impl_did={:?}", impl_did);
 
     let span = tcx.def_span(impl_did);
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index d6281fa08f7..fc7a73e12be 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -134,11 +134,12 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
     let mut res = tcx.ensure().specialization_graph_of(def_id);
 
     for &impl_def_id in impls {
-        let trait_header = tcx.impl_trait_header(impl_def_id).unwrap().instantiate_identity();
-        let trait_def = tcx.trait_def(trait_header.trait_ref.def_id);
+        let trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
+        let trait_ref = trait_header.trait_ref.instantiate_identity();
+        let trait_def = tcx.trait_def(trait_ref.def_id);
 
-        res = res.and(check_impl(tcx, impl_def_id, trait_header.trait_ref, trait_def));
-        res = res.and(check_object_overlap(tcx, impl_def_id, trait_header.trait_ref));
+        res = res.and(check_impl(tcx, impl_def_id, trait_ref, trait_def));
+        res = res.and(check_object_overlap(tcx, impl_def_id, trait_ref));
 
         res = res.and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def));
         res = res.and(tcx.ensure().orphan_check_impl(impl_def_id));
diff --git a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
index 53a5ada4105..13ce4f07593 100644
--- a/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/unsafety.rs
@@ -13,9 +13,10 @@ pub(super) fn check_item(
     trait_header: ImplTraitHeader<'_>,
     trait_def: &TraitDef,
 ) -> Result<(), ErrorGuaranteed> {
-    let trait_ref = trait_header.trait_ref;
     let unsafe_attr =
         tcx.generics_of(def_id).params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle");
+    let trait_ref = trait_header.trait_ref.instantiate_identity();
+
     match (trait_def.unsafety, unsafe_attr, trait_header.unsafety, trait_header.polarity) {
         (Unsafety::Normal, None, Unsafety::Unsafe, Positive | Reservation) => {
             let span = tcx.def_span(def_id);
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 2cc37651ef5..e1704ffc8bf 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1519,10 +1519,7 @@ fn suggest_impl_trait<'tcx>(
     None
 }
 
-fn impl_trait_header(
-    tcx: TyCtxt<'_>,
-    def_id: LocalDefId,
-) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> {
+fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTraitHeader<'_>> {
     let icx = ItemCtxt::new(tcx, def_id);
     let item = tcx.hir().expect_item(def_id);
     let impl_ = item.expect_impl();
@@ -1558,11 +1555,11 @@ fn impl_trait_header(
             } else {
                 icx.astconv().instantiate_mono_trait_ref(ast_trait_ref, selfty)
             };
-            ty::EarlyBinder::bind(ty::ImplTraitHeader {
-                trait_ref,
+            ty::ImplTraitHeader {
+                trait_ref: ty::EarlyBinder::bind(trait_ref),
                 unsafety: impl_.unsafety,
                 polarity: polarity_of_impl(tcx, def_id,  impl_, item.span)
-            })
+            }
         })
 }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 9cc6c16c126..c86788db988 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -14,6 +14,43 @@ use rustc_span::Span;
 pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
     use rustc_hir::*;
 
+    // For an RPITIT, synthesize generics which are equal to the opaque's generics
+    // and parent fn's generics compressed into one list.
+    if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) =
+        tcx.opt_rpitit_info(def_id.to_def_id())
+    {
+        let trait_def_id = tcx.parent(fn_def_id);
+        let opaque_ty_generics = tcx.generics_of(opaque_def_id);
+        let opaque_ty_parent_count = opaque_ty_generics.parent_count;
+        let mut params = opaque_ty_generics.params.clone();
+
+        let parent_generics = tcx.generics_of(trait_def_id);
+        let parent_count = parent_generics.parent_count + parent_generics.params.len();
+
+        let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
+
+        for param in &mut params {
+            param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
+                - opaque_ty_parent_count as u32;
+        }
+
+        trait_fn_params.extend(params);
+        params = trait_fn_params;
+
+        let param_def_id_to_index =
+            params.iter().map(|param| (param.def_id, param.index)).collect();
+
+        return ty::Generics {
+            parent: Some(trait_def_id),
+            parent_count,
+            params,
+            param_def_id_to_index,
+            has_self: opaque_ty_generics.has_self,
+            has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
+            host_effect_index: parent_generics.host_effect_index,
+        };
+    }
+
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
 
     let node = tcx.hir_node(hir_id);
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 417f0fceaa8..2217e5280a7 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -5,7 +5,7 @@ use rustc_hir::HirId;
 use rustc_middle::query::plumbing::CyclePlaceholder;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::util::IntTypeExt;
-use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -350,22 +350,31 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
     // If we are computing `type_of` the synthesized associated type for an RPITIT in the impl
     // side, use `collect_return_position_impl_trait_in_trait_tys` to infer the value of the
     // associated type in the impl.
-    if let Some(ImplTraitInTraitData::Impl { fn_def_id, .. }) =
-        tcx.opt_rpitit_info(def_id.to_def_id())
-    {
-        match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
-            Ok(map) => {
-                let assoc_item = tcx.associated_item(def_id);
-                return map[&assoc_item.trait_item_def_id.unwrap()];
-            }
-            Err(_) => {
-                return ty::EarlyBinder::bind(Ty::new_error_with_message(
-                    tcx,
-                    DUMMY_SP,
-                    "Could not collect return position impl trait in trait tys",
-                ));
+    match tcx.opt_rpitit_info(def_id.to_def_id()) {
+        Some(ty::ImplTraitInTraitData::Impl { fn_def_id }) => {
+            match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
+                Ok(map) => {
+                    let assoc_item = tcx.associated_item(def_id);
+                    return map[&assoc_item.trait_item_def_id.unwrap()];
+                }
+                Err(_) => {
+                    return ty::EarlyBinder::bind(Ty::new_error_with_message(
+                        tcx,
+                        DUMMY_SP,
+                        "Could not collect return position impl trait in trait tys",
+                    ));
+                }
             }
         }
+        // For an RPITIT in a trait, just return the corresponding opaque.
+        Some(ty::ImplTraitInTraitData::Trait { opaque_def_id, .. }) => {
+            return ty::EarlyBinder::bind(Ty::new_opaque(
+                tcx,
+                opaque_def_id,
+                ty::GenericArgs::identity_for_item(tcx, opaque_def_id),
+            ));
+        }
+        None => {}
     }
 
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
index 9d7866fe3e0..caa85092415 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs
@@ -14,8 +14,7 @@ use min_specialization::check_min_specialization;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{LocalDefId, LocalModDefId};
-use rustc_middle::query::Providers;
+use rustc_hir::def_id::LocalDefId;
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_span::{ErrorGuaranteed, Span, Symbol};
 
@@ -51,23 +50,16 @@ mod min_specialization;
 /// impl<'a> Trait<Foo> for Bar { type X = &'a i32; }
 /// //   ^ 'a is unused and appears in assoc type, error
 /// ```
-fn check_mod_impl_wf(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) -> Result<(), ErrorGuaranteed> {
+pub fn check_impl_wf(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
     let min_specialization = tcx.features().min_specialization;
-    let module = tcx.hir_module_items(module_def_id);
     let mut res = Ok(());
-    for id in module.items() {
-        if matches!(tcx.def_kind(id.owner_id), DefKind::Impl { .. }) {
-            res = res.and(enforce_impl_params_are_constrained(tcx, id.owner_id.def_id));
-            if min_specialization {
-                res = res.and(check_min_specialization(tcx, id.owner_id.def_id));
-            }
-        }
+    debug_assert!(matches!(tcx.def_kind(impl_def_id), DefKind::Impl { .. }));
+    res = res.and(enforce_impl_params_are_constrained(tcx, impl_def_id));
+    if min_specialization {
+        res = res.and(check_min_specialization(tcx, impl_def_id));
     }
-    res
-}
 
-pub fn provide(providers: &mut Providers) {
-    *providers = Providers { check_mod_impl_wf, ..*providers };
+    res
 }
 
 fn enforce_impl_params_are_constrained(
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 7cb103626da..77c4ff382b9 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -153,7 +153,6 @@ pub fn provide(providers: &mut Providers) {
     check_unused::provide(providers);
     variance::provide(providers);
     outlives::provide(providers);
-    impl_wf_check::provide(providers);
     hir_wf_check::provide(providers);
 }
 
@@ -171,9 +170,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
     }
 
     tcx.sess.time("coherence_checking", || {
-        // Check impls constrain their parameters
-        let res =
-            tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
+        tcx.hir().par_for_each_module(|module| {
+            let _ = tcx.ensure().check_mod_type_wf(module);
+        });
 
         for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
             let _ = tcx.ensure().coherent_trait(trait_def_id);
@@ -181,19 +180,12 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
         // these queries are executed for side-effects (error reporting):
         let _ = tcx.ensure().crate_inherent_impls(());
         let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
-        res
-    })?;
+    });
 
     if tcx.features().rustc_attrs {
         tcx.sess.time("variance_testing", || variance::test::test_variance(tcx))?;
     }
 
-    tcx.sess.time("wf_checking", || {
-        tcx.hir().par_for_each_module(|module| {
-            let _ = tcx.ensure().check_mod_type_wf(module);
-        })
-    });
-
     if tcx.features().rustc_attrs {
         collect::test_opaque_hidden_types(tcx)?;
     }
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 893b3f9534d..7012f40e349 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -3368,11 +3368,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 "inherent impls can't be candidates, only trait impls can be",
                             )
                         })
-                        .filter(|header| {
-                            header.skip_binder().polarity == ty::ImplPolarity::Negative
-                        })
+                        .filter(|header| header.polarity == ty::ImplPolarity::Negative)
                         .any(|header| {
-                            let imp = header.instantiate_identity().trait_ref;
+                            let imp = header.trait_ref.instantiate_identity();
                             let imp_simp =
                                 simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
                             imp_simp.is_some_and(|s| s == simp_rcvr_ty)
diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs
index d876174e620..88298150a79 100644
--- a/compiler/rustc_index/src/vec.rs
+++ b/compiler/rustc_index/src/vec.rs
@@ -12,7 +12,24 @@ use std::vec;
 use crate::{Idx, IndexSlice};
 
 /// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`.
-/// Its purpose is to avoid mixing indexes.
+///
+/// ## Why use this instead of a `Vec`?
+///
+/// An `IndexVec` allows element access only via a specific associated index type, meaning that
+/// trying to use the wrong index type (possibly accessing an invalid element) will fail at
+/// compile time.
+///
+/// It also documents what the index is indexing: in a `HashMap<usize, Something>` it's not
+/// immediately clear what the `usize` means, while a `HashMap<FieldIdx, Something>` makes it obvious.
+///
+/// ```compile_fail
+/// use rustc_index::{Idx, IndexVec};
+///
+/// fn f<I1: Idx, I2: Idx>(vec1: IndexVec<I1, u8>, idx1: I1, idx2: I2) {
+///   &vec1[idx1]; // Ok
+///   &vec1[idx2]; // Compile error!
+/// }
+/// ```
 ///
 /// While it's possible to use `u32` or `usize` directly for `I`,
 /// you almost certainly want to use a [`newtype_index!`]-generated type instead.
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/README.md b/compiler/rustc_infer/src/infer/higher_ranked/README.md
deleted file mode 100644
index 533d0ef7e6c..00000000000
--- a/compiler/rustc_infer/src/infer/higher_ranked/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-To learn more about how Higher-ranked trait bounds work in the _old_ trait
-solver, see [this chapter][oldhrtb] of the rustc-dev-guide.
-
-To learn more about how they work in the _new_ trait solver, see [this
-chapter][newhrtb].
-
-[oldhrtb]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
-[newhrtb]: https://rustc-dev-guide.rust-lang.org/borrow_check/region_inference.html#placeholders-and-universes
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 73a25637e1a..15cdd6a910e 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -1,23 +1,25 @@
-pub use self::at::DefineOpaqueTypes;
-pub use self::freshen::TypeFreshener;
-pub use self::lexical_region_resolve::RegionResolutionError;
-pub use self::BoundRegionConversionTime::*;
-pub use self::RegionVariableOrigin::*;
-pub use self::SubregionOrigin::*;
-pub use self::ValuePairs::*;
+pub use at::DefineOpaqueTypes;
+pub use freshen::TypeFreshener;
+pub use lexical_region_resolve::RegionResolutionError;
+pub use relate::combine::CombineFields;
 pub use relate::combine::ObligationEmittingRelation;
-use rustc_data_structures::captures::Captures;
-use rustc_data_structures::undo_log::UndoLogs;
-use rustc_middle::infer::unify_key::EffectVarValue;
-use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
-
-use self::opaque_types::OpaqueTypeStorage;
-pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog};
+pub use relate::StructurallyRelateAliases;
+pub use rustc_middle::ty::IntVarValue;
+pub use BoundRegionConversionTime::*;
+pub use RegionVariableOrigin::*;
+pub use SubregionOrigin::*;
+pub use ValuePairs::*;
 
 use crate::traits::{
     self, ObligationCause, ObligationInspector, PredicateObligations, TraitEngine, TraitEngineExt,
 };
-
+use error_reporting::TypeErrCtxt;
+use free_regions::RegionRelations;
+use lexical_region_resolve::LexicalRegionResolutions;
+use opaque_types::OpaqueTypeStorage;
+use region_constraints::{GenericKind, VarInfos, VerifyBound};
+use region_constraints::{RegionConstraintCollector, RegionConstraintStorage};
+use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::sync::Lrc;
@@ -27,7 +29,9 @@ use rustc_errors::{Diag, DiagCtxt, ErrorGuaranteed};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
 use rustc_middle::infer::unify_key::ConstVariableValue;
+use rustc_middle::infer::unify_key::EffectVarValue;
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
+use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
 use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::{select, DefiningAnchor};
@@ -36,33 +40,21 @@ use rustc_middle::ty::fold::BoundVarReplacerDelegate;
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::visit::TypeVisitableExt;
-pub use rustc_middle::ty::IntVarValue;
 use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt};
 use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
 use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
 use rustc_span::symbol::Symbol;
 use rustc_span::Span;
-
+use snapshot::undo_log::InferCtxtUndoLogs;
 use std::cell::{Cell, RefCell};
 use std::fmt;
-
-use self::error_reporting::TypeErrCtxt;
-use self::free_regions::RegionRelations;
-use self::lexical_region_resolve::LexicalRegionResolutions;
-use self::region_constraints::{GenericKind, VarInfos, VerifyBound};
-use self::region_constraints::{
-    RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot,
-};
-pub use self::relate::combine::CombineFields;
-pub use self::relate::StructurallyRelateAliases;
-use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 
 pub mod at;
 pub mod canonical;
 pub mod error_reporting;
 pub mod free_regions;
 mod freshen;
-mod fudge;
 mod lexical_region_resolve;
 pub mod opaque_types;
 pub mod outlives;
@@ -70,8 +62,8 @@ mod projection;
 pub mod region_constraints;
 mod relate;
 pub mod resolve;
+pub(crate) mod snapshot;
 pub mod type_variable;
-mod undo_log;
 
 #[must_use]
 #[derive(Debug)]
@@ -738,13 +730,6 @@ impl<'tcx> InferOk<'tcx, ()> {
     }
 }
 
-#[must_use = "once you start a snapshot, you should always consume it"]
-pub struct CombinedSnapshot<'tcx> {
-    undo_snapshot: Snapshot<'tcx>,
-    region_constraints_snapshot: RegionSnapshot,
-    universe: ty::UniverseIndex,
-}
-
 impl<'tcx> InferCtxt<'tcx> {
     pub fn dcx(&self) -> &'tcx DiagCtxt {
         self.tcx.dcx()
@@ -842,90 +827,6 @@ impl<'tcx> InferCtxt<'tcx> {
         }
     }
 
-    pub fn in_snapshot(&self) -> bool {
-        UndoLogs::<UndoLog<'tcx>>::in_snapshot(&self.inner.borrow_mut().undo_log)
-    }
-
-    pub fn num_open_snapshots(&self) -> usize {
-        UndoLogs::<UndoLog<'tcx>>::num_open_snapshots(&self.inner.borrow_mut().undo_log)
-    }
-
-    fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
-        debug!("start_snapshot()");
-
-        let mut inner = self.inner.borrow_mut();
-
-        CombinedSnapshot {
-            undo_snapshot: inner.undo_log.start_snapshot(),
-            region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(),
-            universe: self.universe(),
-        }
-    }
-
-    #[instrument(skip(self, snapshot), level = "debug")]
-    fn rollback_to(&self, snapshot: CombinedSnapshot<'tcx>) {
-        let CombinedSnapshot { undo_snapshot, region_constraints_snapshot, universe } = snapshot;
-
-        self.universe.set(universe);
-
-        let mut inner = self.inner.borrow_mut();
-        inner.rollback_to(undo_snapshot);
-        inner.unwrap_region_constraints().rollback_to(region_constraints_snapshot);
-    }
-
-    #[instrument(skip(self, snapshot), level = "debug")]
-    fn commit_from(&self, snapshot: CombinedSnapshot<'tcx>) {
-        let CombinedSnapshot { undo_snapshot, region_constraints_snapshot: _, universe: _ } =
-            snapshot;
-
-        self.inner.borrow_mut().commit(undo_snapshot);
-    }
-
-    /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`.
-    #[instrument(skip(self, f), level = "debug")]
-    pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
-    where
-        F: FnOnce(&CombinedSnapshot<'tcx>) -> Result<T, E>,
-    {
-        let snapshot = self.start_snapshot();
-        let r = f(&snapshot);
-        debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
-        match r {
-            Ok(_) => {
-                self.commit_from(snapshot);
-            }
-            Err(_) => {
-                self.rollback_to(snapshot);
-            }
-        }
-        r
-    }
-
-    /// Execute `f` then unroll any bindings it creates.
-    #[instrument(skip(self, f), level = "debug")]
-    pub fn probe<R, F>(&self, f: F) -> R
-    where
-        F: FnOnce(&CombinedSnapshot<'tcx>) -> R,
-    {
-        let snapshot = self.start_snapshot();
-        let r = f(&snapshot);
-        self.rollback_to(snapshot);
-        r
-    }
-
-    /// Scan the constraints produced since `snapshot` and check whether
-    /// we added any region constraints.
-    pub fn region_constraints_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
-        self.inner
-            .borrow_mut()
-            .unwrap_region_constraints()
-            .region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
-    }
-
-    pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
-        self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
-    }
-
     pub fn can_sub<T>(&self, param_env: ty::ParamEnv<'tcx>, expected: T, actual: T) -> bool
     where
         T: at::ToTrace<'tcx>,
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index b6f3c38cb3f..b6f3c38cb3f 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
diff --git a/compiler/rustc_infer/src/infer/opaque_types/table.rs b/compiler/rustc_infer/src/infer/opaque_types/table.rs
index 9f49ed00219..a7ddf475436 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/table.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/table.rs
@@ -1,7 +1,7 @@
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
 
-use crate::infer::{InferCtxtUndoLogs, UndoLog};
+use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
 
 use super::{OpaqueTypeDecl, OpaqueTypeMap};
 
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index 8dd3a1f40cc..fe323982ec0 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -63,9 +63,8 @@ use crate::infer::outlives::components::{push_outlives_components, Component};
 use crate::infer::outlives::env::RegionBoundPairs;
 use crate::infer::outlives::verify::VerifyBoundCx;
 use crate::infer::resolve::OpportunisticRegionResolver;
-use crate::infer::{
-    self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, UndoLog, VerifyBound,
-};
+use crate::infer::snapshot::undo_log::UndoLog;
+use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
 use crate::traits::{ObligationCause, ObligationCauseCode};
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::mir::ConstraintCategory;
diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
index 9e2f3a10b6a..06f8dd4a4c6 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs
@@ -1,9 +1,7 @@
 use super::*;
-use crate::infer::CombinedSnapshot;
-use rustc_data_structures::{
-    fx::FxIndexMap,
-    graph::{scc::Sccs, vec_graph::VecGraph},
-};
+use crate::infer::snapshot::CombinedSnapshot;
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::graph::{scc::Sccs, vec_graph::VecGraph};
 use rustc_index::Idx;
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::relate::RelateResult;
diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
index ee97dd36807..0f3f2bc5fa6 100644
--- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs
+++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs
@@ -3,9 +3,8 @@
 use self::CombineMapType::*;
 use self::UndoLog::*;
 
-use super::{
-    InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin,
-};
+use super::{MiscVariable, RegionVariableOrigin, Rollback, SubregionOrigin};
+use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, Snapshot};
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
@@ -360,7 +359,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
     ///
     /// Not legal during a snapshot.
     pub fn into_infos_and_data(self) -> (VarInfos, RegionConstraintData<'tcx>) {
-        assert!(!UndoLogs::<super::UndoLog<'_>>::in_snapshot(&self.undo_log));
+        assert!(!UndoLogs::<UndoLog<'_>>::in_snapshot(&self.undo_log));
         (mem::take(&mut self.storage.var_infos), mem::take(&mut self.storage.data))
     }
 
@@ -377,7 +376,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
     ///
     /// Not legal during a snapshot.
     pub fn take_and_reset_data(&mut self) -> RegionConstraintData<'tcx> {
-        assert!(!UndoLogs::<super::UndoLog<'_>>::in_snapshot(&self.undo_log));
+        assert!(!UndoLogs::<UndoLog<'_>>::in_snapshot(&self.undo_log));
 
         // If you add a new field to `RegionConstraintCollector`, you
         // should think carefully about whether it needs to be cleared
diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index f30e366c198..70ed7cf9af1 100644
--- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -1,7 +1,7 @@
 //! Helper routines for higher-ranked things. See the `doc` module at
 //! the end of the file for details.
 
-use crate::infer::CombinedSnapshot;
+use crate::infer::snapshot::CombinedSnapshot;
 use crate::infer::InferCtxt;
 use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::relate::RelateResult;
@@ -77,7 +77,7 @@ impl<'tcx> InferCtxt<'tcx> {
         // that name placeholders created in this function. Nested goals from type relations can
         // also contain placeholders created by this function.
         let value = self.enter_forall_and_leak_universe(forall);
-        debug!("?value");
+        debug!(?value);
         f(value)
     }
 
diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
index 99033922bdf..14de461cd17 100644
--- a/compiler/rustc_infer/src/infer/fudge.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/fudge.rs
@@ -2,9 +2,9 @@ use rustc_middle::infer::unify_key::{ConstVariableOriginKind, ConstVariableValue
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid};
 
-use super::type_variable::TypeVariableOrigin;
-use super::InferCtxt;
-use super::{ConstVariableOrigin, RegionVariableOrigin, UnificationTable};
+use crate::infer::type_variable::TypeVariableOrigin;
+use crate::infer::InferCtxt;
+use crate::infer::{ConstVariableOrigin, RegionVariableOrigin, UnificationTable};
 
 use rustc_data_structures::snapshot_vec as sv;
 use rustc_data_structures::unify as ut;
diff --git a/compiler/rustc_infer/src/infer/snapshot/mod.rs b/compiler/rustc_infer/src/infer/snapshot/mod.rs
new file mode 100644
index 00000000000..9eef1471b1a
--- /dev/null
+++ b/compiler/rustc_infer/src/infer/snapshot/mod.rs
@@ -0,0 +1,102 @@
+use super::region_constraints::RegionSnapshot;
+use super::InferCtxt;
+use rustc_data_structures::undo_log::UndoLogs;
+use rustc_middle::ty;
+
+mod fudge;
+pub(crate) mod undo_log;
+
+use undo_log::{Snapshot, UndoLog};
+
+#[must_use = "once you start a snapshot, you should always consume it"]
+pub struct CombinedSnapshot<'tcx> {
+    pub(super) undo_snapshot: Snapshot<'tcx>,
+    region_constraints_snapshot: RegionSnapshot,
+    universe: ty::UniverseIndex,
+}
+
+impl<'tcx> InferCtxt<'tcx> {
+    pub fn in_snapshot(&self) -> bool {
+        UndoLogs::<UndoLog<'tcx>>::in_snapshot(&self.inner.borrow_mut().undo_log)
+    }
+
+    pub fn num_open_snapshots(&self) -> usize {
+        UndoLogs::<UndoLog<'tcx>>::num_open_snapshots(&self.inner.borrow_mut().undo_log)
+    }
+
+    fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
+        debug!("start_snapshot()");
+
+        let mut inner = self.inner.borrow_mut();
+
+        CombinedSnapshot {
+            undo_snapshot: inner.undo_log.start_snapshot(),
+            region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(),
+            universe: self.universe(),
+        }
+    }
+
+    #[instrument(skip(self, snapshot), level = "debug")]
+    fn rollback_to(&self, snapshot: CombinedSnapshot<'tcx>) {
+        let CombinedSnapshot { undo_snapshot, region_constraints_snapshot, universe } = snapshot;
+
+        self.universe.set(universe);
+
+        let mut inner = self.inner.borrow_mut();
+        inner.rollback_to(undo_snapshot);
+        inner.unwrap_region_constraints().rollback_to(region_constraints_snapshot);
+    }
+
+    #[instrument(skip(self, snapshot), level = "debug")]
+    fn commit_from(&self, snapshot: CombinedSnapshot<'tcx>) {
+        let CombinedSnapshot { undo_snapshot, region_constraints_snapshot: _, universe: _ } =
+            snapshot;
+
+        self.inner.borrow_mut().commit(undo_snapshot);
+    }
+
+    /// Execute `f` and commit the bindings if closure `f` returns `Ok(_)`.
+    #[instrument(skip(self, f), level = "debug")]
+    pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
+    where
+        F: FnOnce(&CombinedSnapshot<'tcx>) -> Result<T, E>,
+    {
+        let snapshot = self.start_snapshot();
+        let r = f(&snapshot);
+        debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
+        match r {
+            Ok(_) => {
+                self.commit_from(snapshot);
+            }
+            Err(_) => {
+                self.rollback_to(snapshot);
+            }
+        }
+        r
+    }
+
+    /// Execute `f` then unroll any bindings it creates.
+    #[instrument(skip(self, f), level = "debug")]
+    pub fn probe<R, F>(&self, f: F) -> R
+    where
+        F: FnOnce(&CombinedSnapshot<'tcx>) -> R,
+    {
+        let snapshot = self.start_snapshot();
+        let r = f(&snapshot);
+        self.rollback_to(snapshot);
+        r
+    }
+
+    /// Scan the constraints produced since `snapshot` and check whether
+    /// we added any region constraints.
+    pub fn region_constraints_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
+        self.inner
+            .borrow_mut()
+            .unwrap_region_constraints()
+            .region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
+    }
+
+    pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
+        self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
+    }
+}
diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
index 829b0a73a0d..829b0a73a0d 100644
--- a/compiler/rustc_infer/src/infer/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/snapshot/undo_log.rs
diff --git a/compiler/rustc_infer/src/traits/project.rs b/compiler/rustc_infer/src/traits/project.rs
index afba2e50a23..31ceb234332 100644
--- a/compiler/rustc_infer/src/traits/project.rs
+++ b/compiler/rustc_infer/src/traits/project.rs
@@ -2,7 +2,7 @@
 
 use super::PredicateObligation;
 
-use crate::infer::InferCtxtUndoLogs;
+use crate::infer::snapshot::undo_log::InferCtxtUndoLogs;
 
 use rustc_data_structures::{
     snapshot_map::{self, SnapshotMapRef, SnapshotMapStorage},
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 085e9026051..4b4c1d6cf67 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -280,7 +280,7 @@ fn configure_and_expand(
 
 fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
     let sess = tcx.sess;
-    let (resolver, krate) = &*tcx.resolver_for_lowering(()).borrow();
+    let (resolver, krate) = &*tcx.resolver_for_lowering().borrow();
     let mut lint_buffer = resolver.lint_buffer.steal();
 
     if sess.opts.unstable_opts.input_stats {
@@ -531,10 +531,10 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
     }
 }
 
-fn resolver_for_lowering<'tcx>(
+fn resolver_for_lowering_raw<'tcx>(
     tcx: TyCtxt<'tcx>,
     (): (),
-) -> &'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)> {
+) -> (&'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)>, &'tcx ty::ResolverGlobalCtxt) {
     let arenas = Resolver::arenas();
     let _ = tcx.registered_tools(()); // Uses `crate_for_resolver`.
     let (krate, pre_configured_attrs) = tcx.crate_for_resolver(()).steal();
@@ -549,16 +549,15 @@ fn resolver_for_lowering<'tcx>(
         ast_lowering: untracked_resolver_for_lowering,
     } = resolver.into_outputs();
 
-    let feed = tcx.feed_unit_query();
-    feed.resolutions(tcx.arena.alloc(untracked_resolutions));
-    tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate))))
+    let resolutions = tcx.arena.alloc(untracked_resolutions);
+    (tcx.arena.alloc(Steal::new((untracked_resolver_for_lowering, Lrc::new(krate)))), resolutions)
 }
 
 pub(crate) fn write_dep_info(tcx: TyCtxt<'_>) {
     // Make sure name resolution and macro expansion is run for
     // the side-effect of providing a complete set of all
     // accessed files and env vars.
-    let _ = tcx.resolver_for_lowering(());
+    let _ = tcx.resolver_for_lowering();
 
     let sess = tcx.sess;
     let _timer = sess.timer("write_dep_info");
@@ -607,7 +606,10 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
     let providers = &mut Providers::default();
     providers.analysis = analysis;
     providers.hir_crate = rustc_ast_lowering::lower_to_hir;
-    providers.resolver_for_lowering = resolver_for_lowering;
+    providers.resolver_for_lowering_raw = resolver_for_lowering_raw;
+    providers.stripped_cfg_items =
+        |tcx, _| tcx.arena.alloc_from_iter(tcx.resolutions(()).stripped_cfg_items.steal());
+    providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
     providers.early_lint_checks = early_lint_checks;
     proc_macro_decls::provide(providers);
     rustc_const_eval::provide(providers);
@@ -686,6 +688,11 @@ pub fn create_global_ctxt<'tcx>(
 /// Runs the type-checking, region checking and other miscellaneous analysis
 /// passes on the crate.
 fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
+    if tcx.sess.opts.unstable_opts.hir_stats {
+        rustc_passes::hir_stats::print_hir_stats(tcx);
+    }
+
+    #[cfg(debug_assertions)]
     rustc_passes::hir_id_validator::check_crate(tcx);
 
     let sess = tcx.sess;
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 7cdf7cd25b1..da11d090b74 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -8,8 +8,7 @@ use rustc_codegen_ssa::CodegenResults;
 use rustc_data_structures::steal::Steal;
 use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, OnceLock, WorkerLocal};
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
+use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
 use rustc_incremental::setup_dep_graph;
 use rustc_metadata::creader::CStore;
@@ -144,10 +143,8 @@ impl<'tcx> Queries<'tcx> {
                 stable_crate_id,
             )) as _);
             let definitions = FreezeLock::new(Definitions::new(stable_crate_id));
-            let source_span = AppendOnlyIndexVec::new();
-            let _id = source_span.push(krate.spans.inner_span);
-            debug_assert_eq!(_id, CRATE_DEF_ID);
-            let untracked = Untracked { cstore, source_span, definitions };
+            let untracked =
+                Untracked { cstore, source_span: AppendOnlyIndexVec::new(), definitions };
 
             let qcx = passes::create_global_ctxt(
                 self.compiler,
@@ -172,9 +169,6 @@ impl<'tcx> Queries<'tcx> {
                 )));
                 feed.crate_for_resolver(tcx.arena.alloc(Steal::new((krate, pre_configured_attrs))));
                 feed.output_filenames(Arc::new(outputs));
-
-                let feed = tcx.feed_local_def_id(CRATE_DEF_ID);
-                feed.def_kind(DefKind::Mod);
             });
             Ok(qcx)
         })
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index a58a37bf3ac..a0be1c09c9a 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -143,7 +143,11 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
         BuiltinLintDiag::RedundantImport(spans, ident) => {
             for (span, is_imported) in spans {
                 let introduced = if is_imported { "imported" } else { "defined" };
-                diag.span_label(span, format!("the item `{ident}` is already {introduced} here"));
+                let span_msg = if span.is_dummy() { "by prelude" } else { "here" };
+                diag.span_label(
+                    span,
+                    format!("the item `{ident}` is already {introduced} {span_msg}"),
+                );
             }
         }
         BuiltinLintDiag::DeprecatedMacro(suggestion, span) => {
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 6cb6fd1cbd5..a4fd5a7c45f 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -14,6 +14,7 @@ declare_lint! {
     /// ### Example
     ///
     /// ```rust
+    /// #![warn(non_local_definitions)]
     /// trait MyTrait {}
     /// struct MyStruct;
     ///
@@ -36,7 +37,7 @@ declare_lint! {
     /// All nested bodies (functions, enum discriminant, array length, consts) (expect for
     /// `const _: Ty = { ... }` in top-level module, which is still undecided) are checked.
     pub NON_LOCAL_DEFINITIONS,
-    Warn,
+    Allow,
     "checks for non-local definitions",
     report_in_external_macro
 }
diff --git a/compiler/rustc_llvm/Cargo.toml b/compiler/rustc_llvm/Cargo.toml
index 6598f1db86d..c206380a06f 100644
--- a/compiler/rustc_llvm/Cargo.toml
+++ b/compiler/rustc_llvm/Cargo.toml
@@ -8,12 +8,7 @@ edition = "2021"
 libc = "0.2.73"
 # tidy-alphabetical-end
 
-# FIXME: updating cc past 1.0.79 breaks libstd bootstrapping, pin
-# to the last working version here so `cargo update` doesn't cause the
-# a higher version to be selected
-# https://github.com/rust-lang/cc-rs/issues/913
-# 1.0.{84, 85} fix this but have been yanked
 [build-dependencies]
 # tidy-alphabetical-start
-cc = "=1.0.79"
+cc = "1.0.90"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index 627be997513..60789b07e54 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -120,7 +120,7 @@ extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
   }
   auto FilenamesWriter =
       coverage::CoverageFilenamesSectionWriter(ArrayRef<std::string>(FilenameRefs));
-  RawRustStringOstream OS(BufferOut);
+  auto OS = RawRustStringOstream(BufferOut);
   FilenamesWriter.write(OS);
 }
 
@@ -160,7 +160,7 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
       ArrayRef<unsigned>(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
       Expressions,
       MappingRegions);
-  RawRustStringOstream OS(BufferOut);
+  auto OS = RawRustStringOstream(BufferOut);
   CoverageMappingWriter.write(OS);
 }
 
@@ -168,23 +168,23 @@ extern "C" LLVMValueRef LLVMRustCoverageCreatePGOFuncNameVar(
     LLVMValueRef F,
     const char *FuncName,
     size_t FuncNameLen) {
-  StringRef FuncNameRef(FuncName, FuncNameLen);
+  auto FuncNameRef = StringRef(FuncName, FuncNameLen);
   return wrap(createPGOFuncNameVar(*cast<Function>(unwrap(F)), FuncNameRef));
 }
 
 extern "C" uint64_t LLVMRustCoverageHashByteArray(
     const char *Bytes,
     size_t NumBytes) {
-  StringRef StrRef(Bytes, NumBytes);
+  auto StrRef = StringRef(Bytes, NumBytes);
   return IndexedInstrProf::ComputeHash(StrRef);
 }
 
 static void WriteSectionNameToString(LLVMModuleRef M,
                                      InstrProfSectKind SK,
                                      RustStringRef Str) {
-  Triple TargetTriple(unwrap(M)->getTargetTriple());
+  auto TargetTriple = Triple(unwrap(M)->getTargetTriple());
   auto name = getInstrProfSectionName(SK, TargetTriple.getObjectFormat());
-  RawRustStringOstream OS(Str);
+  auto OS = RawRustStringOstream(Str);
   OS << name;
 }
 
@@ -200,7 +200,7 @@ extern "C" void LLVMRustCoverageWriteFuncSectionNameToString(LLVMModuleRef M,
 
 extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) {
   auto name = getCoverageMappingVarName();
-  RawRustStringOstream OS(Str);
+  auto OS = RawRustStringOstream(Str);
   OS << name;
 }
 
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 4ec784e2590..1cdfc22431e 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -77,9 +77,9 @@ extern "C" void LLVMRustTimeTraceProfilerFinishThread() {
 }
 
 extern "C" void LLVMRustTimeTraceProfilerFinish(const char* FileName) {
-  StringRef FN(FileName);
+  auto FN = StringRef(FileName);
   std::error_code EC;
-  raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
+  auto OS = raw_fd_ostream(FN, EC, sys::fs::CD_CreateAlways);
 
   timeTraceProfilerWrite(OS);
   timeTraceProfilerCleanup();
@@ -424,7 +424,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   auto CM = fromRust(RustCM);
 
   std::string Error;
-  Triple Trip(Triple::normalize(TripleStr));
+  auto Trip = Triple(Triple::normalize(TripleStr));
   const llvm::Target *TheTarget =
       TargetRegistry::lookupTarget(Trip.getTriple(), Error);
   if (TheTarget == nullptr) {
@@ -537,8 +537,8 @@ extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
 // TargetLibraryInfo pass, so we use this method to do so.
 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
                                        bool DisableSimplifyLibCalls) {
-  Triple TargetTriple(unwrap(M)->getTargetTriple());
-  TargetLibraryInfoImpl TLII(TargetTriple);
+  auto TargetTriple = Triple(unwrap(M)->getTargetTriple());
+  auto TLII = TargetLibraryInfoImpl(TargetTriple);
   if (DisableSimplifyLibCalls)
     TLII.disableAllFunctions();
   unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
@@ -589,7 +589,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
 
   std::string ErrorInfo;
   std::error_code EC;
-  raw_fd_ostream OS(Path, EC, sys::fs::OF_None);
+  auto OS = raw_fd_ostream(Path, EC, sys::fs::OF_None);
   if (EC)
     ErrorInfo = EC.message();
   if (ErrorInfo != "") {
@@ -597,9 +597,9 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
     return LLVMRustResult::Failure;
   }
 
-  buffer_ostream BOS(OS);
+  auto BOS = buffer_ostream(OS);
   if (DwoPath) {
-    raw_fd_ostream DOS(DwoPath, EC, sys::fs::OF_None);
+    auto DOS = raw_fd_ostream(DwoPath, EC, sys::fs::OF_None);
     EC.clear();
     if (EC)
         ErrorInfo = EC.message();
@@ -607,7 +607,7 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
       LLVMRustSetLastError(ErrorInfo.c_str());
       return LLVMRustResult::Failure;
     }
-    buffer_ostream DBOS(DOS);
+    auto DBOS = buffer_ostream(DOS);
     unwrap(Target)->addPassesToEmitFile(*PM, BOS, &DBOS, FileType, false);
     PM->run(*unwrap(M));
   } else {
@@ -796,7 +796,7 @@ LLVMRustOptimize(
                         DebugInfoForProfiling);
   }
 
-  PassBuilder PB(TM, PTO, PGOOpt, &PIC);
+  auto PB = PassBuilder(TM, PTO, PGOOpt, &PIC);
   LoopAnalysisManager LAM;
   FunctionAnalysisManager FAM;
   CGSCCAnalysisManager CGAM;
@@ -1112,7 +1112,7 @@ extern "C" LLVMRustResult
 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
   std::string ErrorInfo;
   std::error_code EC;
-  raw_fd_ostream OS(Path, EC, sys::fs::OF_None);
+  auto OS = raw_fd_ostream(Path, EC, sys::fs::OF_None);
   if (EC)
     ErrorInfo = EC.message();
   if (ErrorInfo != "") {
@@ -1120,8 +1120,8 @@ LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
     return LLVMRustResult::Failure;
   }
 
-  RustAssemblyAnnotationWriter AAW(Demangle);
-  formatted_raw_ostream FOS(OS);
+  auto AAW = RustAssemblyAnnotationWriter(Demangle);
+  auto FOS = formatted_raw_ostream(OS);
   unwrap(M)->print(FOS, &AAW);
 
   return LLVMRustResult::Success;
@@ -1281,8 +1281,8 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
   // Load each module's summary and merge it into one combined index
   for (int i = 0; i < num_modules; i++) {
     auto module = &modules[i];
-    StringRef buffer(module->data, module->len);
-    MemoryBufferRef mem_buffer(buffer, module->identifier);
+    auto buffer = StringRef(module->data, module->len);
+    auto mem_buffer = MemoryBufferRef(buffer, module->identifier);
 
     Ret->ModuleMap[module->identifier] = mem_buffer;
 
@@ -1485,7 +1485,7 @@ LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
     return MOrErr;
   };
   bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
-  FunctionImporter Importer(Data->Index, Loader, ClearDSOLocal);
+  auto Importer = FunctionImporter(Data->Index, Loader, ClearDSOLocal);
   Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
   if (!Result) {
     LLVMRustSetLastError(toString(Result.takeError()).c_str());
@@ -1510,7 +1510,7 @@ extern "C" LLVMRustThinLTOBuffer*
 LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
   auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
   {
-    raw_string_ostream OS(Ret->data);
+    auto OS = raw_string_ostream(Ret->data);
     {
       if (is_thin) {
         PassBuilder PB;
@@ -1557,8 +1557,8 @@ LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
                            const char *data,
                            size_t len,
                            const char *identifier) {
-  StringRef Data(data, len);
-  MemoryBufferRef Buffer(Data, identifier);
+  auto Data = StringRef(data, len);
+  auto Buffer = MemoryBufferRef(Data, identifier);
   unwrap(Context)->enableDebugTypeODRUniquing();
   Expected<std::unique_ptr<Module>> SrcOrError =
       parseBitcodeFile(Buffer, *unwrap(Context));
@@ -1576,8 +1576,8 @@ extern "C" const char *LLVMRustGetSliceFromObjectDataByName(const char *data,
                                                             const char *name,
                                                             size_t *out_len) {
   *out_len = 0;
-  StringRef Data(data, len);
-  MemoryBufferRef Buffer(Data, ""); // The id is unused.
+  auto Data = StringRef(data, len);
+  auto Buffer = MemoryBufferRef(Data, ""); // The id is unused.
   file_magic Type = identify_magic(Buffer.getBuffer());
   Expected<std::unique_ptr<object::ObjectFile>> ObjFileOrError =
       object::ObjectFile::createObjectFile(Buffer, Type);
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index cb7cce4da0d..d9262a92782 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -66,12 +66,22 @@ static LLVM_THREAD_LOCAL char *LastError;
 static void FatalErrorHandler(void *UserData,
                               const char* Reason,
                               bool GenCrashDiag) {
-  // Do the same thing that the default error handler does.
-  std::cerr << "LLVM ERROR: " << Reason << std::endl;
+  // Once upon a time we emitted "LLVM ERROR:" specifically to mimic LLVM. Then,
+  // we developed crater and other tools which only expose logs, not error codes.
+  // Use a more greppable prefix that will still match the "LLVM ERROR:" prefix.
+  std::cerr << "rustc-LLVM ERROR: " << Reason << std::endl;
 
   // Since this error handler exits the process, we have to run any cleanup that
   // LLVM would run after handling the error. This might change with an LLVM
   // upgrade.
+  //
+  // In practice, this will do nothing, because the only cleanup LLVM does is
+  // to remove all files that were registered with it via a frontend calling
+  // one of the `createOutputFile` family of functions in LLVM and passing true
+  // to RemoveFileOnSignal, something that rustc does not do. However, it would
+  // be... inadvisable to suddenly stop running these handlers, if LLVM gets
+  // "interesting" ideas in the future about what cleanup should be done.
+  // We might even find it useful for generating less artifacts.
   sys::RunInterruptHandlers();
 
   exit(101);
@@ -109,7 +119,7 @@ extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M,
 
 extern "C" const char *LLVMRustPrintPassTimings(size_t *Len) {
   std::string buf;
-  raw_string_ostream SS(buf);
+  auto SS = raw_string_ostream(buf);
   TimerGroup::printAll(SS);
   SS.flush();
   *Len = buf.length();
@@ -120,7 +130,7 @@ extern "C" const char *LLVMRustPrintPassTimings(size_t *Len) {
 
 extern "C" const char *LLVMRustPrintStatistics(size_t *Len) {
   std::string buf;
-  raw_string_ostream SS(buf);
+  auto SS = raw_string_ostream(buf);
   llvm::PrintStatistics(SS);
   SS.flush();
   *Len = buf.length();
@@ -174,7 +184,7 @@ extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
 extern "C" LLVMValueRef
 LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, size_t NameLen, LLVMTypeRef Ty) {
   Module *Mod = unwrap(M);
-  StringRef NameRef(Name, NameLen);
+  auto NameRef = StringRef(Name, NameLen);
 
   // We don't use Module::getOrInsertGlobal because that returns a Constant*,
   // which may either be the real GlobalVariable*, or a constant bitcast of it
@@ -285,7 +295,7 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
 template<typename T> static inline void AddAttributes(T *t, unsigned Index,
                                                       LLVMAttributeRef *Attrs, size_t AttrsLen) {
   AttributeList PAL = t->getAttributes();
-  AttrBuilder B(t->getContext());
+  auto B = AttrBuilder(t->getContext());
   for (LLVMAttributeRef Attr : ArrayRef<LLVMAttributeRef>(Attrs, AttrsLen))
     B.addAttribute(unwrap(Attr));
   AttributeList PALNew = PAL.addAttributesAtIndex(t->getContext(), Index, B);
@@ -1195,13 +1205,13 @@ extern "C" int64_t LLVMRustDIBuilderCreateOpLLVMFragment() {
 }
 
 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Ty, RustStringRef Str) {
-  RawRustStringOstream OS(Str);
+  auto OS = RawRustStringOstream(Str);
   unwrap<llvm::Type>(Ty)->print(OS);
 }
 
 extern "C" void LLVMRustWriteValueToString(LLVMValueRef V,
                                            RustStringRef Str) {
-  RawRustStringOstream OS(Str);
+  auto OS = RawRustStringOstream(Str);
   if (!V) {
     OS << "(null)";
   } else {
@@ -1224,7 +1234,7 @@ extern "C" LLVMTypeRef LLVMRustArrayType(LLVMTypeRef ElementTy,
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
 
 extern "C" void LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef Str) {
-  RawRustStringOstream OS(Str);
+  auto OS = RawRustStringOstream(Str);
   unwrap(T)->print(OS);
 }
 
@@ -1236,11 +1246,11 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic(
   llvm::DiagnosticInfoOptimizationBase *Opt =
       static_cast<llvm::DiagnosticInfoOptimizationBase *>(unwrap(DI));
 
-  RawRustStringOstream PassNameOS(PassNameOut);
+  auto PassNameOS = RawRustStringOstream(PassNameOut);
   PassNameOS << Opt->getPassName();
   *FunctionOut = wrap(&Opt->getFunction());
 
-  RawRustStringOstream FilenameOS(FilenameOut);
+  auto FilenameOS = RawRustStringOstream(FilenameOut);
   DiagnosticLocation loc = Opt->getLocation();
   if (loc.isValid()) {
     *Line = loc.getLine();
@@ -1248,7 +1258,7 @@ extern "C" void LLVMRustUnpackOptimizationDiagnostic(
     FilenameOS << loc.getAbsolutePath();
   }
 
-  RawRustStringOstream MessageOS(MessageOut);
+  auto MessageOS = RawRustStringOstream(MessageOut);
   MessageOS << Opt->getMsg();
 }
 
@@ -1291,8 +1301,8 @@ LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
 
 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef DI,
                                                     RustStringRef Str) {
-  RawRustStringOstream OS(Str);
-  DiagnosticPrinterRawOStream DP(OS);
+  auto OS = RawRustStringOstream(Str);
+  auto DP = DiagnosticPrinterRawOStream(OS);
   unwrap(DI)->print(DP);
 }
 
@@ -1406,7 +1416,7 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
   default:
     {
       std::string error;
-      llvm::raw_string_ostream stream(error);
+      auto stream = llvm::raw_string_ostream(error);
       stream << "Rust does not support the TypeID: " << unwrap(Ty)->getTypeID()
              << " for the type: " << *unwrap(Ty);
       stream.flush();
@@ -1432,7 +1442,7 @@ extern "C" bool LLVMRustUnpackSMDiagnostic(LLVMSMDiagnosticRef DRef,
                                            unsigned* RangesOut,
                                            size_t* NumRanges) {
   SMDiagnostic& D = *unwrap(DRef);
-  RawRustStringOstream MessageOS(MessageOut);
+  auto MessageOS = RawRustStringOstream(MessageOut);
   MessageOS << D.getMessage();
 
   switch (D.getKind()) {
@@ -1547,7 +1557,7 @@ extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B,
 
 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V,
                                   const char *Name, size_t NameLen) {
-  Triple TargetTriple(unwrap(M)->getTargetTriple());
+  Triple TargetTriple = Triple(unwrap(M)->getTargetTriple());
   GlobalObject *GV = unwrap<GlobalObject>(V);
   if (TargetTriple.supportsCOMDAT()) {
     StringRef NameRef(Name, NameLen);
@@ -1711,7 +1721,7 @@ extern "C" LLVMRustModuleBuffer*
 LLVMRustModuleBufferCreate(LLVMModuleRef M) {
   auto Ret = std::make_unique<LLVMRustModuleBuffer>();
   {
-    raw_string_ostream OS(Ret->data);
+    auto OS = raw_string_ostream(Ret->data);
     WriteBitcodeToFile(*unwrap(M), OS);
   }
   return Ret.release();
@@ -1741,8 +1751,8 @@ LLVMRustModuleCost(LLVMModuleRef M) {
 extern "C" void
 LLVMRustModuleInstructionStats(LLVMModuleRef M, RustStringRef Str)
 {
-  RawRustStringOstream OS(Str);
-  llvm::json::OStream JOS(OS);
+  auto OS = RawRustStringOstream(Str);
+  auto JOS = llvm::json::OStream(OS);
   auto Module = unwrap(M);
 
   JOS.object([&] {
@@ -1857,7 +1867,7 @@ extern "C" LLVMRustResult LLVMRustWriteImportLibrary(
     MinGW);
   if (Error) {
     std::string errorString;
-    llvm::raw_string_ostream stream(errorString);
+    auto stream = llvm::raw_string_ostream(errorString);
     stream << Error;
     stream.flush();
     LLVMRustSetLastError(errorString.c_str());
@@ -2041,7 +2051,7 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler(
 }
 
 extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) {
-  RawRustStringOstream OS(Str);
+  auto OS = RawRustStringOstream(Str);
   GlobalValue *GV = unwrap<GlobalValue>(V);
   Mangler().getNameWithPrefix(OS, GV, true);
 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
index 91f84692df8..ee8239ef8e7 100644
--- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
@@ -11,6 +11,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/Object/ObjectFile.h"
+#include <llvm/Support/raw_ostream.h>
 
 using namespace llvm;
 using namespace llvm::sys;
@@ -42,7 +43,7 @@ extern "C" void *LLVMRustGetSymbols(
     MemoryBuffer::getMemBuffer(StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"),
                                false);
   SmallString<0> SymNameBuf;
-  raw_svector_ostream SymName(SymNameBuf);
+  auto SymName = raw_svector_ostream(SymNameBuf);
 
   // In the scenario when LLVMContext is populated SymbolicFile will contain a
   // reference to it, thus SymbolicFile should be destroyed first.
@@ -60,7 +61,7 @@ extern "C" void *LLVMRustGetSymbols(
     if (!ObjOrErr) {
       Error E = ObjOrErr.takeError();
       SmallString<0> ErrorBuf;
-      raw_svector_ostream Error(ErrorBuf);
+      auto Error = raw_svector_ostream(ErrorBuf);
       Error << E << '\0';
       return ErrorCallback(Error.str().data());
     }
@@ -70,7 +71,7 @@ extern "C" void *LLVMRustGetSymbols(
     if (!ObjOrErr) {
       Error E = ObjOrErr.takeError();
       SmallString<0> ErrorBuf;
-      raw_svector_ostream Error(ErrorBuf);
+      auto Error = raw_svector_ostream(ErrorBuf);
       Error << E << '\0';
       return ErrorCallback(Error.str().data());
     }
@@ -83,7 +84,7 @@ extern "C" void *LLVMRustGetSymbols(
       continue;
     if (Error E = S.printName(SymName)) {
       SmallString<0> ErrorBuf;
-      raw_svector_ostream Error(ErrorBuf);
+      auto Error = raw_svector_ostream(ErrorBuf);
       Error << E << '\0';
       return ErrorCallback(Error.str().data());
     }
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 90e68a6b5b9..dcccace12b0 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -1077,7 +1077,7 @@ impl CrateError {
                         crate_rejections,
                     });
                 } else {
-                    dcx.emit_err(errors::CannotFindCrate {
+                    let error = errors::CannotFindCrate {
                         span,
                         crate_name,
                         add_info,
@@ -1091,11 +1091,18 @@ impl CrateError {
                         profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime),
                         locator_triple: locator.triple,
                         is_ui_testing: sess.opts.unstable_opts.ui_testing,
-                    });
+                    };
+                    // The diagnostic for missing core is very good, but it is followed by a lot of
+                    // other diagnostics that do not add information.
+                    if missing_core {
+                        dcx.emit_fatal(error);
+                    } else {
+                        dcx.emit_err(error);
+                    }
                 }
             }
             CrateError::NotFound(crate_name) => {
-                dcx.emit_err(errors::CannotFindCrate {
+                let error = errors::CannotFindCrate {
                     span,
                     crate_name,
                     add_info: String::new(),
@@ -1105,7 +1112,14 @@ impl CrateError {
                     profiler_runtime: Symbol::intern(&sess.opts.unstable_opts.profiler_runtime),
                     locator_triple: sess.opts.target_triple.clone(),
                     is_ui_testing: sess.opts.unstable_opts.ui_testing,
-                });
+                };
+                // The diagnostic for missing core is very good, but it is followed by a lot of
+                // other diagnostics that do not add information.
+                if missing_core {
+                    dcx.emit_fatal(error);
+                } else {
+                    dcx.emit_err(error);
+                }
             }
         }
     }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 3866d6fec2d..6e9cbfdcfee 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1993,9 +1993,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
             if of_trait && let Some(header) = tcx.impl_trait_header(def_id) {
                 record!(self.tables.impl_trait_header[def_id] <- header);
-                let trait_ref = header.map_bound(|h| h.trait_ref);
 
-                let trait_ref = trait_ref.instantiate_identity();
+                let trait_ref = header.trait_ref.instantiate_identity();
                 let simplified_self_ty = fast_reject::simplify_type(
                     self.tcx,
                     trait_ref.self_ty(),
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 28166687606..8aa31ef564f 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -423,7 +423,7 @@ define_tables! {
     variances_of: Table<DefIndex, LazyArray<ty::Variance>>,
     fn_sig: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::PolyFnSig<'static>>>>,
     codegen_fn_attrs: Table<DefIndex, LazyValue<CodegenFnAttrs>>,
-    impl_trait_header: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::ImplTraitHeader<'static>>>>,
+    impl_trait_header: Table<DefIndex, LazyValue<ty::ImplTraitHeader<'static>>>,
     const_param_default: Table<DefIndex, LazyValue<ty::EarlyBinder<rustc_middle::ty::Const<'static>>>>,
     object_lifetime_default: Table<DefIndex, LazyValue<ObjectLifetimeDefault>>,
     optimized_mir: Table<DefIndex, LazyValue<mir::Body<'static>>>,
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index d0711baa181..33ee3371605 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -177,8 +177,8 @@ impl EraseType for Option<mir::DestructuredConstant<'_>> {
     type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()];
 }
 
-impl EraseType for Option<ty::EarlyBinder<ty::ImplTraitHeader<'_>>> {
-    type Result = [u8; size_of::<Option<ty::EarlyBinder<ty::ImplTraitHeader<'static>>>>()];
+impl EraseType for Option<ty::ImplTraitHeader<'_>> {
+    type Result = [u8; size_of::<Option<ty::ImplTraitHeader<'static>>>()];
 }
 
 impl EraseType for Option<ty::EarlyBinder<Ty<'_>>> {
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b0431ae05d3..7c6e9762f2a 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -125,12 +125,11 @@ rustc_queries! {
     }
 
     query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt {
-        feedable
         no_hash
         desc { "getting the resolver outputs" }
     }
 
-    query resolver_for_lowering(_: ()) -> &'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)> {
+    query resolver_for_lowering_raw(_: ()) -> (&'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)>, &'tcx ty::ResolverGlobalCtxt) {
         eval_always
         no_hash
         desc { "getting the resolver for lowering" }
@@ -826,7 +825,7 @@ rustc_queries! {
     /// creates and returns the associated items that correspond to each impl trait in return position
     /// of the implemented trait.
     query associated_types_for_impl_traits_in_associated_fn(fn_def_id: DefId) -> &'tcx [DefId] {
-        desc { |tcx| "creating associated items for impl trait in trait returned by `{}`", tcx.def_path_str(fn_def_id) }
+        desc { |tcx| "creating associated items for opaque types returned by `{}`", tcx.def_path_str(fn_def_id) }
         cache_on_disk_if { fn_def_id.is_local() }
         separate_provide_extern
     }
@@ -834,13 +833,13 @@ rustc_queries! {
     /// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding
     /// associated item.
     query associated_type_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId {
-        desc { |tcx| "creates the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
+        desc { |tcx| "creating the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) }
         cache_on_disk_if { true }
     }
 
     /// Given an `impl_id`, return the trait it implements along with some header information.
     /// Return `None` if this is an inherent impl.
-    query impl_trait_header(impl_id: DefId) -> Option<ty::EarlyBinder<ty::ImplTraitHeader<'tcx>>> {
+    query impl_trait_header(impl_id: DefId) -> Option<ty::ImplTraitHeader<'tcx>> {
         desc { |tcx| "computing trait implemented by `{}`", tcx.def_path_str(impl_id) }
         cache_on_disk_if { impl_id.is_local() }
         separate_provide_extern
@@ -955,11 +954,6 @@ rustc_queries! {
         desc { |tcx| "checking deathness of variables in {}", describe_as_module(key, tcx) }
     }
 
-    query check_mod_impl_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
-        desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) }
-        ensure_forwards_result_if_red
-    }
-
     query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
         desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
         ensure_forwards_result_if_red
@@ -2221,7 +2215,6 @@ rustc_queries! {
     /// Should not be called for the local crate before the resolver outputs are created, as it
     /// is only fed there.
     query stripped_cfg_items(cnum: CrateNum) -> &'tcx [StrippedCfgItem] {
-        feedable
         desc { "getting cfg-ed out item names" }
         separate_provide_extern
     }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 4eec93532a2..4f8e4aa90f4 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -39,7 +39,7 @@ use rustc_data_structures::profiling::SelfProfilerRef;
 use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::steal::Steal;
-use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, WorkerLocal};
+use rustc_data_structures::sync::{self, FreezeReadGuard, Lock, Lrc, WorkerLocal};
 #[cfg(parallel_compiler)]
 use rustc_data_structures::sync::{DynSend, DynSync};
 use rustc_data_structures::unord::UnordSet;
@@ -60,7 +60,7 @@ use rustc_session::config::CrateType;
 use rustc_session::cstore::{CrateStoreDyn, Untracked};
 use rustc_session::lint::Lint;
 use rustc_session::{Limit, MetadataKind, Session};
-use rustc_span::def_id::{DefPathHash, StableCrateId};
+use rustc_span::def_id::{DefPathHash, StableCrateId, CRATE_DEF_ID};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx};
@@ -74,6 +74,7 @@ use std::cmp::Ordering;
 use std::fmt;
 use std::hash::{Hash, Hasher};
 use std::iter;
+use std::marker::PhantomData;
 use std::mem;
 use std::ops::{Bound, Deref};
 
@@ -498,14 +499,55 @@ pub struct TyCtxtFeed<'tcx, KEY: Copy> {
     key: KEY,
 }
 
+/// Never return a `Feed` from a query. Only queries that create a `DefId` are
+/// allowed to feed queries for that `DefId`.
+impl<KEY: Copy, CTX> !HashStable<CTX> for TyCtxtFeed<'_, KEY> {}
+
+/// The same as `TyCtxtFeed`, but does not contain a `TyCtxt`.
+/// Use this to pass around when you have a `TyCtxt` elsewhere.
+/// Just an optimization to save space and not store hundreds of
+/// `TyCtxtFeed` in the resolver.
+#[derive(Copy, Clone)]
+pub struct Feed<'tcx, KEY: Copy> {
+    _tcx: PhantomData<TyCtxt<'tcx>>,
+    // Do not allow direct access, as downstream code must not mutate this field.
+    key: KEY,
+}
+
+/// Never return a `Feed` from a query. Only queries that create a `DefId` are
+/// allowed to feed queries for that `DefId`.
+impl<KEY: Copy, CTX> !HashStable<CTX> for Feed<'_, KEY> {}
+
+impl<T: fmt::Debug + Copy> fmt::Debug for Feed<'_, T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.key.fmt(f)
+    }
+}
+
+/// Some workarounds to use cases that cannot use `create_def`.
+/// Do not add new ways to create `TyCtxtFeed` without consulting
+/// with T-compiler and making an analysis about why your addition
+/// does not cause incremental compilation issues.
 impl<'tcx> TyCtxt<'tcx> {
+    /// Can only be fed before queries are run, and is thus exempt from any
+    /// incremental issues. Do not use except for the initial query feeding.
     pub fn feed_unit_query(self) -> TyCtxtFeed<'tcx, ()> {
+        self.dep_graph.assert_ignored();
         TyCtxtFeed { tcx: self, key: () }
     }
+
+    /// Can only be fed before queries are run, and is thus exempt from any
+    /// incremental issues. Do not use except for the initial query feeding.
     pub fn feed_local_crate(self) -> TyCtxtFeed<'tcx, CrateNum> {
+        self.dep_graph.assert_ignored();
         TyCtxtFeed { tcx: self, key: LOCAL_CRATE }
     }
-    pub fn feed_local_def_id(self, key: LocalDefId) -> TyCtxtFeed<'tcx, LocalDefId> {
+
+    /// Only used in the resolver to register the `CRATE_DEF_ID` `DefId` and feed
+    /// some queries for it. It will panic if used twice.
+    pub fn create_local_crate_def_id(self, span: Span) -> TyCtxtFeed<'tcx, LocalDefId> {
+        let key = self.untracked().source_span.push(span);
+        assert_eq!(key, CRATE_DEF_ID);
         TyCtxtFeed { tcx: self, key }
     }
 
@@ -523,6 +565,23 @@ impl<'tcx, KEY: Copy> TyCtxtFeed<'tcx, KEY> {
     pub fn key(&self) -> KEY {
         self.key
     }
+
+    #[inline(always)]
+    pub fn downgrade(self) -> Feed<'tcx, KEY> {
+        Feed { _tcx: PhantomData, key: self.key }
+    }
+}
+
+impl<'tcx, KEY: Copy> Feed<'tcx, KEY> {
+    #[inline(always)]
+    pub fn key(&self) -> KEY {
+        self.key
+    }
+
+    #[inline(always)]
+    pub fn upgrade(self, tcx: TyCtxt<'tcx>) -> TyCtxtFeed<'tcx, KEY> {
+        TyCtxtFeed { tcx, key: self.key }
+    }
 }
 
 impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
@@ -1067,7 +1126,7 @@ impl<'tcx> TyCtxt<'tcx> {
         // needs to be re-evaluated.
         self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
 
-        let feed = self.feed_local_def_id(def_id);
+        let feed = TyCtxtFeed { tcx: self, key: def_id };
         feed.def_kind(def_kind);
         // Unique types created for closures participate in type privacy checking.
         // They have visibilities inherited from the module they are defined in.
@@ -2304,18 +2363,21 @@ impl<'tcx> TyCtxt<'tcx> {
         self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..])
     }
 
+    pub fn resolver_for_lowering(self) -> &'tcx Steal<(ty::ResolverAstLowering, Lrc<ast::Crate>)> {
+        self.resolver_for_lowering_raw(()).0
+    }
+
     /// Given an `impl_id`, return the trait it implements.
     /// Return `None` if this is an inherent impl.
     pub fn impl_trait_ref(
         self,
         def_id: impl IntoQueryParam<DefId>,
     ) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> {
-        Some(self.impl_trait_header(def_id)?.map_bound(|h| h.trait_ref))
+        Some(self.impl_trait_header(def_id)?.trait_ref)
     }
 
     pub fn impl_polarity(self, def_id: impl IntoQueryParam<DefId>) -> ty::ImplPolarity {
-        self.impl_trait_header(def_id)
-            .map_or(ty::ImplPolarity::Positive, |h| h.skip_binder().polarity)
+        self.impl_trait_header(def_id).map_or(ty::ImplPolarity::Positive, |h| h.polarity)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 260d0885089..9fc8d418f5b 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -694,6 +694,7 @@ impl<'tcx> Instance<'tcx> {
     }
 
     #[inline(always)]
+    // Keep me in sync with try_instantiate_mir_and_normalize_erasing_regions
     pub fn instantiate_mir_and_normalize_erasing_regions<T>(
         &self,
         tcx: TyCtxt<'tcx>,
@@ -701,16 +702,17 @@ impl<'tcx> Instance<'tcx> {
         v: EarlyBinder<T>,
     ) -> T
     where
-        T: TypeFoldable<TyCtxt<'tcx>> + Clone,
+        T: TypeFoldable<TyCtxt<'tcx>>,
     {
         if let Some(args) = self.args_for_mir_body() {
             tcx.instantiate_and_normalize_erasing_regions(args, param_env, v)
         } else {
-            tcx.normalize_erasing_regions(param_env, v.skip_binder())
+            tcx.normalize_erasing_regions(param_env, v.instantiate_identity())
         }
     }
 
     #[inline(always)]
+    // Keep me in sync with instantiate_mir_and_normalize_erasing_regions
     pub fn try_instantiate_mir_and_normalize_erasing_regions<T>(
         &self,
         tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 0a38d379a52..4edec0e6951 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -32,6 +32,7 @@ pub use generic_args::*;
 pub use generics::*;
 pub use intrinsic::IntrinsicDef;
 use rustc_ast as ast;
+use rustc_ast::expand::StrippedCfgItem;
 use rustc_ast::node_id::NodeMap;
 pub use rustc_ast_ir::{try_visit, Movability, Mutability};
 use rustc_attr as attr;
@@ -85,7 +86,8 @@ pub use self::consts::{
     Const, ConstData, ConstInt, ConstKind, Expr, ScalarInt, UnevaluatedConst, ValTree,
 };
 pub use self::context::{
-    tls, CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed,
+    tls, CtxtInterners, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt,
+    TyCtxtFeed,
 };
 pub use self::instance::{Instance, InstanceDef, ShortInstance, UnusedGenericParams};
 pub use self::list::List;
@@ -189,6 +191,7 @@ pub struct ResolverGlobalCtxt {
     pub doc_link_resolutions: FxHashMap<LocalDefId, DocLinkResMap>,
     pub doc_link_traits_in_scope: FxHashMap<LocalDefId, Vec<DefId>>,
     pub all_macro_rules: FxHashMap<Symbol, Res<ast::NodeId>>,
+    pub stripped_cfg_items: Steal<Vec<StrippedCfgItem>>,
 }
 
 /// Resolutions that should only be used for lowering.
@@ -250,9 +253,9 @@ pub struct ImplHeader<'tcx> {
     pub predicates: Vec<Predicate<'tcx>>,
 }
 
-#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, TyEncodable, TyDecodable, HashStable)]
+#[derive(Copy, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
 pub struct ImplTraitHeader<'tcx> {
-    pub trait_ref: ty::TraitRef<'tcx>,
+    pub trait_ref: ty::EarlyBinder<ty::TraitRef<'tcx>>,
     pub polarity: ImplPolarity,
     pub unsafety: hir::Unsafety,
 }
@@ -1624,12 +1627,15 @@ impl<'tcx> TyCtxt<'tcx> {
         def_id1: DefId,
         def_id2: DefId,
     ) -> Option<ImplOverlapKind> {
-        let impl1 = self.impl_trait_header(def_id1).unwrap().instantiate_identity();
-        let impl2 = self.impl_trait_header(def_id2).unwrap().instantiate_identity();
+        let impl1 = self.impl_trait_header(def_id1).unwrap();
+        let impl2 = self.impl_trait_header(def_id2).unwrap();
+
+        let trait_ref1 = impl1.trait_ref.skip_binder();
+        let trait_ref2 = impl2.trait_ref.skip_binder();
 
         // If either trait impl references an error, they're allowed to overlap,
         // as one of them essentially doesn't exist.
-        if impl1.references_error() || impl2.references_error() {
+        if trait_ref1.references_error() || trait_ref2.references_error() {
             return Some(ImplOverlapKind::Permitted { marker: false });
         }
 
@@ -1650,7 +1656,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let is_marker_overlap = {
             let is_marker_impl =
                 |trait_ref: TraitRef<'_>| -> bool { self.trait_def(trait_ref.def_id).is_marker };
-            is_marker_impl(impl1.trait_ref) && is_marker_impl(impl2.trait_ref)
+            is_marker_impl(trait_ref1) && is_marker_impl(trait_ref2)
         };
 
         if is_marker_overlap {
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 9a6d4498352..8a9dc34bc7b 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -58,52 +58,60 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 this.thir[scrutinee].span,
             ),
             ExprKind::If { cond, then, else_opt, if_then_scope } => {
-                let then_blk;
                 let then_span = this.thir[then].span;
                 let then_source_info = this.source_info(then_span);
                 let condition_scope = this.local_scope();
 
-                let mut else_blk = unpack!(
-                    then_blk = this.in_scope(
-                        (if_then_scope, then_source_info),
-                        LintLevel::Inherited,
-                        |this| {
-                            let source_info = if this.is_let(cond) {
-                                let variable_scope =
-                                    this.new_source_scope(then_span, LintLevel::Inherited, None);
-                                this.source_scope = variable_scope;
-                                SourceInfo { span: then_span, scope: variable_scope }
-                            } else {
-                                this.source_info(then_span)
-                            };
-                            let (then_block, else_block) =
-                                this.in_if_then_scope(condition_scope, then_span, |this| {
-                                    let then_blk = unpack!(this.then_else_break(
-                                        block,
-                                        cond,
-                                        Some(condition_scope), // Temp scope
-                                        condition_scope,
-                                        source_info,
-                                        true, // Declare `let` bindings normally
-                                    ));
-
-                                    this.expr_into_dest(destination, then_blk, then)
-                                });
-                            then_block.and(else_block)
-                        },
-                    )
+                let then_and_else_blocks = this.in_scope(
+                    (if_then_scope, then_source_info),
+                    LintLevel::Inherited,
+                    |this| {
+                        // FIXME: Does this need extra logic to handle let-chains?
+                        let source_info = if this.is_let(cond) {
+                            let variable_scope =
+                                this.new_source_scope(then_span, LintLevel::Inherited, None);
+                            this.source_scope = variable_scope;
+                            SourceInfo { span: then_span, scope: variable_scope }
+                        } else {
+                            this.source_info(then_span)
+                        };
+
+                        // Lower the condition, and have it branch into `then` and `else` blocks.
+                        let (then_block, else_block) =
+                            this.in_if_then_scope(condition_scope, then_span, |this| {
+                                let then_blk = unpack!(this.then_else_break(
+                                    block,
+                                    cond,
+                                    Some(condition_scope), // Temp scope
+                                    source_info,
+                                    true, // Declare `let` bindings normally
+                                ));
+
+                                // Lower the `then` arm into its block.
+                                this.expr_into_dest(destination, then_blk, then)
+                            });
+
+                        // Pack `(then_block, else_block)` into `BlockAnd<BasicBlock>`.
+                        then_block.and(else_block)
+                    },
                 );
 
-                else_blk = if let Some(else_opt) = else_opt {
-                    unpack!(this.expr_into_dest(destination, else_blk, else_opt))
+                // Unpack `BlockAnd<BasicBlock>` into `(then_blk, else_blk)`.
+                let (then_blk, mut else_blk);
+                else_blk = unpack!(then_blk = then_and_else_blocks);
+
+                // If there is an `else` arm, lower it into `else_blk`.
+                if let Some(else_expr) = else_opt {
+                    unpack!(else_blk = this.expr_into_dest(destination, else_blk, else_expr));
                 } else {
-                    // Body of the `if` expression without an `else` clause must return `()`, thus
-                    // we implicitly generate an `else {}` if it is not specified.
+                    // There is no `else` arm, so we know both arms have type `()`.
+                    // Generate the implicit `else {}` by assigning unit.
                     let correct_si = this.source_info(expr_span.shrink_to_hi());
                     this.cfg.push_assign_unit(else_blk, correct_si, destination, this.tcx);
-                    else_blk
-                };
+                }
 
+                // The `then` and `else` arms have been lowered into their respective
+                // blocks, so make both of them meet up in a new block.
                 let join_block = this.cfg.start_new_block();
                 this.cfg.goto(then_blk, source_info, join_block);
                 this.cfg.goto(else_blk, source_info, join_block);
@@ -147,7 +155,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             block,
                             lhs,
                             Some(condition_scope), // Temp scope
-                            condition_scope,
                             source_info,
                             // This flag controls how inner `let` expressions are lowered,
                             // but either way there shouldn't be any of those in here.
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 29ee07f5d79..31591983101 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -37,9 +37,6 @@ struct ThenElseArgs {
     /// Used as the temp scope for lowering `expr`. If absent (for match guards),
     /// `self.local_scope()` is used.
     temp_scope_override: Option<region::Scope>,
-    /// Scope to pass to [`Builder::break_for_else`]. Must match the scope used
-    /// by the enclosing call to [`Builder::in_if_then_scope`].
-    break_scope: region::Scope,
     variable_source_info: SourceInfo,
     /// Forwarded to [`Builder::lower_let_expr`] when lowering [`ExprKind::Let`].
     /// When false (for match guards), `let` bindings won't be declared.
@@ -58,19 +55,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         block: BasicBlock,
         expr_id: ExprId,
         temp_scope_override: Option<region::Scope>,
-        break_scope: region::Scope,
         variable_source_info: SourceInfo,
         declare_let_bindings: bool,
     ) -> BlockAnd<()> {
         self.then_else_break_inner(
             block,
             expr_id,
-            ThenElseArgs {
-                temp_scope_override,
-                break_scope,
-                variable_source_info,
-                declare_let_bindings,
-            },
+            ThenElseArgs { temp_scope_override, variable_source_info, declare_let_bindings },
         )
     }
 
@@ -97,11 +88,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         this.then_else_break_inner(
                             block,
                             lhs,
-                            ThenElseArgs {
-                                break_scope: local_scope,
-                                declare_let_bindings: true,
-                                ..args
-                            },
+                            ThenElseArgs { declare_let_bindings: true, ..args },
                         )
                     });
                 let rhs_success_block = unpack!(this.then_else_break_inner(
@@ -130,14 +117,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         this.then_else_break_inner(
                             block,
                             arg,
-                            ThenElseArgs {
-                                break_scope: local_scope,
-                                declare_let_bindings: true,
-                                ..args
-                            },
+                            ThenElseArgs { declare_let_bindings: true, ..args },
                         )
                     });
-                this.break_for_else(success_block, args.break_scope, args.variable_source_info);
+                this.break_for_else(success_block, args.variable_source_info);
                 failure_block.unit()
             }
             ExprKind::Scope { region_scope, lint_level, value } => {
@@ -151,7 +134,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block,
                 expr,
                 pat,
-                args.break_scope,
                 Some(args.variable_source_info.scope),
                 args.variable_source_info.span,
                 args.declare_let_bindings,
@@ -170,7 +152,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
                 let source_info = this.source_info(expr_span);
                 this.cfg.terminate(block, source_info, term);
-                this.break_for_else(else_block, args.break_scope, source_info);
+                this.break_for_else(else_block, source_info);
 
                 then_block.unit()
             }
@@ -1911,7 +1893,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         mut block: BasicBlock,
         expr_id: ExprId,
         pat: &Pat<'tcx>,
-        else_target: region::Scope,
         source_scope: Option<SourceScope>,
         span: Span,
         declare_bindings: bool,
@@ -1933,7 +1914,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let expr_place = expr_place_builder.try_to_place(self);
         let opt_expr_place = expr_place.as_ref().map(|place| (Some(place), expr_span));
         let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
-        self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span));
+        self.break_for_else(otherwise_post_guard_block, self.source_info(expr_span));
 
         if declare_bindings {
             self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place);
@@ -2110,7 +2091,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         block,
                         guard,
                         None, // Use `self.local_scope()` as the temp scope
-                        match_scope,
                         this.source_info(arm.span),
                         false, // For guards, `let` bindings are declared separately
                     )
@@ -2443,7 +2423,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 None,
                 true,
             );
-            this.break_for_else(failure, *let_else_scope, this.source_info(initializer_span));
+            this.break_for_else(failure, this.source_info(initializer_span));
             matching.unit()
         });
         matching.and(failure)
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 04740a96291..961502566ba 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -683,20 +683,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         self.cfg.start_new_block().unit()
     }
 
-    pub(crate) fn break_for_else(
-        &mut self,
-        block: BasicBlock,
-        target: region::Scope,
-        source_info: SourceInfo,
-    ) {
-        let scope_index = self.scopes.scope_index(target, source_info.span);
+    /// Sets up the drops for breaking from `block` due to an `if` condition
+    /// that turned out to be false.
+    ///
+    /// Must be called in the context of [`Builder::in_if_then_scope`], so that
+    /// there is an if-then scope to tell us what the target scope is.
+    pub(crate) fn break_for_else(&mut self, block: BasicBlock, source_info: SourceInfo) {
         let if_then_scope = self
             .scopes
             .if_then_scope
-            .as_mut()
+            .as_ref()
             .unwrap_or_else(|| span_bug!(source_info.span, "no if-then scope found"));
 
-        assert_eq!(if_then_scope.region_scope, target, "breaking to incorrect scope");
+        let target = if_then_scope.region_scope;
+        let scope_index = self.scopes.scope_index(target, source_info.span);
+
+        // Upgrade `if_then_scope` to `&mut`.
+        let if_then_scope = self.scopes.if_then_scope.as_mut().expect("upgrading & to &mut");
 
         let mut drop_idx = ROOT_NODE;
         let drops = &mut if_then_scope.else_drops;
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 14d9b0b0350..19109735d48 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -929,7 +929,7 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
         _instance: ty::Instance<'tcx>,
         _abi: rustc_target::spec::abi::Abi,
         _args: &[rustc_const_eval::interpret::FnArg<'tcx, Self::Provenance>],
-        _destination: &rustc_const_eval::interpret::PlaceTy<'tcx, Self::Provenance>,
+        _destination: &rustc_const_eval::interpret::MPlaceTy<'tcx, Self::Provenance>,
         _target: Option<BasicBlock>,
         _unwind: UnwindAction,
     ) -> interpret::InterpResult<'tcx, Option<(&'mir Body<'tcx>, ty::Instance<'tcx>)>> {
@@ -947,7 +947,7 @@ impl<'mir, 'tcx: 'mir> rustc_const_eval::interpret::Machine<'mir, 'tcx> for Dumm
         _ecx: &mut InterpCx<'mir, 'tcx, Self>,
         _instance: ty::Instance<'tcx>,
         _args: &[rustc_const_eval::interpret::OpTy<'tcx, Self::Provenance>],
-        _destination: &rustc_const_eval::interpret::PlaceTy<'tcx, Self::Provenance>,
+        _destination: &rustc_const_eval::interpret::MPlaceTy<'tcx, Self::Provenance>,
         _target: Option<BasicBlock>,
         _unwind: UnwindAction,
     ) -> interpret::InterpResult<'tcx> {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index b0cb9fa517f..37cce625c8e 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1361,7 +1361,7 @@ fn create_mono_items_for_default_impls<'tcx>(
         return;
     };
 
-    if matches!(impl_.skip_binder().polarity, ty::ImplPolarity::Negative) {
+    if matches!(impl_.polarity, ty::ImplPolarity::Negative) {
         return;
     }
 
@@ -1385,7 +1385,7 @@ fn create_mono_items_for_default_impls<'tcx>(
         }
     };
     let impl_args = GenericArgs::for_item(tcx, item.owner_id.to_def_id(), only_region_params);
-    let trait_ref = impl_.instantiate(tcx, impl_args).trait_ref;
+    let trait_ref = impl_.trait_ref.instantiate(tcx, impl_args);
 
     // Unlike 'lazy' monomorphization that begins by collecting items transitively
     // called by `main` or other global items, when eagerly monomorphizing impl
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 54854cd2da9..ea9c78ca34c 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -787,13 +787,17 @@ impl<'a> Parser<'a> {
                             let suggest_eq = if self.token.kind == token::Dot
                                 && let _ = self.bump()
                                 && let mut snapshot = self.create_snapshot_for_diagnostic()
-                                && let Ok(_) = snapshot.parse_dot_suffix_expr(
-                                    colon_sp,
-                                    self.mk_expr_err(
+                                && let Ok(_) = snapshot
+                                    .parse_dot_suffix_expr(
                                         colon_sp,
-                                        self.dcx().delayed_bug("error during `:` -> `=` recovery"),
-                                    ),
-                                ) {
+                                        self.mk_expr_err(
+                                            colon_sp,
+                                            self.dcx()
+                                                .delayed_bug("error during `:` -> `=` recovery"),
+                                        ),
+                                    )
+                                    .map_err(Diag::cancel)
+                            {
                                 true
                             } else if let Some(op) = self.check_assoc_op()
                                 && op.node.can_continue_expr_unambiguously()
diff --git a/compiler/rustc_passes/src/debugger_visualizer.rs b/compiler/rustc_passes/src/debugger_visualizer.rs
index 4bfe6be5493..96893e58549 100644
--- a/compiler/rustc_passes/src/debugger_visualizer.rs
+++ b/compiler/rustc_passes/src/debugger_visualizer.rs
@@ -87,7 +87,7 @@ impl<'ast> rustc_ast::visit::Visitor<'ast> for DebuggerVisualizerCollector<'_> {
 
 /// Traverses and collects the debugger visualizers for a specific crate.
 fn debugger_visualizers(tcx: TyCtxt<'_>, _: LocalCrate) -> Vec<DebuggerVisualizerFile> {
-    let resolver_and_krate = tcx.resolver_for_lowering(()).borrow();
+    let resolver_and_krate = tcx.resolver_for_lowering().borrow();
     let krate = &*resolver_and_krate.1;
 
     let mut visitor = DebuggerVisualizerCollector { sess: tcx.sess, visualizers: Vec::new() };
diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index 02f56ecb10b..dd6c1166957 100644
--- a/compiler/rustc_passes/src/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
@@ -1,38 +1,26 @@
 use rustc_data_structures::sync::Lock;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::intravisit;
-use rustc_hir::{HirId, ItemLocalId};
+use rustc_hir::{intravisit, HirId, ItemLocalId};
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 
 pub fn check_crate(tcx: TyCtxt<'_>) {
-    if tcx.sess.opts.unstable_opts.hir_stats {
-        crate::hir_stats::print_hir_stats(tcx);
-    }
-
-    #[cfg(debug_assertions)]
-    {
-        let errors = Lock::new(Vec::new());
+    let errors = Lock::new(Vec::new());
 
-        tcx.hir().par_for_each_module(|module_id| {
-            let mut v = HirIdValidator {
-                tcx,
-                owner: None,
-                hir_ids_seen: Default::default(),
-                errors: &errors,
-            };
+    tcx.hir().par_for_each_module(|module_id| {
+        let mut v =
+            HirIdValidator { tcx, owner: None, hir_ids_seen: Default::default(), errors: &errors };
 
-            tcx.hir().visit_item_likes_in_module(module_id, &mut v);
-        });
+        tcx.hir().visit_item_likes_in_module(module_id, &mut v);
+    });
 
-        let errors = errors.into_inner();
+    let errors = errors.into_inner();
 
-        if !errors.is_empty() {
-            let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2);
-            tcx.dcx().delayed_bug(message);
-        }
+    if !errors.is_empty() {
+        let message = errors.iter().fold(String::new(), |s1, s2| s1 + "\n" + s2);
+        tcx.dcx().delayed_bug(message);
     }
 }
 
@@ -90,7 +78,7 @@ impl<'a, 'hir> HirIdValidator<'a, 'hir> {
             self.error(|| {
                 format!(
                     "ItemLocalIds not assigned densely in {pretty_owner}. \
-                Max ItemLocalId = {max}, missing IDs = {missing_items:#?}; seen IDs = {seen_items:#?}"
+            Max ItemLocalId = {max}, missing IDs = {missing_items:#?}; seen IDs = {seen_items:#?}"
                 )
             });
         }
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index d3e3e183845..d1368267224 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -243,7 +243,7 @@ impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
 
 /// Traverses and collects all the lang items in all crates.
 fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
-    let resolver = tcx.resolver_for_lowering(()).borrow();
+    let resolver = tcx.resolver_for_lowering().borrow();
     let (resolver, krate) = &*resolver;
 
     // Initialize the collector.
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 7227b185f4d..e03052bcfed 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -28,6 +28,7 @@ mod debugger_visualizer;
 mod diagnostic_items;
 pub mod entry;
 mod errors;
+#[cfg(debug_assertions)]
 pub mod hir_id_validator;
 pub mod hir_stats;
 mod lang_items;
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 1c4aeefcbcf..dd18ab7d9d2 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -25,6 +25,7 @@ use rustc_hir::def::{self, *};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
 use rustc_metadata::creader::LoadedMacro;
 use rustc_middle::metadata::ModChild;
+use rustc_middle::ty::Feed;
 use rustc_middle::{bug, ty};
 use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -407,7 +408,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         // Top level use tree reuses the item's id and list stems reuse their parent
         // use tree's ids, so in both cases their visibilities are already filled.
         if nested && !list_stem {
-            self.r.feed_visibility(self.r.local_def_id(id), vis);
+            self.r.feed_visibility(self.r.feed(id), vis);
         }
 
         let mut prefix_iter = parent_prefix
@@ -632,7 +633,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         &mut self,
         fields: &[ast::FieldDef],
         ident: Ident,
-        def_id: LocalDefId,
+        feed: Feed<'tcx, LocalDefId>,
         adt_res: Res,
         adt_vis: ty::Visibility,
         adt_span: Span,
@@ -643,7 +644,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
         // Define a name in the type namespace if it is not anonymous.
         self.r.define(parent, ident, TypeNS, (adt_res, adt_vis, adt_span, expansion));
-        self.r.feed_visibility(def_id, adt_vis);
+        self.r.feed_visibility(feed, adt_vis);
+        let def_id = feed.key();
 
         // Record field names for error reporting.
         self.insert_field_def_ids(def_id, fields);
@@ -653,14 +655,15 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             match &field.ty.kind {
                 ast::TyKind::AnonStruct(id, nested_fields)
                 | ast::TyKind::AnonUnion(id, nested_fields) => {
-                    let local_def_id = self.r.local_def_id(*id);
+                    let feed = self.r.feed(*id);
+                    let local_def_id = feed.key();
                     let def_id = local_def_id.to_def_id();
                     let def_kind = self.r.tcx.def_kind(local_def_id);
                     let res = Res::Def(def_kind, def_id);
                     self.build_reduced_graph_for_struct_variant(
                         &nested_fields,
                         Ident::empty(),
-                        local_def_id,
+                        feed,
                         res,
                         // Anonymous adts inherit visibility from their parent adts.
                         adt_vis,
@@ -680,12 +683,13 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let ident = item.ident;
         let sp = item.span;
         let vis = self.resolve_visibility(&item.vis);
-        let local_def_id = self.r.local_def_id(item.id);
+        let feed = self.r.feed(item.id);
+        let local_def_id = feed.key();
         let def_id = local_def_id.to_def_id();
         let def_kind = self.r.tcx.def_kind(def_id);
         let res = Res::Def(def_kind, def_id);
 
-        self.r.feed_visibility(local_def_id, vis);
+        self.r.feed_visibility(feed, vis);
 
         match item.kind {
             ItemKind::Use(ref use_tree) => {
@@ -762,7 +766,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 self.build_reduced_graph_for_struct_variant(
                     vdata.fields(),
                     ident,
-                    local_def_id,
+                    feed,
                     res,
                     vis,
                     sp,
@@ -795,10 +799,11 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                         }
                         ret_fields.push(field_vis.to_def_id());
                     }
-                    let ctor_def_id = self.r.local_def_id(ctor_node_id);
+                    let feed = self.r.feed(ctor_node_id);
+                    let ctor_def_id = feed.key();
                     let ctor_res = self.res(ctor_def_id);
                     self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion));
-                    self.r.feed_visibility(ctor_def_id, ctor_vis);
+                    self.r.feed_visibility(feed, ctor_vis);
                     // We need the field visibility spans also for the constructor for E0603.
                     self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata.fields());
 
@@ -812,7 +817,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 self.build_reduced_graph_for_struct_variant(
                     vdata.fields(),
                     ident,
-                    local_def_id,
+                    feed,
                     res,
                     vis,
                     sp,
@@ -919,7 +924,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
     /// Constructs the reduced graph for one foreign item.
     fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) {
-        let local_def_id = self.r.local_def_id(item.id);
+        let feed = self.r.feed(item.id);
+        let local_def_id = feed.key();
         let def_id = local_def_id.to_def_id();
         let ns = match item.kind {
             ForeignItemKind::Fn(..) => ValueNS,
@@ -931,7 +937,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let expansion = self.parent_scope.expansion;
         let vis = self.resolve_visibility(&item.vis);
         self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion));
-        self.r.feed_visibility(local_def_id, vis);
+        self.r.feed_visibility(feed, vis);
     }
 
     fn build_reduced_graph_for_block(&mut self, block: &Block) {
@@ -1218,7 +1224,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
     fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> {
         let parent_scope = self.parent_scope;
         let expansion = parent_scope.expansion;
-        let def_id = self.r.local_def_id(item.id);
+        let feed = self.r.feed(item.id);
+        let def_id = feed.key();
         let (res, ident, span, macro_rules) = match &item.kind {
             ItemKind::MacroDef(def) => (self.res(def_id), item.ident, item.span, def.macro_rules),
             ItemKind::Fn(..) => match self.proc_macro_stub(item) {
@@ -1269,7 +1276,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 self.r.check_reserved_macro_name(ident, res);
                 self.insert_unused_macro(ident, def_id, item.id);
             }
-            self.r.feed_visibility(def_id, vis);
+            self.r.feed_visibility(feed, vis);
             let scope = self.r.arenas.alloc_macro_rules_scope(MacroRulesScope::Binding(
                 self.r.arenas.alloc_macro_rules_binding(MacroRulesBinding {
                     parent_macro_rules_scope: parent_scope.macro_rules,
@@ -1293,7 +1300,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 self.insert_unused_macro(ident, def_id, item.id);
             }
             self.r.define(module, ident, MacroNS, (res, vis, span, expansion));
-            self.r.feed_visibility(def_id, vis);
+            self.r.feed_visibility(feed, vis);
             self.parent_scope.macro_rules
         }
     }
@@ -1385,7 +1392,8 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         }
 
         let vis = self.resolve_visibility(&item.vis);
-        let local_def_id = self.r.local_def_id(item.id);
+        let feed = self.r.feed(item.id);
+        let local_def_id = feed.key();
         let def_id = local_def_id.to_def_id();
 
         if !(ctxt == AssocCtxt::Impl
@@ -1395,7 +1403,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             // Trait impl item visibility is inherited from its trait when not specified
             // explicitly. In that case we cannot determine it here in early resolve,
             // so we leave a hole in the visibility table to be filled later.
-            self.r.feed_visibility(local_def_id, vis);
+            self.r.feed_visibility(feed, vis);
         }
 
         if ctxt == AssocCtxt::Trait {
@@ -1469,7 +1477,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
             self.visit_invoc(sf.id);
         } else {
             let vis = self.resolve_visibility(&sf.vis);
-            self.r.feed_visibility(self.r.local_def_id(sf.id), vis);
+            self.r.feed_visibility(self.r.feed(sf.id), vis);
             visit::walk_field_def(self, sf);
         }
     }
@@ -1487,10 +1495,11 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
         let ident = variant.ident;
 
         // Define a name in the type namespace.
-        let def_id = self.r.local_def_id(variant.id);
+        let feed = self.r.feed(variant.id);
+        let def_id = feed.key();
         let vis = self.resolve_visibility(&variant.vis);
         self.r.define(parent, ident, TypeNS, (self.res(def_id), vis, variant.span, expn_id));
-        self.r.feed_visibility(def_id, vis);
+        self.r.feed_visibility(feed, vis);
 
         // If the variant is marked as non_exhaustive then lower the visibility to within the crate.
         let ctor_vis =
@@ -1502,10 +1511,11 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
         // Define a constructor name in the value namespace.
         if let Some(ctor_node_id) = variant.data.ctor_node_id() {
-            let ctor_def_id = self.r.local_def_id(ctor_node_id);
+            let feed = self.r.feed(ctor_node_id);
+            let ctor_def_id = feed.key();
             let ctor_res = self.res(ctor_def_id);
             self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id));
-            self.r.feed_visibility(ctor_def_id, ctor_vis);
+            self.r.feed_visibility(feed, ctor_vis);
         }
 
         // Record field names for error reporting.
diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs
index 13fec70e0a7..bf1ea2e2709 100644
--- a/compiler/rustc_resolve/src/check_unused.rs
+++ b/compiler/rustc_resolve/src/check_unused.rs
@@ -137,6 +137,81 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
             self.check_import_as_underscore(item, *id);
         }
     }
+
+    fn report_unused_extern_crate_items(
+        &mut self,
+        maybe_unused_extern_crates: FxHashMap<ast::NodeId, Span>,
+    ) {
+        let tcx = self.r.tcx();
+        for extern_crate in &self.extern_crate_items {
+            let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
+
+            // If the crate is fully unused, we suggest removing it altogether.
+            // We do this in any edition.
+            if warn_if_unused {
+                if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
+                    self.r.lint_buffer.buffer_lint_with_diagnostic(
+                        UNUSED_EXTERN_CRATES,
+                        extern_crate.id,
+                        span,
+                        "unused extern crate",
+                        BuiltinLintDiag::UnusedExternCrate {
+                            removal_span: extern_crate.span_with_attributes,
+                        },
+                    );
+                    continue;
+                }
+            }
+
+            // If we are not in Rust 2018 edition, then we don't make any further
+            // suggestions.
+            if !tcx.sess.at_least_rust_2018() {
+                continue;
+            }
+
+            // If the extern crate has any attributes, they may have funky
+            // semantics we can't faithfully represent using `use` (most
+            // notably `#[macro_use]`). Ignore it.
+            if extern_crate.has_attrs {
+                continue;
+            }
+
+            // If the extern crate is renamed, then we cannot suggest replacing it with a use as this
+            // would not insert the new name into the prelude, where other imports in the crate may be
+            // expecting it.
+            if extern_crate.renames {
+                continue;
+            }
+
+            // If the extern crate isn't in the extern prelude,
+            // there is no way it can be written as a `use`.
+            if !self
+                .r
+                .extern_prelude
+                .get(&extern_crate.ident)
+                .is_some_and(|entry| !entry.introduced_by_item)
+            {
+                continue;
+            }
+
+            let vis_span = extern_crate
+                .vis_span
+                .find_ancestor_inside(extern_crate.span)
+                .unwrap_or(extern_crate.vis_span);
+            let ident_span = extern_crate
+                .ident
+                .span
+                .find_ancestor_inside(extern_crate.span)
+                .unwrap_or(extern_crate.ident.span);
+            self.r.lint_buffer.buffer_lint_with_diagnostic(
+                UNUSED_EXTERN_CRATES,
+                extern_crate.id,
+                extern_crate.span,
+                "`extern crate` is not idiomatic in the new edition",
+                BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
+            );
+        }
+    }
 }
 
 impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
@@ -335,6 +410,8 @@ impl Resolver<'_, '_> {
         };
         visit::walk_crate(&mut visitor, krate);
 
+        visitor.report_unused_extern_crate_items(maybe_unused_extern_crates);
+
         for unused in visitor.unused_imports.values() {
             let mut fixes = Vec::new();
             let spans = match calc_unused_spans(unused, &unused.use_tree, unused.use_tree_id) {
@@ -416,75 +493,6 @@ impl Resolver<'_, '_> {
             );
         }
 
-        for extern_crate in visitor.extern_crate_items {
-            let warn_if_unused = !extern_crate.ident.name.as_str().starts_with('_');
-
-            // If the crate is fully unused, we suggest removing it altogether.
-            // We do this in any edition.
-            if warn_if_unused {
-                if let Some(&span) = maybe_unused_extern_crates.get(&extern_crate.id) {
-                    visitor.r.lint_buffer.buffer_lint_with_diagnostic(
-                        UNUSED_EXTERN_CRATES,
-                        extern_crate.id,
-                        span,
-                        "unused extern crate",
-                        BuiltinLintDiag::UnusedExternCrate {
-                            removal_span: extern_crate.span_with_attributes,
-                        },
-                    );
-                    continue;
-                }
-            }
-
-            // If we are not in Rust 2018 edition, then we don't make any further
-            // suggestions.
-            if !tcx.sess.at_least_rust_2018() {
-                continue;
-            }
-
-            // If the extern crate has any attributes, they may have funky
-            // semantics we can't faithfully represent using `use` (most
-            // notably `#[macro_use]`). Ignore it.
-            if extern_crate.has_attrs {
-                continue;
-            }
-
-            // If the extern crate is renamed, then we cannot suggest replacing it with a use as this
-            // would not insert the new name into the prelude, where other imports in the crate may be
-            // expecting it.
-            if extern_crate.renames {
-                continue;
-            }
-
-            // If the extern crate isn't in the extern prelude,
-            // there is no way it can be written as a `use`.
-            if !visitor
-                .r
-                .extern_prelude
-                .get(&extern_crate.ident)
-                .is_some_and(|entry| !entry.introduced_by_item)
-            {
-                continue;
-            }
-
-            let vis_span = extern_crate
-                .vis_span
-                .find_ancestor_inside(extern_crate.span)
-                .unwrap_or(extern_crate.vis_span);
-            let ident_span = extern_crate
-                .ident
-                .span
-                .find_ancestor_inside(extern_crate.span)
-                .unwrap_or(extern_crate.ident.span);
-            visitor.r.lint_buffer.buffer_lint_with_diagnostic(
-                UNUSED_EXTERN_CRATES,
-                extern_crate.id,
-                extern_crate.span,
-                "`extern crate` is not idiomatic in the new edition",
-                BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
-            );
-        }
-
         let unused_imports = visitor.unused_imports;
         let mut check_redundant_imports = FxIndexSet::default();
         for module in self.arenas.local_modules().iter() {
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 12bf462a6fd..bb3b902c0de 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -38,14 +38,16 @@ impl<'a, 'b, 'tcx> DefCollector<'a, 'b, 'tcx> {
             "create_def(node_id={:?}, def_kind={:?}, parent_def={:?})",
             node_id, def_kind, parent_def
         );
-        self.resolver.create_def(
-            parent_def,
-            node_id,
-            name,
-            def_kind,
-            self.expansion.to_expn_id(),
-            span.with_parent(None),
-        )
+        self.resolver
+            .create_def(
+                parent_def,
+                node_id,
+                name,
+                def_kind,
+                self.expansion.to_expn_id(),
+                span.with_parent(None),
+            )
+            .def_id()
     }
 
     fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: LocalDefId, f: F) {
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 9e5b2fe094f..ea08041f2aa 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -1336,9 +1336,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         let mut is_redundant = true;
-
         let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None };
-
         self.per_ns(|this, ns| {
             if is_redundant && let Ok(binding) = source_bindings[ns].get() {
                 if binding.res() == Res::Err {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 83ee1d8bdcb..455afb8de8e 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -2593,10 +2593,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                     let span = *entry.get();
                     let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
                     self.report_error(param.ident.span, err);
-                    if let GenericParamKind::Lifetime = param.kind {
-                        // Record lifetime res, so lowering knows there is something fishy.
-                        self.record_lifetime_param(param.id, LifetimeRes::Error);
-                    }
+                    let rib = match param.kind {
+                        GenericParamKind::Lifetime => {
+                            // Record lifetime res, so lowering knows there is something fishy.
+                            self.record_lifetime_param(param.id, LifetimeRes::Error);
+                            continue;
+                        }
+                        GenericParamKind::Type { .. } => &mut function_type_rib,
+                        GenericParamKind::Const { .. } => &mut function_value_rib,
+                    };
+
+                    // Taint the resolution in case of errors to prevent follow up errors in typeck
+                    self.r.record_partial_res(param.id, PartialRes::new(Res::Err));
+                    rib.bindings.insert(ident, Res::Err);
                     continue;
                 }
                 Entry::Vacant(entry) => {
@@ -3112,7 +3121,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 );
                 rustc_middle::ty::Visibility::Public
             };
-            this.r.feed_visibility(this.r.local_def_id(id), vis);
+            this.r.feed_visibility(this.r.feed(id), vis);
         };
 
         let Some(binding) = binding else {
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 5de147c2b24..ccb67ea78cf 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -52,8 +52,8 @@ use rustc_middle::metadata::ModChild;
 use rustc_middle::middle::privacy::EffectiveVisibilities;
 use rustc_middle::query::Providers;
 use rustc_middle::span_bug;
-use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt};
-use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs};
+use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt, TyCtxtFeed};
+use rustc_middle::ty::{Feed, ResolverGlobalCtxt, ResolverOutputs};
 use rustc_query_system::ich::StableHashingContext;
 use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
 use rustc_session::lint::LintBuffer;
@@ -1117,7 +1117,7 @@ pub struct Resolver<'a, 'tcx> {
 
     next_node_id: NodeId,
 
-    node_id_to_def_id: NodeMap<LocalDefId>,
+    node_id_to_def_id: NodeMap<Feed<'tcx, LocalDefId>>,
     def_id_to_node_id: IndexVec<LocalDefId, ast::NodeId>,
 
     /// Indices of unnamed struct or variant fields with unresolved attributes.
@@ -1233,11 +1233,19 @@ impl<'a, 'tcx> AsMut<Resolver<'a, 'tcx>> for Resolver<'a, 'tcx> {
 
 impl<'tcx> Resolver<'_, 'tcx> {
     fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> {
-        self.node_id_to_def_id.get(&node).copied()
+        self.opt_feed(node).map(|f| f.key())
     }
 
     fn local_def_id(&self, node: NodeId) -> LocalDefId {
-        self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
+        self.feed(node).key()
+    }
+
+    fn opt_feed(&self, node: NodeId) -> Option<Feed<'tcx, LocalDefId>> {
+        self.node_id_to_def_id.get(&node).copied()
+    }
+
+    fn feed(&self, node: NodeId) -> Feed<'tcx, LocalDefId> {
+        self.opt_feed(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
     }
 
     fn local_def_kind(&self, node: NodeId) -> DefKind {
@@ -1253,18 +1261,19 @@ impl<'tcx> Resolver<'_, 'tcx> {
         def_kind: DefKind,
         expn_id: ExpnId,
         span: Span,
-    ) -> LocalDefId {
+    ) -> TyCtxtFeed<'tcx, LocalDefId> {
         let data = def_kind.def_path_data(name);
         assert!(
             !self.node_id_to_def_id.contains_key(&node_id),
             "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
             node_id,
             data,
-            self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id]),
+            self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id].key()),
         );
 
         // FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()`
-        let def_id = self.tcx.create_def(parent, name, def_kind).def_id();
+        let feed = self.tcx.create_def(parent, name, def_kind);
+        let def_id = feed.def_id();
 
         // Create the definition.
         if expn_id != ExpnId::root() {
@@ -1281,11 +1290,11 @@ impl<'tcx> Resolver<'_, 'tcx> {
         // we don't need a mapping from `NodeId` to `LocalDefId`.
         if node_id != ast::DUMMY_NODE_ID {
             debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);
-            self.node_id_to_def_id.insert(node_id, def_id);
+            self.node_id_to_def_id.insert(node_id, feed.downgrade());
         }
         assert_eq!(self.def_id_to_node_id.push(node_id), def_id);
 
-        def_id
+        feed
     }
 
     fn item_generics_num_lifetimes(&self, def_id: DefId) -> usize {
@@ -1333,7 +1342,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let mut def_id_to_node_id = IndexVec::default();
         assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID);
         let mut node_id_to_def_id = NodeMap::default();
-        node_id_to_def_id.insert(CRATE_NODE_ID, CRATE_DEF_ID);
+        let crate_feed = tcx.create_local_crate_def_id(crate_span);
+
+        crate_feed.def_kind(DefKind::Mod);
+        let crate_feed = crate_feed.downgrade();
+        node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed);
 
         let mut invocation_parents = FxHashMap::default();
         invocation_parents.insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential));
@@ -1484,7 +1497,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         let root_parent_scope = ParentScope::module(graph_root, &resolver);
         resolver.invocation_parent_scopes.insert(LocalExpnId::ROOT, root_parent_scope);
-        resolver.feed_visibility(CRATE_DEF_ID, ty::Visibility::Public);
+        resolver.feed_visibility(crate_feed, ty::Visibility::Public);
 
         resolver
     }
@@ -1532,9 +1545,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         Default::default()
     }
 
-    fn feed_visibility(&mut self, def_id: LocalDefId, vis: ty::Visibility) {
-        self.tcx.feed_local_def_id(def_id).visibility(vis.to_def_id());
-        self.visibilities_for_hashing.push((def_id, vis));
+    fn feed_visibility(&mut self, feed: Feed<'tcx, LocalDefId>, vis: ty::Visibility) {
+        let feed = feed.upgrade(self.tcx);
+        feed.visibility(vis.to_def_id());
+        self.visibilities_for_hashing.push((feed.def_id(), vis));
     }
 
     pub fn into_outputs(self) -> ResolverOutputs {
@@ -1547,12 +1561,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let confused_type_with_std_module = self.confused_type_with_std_module;
         let effective_visibilities = self.effective_visibilities;
 
-        self.tcx.feed_local_crate().stripped_cfg_items(self.tcx.arena.alloc_from_iter(
-            self.stripped_cfg_items.into_iter().filter_map(|item| {
-                let parent_module = self.node_id_to_def_id.get(&item.parent_module)?.to_def_id();
-                Some(StrippedCfgItem { parent_module, name: item.name, cfg: item.cfg })
-            }),
-        ));
+        let stripped_cfg_items = Steal::new(
+            self.stripped_cfg_items
+                .into_iter()
+                .filter_map(|item| {
+                    let parent_module =
+                        self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id();
+                    Some(StrippedCfgItem { parent_module, name: item.name, cfg: item.cfg })
+                })
+                .collect(),
+        );
 
         let global_ctxt = ResolverGlobalCtxt {
             expn_that_defined,
@@ -1569,6 +1587,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             doc_link_resolutions: self.doc_link_resolutions,
             doc_link_traits_in_scope: self.doc_link_traits_in_scope,
             all_macro_rules: self.all_macro_rules,
+            stripped_cfg_items,
         };
         let ast_lowering = ty::ResolverAstLowering {
             legacy_const_generic_args: self.legacy_const_generic_args,
@@ -1578,7 +1597,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             lifetimes_res_map: self.lifetimes_res_map,
             extra_lifetime_params_map: self.extra_lifetime_params_map,
             next_node_id: self.next_node_id,
-            node_id_to_def_id: self.node_id_to_def_id,
+            node_id_to_def_id: self
+                .node_id_to_def_id
+                .into_items()
+                .map(|(k, f)| (k, f.key()))
+                .collect(),
             def_id_to_node_id: self.def_id_to_node_id,
             trait_map: self.trait_map,
             lifetime_elision_allowed: self.lifetime_elision_allowed,
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 66177d551ba..f4967b94e93 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -814,7 +814,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
                     }
                 }
             },
-            "aarch64" => {
+            "aarch64" | "arm64ec" => {
                 let kind = if cx.target_spec().is_like_osx {
                     aarch64::AbiKind::DarwinPCS
                 } else if cx.target_spec().is_like_windows {
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 3fda1e1833c..a68dae0ade3 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1564,6 +1564,7 @@ supported_targets! {
 
     ("aarch64-pc-windows-msvc", aarch64_pc_windows_msvc),
     ("aarch64-uwp-windows-msvc", aarch64_uwp_windows_msvc),
+    ("arm64ec-pc-windows-msvc", arm64ec_pc_windows_msvc),
     ("x86_64-pc-windows-msvc", x86_64_pc_windows_msvc),
     ("x86_64-uwp-windows-msvc", x86_64_uwp_windows_msvc),
     ("x86_64-win7-windows-msvc", x86_64_win7_windows_msvc),
diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
new file mode 100644
index 00000000000..f1af4d9a80e
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs
@@ -0,0 +1,21 @@
+use crate::spec::{add_link_args, base, LinkerFlavor, Lld, Target};
+
+pub fn target() -> Target {
+    let mut base = base::windows_msvc::opts();
+    base.max_atomic_width = Some(128);
+    base.features = "+v8a,+neon,+fp-armv8".into();
+    add_link_args(
+        &mut base.late_link_args,
+        LinkerFlavor::Msvc(Lld::No),
+        &["/machine:arm64ec", "softintrin.lib"],
+    );
+
+    Target {
+        llvm_target: "arm64ec-pc-windows-msvc".into(),
+        description: None,
+        pointer_width: 64,
+        data_layout: "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128".into(),
+        arch: "arm64ec".into(),
+        options: base,
+    }
+}
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 2b7ac68c21d..c003982278e 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -377,10 +377,12 @@ const LOONGARCH_ALLOWED_FEATURES: &[(&str, Stability)] = &[
     // tidy-alphabetical-start
     ("d", Unstable(sym::loongarch_target_feature)),
     ("f", Unstable(sym::loongarch_target_feature)),
+    ("frecipe", Unstable(sym::loongarch_target_feature)),
     ("lasx", Unstable(sym::loongarch_target_feature)),
     ("lbt", Unstable(sym::loongarch_target_feature)),
     ("lsx", Unstable(sym::loongarch_target_feature)),
     ("lvz", Unstable(sym::loongarch_target_feature)),
+    ("relax", Unstable(sym::loongarch_target_feature)),
     ("ual", Unstable(sym::loongarch_target_feature)),
     // tidy-alphabetical-end
 ];
@@ -409,7 +411,7 @@ impl super::spec::Target {
     pub fn supported_target_features(&self) -> &'static [(&'static str, Stability)] {
         match &*self.arch {
             "arm" => ARM_ALLOWED_FEATURES,
-            "aarch64" => AARCH64_ALLOWED_FEATURES,
+            "aarch64" | "arm64ec" => AARCH64_ALLOWED_FEATURES,
             "x86" | "x86_64" => X86_ALLOWED_FEATURES,
             "hexagon" => HEXAGON_ALLOWED_FEATURES,
             "mips" | "mips32r6" | "mips64" | "mips64r6" => MIPS_ALLOWED_FEATURES,
@@ -425,7 +427,7 @@ impl super::spec::Target {
 
     pub fn tied_target_features(&self) -> &'static [&'static [&'static str]] {
         match &*self.arch {
-            "aarch64" => AARCH64_TIED_FEATURES,
+            "aarch64" | "arm64ec" => AARCH64_TIED_FEATURES,
             _ => &[],
         }
     }
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 248985715c2..ed839d14dc7 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -166,13 +166,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
         let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
         if !drcx.args_may_unify(
             goal.predicate.trait_ref(tcx).args,
-            impl_trait_header.skip_binder().trait_ref.args,
+            impl_trait_header.trait_ref.skip_binder().args,
         ) {
             return Err(NoSolution);
         }
 
         // We have to ignore negative impls when projecting.
-        let impl_polarity = impl_trait_header.skip_binder().polarity;
+        let impl_polarity = impl_trait_header.polarity;
         match impl_polarity {
             ty::ImplPolarity::Negative => return Err(NoSolution),
             ty::ImplPolarity::Reservation => {
@@ -183,7 +183,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
         ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
             let impl_args = ecx.fresh_args_for_item(impl_def_id);
-            let impl_trait_ref = impl_trait_header.instantiate(tcx, impl_args).trait_ref;
+            let impl_trait_ref = impl_trait_header.trait_ref.instantiate(tcx, impl_args);
 
             ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
 
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index 80198ba39f9..281f5cc5685 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -47,14 +47,14 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
         let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup };
         if !drcx.args_may_unify(
             goal.predicate.trait_ref.args,
-            impl_trait_header.skip_binder().trait_ref.args,
+            impl_trait_header.trait_ref.skip_binder().args,
         ) {
             return Err(NoSolution);
         }
 
         // An upper bound of the certainty of this goal, used to lower the certainty
         // of reservation impl to ambiguous during coherence.
-        let impl_polarity = impl_trait_header.skip_binder().polarity;
+        let impl_polarity = impl_trait_header.polarity;
         let maximal_certainty = match impl_polarity {
             ty::ImplPolarity::Positive | ty::ImplPolarity::Negative => {
                 match impl_polarity == goal.predicate.polarity {
@@ -70,7 +70,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
 
         ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
             let impl_args = ecx.fresh_args_for_item(impl_def_id);
-            let impl_trait_ref = impl_trait_header.instantiate(tcx, impl_args).trait_ref;
+            let impl_trait_ref = impl_trait_header.trait_ref.instantiate(tcx, impl_args);
 
             ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
             let where_clause_bounds = tcx
@@ -102,7 +102,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
             if trait_clause.def_id() == goal.predicate.def_id()
                 && trait_clause.polarity() == goal.predicate.polarity
             {
-                // FIXME: Constness
                 ecx.probe_misc_candidate("assumption").enter(|ecx| {
                     let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
                     ecx.eq(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 7a930937255..ac2b738d3b6 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -1431,45 +1431,64 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
 
 #[extension(pub(super) trait InferCtxtPrivExt<'tcx>)]
 impl<'tcx> TypeErrCtxt<'_, 'tcx> {
+    fn can_match_trait(
+        &self,
+        goal: ty::TraitPredicate<'tcx>,
+        assumption: ty::PolyTraitPredicate<'tcx>,
+    ) -> bool {
+        if goal.polarity != assumption.polarity() {
+            return false;
+        }
+
+        let trait_goal = goal.trait_ref;
+        let trait_assumption = self.instantiate_binder_with_fresh_vars(
+            DUMMY_SP,
+            infer::BoundRegionConversionTime::HigherRankedType,
+            assumption.to_poly_trait_ref(),
+        );
+
+        self.can_eq(ty::ParamEnv::empty(), trait_goal, trait_assumption)
+    }
+
+    fn can_match_projection(
+        &self,
+        goal: ty::ProjectionPredicate<'tcx>,
+        assumption: ty::PolyProjectionPredicate<'tcx>,
+    ) -> bool {
+        let assumption = self.instantiate_binder_with_fresh_vars(
+            DUMMY_SP,
+            infer::BoundRegionConversionTime::HigherRankedType,
+            assumption,
+        );
+
+        let param_env = ty::ParamEnv::empty();
+        self.can_eq(param_env, goal.projection_ty, assumption.projection_ty)
+            && self.can_eq(param_env, goal.term, assumption.term)
+    }
+
     // returns if `cond` not occurring implies that `error` does not occur - i.e., that
     // `error` occurring implies that `cond` occurs.
+    #[instrument(level = "debug", skip(self), ret)]
     fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool {
         if cond == error {
             return true;
         }
 
-        // FIXME: It should be possible to deal with `ForAll` in a cleaner way.
-        let bound_error = error.kind();
-        let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) {
-            (
-                ty::PredicateKind::Clause(ty::ClauseKind::Trait(..)),
-                ty::PredicateKind::Clause(ty::ClauseKind::Trait(error)),
-            ) => (cond, bound_error.rebind(error)),
-            _ => {
-                // FIXME: make this work in other cases too.
-                return false;
-            }
-        };
-
-        for pred in elaborate(self.tcx, std::iter::once(cond)) {
-            let bound_predicate = pred.kind();
-            if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(implication)) =
-                bound_predicate.skip_binder()
-            {
-                let error = error.to_poly_trait_ref();
-                let implication = bound_predicate.rebind(implication.trait_ref);
-                // FIXME: I'm just not taking associated types at all here.
-                // Eventually I'll need to implement param-env-aware
-                // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
-                let param_env = ty::ParamEnv::empty();
-                if self.can_sub(param_env, error, implication) {
-                    debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication);
-                    return true;
-                }
-            }
+        if let Some(error) = error.to_opt_poly_trait_pred() {
+            self.enter_forall(error, |error| {
+                elaborate(self.tcx, std::iter::once(cond))
+                    .filter_map(|implied| implied.to_opt_poly_trait_pred())
+                    .any(|implied| self.can_match_trait(error, implied))
+            })
+        } else if let Some(error) = error.to_opt_poly_projection_pred() {
+            self.enter_forall(error, |error| {
+                elaborate(self.tcx, std::iter::once(cond))
+                    .filter_map(|implied| implied.to_opt_poly_projection_pred())
+                    .any(|implied| self.can_match_projection(error, implied))
+            })
+        } else {
+            false
         }
-
-        false
     }
 
     #[instrument(skip(self), level = "debug")]
@@ -1888,13 +1907,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             .tcx
             .all_impls(trait_pred.def_id())
             .filter_map(|def_id| {
-                let imp = self.tcx.impl_trait_header(def_id).unwrap().skip_binder();
+                let imp = self.tcx.impl_trait_header(def_id).unwrap();
                 if imp.polarity == ty::ImplPolarity::Negative
                     || !self.tcx.is_user_visible_dep(def_id.krate)
                 {
                     return None;
                 }
-                let imp = imp.trait_ref;
+                let imp = imp.trait_ref.skip_binder();
 
                 self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false).map(
                     |similarity| ImplCandidate { trait_ref: imp, similarity, impl_def_id: def_id },
@@ -2078,12 +2097,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 .all_impls(def_id)
                 // Ignore automatically derived impls and `!Trait` impls.
                 .filter_map(|def_id| self.tcx.impl_trait_header(def_id))
-                .map(ty::EarlyBinder::instantiate_identity)
-                .filter(|header| {
-                    header.polarity != ty::ImplPolarity::Negative
-                        || self.tcx.is_automatically_derived(def_id)
+                .filter_map(|header| {
+                    (header.polarity != ty::ImplPolarity::Negative
+                        || self.tcx.is_automatically_derived(def_id))
+                    .then(|| header.trait_ref.instantiate_identity())
                 })
-                .map(|header| header.trait_ref)
                 .filter(|trait_ref| {
                     let self_ty = trait_ref.self_ty();
                     // Avoid mentioning type parameters.
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 39f4ceda9f1..66f740b761d 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -562,7 +562,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // and so forth that we need to.
                 let impl_trait_header = self.tcx().impl_trait_header(impl_def_id).unwrap();
                 if !drcx
-                    .args_may_unify(obligation_args, impl_trait_header.skip_binder().trait_ref.args)
+                    .args_may_unify(obligation_args, impl_trait_header.trait_ref.skip_binder().args)
                 {
                     return;
                 }
@@ -577,7 +577,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 if self.reject_fn_ptr_impls(
                     impl_def_id,
                     obligation,
-                    impl_trait_header.skip_binder().trait_ref.self_ty(),
+                    impl_trait_header.trait_ref.skip_binder().self_ty(),
                 ) {
                     return;
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 7dbea0cdb90..a6bd1ba9c3f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -42,7 +42,7 @@ use rustc_middle::ty::_match::MatchAgainstFreshVars;
 use rustc_middle::ty::abstract_const::NotConstEvaluatable;
 use rustc_middle::ty::relate::TypeRelation;
 use rustc_middle::ty::GenericArgsRef;
-use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
+use rustc_middle::ty::{self, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
 use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_span::symbol::sym;
 use rustc_span::Symbol;
@@ -2441,7 +2441,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
     fn match_impl(
         &mut self,
         impl_def_id: DefId,
-        impl_trait_header: EarlyBinder<ty::ImplTraitHeader<'tcx>>,
+        impl_trait_header: ty::ImplTraitHeader<'tcx>,
         obligation: &PolyTraitObligation<'tcx>,
     ) -> Result<Normalized<'tcx, GenericArgsRef<'tcx>>, ()> {
         let placeholder_obligation =
@@ -2450,8 +2450,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
 
         let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id);
 
-        let impl_trait_header = impl_trait_header.instantiate(self.tcx(), impl_args);
-        if impl_trait_header.references_error() {
+        let trait_ref = impl_trait_header.trait_ref.instantiate(self.tcx(), impl_args);
+        if trait_ref.references_error() {
             return Err(());
         }
 
@@ -2464,7 +2464,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                     obligation.param_env,
                     obligation.cause.clone(),
                     obligation.recursion_depth + 1,
-                    impl_trait_header.trait_ref,
+                    trait_ref,
                 )
             });
 
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index f5bc6c3ad2c..27dd8f26489 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -169,7 +169,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
         }
     }
 
-    let impl1_trait_header = tcx.impl_trait_header(impl1_def_id).unwrap().instantiate_identity();
+    let impl1_trait_header = tcx.impl_trait_header(impl1_def_id).unwrap();
 
     // We determine whether there's a subset relationship by:
     //
@@ -198,7 +198,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
     fulfill_implication(
         &infcx,
         penv,
-        impl1_trait_header.trait_ref,
+        impl1_trait_header.trait_ref.instantiate_identity(),
         impl1_def_id,
         impl2_def_id,
         |_, _| ObligationCause::dummy(),
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 6e01e0b76aa..3f433a9e919 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -127,7 +127,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
         }
 
         // Get components of trait alias.
-        let predicates = tcx.implied_predicates_of(trait_ref.def_id());
+        let predicates = tcx.super_predicates_of(trait_ref.def_id());
         debug!(?predicates);
 
         let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 15059bc6613..b09a803e856 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -223,60 +223,87 @@ enum Elaborate {
     None,
 }
 
+/// Points the cause span of a super predicate at the relevant associated type.
+///
+/// Given a trait impl item:
+///
+/// ```ignore (incomplete)
+/// impl TargetTrait for TargetType {
+///    type Assoc = SomeType;
+/// }
+/// ```
+///
+/// And a super predicate of `TargetTrait` that has any of the following forms:
+///
+/// 1. `<OtherType as OtherTrait>::Assoc == <TargetType as TargetTrait>::Assoc`
+/// 2. `<<TargetType as TargetTrait>::Assoc as OtherTrait>::Assoc == OtherType`
+/// 3. `<TargetType as TargetTrait>::Assoc: OtherTrait`
+///
+/// Replace the span of the cause with the span of the associated item:
+///
+/// ```ignore (incomplete)
+/// impl TargetTrait for TargetType {
+///     type Assoc = SomeType;
+/// //               ^^^^^^^^ this span
+/// }
+/// ```
+///
+/// Note that bounds that can be expressed as associated item bounds are **not**
+/// super predicates. This means that form 2 and 3 from above are only relevant if
+/// the [`GenericArgsRef`] of the projection type are not its identity arguments.
 fn extend_cause_with_original_assoc_item_obligation<'tcx>(
     tcx: TyCtxt<'tcx>,
-    trait_ref: ty::TraitRef<'tcx>,
     item: Option<&hir::Item<'tcx>>,
     cause: &mut traits::ObligationCause<'tcx>,
     pred: ty::Predicate<'tcx>,
 ) {
-    debug!(
-        "extended_cause_with_original_assoc_item_obligation {:?} {:?} {:?} {:?}",
-        trait_ref, item, cause, pred
-    );
+    debug!(?item, ?cause, ?pred, "extended_cause_with_original_assoc_item_obligation");
     let (items, impl_def_id) = match item {
         Some(hir::Item { kind: hir::ItemKind::Impl(impl_), owner_id, .. }) => {
             (impl_.items, *owner_id)
         }
         _ => return,
     };
-    let fix_span =
-        |impl_item_ref: &hir::ImplItemRef| match tcx.hir().impl_item(impl_item_ref.id).kind {
-            hir::ImplItemKind::Const(ty, _) | hir::ImplItemKind::Type(ty) => ty.span,
-            _ => impl_item_ref.span,
-        };
+
+    let ty_to_impl_span = |ty: Ty<'_>| {
+        if let ty::Alias(ty::Projection, projection_ty) = ty.kind()
+            && let Some(&impl_item_id) =
+                tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
+            && let Some(impl_item) =
+                items.iter().find(|item| item.id.owner_id.to_def_id() == impl_item_id)
+        {
+            Some(tcx.hir().impl_item(impl_item.id).expect_type().span)
+        } else {
+            None
+        }
+    };
 
     // It is fine to skip the binder as we don't care about regions here.
     match pred.kind().skip_binder() {
         ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj)) => {
-            // The obligation comes not from the current `impl` nor the `trait` being implemented,
-            // but rather from a "second order" obligation, where an associated type has a
-            // projection coming from another associated type. See
-            // `tests/ui/associated-types/point-at-type-on-obligation-failure.rs` and
-            // `traits-assoc-type-in-supertrait-bad.rs`.
-            if let Some(ty::Alias(ty::Projection, projection_ty)) =
-                proj.term.ty().map(|ty| ty.kind())
-                && let Some(&impl_item_id) =
-                    tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.def_id)
-                && let Some(impl_item_span) = items
-                    .iter()
-                    .find(|item| item.id.owner_id.to_def_id() == impl_item_id)
-                    .map(fix_span)
+            // Form 1: The obligation comes not from the current `impl` nor the `trait` being
+            // implemented, but rather from a "second order" obligation, where an associated
+            // type has a projection coming from another associated type.
+            // See `tests/ui/traits/assoc-type-in-superbad.rs` for an example.
+            if let Some(term_ty) = proj.term.ty()
+                && let Some(impl_item_span) = ty_to_impl_span(term_ty)
             {
                 cause.span = impl_item_span;
             }
+
+            // Form 2: A projection obligation for an associated item failed to be met.
+            // We overwrite the span from above to ensure that a bound like
+            // `Self::Assoc1: Trait<OtherAssoc = Self::Assoc2>` gets the same
+            // span for both obligations that it is lowered to.
+            if let Some(impl_item_span) = ty_to_impl_span(proj.self_ty()) {
+                cause.span = impl_item_span;
+            }
         }
+
         ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
-            // An associated item obligation born out of the `trait` failed to be met. An example
-            // can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
+            // Form 3: A trait obligation for an associated item failed to be met.
             debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
-            if let ty::Alias(ty::Projection, ty::AliasTy { def_id, .. }) = *pred.self_ty().kind()
-                && let Some(&impl_item_id) = tcx.impl_item_implementor_ids(impl_def_id).get(&def_id)
-                && let Some(impl_item_span) = items
-                    .iter()
-                    .find(|item| item.id.owner_id.to_def_id() == impl_item_id)
-                    .map(fix_span)
-            {
+            if let Some(impl_item_span) = ty_to_impl_span(pred.self_ty()) {
                 cause.span = impl_item_span;
             }
         }
@@ -355,9 +382,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                     traits::ObligationCauseCode::DerivedObligation,
                 );
             }
-            extend_cause_with_original_assoc_item_obligation(
-                tcx, trait_ref, item, &mut cause, predicate,
-            );
+            extend_cause_with_original_assoc_item_obligation(tcx, item, &mut cause, predicate);
             traits::Obligation::with_depth(tcx, cause, depth, param_env, predicate)
         };
 
diff --git a/compiler/rustc_traits/src/codegen.rs b/compiler/rustc_traits/src/codegen.rs
index f3fae63ecc7..b2b5c6cd909 100644
--- a/compiler/rustc_traits/src/codegen.rs
+++ b/compiler/rustc_traits/src/codegen.rs
@@ -6,7 +6,7 @@
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{FulfillmentErrorCode, TraitEngineExt as _};
 use rustc_middle::traits::CodegenObligationError;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::{
     ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
@@ -72,6 +72,13 @@ pub fn codegen_select_candidate<'tcx>(
 
     let impl_source = infcx.resolve_vars_if_possible(impl_source);
     let impl_source = infcx.tcx.erase_regions(impl_source);
+    if impl_source.has_infer() {
+        // Unused lifetimes on an impl get replaced with inference vars, but never resolved,
+        // causing the return value of a query to contain inference vars. We do not have a concept
+        // for this and will in fact ICE in stable hashing of the return value. So bail out instead.
+        infcx.tcx.dcx().has_errors().unwrap();
+        return Err(CodegenObligationError::FulfillmentError);
+    }
 
     Ok(&*tcx.arena.alloc(impl_source))
 }
diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs
index db37bec4b82..26d3370469a 100644
--- a/compiler/rustc_ty_utils/src/assoc.rs
+++ b/compiler/rustc_ty_utils/src/assoc.rs
@@ -4,7 +4,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, GenericArgs, ImplTraitInTraitData, Ty, TyCtxt};
+use rustc_middle::ty::{self, ImplTraitInTraitData, TyCtxt};
 use rustc_span::symbol::kw;
 
 pub(crate) fn provide(providers: &mut Providers) {
@@ -284,48 +284,8 @@ fn associated_type_for_impl_trait_in_trait(
     // Copy defaultness of the containing function.
     trait_assoc_ty.defaultness(tcx.defaultness(fn_def_id));
 
-    // Copy type_of of the opaque.
-    trait_assoc_ty.type_of(ty::EarlyBinder::bind(Ty::new_opaque(
-        tcx,
-        opaque_ty_def_id.to_def_id(),
-        GenericArgs::identity_for_item(tcx, opaque_ty_def_id),
-    )));
-
     trait_assoc_ty.is_type_alias_impl_trait(false);
 
-    // Copy generics_of of the opaque type item but the trait is the parent.
-    trait_assoc_ty.generics_of({
-        let opaque_ty_generics = tcx.generics_of(opaque_ty_def_id);
-        let opaque_ty_parent_count = opaque_ty_generics.parent_count;
-        let mut params = opaque_ty_generics.params.clone();
-
-        let parent_generics = tcx.generics_of(trait_def_id);
-        let parent_count = parent_generics.parent_count + parent_generics.params.len();
-
-        let mut trait_fn_params = tcx.generics_of(fn_def_id).params.clone();
-
-        for param in &mut params {
-            param.index = param.index + parent_count as u32 + trait_fn_params.len() as u32
-                - opaque_ty_parent_count as u32;
-        }
-
-        trait_fn_params.extend(params);
-        params = trait_fn_params;
-
-        let param_def_id_to_index =
-            params.iter().map(|param| (param.def_id, param.index)).collect();
-
-        ty::Generics {
-            parent: Some(trait_def_id.to_def_id()),
-            parent_count,
-            params,
-            param_def_id_to_index,
-            has_self: opaque_ty_generics.has_self,
-            has_late_bound_regions: opaque_ty_generics.has_late_bound_regions,
-            host_effect_index: parent_generics.host_effect_index,
-        }
-    });
-
     // There are no inferred outlives for the synthesized associated type.
     trait_assoc_ty.inferred_outlives_of(&[]);
 
@@ -382,8 +342,9 @@ fn associated_type_for_impl_trait_in_impl(
     impl_assoc_ty.defaultness(tcx.defaultness(impl_fn_def_id));
 
     // Copy generics_of the trait's associated item but the impl as the parent.
-    // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty) resolves to the trait instead of the impl
-    // generics.
+    // FIXME: This may be detrimental to diagnostics, as we resolve the early-bound vars
+    // here to paramswhose parent are items in the trait. We could synthesize new params
+    // here, but it seems overkill.
     impl_assoc_ty.generics_of({
         let trait_assoc_generics = tcx.generics_of(trait_assoc_def_id);
         let trait_assoc_parent_count = trait_assoc_generics.parent_count;
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 48d9a5e27b7..2b6b91672c3 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -255,10 +255,9 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<'
 
     let impl_ = tcx
         .impl_trait_header(def_id)
-        .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id))
-        .skip_binder();
+        .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id));
 
-    let trait_ref = impl_.trait_ref;
+    let trait_ref = impl_.trait_ref.skip_binder();
     debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref);
 
     let is_marker_like = impl_.polarity == ty::ImplPolarity::Positive
diff --git a/config.example.toml b/config.example.toml
index d12ed052fe4..c1939933850 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -300,6 +300,10 @@
 # This is only useful for verifying that rustc generates reproducible builds.
 #full-bootstrap = false
 
+# Set the bootstrap/download cache path. It is useful when building rust
+# repeatedly in a CI invironment.
+# bootstrap-cache-path = /shared/cache
+
 # Enable a build of the extended Rust tool set which is not only the compiler
 # but also tools such as Cargo. This will also produce "combined installers"
 # which are used to install Rust and Cargo together.
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index dd8d6f6c7e6..4d9694d4beb 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -259,7 +259,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         } else {
             // We could use Layout::array here which ensures the absence of isize and usize overflows
             // and could hypothetically handle differences between stride and size, but this memory
-            // has already been allocated so we know it can't overflow and currently rust does not
+            // has already been allocated so we know it can't overflow and currently Rust does not
             // support such types. So we can do better by skipping some checks and avoid an unwrap.
             const { assert!(mem::size_of::<T>() % mem::align_of::<T>() == 0) };
             unsafe {
diff --git a/library/core/src/arch.rs b/library/core/src/arch.rs
index 8817ec0777b..31d6bc36fc8 100644
--- a/library/core/src/arch.rs
+++ b/library/core/src/arch.rs
@@ -6,10 +6,10 @@ pub use crate::core_arch::arch::*;
 
 /// Inline assembly.
 ///
-/// Refer to [rust by example] for a usage guide and the [reference] for
+/// Refer to [Rust By Example] for a usage guide and the [reference] for
 /// detailed information about the syntax and available options.
 ///
-/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
+/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
 /// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
 #[stable(feature = "asm", since = "1.59.0")]
 #[rustc_builtin_macro]
@@ -19,10 +19,10 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
 
 /// Module-level inline assembly.
 ///
-/// Refer to [rust by example] for a usage guide and the [reference] for
+/// Refer to [Rust By Example] for a usage guide and the [reference] for
 /// detailed information about the syntax and available options.
 ///
-/// [rust by example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
+/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
 /// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
 #[stable(feature = "global_asm", since = "1.59.0")]
 #[rustc_builtin_macro]
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 42663ff2b53..8b5b48c59c2 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -360,6 +360,7 @@ where
     }
 }
 
+/// Implements comparison of arrays [lexicographically](Ord#lexicographical-comparison).
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialOrd, const N: usize> PartialOrd for [T; N] {
     #[inline]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 7b735d48bdf..0f7885769c2 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -202,6 +202,7 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(diagnostic_namespace))]
 #![cfg_attr(bootstrap, feature(platform_intrinsics))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
@@ -223,7 +224,6 @@
 #![feature(const_trait_impl)]
 #![feature(decl_macro)]
 #![feature(deprecated_suggestion)]
-#![feature(diagnostic_namespace)]
 #![feature(doc_cfg)]
 #![feature(doc_cfg_hide)]
 #![feature(doc_notable_trait)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 643968c35e8..0ee7e190e3d 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1481,7 +1481,7 @@ pub(crate) mod builtin {
     /// script](https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script).
     ///
     /// When using the `include` macro to include stretches of documentation, remember that the
-    /// included file still needs to be a valid rust syntax. It is also possible to
+    /// included file still needs to be a valid Rust syntax. It is also possible to
     /// use the [`include_str`] macro as `#![doc = include_str!("...")]` (at the module level) or
     /// `#[doc = include_str!("...")]` (at the item level) to include documentation from a plain
     /// text or markdown file.
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index 3eea065eef6..3508b0c7f23 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -3,7 +3,7 @@ use crate::num::NonZero;
 use crate::{cmp, fmt, hash, mem, num};
 
 /// A type storing a `usize` which is a power of two, and thus
-/// represents a possible alignment in the rust abstract machine.
+/// represents a possible alignment in the Rust abstract machine.
 ///
 /// Note that particularly large alignments, while representable in this type,
 /// are likely not to be supported by actual allocators and linkers.
diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs
index e8b0010ba15..5bee4d55135 100644
--- a/library/core/src/slice/cmp.rs
+++ b/library/core/src/slice/cmp.rs
@@ -24,7 +24,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Eq> Eq for [T] {}
 
-/// Implements comparison of vectors [lexicographically](Ord#lexicographical-comparison).
+/// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Ord for [T] {
     fn cmp(&self, other: &[T]) -> Ordering {
@@ -32,7 +32,7 @@ impl<T: Ord> Ord for [T] {
     }
 }
 
-/// Implements comparison of vectors [lexicographically](Ord#lexicographical-comparison).
+/// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialOrd> PartialOrd for [T] {
     fn partial_cmp(&self, other: &[T]) -> Option<Ordering> {
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index aaedbed0d55..643b7971a66 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -23,7 +23,7 @@ use crate::slice;
     issue = "none",
     reason = "exposed from core to be reused in std; use the memchr crate"
 )]
-/// Pure rust memchr implementation, taken from rust-memchr
+/// Pure Rust memchr implementation, taken from rust-memchr
 pub mod memchr;
 
 #[unstable(
diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs
index fa02dd52e00..e8170c13ed2 100644
--- a/library/core/src/sync/exclusive.rs
+++ b/library/core/src/sync/exclusive.rs
@@ -19,7 +19,7 @@ use core::task::{Context, Poll};
 ///
 /// Certain constructs like [`Future`]s can only be used with _exclusive_ access,
 /// and are often `Send` but not `Sync`, so `Exclusive` can be used as hint to the
-/// rust compiler that something is `Sync` in practice.
+/// Rust compiler that something is `Sync` in practice.
 ///
 /// ## Examples
 /// Using a non-`Sync` future prevents the wrapping struct from being `Sync`
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index e44da8e637e..8927e9a47fa 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -157,7 +157,7 @@ impl OsString {
     /// # Safety
     ///
     /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
-    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version
+    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same Rust version
     /// built for the same target platform.  For example, reconstructing an `OsString` from bytes sent
     /// over the network or stored in a file will likely violate these safety rules.
     ///
@@ -213,7 +213,7 @@ impl OsString {
     /// ASCII.
     ///
     /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should
-    /// be treated as opaque and only comparable within the same rust version built for the same
+    /// be treated as opaque and only comparable within the same Rust version built for the same
     /// target platform.  For example, sending the bytes over the network or storing it in a file
     /// will likely result in incompatible data.  See [`OsString`] for more encoding details
     /// and [`std::ffi`] for platform-specific, specified conversions.
@@ -747,7 +747,7 @@ impl OsStr {
     /// # Safety
     ///
     /// As the encoding is unspecified, callers must pass in bytes that originated as a mixture of
-    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same rust version
+    /// validated UTF-8 and bytes from [`OsStr::as_encoded_bytes`] from within the same Rust version
     /// built for the same target platform.  For example, reconstructing an `OsStr` from bytes sent
     /// over the network or stored in a file will likely violate these safety rules.
     ///
@@ -955,7 +955,7 @@ impl OsStr {
     /// ASCII.
     ///
     /// Note: As the encoding is unspecified, any sub-slice of bytes that is not valid UTF-8 should
-    /// be treated as opaque and only comparable within the same rust version built for the same
+    /// be treated as opaque and only comparable within the same Rust version built for the same
     /// target platform.  For example, sending the slice over the network or storing it in a file
     /// will likely result in incompatible byte slices.  See [`OsString`] for more encoding details
     /// and [`std::ffi`] for platform-specific, specified conversions.
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 288cce3aa08..55a5292a4a4 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -84,7 +84,7 @@
 //!
 //! # Contributing changes to the documentation
 //!
-//! Check out the rust contribution guidelines [here](
+//! Check out the Rust contribution guidelines [here](
 //! https://rustc-dev-guide.rust-lang.org/contributing.html#writing-documentation).
 //! The source for this documentation can be found on
 //! [GitHub](https://github.com/rust-lang/rust).
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index 5ba8719e6ff..b0633fd7bfc 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -95,22 +95,6 @@ pub mod process;
 pub mod raw;
 pub mod thread;
 
-#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
-#[cfg(any(
-    target_os = "android",
-    target_os = "linux",
-    target_os = "dragonfly",
-    target_os = "freebsd",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos",
-    target_os = "macos",
-    target_os = "netbsd",
-    target_os = "openbsd",
-    target_os = "nto",
-))]
-pub mod ucred;
-
 /// A prelude for conveniently writing platform-specific code.
 ///
 /// Includes all extension traits, and some important type definitions.
diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs
index 6da3e350bf1..28c1188677b 100644
--- a/library/std/src/os/unix/net/mod.rs
+++ b/library/std/src/os/unix/net/mod.rs
@@ -12,6 +12,20 @@ mod listener;
 mod stream;
 #[cfg(all(test, not(target_os = "emscripten")))]
 mod tests;
+#[cfg(any(
+    target_os = "android",
+    target_os = "linux",
+    target_os = "dragonfly",
+    target_os = "freebsd",
+    target_os = "ios",
+    target_os = "tvos",
+    target_os = "watchos",
+    target_os = "macos",
+    target_os = "netbsd",
+    target_os = "openbsd",
+    target_os = "nto",
+))]
+mod ucred;
 
 #[stable(feature = "unix_socket", since = "1.10.0")]
 pub use self::addr::*;
@@ -24,3 +38,18 @@ pub use self::datagram::*;
 pub use self::listener::*;
 #[stable(feature = "unix_socket", since = "1.10.0")]
 pub use self::stream::*;
+#[cfg(any(
+    target_os = "android",
+    target_os = "linux",
+    target_os = "dragonfly",
+    target_os = "freebsd",
+    target_os = "ios",
+    target_os = "tvos",
+    target_os = "watchos",
+    target_os = "macos",
+    target_os = "netbsd",
+    target_os = "openbsd",
+    target_os = "nto",
+))]
+#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
+pub use self::ucred::*;
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index b1cd504e219..069cb299e28 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -1,10 +1,3 @@
-#[cfg(any(doc, target_os = "android", target_os = "linux"))]
-use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary};
-use super::{sockaddr_un, SocketAddr};
-use crate::fmt;
-use crate::io::{self, IoSlice, IoSliceMut};
-use crate::net::Shutdown;
-use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
 #[cfg(any(
     target_os = "android",
     target_os = "linux",
@@ -17,28 +10,20 @@ use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, Owned
     target_os = "netbsd",
     target_os = "openbsd"
 ))]
-use crate::os::unix::ucred;
+use super::{peer_cred, UCred};
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
+use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary};
+use super::{sockaddr_un, SocketAddr};
+use crate::fmt;
+use crate::io::{self, IoSlice, IoSliceMut};
+use crate::net::Shutdown;
+use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
 use crate::path::Path;
 use crate::sys::cvt;
 use crate::sys::net::Socket;
 use crate::sys_common::{AsInner, FromInner};
 use crate::time::Duration;
 
-#[unstable(feature = "peer_credentials_unix_socket", issue = "42839", reason = "unstable")]
-#[cfg(any(
-    target_os = "android",
-    target_os = "linux",
-    target_os = "dragonfly",
-    target_os = "freebsd",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "macos",
-    target_os = "watchos",
-    target_os = "netbsd",
-    target_os = "openbsd"
-))]
-pub use ucred::UCred;
-
 /// A Unix stream socket.
 ///
 /// # Examples
@@ -247,7 +232,7 @@ impl UnixStream {
         target_os = "openbsd"
     ))]
     pub fn peer_cred(&self) -> io::Result<UCred> {
-        ucred::peer_cred(self)
+        peer_cred(self)
     }
 
     /// Sets the read timeout for the socket.
diff --git a/library/std/src/os/unix/ucred.rs b/library/std/src/os/unix/net/ucred.rs
index 6efa74182cc..de09c93840a 100644
--- a/library/std/src/os/unix/ucred.rs
+++ b/library/std/src/os/unix/net/ucred.rs
@@ -1,5 +1,3 @@
-//! Unix peer credentials.
-
 // NOTE: Code in this file is heavily based on work done in PR 13 from the tokio-uds repository on
 //       GitHub.
 //
@@ -26,7 +24,7 @@ pub struct UCred {
 }
 
 #[cfg(any(target_os = "android", target_os = "linux"))]
-pub use self::impl_linux::peer_cred;
+pub(super) use self::impl_linux::peer_cred;
 
 #[cfg(any(
     target_os = "dragonfly",
@@ -34,13 +32,13 @@ pub use self::impl_linux::peer_cred;
     target_os = "openbsd",
     target_os = "netbsd"
 ))]
-pub use self::impl_bsd::peer_cred;
+pub(super) use self::impl_bsd::peer_cred;
 
 #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
-pub use self::impl_mac::peer_cred;
+pub(super) use self::impl_mac::peer_cred;
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
-pub mod impl_linux {
+mod impl_linux {
     use super::UCred;
     use crate::os::unix::io::AsRawFd;
     use crate::os::unix::net::UnixStream;
@@ -82,7 +80,7 @@ pub mod impl_linux {
     target_os = "netbsd",
     target_os = "nto",
 ))]
-pub mod impl_bsd {
+mod impl_bsd {
     use super::UCred;
     use crate::io;
     use crate::os::unix::io::AsRawFd;
@@ -99,7 +97,7 @@ pub mod impl_bsd {
 }
 
 #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
-pub mod impl_mac {
+mod impl_mac {
     use super::UCred;
     use crate::os::unix::io::AsRawFd;
     use crate::os::unix::net::UnixStream;
diff --git a/library/std/src/os/unix/ucred/tests.rs b/library/std/src/os/unix/net/ucred/tests.rs
index dd99ecdd819..dd99ecdd819 100644
--- a/library/std/src/os/unix/ucred/tests.rs
+++ b/library/std/src/os/unix/net/ucred/tests.rs
diff --git a/library/std/src/sys/pal/hermit/time.rs b/library/std/src/sys/pal/hermit/time.rs
index f289dafd8bc..319b835a768 100644
--- a/library/std/src/sys/pal/hermit/time.rs
+++ b/library/std/src/sys/pal/hermit/time.rs
@@ -179,7 +179,7 @@ impl Sub<Instant> for Instant {
     ///
     /// # Panics
     ///
-    /// Previous rust versions panicked when `other` was later than `self`. Currently this
+    /// Previous Rust versions panicked when `other` was later than `self`. Currently this
     /// method saturates. Future versions may reintroduce the panic in some circumstances.
     /// See [Monotonicity].
     ///
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index a8f1e9b726b..970bd9c6ce7 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -26,11 +26,8 @@ impl Thread {
     pub unsafe fn new(stack: usize, p: Box<dyn FnOnce()>) -> io::Result<Thread> {
         let p = Box::into_raw(Box::new(p));
 
-        // FIXME On UNIX, we guard against stack sizes that are too small but
-        // that's because pthreads enforces that stacks are at least
-        // PTHREAD_STACK_MIN bytes big. Windows has no such lower limit, it's
-        // just that below a certain threshold you can't do anything useful.
-        // That threshold is application and architecture-specific, however.
+        // CreateThread rounds up values for the stack size to the nearest page size (at least 4kb).
+        // If a value of zero is given then the default stack size is used instead.
         let ret = c::CreateThread(
             ptr::null_mut(),
             stack,
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 813ede06415..589a5fdad1d 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -80,6 +80,7 @@ fn test_named_thread_truncation() {
 #[test]
 fn test_get_os_named_thread() {
     use crate::sys::thread::Thread;
+    // Spawn a new thread to avoid interfering with other tests running on this thread.
     let handler = thread::spawn(|| {
         let name = c"test me please";
         Thread::set_name(name);
@@ -423,3 +424,16 @@ fn scope_join_race() {
         });
     }
 }
+
+// Test that the smallest value for stack_size works on Windows.
+#[cfg(windows)]
+#[test]
+fn test_minimal_thread_stack() {
+    use crate::sync::atomic::AtomicU8;
+    static COUNT: AtomicU8 = AtomicU8::new(0);
+
+    let builder = thread::Builder::new().stack_size(1);
+    let before = builder.spawn(|| COUNT.fetch_add(1, Ordering::Relaxed)).unwrap().join().unwrap();
+    assert_eq!(before, 0);
+    assert_eq!(COUNT.load(Ordering::Relaxed), 1);
+}
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index 91c010ef2b5..6f1a354d28a 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -59,7 +59,7 @@ pub use core::time::TryFromFloatSecsError;
 /// experience time dilation (slow down or speed up), but it will never go
 /// backwards.
 /// As part of this non-guarantee it is also not specified whether system suspends count as
-/// elapsed time or not. The behavior varies across platforms and rust versions.
+/// elapsed time or not. The behavior varies across platforms and Rust versions.
 ///
 /// Instants are opaque types that can only be compared to one another. There is
 /// no method to get "the number of seconds" from an instant. Instead, it only
@@ -142,7 +142,7 @@ pub use core::time::TryFromFloatSecsError;
 /// where monotonicity is violated, or `Instant`s are subtracted in the wrong order.
 ///
 /// This workaround obscures programming errors where earlier and later instants are accidentally
-/// swapped. For this reason future rust versions may reintroduce panics.
+/// swapped. For this reason future Rust versions may reintroduce panics.
 ///
 /// [tier 1]: https://doc.rust-lang.org/rustc/platform-support.html
 /// [`duration_since`]: Instant::duration_since
@@ -290,7 +290,7 @@ impl Instant {
     ///
     /// # Panics
     ///
-    /// Previous rust versions panicked when `earlier` was later than `self`. Currently this
+    /// Previous Rust versions panicked when `earlier` was later than `self`. Currently this
     /// method saturates. Future versions may reintroduce the panic in some circumstances.
     /// See [Monotonicity].
     ///
@@ -365,7 +365,7 @@ impl Instant {
     ///
     /// # Panics
     ///
-    /// Previous rust versions panicked when the current time was earlier than self. Currently this
+    /// Previous Rust versions panicked when the current time was earlier than self. Currently this
     /// method returns a Duration of zero in that case. Future versions may reintroduce the panic.
     /// See [Monotonicity].
     ///
@@ -450,7 +450,7 @@ impl Sub<Instant> for Instant {
     ///
     /// # Panics
     ///
-    /// Previous rust versions panicked when `other` was later than `self`. Currently this
+    /// Previous Rust versions panicked when `other` was later than `self`. Currently this
     /// method saturates. Future versions may reintroduce the panic in some circumstances.
     /// See [Monotonicity].
     ///
diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs
index 22c28e4954e..875c66e5fa3 100644
--- a/library/test/src/formatters/terse.rs
+++ b/library/test/src/formatters/terse.rs
@@ -84,7 +84,7 @@ impl<T: Write> TerseFormatter<T> {
         if self.test_column % QUIET_MODE_MAX_COLUMN == QUIET_MODE_MAX_COLUMN - 1 {
             // We insert a new line regularly in order to flush the
             // screen when dealing with line-buffered output (e.g., piping to
-            // `stamp` in the rust CI).
+            // `stamp` in the Rust CI).
             self.write_progress()?;
         }
 
diff --git a/library/test/src/types.rs b/library/test/src/types.rs
index 1a8ae889c8c..6a7035a8e29 100644
--- a/library/test/src/types.rs
+++ b/library/test/src/types.rs
@@ -13,7 +13,7 @@ pub use NamePadding::*;
 pub use TestFn::*;
 pub use TestName::*;
 
-/// Type of the test according to the [rust book](https://doc.rust-lang.org/cargo/guide/tests.html)
+/// Type of the test according to the [Rust book](https://doc.rust-lang.org/cargo/guide/tests.html)
 /// conventions.
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum TestType {
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 0d604c0d3e5..6e49bcc9744 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -557,7 +557,9 @@ class RustBuild(object):
                 shutil.rmtree(bin_root)
 
             key = self.stage0_compiler.date
-            cache_dst = os.path.join(self.build_dir, "cache")
+            cache_dst = (self.get_toml('bootstrap-cache-path', 'build') or
+                os.path.join(self.build_dir, "cache"))
+
             rustc_cache = os.path.join(cache_dst, key)
             if not os.path.exists(rustc_cache):
                 os.makedirs(rustc_cache)
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 8b65e8ff9c3..4257c0f7991 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -149,6 +149,7 @@ v("default-linker", "rust.default-linker", "the default linker")
 # (others are conditionally saved).
 o("manage-submodules", "build.submodules", "let the build manage the git submodules")
 o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two (not recommended except for testing reproducible builds)")
+o("bootstrap-cache-path", "build.bootstrap-cache-path", "use provided path for the bootstrap cache")
 o("extended", "build.extended", "build an extended rust tool set")
 
 v("tools", None, "List of extended tools will be installed")
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 6c7cc3bf6a7..1090edc9c92 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -129,6 +129,7 @@ pub struct RustcDocs {
 impl Step for RustcDocs {
     type Output = Option<GeneratedTarball>;
     const DEFAULT: bool = true;
+    const ONLY_HOSTS: bool = true;
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
@@ -2046,7 +2047,15 @@ fn install_llvm_file(
             // projects like miri link against librustc_driver.so. We don't use a symlink, as
             // these are not allowed inside rustup components.
             let link = t!(fs::read_link(source));
-            t!(std::fs::write(full_dest, format!("INPUT({})\n", link.display())));
+            let mut linker_script = t!(fs::File::create(full_dest));
+            t!(write!(linker_script, "INPUT({})\n", link.display()));
+
+            // We also want the linker script to have the same mtime as the source, otherwise it
+            // can trigger rebuilds.
+            let meta = t!(fs::metadata(source));
+            if let Ok(mtime) = meta.modified() {
+                t!(linker_script.set_modified(mtime));
+            }
         }
     } else {
         builder.install(&source, destination, 0o644);
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index a4903ce2353..c4235755ba8 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -797,7 +797,10 @@ impl Step for Rustc {
         cargo.rustdocflag("-Zunstable-options");
         cargo.rustdocflag("-Znormalize-docs");
         cargo.rustdocflag("--show-type-layout");
-        cargo.rustdocflag("--generate-link-to-definition");
+        // FIXME: `--generate-link-to-definition` tries to resolve cfged out code
+        // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222
+        // cargo.rustdocflag("--generate-link-to-definition");
+
         compile::rustc_cargo(builder, &mut cargo, target, compiler.stage);
         cargo.arg("-Zunstable-options");
         cargo.arg("-Zskip-rustdoc-fingerprint");
@@ -953,8 +956,10 @@ macro_rules! tool_doc {
                 cargo.rustdocflag("-Arustdoc::private-intra-doc-links");
                 cargo.rustdocflag("--enable-index-page");
                 cargo.rustdocflag("--show-type-layout");
-                cargo.rustdocflag("--generate-link-to-definition");
                 cargo.rustdocflag("-Zunstable-options");
+                // FIXME: `--generate-link-to-definition` tries to resolve cfged out code
+                // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222
+                // cargo.rustdocflag("--generate-link-to-definition");
 
                 let out_dir = builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc");
                 $(for krate in $crates {
diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 700c3ee4fda..fc9f9789bd6 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -81,7 +81,7 @@ fn update_rustfmt_version(build: &Builder<'_>) {
 }
 
 /// Returns the Rust files modified between the `merge-base` of HEAD and
-/// rust-lang/master and what is now on the disk.
+/// rust-lang/master and what is now on the disk. Does not include removed files.
 ///
 /// Returns `None` if all files should be formatted.
 fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, String> {
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 875a4efae02..326f8f57173 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -161,6 +161,7 @@ pub struct Config {
     pub vendor: bool,
     pub target_config: HashMap<TargetSelection, Target>,
     pub full_bootstrap: bool,
+    pub bootstrap_cache_path: Option<PathBuf>,
     pub extended: bool,
     pub tools: Option<HashSet<String>>,
     pub sanitizers: bool,
@@ -827,6 +828,7 @@ define_config! {
         locked_deps: Option<bool> = "locked-deps",
         vendor: Option<bool> = "vendor",
         full_bootstrap: Option<bool> = "full-bootstrap",
+        bootstrap_cache_path: Option<PathBuf> = "bootstrap-cache-path",
         extended: Option<bool> = "extended",
         tools: Option<HashSet<String>> = "tools",
         verbose: Option<usize> = "verbose",
@@ -1389,6 +1391,7 @@ impl Config {
             locked_deps,
             vendor,
             full_bootstrap,
+            bootstrap_cache_path,
             extended,
             tools,
             verbose,
@@ -1477,6 +1480,7 @@ impl Config {
         config.reuse = reuse.map(PathBuf::from);
         config.submodules = submodules;
         config.android_ndk = android_ndk;
+        config.bootstrap_cache_path = bootstrap_cache_path;
         set(&mut config.low_priority, low_priority);
         set(&mut config.compiler_docs, compiler_docs);
         set(&mut config.library_docs_private_items, library_docs_private_items);
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 185089a646b..27829eab937 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -578,7 +578,9 @@ impl Config {
             return;
         }
 
-        let cache_dst = self.out.join("cache");
+        let cache_dst =
+            self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache"));
+
         let cache_dir = cache_dst.join(key);
         if !cache_dir.exists() {
             t!(fs::create_dir_all(&cache_dir));
@@ -705,7 +707,9 @@ download-rustc = false
         let llvm_assertions = self.llvm_assertions;
 
         let cache_prefix = format!("llvm-{llvm_sha}-{llvm_assertions}");
-        let cache_dst = self.out.join("cache");
+        let cache_dst =
+            self.bootstrap_cache_path.as_ref().cloned().unwrap_or_else(|| self.out.join("cache"));
+
         let rustc_cache = cache_dst.join(cache_prefix);
         if !rustc_cache.exists() {
             t!(fs::create_dir_all(&rustc_cache));
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index f7748621d93..ab8f3c0d9e4 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -91,7 +91,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     /* Extra values not defined in the built-in targets yet, but used in std */
     (Some(Mode::Std), "target_env", Some(&["libnx", "p2"])),
     // (Some(Mode::Std), "target_os", Some(&[])),
-    (Some(Mode::Std), "target_arch", Some(&["spirv", "nvptx", "xtensa"])),
+    (Some(Mode::Std), "target_arch", Some(&["arm64ec", "spirv", "nvptx", "xtensa"])),
     /* Extra names used by dependencies */
     // FIXME: Used by serde_json, but we should not be triggering on external dependencies.
     (Some(Mode::Rustc), "no_btreemap_remove_entry", None),
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 9a50ad4437e..d166b84e51f 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -136,4 +136,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "`x install` now skips providing tarball sources (under 'build/dist' path) to speed up the installation process.",
     },
+    ChangeInfo {
+        change_id: 121976,
+        severity: ChangeSeverity::Info,
+        summary: "A new `boostrap-cache-path` option has been introduced which can be utilized to modify the cache path for bootstrap.",
+    },
 ];
diff --git a/src/doc/rust.css b/src/doc/rust.css
index e0bf64c33bc..bd2e0b94518 100644
--- a/src/doc/rust.css
+++ b/src/doc/rust.css
@@ -5,12 +5,13 @@ body {
 	margin: 0 auto;
 	padding: 0 15px;
 	font-size: 18px;
-	color: #333;
+	color: #000;
 	line-height: 1.428571429;
 
 	-webkit-box-sizing: unset;
 	-moz-box-sizing: unset;
 	box-sizing: unset;
+	background: #fff;
 }
 @media (min-width: 768px) {
 	body {
@@ -39,7 +40,6 @@ h4, h5, h6 {
 	padding: 5px 10px;
 }
 h5, h6 {
-	color: black;
 	text-decoration: underline;
 }
 
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 26e43491c40..5a0168e30cb 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -18,6 +18,7 @@
     - [arm64e-apple-ios.md](platform-support/arm64e-apple-ios.md)
     - [arm64e-apple-darwin.md](platform-support/arm64e-apple-darwin.md)
     - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
+    - [arm64ec-pc-windows-msvc](platform-support/arm64ec-pc-windows-msvc.md)
     - [\*-apple-tvos](platform-support/apple-tvos.md)
     - [\*-apple-watchos\*](platform-support/apple-watchos.md)
     - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 4c4bbd29ac6..6819508caaa 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -32,7 +32,7 @@ All tier 1 targets with host tools support the full standard library.
 
 target | notes
 -------|-------
-`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) [^missing-stack-probes]
+`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+)
 `i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI]
 `i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support] [^x86_32-floats-return-ABI]
 `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI]
@@ -41,10 +41,6 @@ target | notes
 `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) [^windows-support]
 `x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 3.2+, glibc 2.17+)
 
-[^missing-stack-probes]: Stack probes support is missing on
-  `aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near
-  future. The implementation is tracked on [issue #77071][77071].
-
 [^windows-support]: Only Windows 10 currently undergoes automated testing. Earlier versions of Windows rely on testing and support from the community.
 
 [^x86_32-floats-return-ABI]: Due to limitations of the C ABI, floating-point support on `i686` targets is non-compliant: floating-point return values are passed via an x87 register, so NaN payload bits can be lost. See [issue #114479][x86-32-float-issue].
@@ -241,6 +237,7 @@ target | std | host | notes
 -------|:---:|:----:|-------
 [`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
 [`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md)  | ✓ | ✓ | ARM64e Apple Darwin
+[`arm64ec-pc-windows-msvc`](platform-support/arm64ec-pc-windows-msvc.md) | ? | | Arm64EC Windows MSVC
 `aarch64-apple-ios-macabi` | ? |  | Apple Catalyst on ARM64
 [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ? |  | ARM64 tvOS
 [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ? |  | ARM64 tvOS Simulator
diff --git a/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md
new file mode 100644
index 00000000000..1bb2c677b08
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/arm64ec-pc-windows-msvc.md
@@ -0,0 +1,69 @@
+# `arm64ec-pc-windows-msvc`
+
+**Tier: 3**
+
+Arm64EC ("Emulation Compatible") for mixed architecture (AArch64 and x86_64)
+applications on AArch64 Windows 11. See <https://learn.microsoft.com/en-us/windows/arm/arm64ec>.
+
+## Target maintainers
+
+- [@dpaoliello](https://github.com/dpaoliello)
+
+## Requirements
+
+Target only supports cross-compilation, `core` and `alloc` are supported but
+`std` is not.
+
+Builds Arm64EC static and dynamic libraries and executables which can be run on
+AArch64 Windows 11 devices. Arm64EC static libraries can also be linked into
+Arm64X dynamic libraries and executables.
+
+Uses `arm64ec` as its `target_arch` - code built for Arm64EC must be compatible
+with x86_64 code (e.g., same structure layouts, function signatures, etc.) but
+use AArch64 intrinsics.
+
+Only supported backend is LLVM 18 (or above).
+
+## Building the target
+
+You can build Rust with support for the targets by adding it to the `target`
+list in `config.toml` and disabling `std`:
+
+```toml
+[build]
+target = [ "arm64ec-pc-windows-msvc" ]
+
+[target.arm64ec-pc-windows-msvc]
+no-std = true
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will either need to build Rust with the target enabled (see
+"Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+## Testing
+
+Tests can be run on AArch64 Windows 11 devices.
+
+Since this is a `no_std` target, the Rust test suite is not supported.
+
+## Cross-compilation toolchains and C code
+
+C code can be built using the Arm64-targetting MSVC toolchain.
+
+To compile:
+
+```bash
+cl /arm64EC /c ...
+```
+
+To link:
+
+```bash
+link /MACHINE:ARM64EC ...
+```
+
+Further reading: <https://learn.microsoft.com/en-us/windows/arm/arm64ec-build>
diff --git a/src/doc/unstable-book/src/language-features/diagnostic-namespace.md b/src/doc/unstable-book/src/language-features/diagnostic-namespace.md
deleted file mode 100644
index 7c46811a27a..00000000000
--- a/src/doc/unstable-book/src/language-features/diagnostic-namespace.md
+++ /dev/null
@@ -1,84 +0,0 @@
-# `diagnostic_namespace`
-
-The tracking issue for this feature is: [#111996]
-
-[#111996]: https://github.com/rust-lang/rust/issues/111996
-
-------------------------
-
-The `diagnostic_namespace` feature permits customization of compilation errors.
-
-## diagnostic::on_unimplemented
-
-With [#114452] support for `diagnostic::on_unimplemented` was added.
-
-When used on a trait declaration, the following options are available:
-
-* `message` to customize the primary error message
-* `note` to add a customized note message to an error message
-* `label` to customize the label part of the error message
-
-The attribute will hint to the compiler to use these in error messages:
-```rust
-// some library
-#![feature(diagnostic_namespace)]
-
-#[diagnostic::on_unimplemented(
-    message = "cannot insert element",
-    label = "cannot be put into a table",
-    note = "see <link> for more information about the Table api"
-)]
-pub trait Element {
-    // ...
-}
-```
-
-```rust,compile_fail,E0277
-# #![feature(diagnostic_namespace)]
-#
-# #[diagnostic::on_unimplemented(
-#    message = "cannot insert element",
-#    label = "cannot be put into a table",
-#    note = "see <link> for more information about the Table api"
-# )]
-# pub trait Element {
-#    // ...
-# }
-# struct Table;
-# impl Table {
-#    fn insert<T: Element>(&self, element: T) {
-#        // ..
-#    }
-# }
-# fn main() {
-#    let table = Table;
-#    let element = ();
-// user code
-table.insert(element);
-# }
-```
-
-```text
-error[E0277]: cannot insert element
-  --> src/main.rs:24:18
-   |
-24 |     table.insert(element);
-   |           ------ ^^^^^^^ cannot be put into a table
-   |           |
-   |           required by a bound introduced by this call
-   |
-   = help: the trait `Element` is not implemented for `<type>`
-   = note: see <link> for more information about the Table api
-note: required by a bound in `Table::insert`
-  --> src/main.rs:15:18
-   |
-15 |     fn insert<T: Element>(&self, element: T) {
-   |                  ^^^^^^^ required by this bound in `Table::insert`
-
-For more information about this error, try `rustc --explain E0277`.
-```
-
-See [RFC 3368] for more information.
-
-[#114452]: https://github.com/rust-lang/rust/pull/114452
-[RFC 3368]: https://github.com/rust-lang/rfcs/blob/master/text/3368-diagnostic-attribute-namespace.md
diff --git a/src/tools/build_helper/src/git.rs b/src/tools/build_helper/src/git.rs
index b91dc38e924..a3c857b0268 100644
--- a/src/tools/build_helper/src/git.rs
+++ b/src/tools/build_helper/src/git.rs
@@ -113,6 +113,7 @@ pub fn get_git_merge_base(
 
 /// Returns the files that have been modified in the current branch compared to the master branch.
 /// The `extensions` parameter can be used to filter the files by their extension.
+/// Does not include removed files.
 /// If `extensions` is empty, all files will be returned.
 pub fn get_git_modified_files(
     config: &GitConfig<'_>,
@@ -125,13 +126,19 @@ pub fn get_git_modified_files(
     if let Some(git_dir) = git_dir {
         git.current_dir(git_dir);
     }
-    let files = output_result(git.args(["diff-index", "--name-only", merge_base.trim()]))?
+    let files = output_result(git.args(["diff-index", "--name-status", merge_base.trim()]))?
         .lines()
-        .map(|s| s.trim().to_owned())
-        .filter(|f| {
-            Path::new(f).extension().map_or(false, |ext| {
+        .filter_map(|f| {
+            let (status, name) = f.trim().split_once(char::is_whitespace).unwrap();
+            if status == "D" {
+                None
+            } else if Path::new(name).extension().map_or(false, |ext| {
                 extensions.is_empty() || extensions.contains(&ext.to_str().unwrap())
-            })
+            }) {
+                Some(name.to_owned())
+            } else {
+                None
+            }
         })
         .collect();
     Ok(Some(files))
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject f772ec0224d3755ce52ac5128a80319fb2eb45d
+Subproject a4c63fe5388beaa09e5f91196c86addab0a0358
diff --git a/src/tools/clippy/.github/driver.sh b/src/tools/clippy/.github/driver.sh
index 11fd6b5c79e..2eafdd0fbc8 100755
--- a/src/tools/clippy/.github/driver.sh
+++ b/src/tools/clippy/.github/driver.sh
@@ -50,11 +50,11 @@ diff -u normalized.stderr tests/ui/double_neg.stderr
 
 # make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
 SYSROOT=$(rustc --print sysroot)
-diff -u <(LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver --rustc --version --verbose) <(rustc --version --verbose)
+diff -u <(./target/debug/clippy-driver --rustc --version --verbose) <(rustc --version --verbose)
 
 echo "fn main() {}" >target/driver_test.rs
 # we can't run 2 rustcs on the same file at the same time
-CLIPPY=$(LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver ./target/driver_test.rs --rustc)
+CLIPPY=$(./target/debug/clippy-driver ./target/driver_test.rs --rustc)
 RUSTC=$(rustc ./target/driver_test.rs)
 diff -u <($CLIPPY) <($RUSTC)
 
diff --git a/src/tools/clippy/.github/workflows/clippy.yml b/src/tools/clippy/.github/workflows/clippy.yml
index 5ba960db66d..603f91a910b 100644
--- a/src/tools/clippy/.github/workflows/clippy.yml
+++ b/src/tools/clippy/.github/workflows/clippy.yml
@@ -44,11 +44,6 @@ jobs:
       run: rustup show active-toolchain
 
     # Run
-    - name: Set LD_LIBRARY_PATH (Linux)
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
-
     - name: Build
       run: cargo build --tests --features deny-warnings,internal
 
@@ -72,6 +67,6 @@ jobs:
       working-directory: clippy_dev
 
     - name: Test clippy-driver
-      run: bash .github/driver.sh
-      env:
-        OS: ${{ runner.os }}
+      run: |
+        TOOLCHAIN=$(rustup show active-toolchain | cut -f1 -d' ')
+        rustup run $TOOLCHAIN bash .github/driver.sh
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index 012797e5ca7..0bc28c1f9d9 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -59,7 +59,7 @@ jobs:
           host: i686-unknown-linux-gnu
         - os: windows-latest
           host: x86_64-pc-windows-msvc
-        - os: macos-latest
+        - os: macos-13
           host: x86_64-apple-darwin
 
     runs-on: ${{ matrix.os }}
@@ -87,23 +87,6 @@ jobs:
         rustup show active-toolchain
 
     # Run
-    - name: Set LD_LIBRARY_PATH (Linux)
-      if: runner.os == 'Linux'
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
-    - name: Link rustc dylib (MacOS)
-      if: runner.os == 'macOS'
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        sudo mkdir -p /usr/local/lib
-        sudo find "${SYSROOT}/lib" -maxdepth 1 -name '*dylib' -exec ln -s {} /usr/local/lib \;
-    - name: Set PATH (Windows)
-      if: runner.os == 'Windows'
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "$SYSROOT/bin" >> $GITHUB_PATH
-
     - name: Build
       run: cargo build --tests --features deny-warnings,internal
 
@@ -136,7 +119,9 @@ jobs:
       working-directory: clippy_dev
 
     - name: Test clippy-driver
-      run: bash .github/driver.sh
+      run: |
+        TOOLCHAIN=$(rustup show active-toolchain | cut -f1 -d' ')
+        rustup run $TOOLCHAIN bash .github/driver.sh
       env:
         OS: ${{ runner.os }}
 
@@ -236,11 +221,6 @@ jobs:
     - name: Install toolchain
       run: rustup show active-toolchain
 
-    - name: Set LD_LIBRARY_PATH
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
-
     # Download
     - name: Download target dir
       uses: actions/download-artifact@v3
@@ -254,8 +234,8 @@ jobs:
     # Run
     - name: Test ${{ matrix.integration }}
       run: |
-        RUSTUP_TOOLCHAIN="$(rustup show active-toolchain | grep -o -E "nightly-[0-9]{4}-[0-9]{2}-[0-9]{2}")" \
-          $CARGO_TARGET_DIR/debug/integration --show-output
+          TOOLCHAIN=$(rustup show active-toolchain | cut -f1 -d' ')
+          rustup run $TOOLCHAIN $CARGO_TARGET_DIR/debug/integration --show-output
       env:
         INTEGRATION: ${{ matrix.integration }}
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index f0b01742deb..d3b2c0a7bf6 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5046,6 +5046,7 @@ Released 2018-09-13
 [`assertions_on_result_states`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_result_states
 [`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
 [`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops
+[`assigning_clones`]: https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones
 [`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async
 [`await_holding_invalid_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type
 [`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
@@ -5423,6 +5424,7 @@ Released 2018-09-13
 [`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop
 [`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_trait_methods
 [`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
+[`mixed_attributes_style`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_attributes_style
 [`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
 [`mixed_read_write_in_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_read_write_in_expression
 [`mod_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#mod_module_files
@@ -5816,74 +5818,74 @@ Released 2018-09-13
 [`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
 <!-- end autogenerated links to lint list -->
 <!-- begin autogenerated links to configuration documentation -->
+[`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
+[`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
+[`accept-comment-above-attributes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-attributes
+[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement
+[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
+[`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests
+[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests
+[`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args
+[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
+[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
+[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
+[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
+[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
+[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
+[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars
+[`allowed-scripts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-scripts
+[`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports
 [`arithmetic-side-effects-allowed`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed
 [`arithmetic-side-effects-allowed-binary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-binary
 [`arithmetic-side-effects-allowed-unary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-unary
+[`array-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#array-size-threshold
 [`avoid-breaking-exported-api`]: https://doc.rust-lang.org/clippy/lint_configuration.html#avoid-breaking-exported-api
-[`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv
+[`await-holding-invalid-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#await-holding-invalid-types
+[`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish
+[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
 [`cognitive-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cognitive-complexity-threshold
-[`excessive-nesting-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#excessive-nesting-threshold
+[`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros
+[`disallowed-methods`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-methods
 [`disallowed-names`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-names
-[`semicolon-inside-block-ignore-singleline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-inside-block-ignore-singleline
-[`semicolon-outside-block-ignore-multiline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-outside-block-ignore-multiline
+[`disallowed-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-types
 [`doc-valid-idents`]: https://doc.rust-lang.org/clippy/lint_configuration.html#doc-valid-idents
-[`too-many-arguments-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-arguments-threshold
-[`type-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#type-complexity-threshold
-[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold
-[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack
+[`enable-raw-pointer-heuristic-for-send`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enable-raw-pointer-heuristic-for-send
+[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
+[`enforced-import-renames`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforced-import-renames
 [`enum-variant-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-name-threshold
-[`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold
 [`enum-variant-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-size-threshold
-[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold
+[`excessive-nesting-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#excessive-nesting-threshold
+[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold
+[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability
+[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold
 [`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold
-[`trivial-copy-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trivial-copy-size-limit
+[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else
+[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools
+[`max-include-file-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-include-file-size
+[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools
+[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length
+[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds
+[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
+[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
+[`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv
 [`pass-by-value-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pass-by-value-size-limit
-[`too-many-lines-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-lines-threshold
-[`array-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#array-size-threshold
+[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
+[`semicolon-inside-block-ignore-singleline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-inside-block-ignore-singleline
+[`semicolon-outside-block-ignore-multiline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-outside-block-ignore-multiline
+[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold
 [`stack-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#stack-size-threshold
-[`vec-box-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#vec-box-size-threshold
-[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds
-[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools
-[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools
-[`warn-on-all-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#warn-on-all-wildcard-imports
-[`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros
-[`disallowed-methods`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-methods
-[`disallowed-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-types
-[`unreadable-literal-lint-fractions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unreadable-literal-lint-fractions
-[`upper-case-acronyms-aggressive`]: https://doc.rust-lang.org/clippy/lint_configuration.html#upper-case-acronyms-aggressive
-[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else
-[`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish
 [`standard-macro-braces`]: https://doc.rust-lang.org/clippy/lint_configuration.html#standard-macro-braces
-[`enforced-import-renames`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforced-import-renames
-[`allowed-scripts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-scripts
-[`enable-raw-pointer-heuristic-for-send`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enable-raw-pointer-heuristic-for-send
-[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length
-[`await-holding-invalid-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#await-holding-invalid-types
-[`max-include-file-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-include-file-size
-[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests
-[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
-[`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests
-[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
-[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold
-[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability
-[`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args
+[`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold
 [`suppress-restriction-lint-in-const`]: https://doc.rust-lang.org/clippy/lint_configuration.html#suppress-restriction-lint-in-const
-[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
-[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold
+[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack
+[`too-many-arguments-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-arguments-threshold
+[`too-many-lines-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-lines-threshold
+[`trivial-copy-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trivial-copy-size-limit
+[`type-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#type-complexity-threshold
 [`unnecessary-box-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unnecessary-box-size
-[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
-[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars
-[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
-[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement
-[`accept-comment-above-attributes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-attributes
-[`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
-[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
-[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
-[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
-[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
-[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
-[`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports
+[`unreadable-literal-lint-fractions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unreadable-literal-lint-fractions
+[`upper-case-acronyms-aggressive`]: https://doc.rust-lang.org/clippy/lint_configuration.html#upper-case-acronyms-aggressive
+[`vec-box-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#vec-box-size-threshold
+[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold
+[`warn-on-all-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#warn-on-all-wildcard-imports
 <!-- end autogenerated links to configuration documentation -->
diff --git a/src/tools/clippy/book/src/development/trait_checking.md b/src/tools/clippy/book/src/development/trait_checking.md
index fb263922cf8..b7d229ccc19 100644
--- a/src/tools/clippy/book/src/development/trait_checking.md
+++ b/src/tools/clippy/book/src/development/trait_checking.md
@@ -94,6 +94,53 @@ impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
 }
 ```
 
+## Creating Types Programmatically
+
+Traits are often generic over a type parameter, e.g. `Borrow<T>` is generic
+over `T`. Rust allows us to implement a trait for a specific type. For example,
+we can implement `Borrow<[u8]>` for a hypothetical type `Foo`. Let's suppose
+that we would like to find whether our type actually implements `Borrow<[u8]>`.
+
+To do so, we can use the same `implements_trait` function as above, and supply
+a type parameter that represents `[u8]`. Since `[u8]` is a specialization of
+`[T]`, we can use the  [`Ty::new_slice`][new_slice] method to create a type
+that represents `[T]` and supply `u8` as a type parameter.
+To create a `ty::Ty` programmatically, we rely on `Ty::new_*` methods. These
+methods create a `TyKind` and then wrap it in a `Ty` struct. This means we
+have access to all the primitive types, such as `Ty::new_char`,
+`Ty::new_bool`, `Ty::new_int`, etc. We can also create more complex types,
+such as slices, tuples, and references out of these basic building blocks.
+
+For trait checking, it is not enough to create the types, we need to convert
+them into [GenericArg]. In rustc, a generic is an entity that the compiler
+understands and has three kinds, type, const and lifetime. By calling
+`.into()` on a constructed [Ty], we wrap the type into a generic which can
+then be used by the query system to decide whether the specialized trait
+is implemented.
+
+The following code demonstrates how to do this:
+
+```rust
+
+use rustc_middle::ty::Ty;
+use clippy_utils::ty::implements_trait;
+use rustc_span::symbol::sym;
+
+let ty = todo!("Get the `Foo` type to check for a trait implementation");
+let borrow_id = cx.tcx.get_diagnostic_item(sym::Borrow).unwrap(); // avoid unwrap in real code
+let slice_of_bytes_t = Ty::new_slice(cx.tcx, cx.tcx.types.u8);
+let generic_param = slice_of_bytes_t.into();
+if implements_trait(cx, ty, borrow_id, &[generic_param]) {
+    todo!("Rest of lint implementation")
+}
+```
+
+In essence, the [Ty] struct allows us to create types programmatically in a
+representation that can be used by the compiler and the query engine. We then
+use the `rustc_middle::Ty` of the type we are interested in, and query the
+compiler to see if it indeed implements the trait we are interested in.
+
+
 [DefId]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
 [diagnostic_items]: https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html
 [lang_items]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/lang_items/struct.LanguageItems.html
@@ -102,4 +149,7 @@ impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
 [symbol]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html
 [symbol_index]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/sym/index.html
 [TyCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html
+[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
 [rust]: https://github.com/rust-lang/rust
+[new_slice]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.new_slice
+[GenericArg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.GenericArg.html
diff --git a/src/tools/clippy/book/src/development/type_checking.md b/src/tools/clippy/book/src/development/type_checking.md
index dc29ab5d08d..136b3fd0270 100644
--- a/src/tools/clippy/book/src/development/type_checking.md
+++ b/src/tools/clippy/book/src/development/type_checking.md
@@ -123,6 +123,22 @@ the [`TypeckResults::node_type()`][node_type] method inside of bodies.
 
 > **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
 
+## Creating Types programmatically
+
+A common usecase for creating types programmatically is when we want to check if a type implements a trait (see
+[Trait Checking](trait_checking.md)).
+
+Here's an example of how to create a `Ty` for a slice of `u8`, i.e. `[u8]`
+
+```rust
+use rustc_middle::ty::Ty;
+// assume we have access to a LateContext
+let ty = Ty::new_slice(cx.tcx, Ty::new_u8());
+```
+
+In general, we rely on `Ty::new_*` methods. These methods define the basic building-blocks that the
+type-system and trait-system use to define and understand the written code.
+
 ## Useful Links
 
 Below are some useful links to further explore the concepts covered
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 214a60d3bfd..a985346b3c0 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -10,334 +10,252 @@ and lints affected.
 
 ---
 
-## `arithmetic-side-effects-allowed`
-Suppress checking of the passed type names in all types of operations.
-
-If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.
-
-#### Example
-
-```toml
-arithmetic-side-effects-allowed = ["SomeType", "AnotherType"]
-```
-
-#### Noteworthy
-
-A type, say `SomeType`, listed in this configuration has the same behavior of
-`["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
+## `absolute-paths-allowed-crates`
+Which crates to allow absolute paths from
 
 **Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
-
-
-## `arithmetic-side-effects-allowed-binary`
-Suppress checking of the passed type pair names in binary operations like addition or
-multiplication.
-
-Supports the "*" wildcard to indicate that a certain type won't trigger the lint regardless
-of the involved counterpart. For example, `["SomeType", "*"]` or `["*", "AnotherType"]`.
+* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
 
-Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the same as
-`["AnotherType", "SomeType"]`.
 
-#### Example
-
-```toml
-arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
-```
+## `absolute-paths-max-segments`
+The maximum number of segments a path can have before being linted, anything above this will
+be linted.
 
-**Default Value:** `[]`
+**Default Value:** `2`
 
 ---
 **Affected lints:**
-* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
-
-
-## `arithmetic-side-effects-allowed-unary`
-Suppress checking of the passed type names in unary operations like "negation" (`-`).
+* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
 
-#### Example
 
-```toml
-arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
-```
+## `accept-comment-above-attributes`
+Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
 
-**Default Value:** `[]`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
+* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
 
 
-## `avoid-breaking-exported-api`
-Suppress lints whenever the suggested change would cause breakage for other crates.
+## `accept-comment-above-statement`
+Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
 
 **Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
-* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
-* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
-* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps)
-* [`unused_self`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self)
-* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
-* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention)
-* [`box_collection`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection)
-* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)
-* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)
-* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
-* [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option)
-* [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist)
-* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)
-* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
-* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn)
+* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
 
 
-## `msrv`
-The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
+## `allow-comparison-to-zero`
+Don't lint when comparing the result of a modulo operation to zero.
+
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)
-* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)
-* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied)
-* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
-* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
-* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
-* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next)
-* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions)
-* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains)
-* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
-* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)
-* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive)
-* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
-* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or)
-* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro)
-* [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)
-* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)
-* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
-* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)
-* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
-* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
-* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant)
-* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr)
-* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
-* [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone)
-* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr)
-* [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits)
-* [`err_expect`](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect)
-* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned)
-* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
-* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp)
-* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
-* [`unchecked_duration_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction)
-* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace)
-* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
-* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
-* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations)
-* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
-* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range)
-* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
-* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls)
-* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check)
-* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid)
-* [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain)
-* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
-* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
-* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
-* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)
-* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
-* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)
+* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic)
 
 
-## `cognitive-complexity-threshold`
-The maximum cognitive complexity a function can have
+## `allow-dbg-in-tests`
+Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
 
-**Default Value:** `25`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity)
+* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro)
 
 
-## `excessive-nesting-threshold`
-The maximum amount of nesting a block can reside in
+## `allow-expect-in-tests`
+Whether `expect` should be allowed in test functions or `#[cfg(test)]`
 
-**Default Value:** `0`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)
+* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)
 
 
-## `disallowed-names`
-The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
-`".."` can be used as part of the list to indicate that the configured values should be appended to the
-default configuration of Clippy. By default, any configuration will replace the default value.
+## `allow-mixed-uninlined-format-args`
+Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
 
-**Default Value:** `["foo", "baz", "quux"]`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names)
+* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
 
 
-## `semicolon-inside-block-ignore-singleline`
-Whether to lint only if it's multiline.
+## `allow-one-hash-in-raw-strings`
+Whether to allow `r#""#` when `r""` can be used
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block)
+* [`unnecessary_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_raw_string_hashes)
 
 
-## `semicolon-outside-block-ignore-multiline`
-Whether to lint only if it's singleline.
+## `allow-print-in-tests`
+Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block)
+* [`print_stderr`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr)
+* [`print_stdout`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout)
 
 
-## `doc-valid-idents`
-The list of words this lint should not consider as identifiers needing ticks. The value
-`".."` can be used as part of the list to indicate, that the configured values should be appended to the
-default configuration of Clippy. By default, any configuration will replace the default value. For example:
-* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
-* `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
+## `allow-private-module-inception`
+Whether to allow module inception if it's not public.
 
-**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown)
+* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception)
 
 
-## `too-many-arguments-threshold`
-The maximum number of argument a function or method can have
+## `allow-unwrap-in-tests`
+Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
 
-**Default Value:** `7`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments)
+* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
 
 
-## `type-complexity-threshold`
-The maximum complexity a type can have
+## `allowed-dotfiles`
+Additional dotfiles (files or directories starting with a dot) to allow
 
-**Default Value:** `250`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`type_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity)
+* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
 
 
-## `single-char-binding-names-threshold`
-The maximum number of single char bindings a scope may have
+## `allowed-duplicate-crates`
+A list of crate names to allow duplicates of
 
-**Default Value:** `4`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names)
+* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
 
 
-## `too-large-for-stack`
-The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
+## `allowed-idents-below-min-chars`
+Allowed names below the minimum allowed characters. The value `".."` can be used as part of
+the list to indicate, that the configured values should be appended to the default
+configuration of Clippy. By default, any configuration will replace the default value.
 
-**Default Value:** `200`
+**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]`
 
 ---
 **Affected lints:**
-* [`boxed_local`](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local)
-* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
+* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
 
 
-## `enum-variant-name-threshold`
-The minimum number of enum variants for the lints about variant names to trigger
+## `allowed-scripts`
+The list of unicode scripts allowed to be used in the scope.
 
-**Default Value:** `3`
+**Default Value:** `["Latin"]`
 
 ---
 **Affected lints:**
-* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
+* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents)
 
 
-## `struct-field-name-threshold`
-The minimum number of struct fields for the lints about field names to trigger
+## `allowed-wildcard-imports`
+List of path segments allowed to have wildcard imports.
 
-**Default Value:** `3`
+#### Example
 
----
-**Affected lints:**
-* [`struct_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names)
+```toml
+allowed-wildcard-imports = [ "utils", "common" ]
+```
 
+#### Noteworthy
 
-## `enum-variant-size-threshold`
-The maximum size of an enum's variant to avoid box suggestion
+1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
+2. Paths with any segment that containing the word 'prelude'
+are already allowed by default.
 
-**Default Value:** `200`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant)
+* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)
 
 
-## `verbose-bit-mask-threshold`
-The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
+## `arithmetic-side-effects-allowed`
+Suppress checking of the passed type names in all types of operations.
 
-**Default Value:** `1`
+If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.
 
----
-**Affected lints:**
-* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask)
+#### Example
 
+```toml
+arithmetic-side-effects-allowed = ["SomeType", "AnotherType"]
+```
 
-## `literal-representation-threshold`
-The lower bound for linting decimal literals
+#### Noteworthy
 
-**Default Value:** `16384`
+A type, say `SomeType`, listed in this configuration has the same behavior of
+`["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation)
+* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
 
 
-## `trivial-copy-size-limit`
-The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
-reference. By default there is no limit
+## `arithmetic-side-effects-allowed-binary`
+Suppress checking of the passed type pair names in binary operations like addition or
+multiplication.
 
----
-**Affected lints:**
-* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
+Supports the "*" wildcard to indicate that a certain type won't trigger the lint regardless
+of the involved counterpart. For example, `["SomeType", "*"]` or `["*", "AnotherType"]`.
 
+Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the same as
+`["AnotherType", "SomeType"]`.
 
-## `pass-by-value-size-limit`
-The minimum size (in bytes) to consider a type for passing by reference instead of by value.
+#### Example
 
-**Default Value:** `256`
+```toml
+arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
+```
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
+* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
 
 
-## `too-many-lines-threshold`
-The maximum number of lines a function or method can have
+## `arithmetic-side-effects-allowed-unary`
+Suppress checking of the passed type names in unary operations like "negation" (`-`).
 
-**Default Value:** `100`
+#### Example
+
+```toml
+arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
+```
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
+* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
 
 
 ## `array-size-threshold`
@@ -347,68 +265,76 @@ The maximum allowed size for arrays on the stack
 
 ---
 **Affected lints:**
-* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays)
 * [`large_const_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays)
+* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays)
 
 
-## `stack-size-threshold`
-The maximum allowed stack size for functions in bytes
-
-**Default Value:** `512000`
-
----
-**Affected lints:**
-* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames)
-
-
-## `vec-box-size-threshold`
-The size of the boxed type in bytes, where boxing in a `Vec` is allowed
+## `avoid-breaking-exported-api`
+Suppress lints whenever the suggested change would cause breakage for other crates.
 
-**Default Value:** `4096`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
+* [`box_collection`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection)
+* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
+* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
+* [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist)
+* [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option)
+* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)
+* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)
+* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)
+* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn)
+* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
+* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
+* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps)
+* [`unused_self`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self)
+* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
 * [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
+* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention)
 
 
-## `max-trait-bounds`
-The maximum number of bounds a trait can have to be linted
+## `await-holding-invalid-types`
 
-**Default Value:** `3`
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
+* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type)
 
 
-## `max-struct-bools`
-The maximum number of bool fields a struct can have
+## `cargo-ignore-publish`
+For internal testing only, ignores the current `publish` settings in the Cargo manifest.
 
-**Default Value:** `3`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools)
+* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata)
 
 
-## `max-fn-params-bools`
-The maximum number of bool parameters a function can have
+## `check-private-items`
+Whether to also run the listed lints on private items.
 
-**Default Value:** `3`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools)
+* [`missing_errors_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc)
+* [`missing_panics_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc)
+* [`missing_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc)
+* [`unnecessary_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc)
 
 
-## `warn-on-all-wildcard-imports`
-Whether to allow certain wildcard imports (prelude, super in tests).
+## `cognitive-complexity-threshold`
+The maximum cognitive complexity a function can have
 
-**Default Value:** `false`
+**Default Value:** `25`
 
 ---
 **Affected lints:**
-* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)
+* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity)
 
 
 ## `disallowed-macros`
@@ -431,218 +357,231 @@ The list of disallowed methods, written as fully qualified paths.
 * [`disallowed_methods`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods)
 
 
-## `disallowed-types`
-The list of disallowed types, written as fully qualified paths.
+## `disallowed-names`
+The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
+`".."` can be used as part of the list to indicate that the configured values should be appended to the
+default configuration of Clippy. By default, any configuration will replace the default value.
 
-**Default Value:** `[]`
+**Default Value:** `["foo", "baz", "quux"]`
 
 ---
 **Affected lints:**
-* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types)
+* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names)
 
 
-## `unreadable-literal-lint-fractions`
-Should the fraction of a decimal be linted to include separators.
+## `disallowed-types`
+The list of disallowed types, written as fully qualified paths.
 
-**Default Value:** `true`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal)
+* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types)
 
 
-## `upper-case-acronyms-aggressive`
-Enables verbose mode. Triggers if there is more than one uppercase char next to each other
+## `doc-valid-idents`
+The list of words this lint should not consider as identifiers needing ticks. The value
+`".."` can be used as part of the list to indicate, that the configured values should be appended to the
+default configuration of Clippy. By default, any configuration will replace the default value. For example:
+* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
+* `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `false`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
-* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
+* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown)
 
 
-## `matches-for-let-else`
-Whether the matches should be considered by the lint, and whether there should
-be filtering for common types.
+## `enable-raw-pointer-heuristic-for-send`
+Whether to apply the raw pointer heuristic to determine if a type is `Send`.
 
-**Default Value:** `"WellKnownTypes"`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
+* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty)
 
 
-## `cargo-ignore-publish`
-For internal testing only, ignores the current `publish` settings in the Cargo manifest.
+## `enforce-iter-loop-reborrow`
+Whether to recommend using implicit into iter for reborrowed values.
+
+#### Example
+```no_run
+let mut vec = vec![1, 2, 3];
+let rmvec = &mut vec;
+for _ in rmvec.iter() {}
+for _ in rmvec.iter_mut() {}
+```
+
+Use instead:
+```no_run
+let mut vec = vec![1, 2, 3];
+let rmvec = &mut vec;
+for _ in &*rmvec {}
+for _ in &mut *rmvec {}
+```
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata)
-
+* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop)
 
-## `standard-macro-braces`
-Enforce the named macros always use the braces specified.
 
-A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
-could be used with a full path two `MacroMatcher`s have to be added one with the full path
-`crate_name::macro_name` and one with just the macro name.
+## `enforced-import-renames`
+The list of imports to always rename, a fully qualified path followed by the rename.
 
 **Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces)
+* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames)
 
 
-## `enforced-import-renames`
-The list of imports to always rename, a fully qualified path followed by the rename.
+## `enum-variant-name-threshold`
+The minimum number of enum variants for the lints about variant names to trigger
 
-**Default Value:** `[]`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames)
+* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
 
 
-## `allowed-scripts`
-The list of unicode scripts allowed to be used in the scope.
+## `enum-variant-size-threshold`
+The maximum size of an enum's variant to avoid box suggestion
 
-**Default Value:** `["Latin"]`
+**Default Value:** `200`
 
 ---
 **Affected lints:**
-* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents)
+* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant)
 
 
-## `enable-raw-pointer-heuristic-for-send`
-Whether to apply the raw pointer heuristic to determine if a type is `Send`.
+## `excessive-nesting-threshold`
+The maximum amount of nesting a block can reside in
 
-**Default Value:** `true`
+**Default Value:** `0`
 
 ---
 **Affected lints:**
-* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty)
+* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)
 
 
-## `max-suggested-slice-pattern-length`
-When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in
-the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.
-For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
+## `future-size-threshold`
+The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
 
-**Default Value:** `3`
+**Default Value:** `16384`
 
 ---
 **Affected lints:**
-* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
-
+* [`large_futures`](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures)
 
-## `await-holding-invalid-types`
 
+## `ignore-interior-mutability`
+A list of paths to types that should be treated like `Arc`, i.e. ignored but
+for the generic parameters for determining interior mutability
 
-**Default Value:** `[]`
+**Default Value:** `["bytes::Bytes"]`
 
 ---
 **Affected lints:**
-* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type)
+* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond)
+* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)
 
 
-## `max-include-file-size`
-The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
+## `large-error-threshold`
+The maximum size of the `Err`-variant in a `Result` returned from a function
 
-**Default Value:** `1000000`
+**Default Value:** `128`
 
 ---
 **Affected lints:**
-* [`large_include_file`](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file)
+* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)
 
 
-## `allow-expect-in-tests`
-Whether `expect` should be allowed in test functions or `#[cfg(test)]`
+## `literal-representation-threshold`
+The lower bound for linting decimal literals
 
-**Default Value:** `false`
+**Default Value:** `16384`
 
 ---
 **Affected lints:**
-* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)
+* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation)
 
 
-## `allow-unwrap-in-tests`
-Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
+## `matches-for-let-else`
+Whether the matches should be considered by the lint, and whether there should
+be filtering for common types.
 
-**Default Value:** `false`
+**Default Value:** `"WellKnownTypes"`
 
 ---
 **Affected lints:**
-* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
+* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
 
 
-## `allow-dbg-in-tests`
-Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
+## `max-fn-params-bools`
+The maximum number of bool parameters a function can have
 
-**Default Value:** `false`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro)
+* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools)
 
 
-## `allow-print-in-tests`
-Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
+## `max-include-file-size`
+The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
 
-**Default Value:** `false`
+**Default Value:** `1000000`
 
 ---
 **Affected lints:**
-* [`print_stdout`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout)
-* [`print_stderr`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr)
+* [`large_include_file`](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file)
 
 
-## `large-error-threshold`
-The maximum size of the `Err`-variant in a `Result` returned from a function
+## `max-struct-bools`
+The maximum number of bool fields a struct can have
 
-**Default Value:** `128`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)
+* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools)
 
 
-## `ignore-interior-mutability`
-A list of paths to types that should be treated like `Arc`, i.e. ignored but
-for the generic parameters for determining interior mutability
+## `max-suggested-slice-pattern-length`
+When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in
+the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.
+For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
 
-**Default Value:** `["bytes::Bytes"]`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)
-* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond)
+* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
 
 
-## `allow-mixed-uninlined-format-args`
-Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
+## `max-trait-bounds`
+The maximum number of bounds a trait can have to be linted
 
-**Default Value:** `true`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
+* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
 
 
-## `suppress-restriction-lint-in-const`
-Whether to suppress a restriction lint in constant code. In same
-cases the restructured operation might not be unavoidable, as the
-suggested counterparts are unavailable in constant code. This
-configuration will cause restriction lints to trigger even
-if no suggestion can be made.
+## `min-ident-chars-threshold`
+Minimum chars an ident can have, anything below or equal to this will be linted.
 
-**Default Value:** `false`
+**Default Value:** `1`
 
 ---
 **Affected lints:**
-* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)
+* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
 
 
 ## `missing-docs-in-crate-items`
@@ -656,205 +595,266 @@ crate. For example, `pub(crate)` items.
 * [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items)
 
 
-## `future-size-threshold`
-The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
+## `msrv`
+The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
+
+---
+**Affected lints:**
+* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range)
+* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant)
+* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr)
+* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned)
+* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions)
+* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied)
+* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace)
+* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr)
+* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls)
+* [`err_expect`](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect)
+* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next)
+* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)
+* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
+* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
+* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
+* [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits)
+* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)
+* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp)
+* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)
+* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check)
+* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
+* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive)
+* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains)
+* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid)
+* [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain)
+* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)
+* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)
+* [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)
+* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
+* [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone)
+* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or)
+* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro)
+* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)
+* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)
+* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
+* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
+* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
+* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
+* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
+* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
+* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
+* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
+* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
+* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
+* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
+* [`unchecked_duration_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction)
+* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
+* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations)
+* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
+* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
 
-**Default Value:** `16384`
+
+## `pass-by-value-size-limit`
+The minimum size (in bytes) to consider a type for passing by reference instead of by value.
+
+**Default Value:** `256`
 
 ---
 **Affected lints:**
-* [`large_futures`](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures)
+* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
 
 
-## `unnecessary-box-size`
-The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
+## `pub-underscore-fields-behavior`
+Lint "public" fields in a struct that are prefixed with an underscore based on their
+exported visibility, or whether they are marked as "pub".
 
-**Default Value:** `128`
+**Default Value:** `"PubliclyExported"`
 
 ---
 **Affected lints:**
-* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
+* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
 
 
-## `allow-private-module-inception`
-Whether to allow module inception if it's not public.
+## `semicolon-inside-block-ignore-singleline`
+Whether to lint only if it's multiline.
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception)
+* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block)
 
 
-## `allowed-idents-below-min-chars`
-Allowed names below the minimum allowed characters. The value `".."` can be used as part of
-the list to indicate, that the configured values should be appended to the default
-configuration of Clippy. By default, any configuration will replace the default value.
+## `semicolon-outside-block-ignore-multiline`
+Whether to lint only if it's singleline.
 
-**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
+* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block)
 
 
-## `min-ident-chars-threshold`
-Minimum chars an ident can have, anything below or equal to this will be linted.
+## `single-char-binding-names-threshold`
+The maximum number of single char bindings a scope may have
 
-**Default Value:** `1`
+**Default Value:** `4`
 
 ---
 **Affected lints:**
-* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
+* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names)
 
 
-## `accept-comment-above-statement`
-Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
+## `stack-size-threshold`
+The maximum allowed stack size for functions in bytes
 
-**Default Value:** `true`
+**Default Value:** `512000`
 
 ---
 **Affected lints:**
-* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
+* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames)
 
 
-## `accept-comment-above-attributes`
-Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
+## `standard-macro-braces`
+Enforce the named macros always use the braces specified.
 
-**Default Value:** `true`
+A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
+could be used with a full path two `MacroMatcher`s have to be added one with the full path
+`crate_name::macro_name` and one with just the macro name.
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
+* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces)
 
 
-## `allow-one-hash-in-raw-strings`
-Whether to allow `r#""#` when `r""` can be used
+## `struct-field-name-threshold`
+The minimum number of struct fields for the lints about field names to trigger
 
-**Default Value:** `false`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`unnecessary_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_raw_string_hashes)
+* [`struct_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names)
 
 
-## `absolute-paths-max-segments`
-The maximum number of segments a path can have before being linted, anything above this will
-be linted.
+## `suppress-restriction-lint-in-const`
+Whether to suppress a restriction lint in constant code. In same
+cases the restructured operation might not be unavoidable, as the
+suggested counterparts are unavailable in constant code. This
+configuration will cause restriction lints to trigger even
+if no suggestion can be made.
 
-**Default Value:** `2`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
+* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)
 
 
-## `absolute-paths-allowed-crates`
-Which crates to allow absolute paths from
+## `too-large-for-stack`
+The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
 
-**Default Value:** `[]`
+**Default Value:** `200`
 
 ---
 **Affected lints:**
-* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
+* [`boxed_local`](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local)
+* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
 
 
-## `allowed-dotfiles`
-Additional dotfiles (files or directories starting with a dot) to allow
+## `too-many-arguments-threshold`
+The maximum number of argument a function or method can have
 
-**Default Value:** `[]`
+**Default Value:** `7`
 
 ---
 **Affected lints:**
-* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
+* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments)
 
 
-## `allowed-duplicate-crates`
-A list of crate names to allow duplicates of
+## `too-many-lines-threshold`
+The maximum number of lines a function or method can have
 
-**Default Value:** `[]`
+**Default Value:** `100`
 
 ---
 **Affected lints:**
-* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
+* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
 
 
-## `enforce-iter-loop-reborrow`
-Whether to recommend using implicit into iter for reborrowed values.
+## `trivial-copy-size-limit`
+The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
+reference. By default there is no limit
 
-#### Example
-```no_run
-let mut vec = vec![1, 2, 3];
-let rmvec = &mut vec;
-for _ in rmvec.iter() {}
-for _ in rmvec.iter_mut() {}
-```
+---
+**Affected lints:**
+* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
 
-Use instead:
-```no_run
-let mut vec = vec![1, 2, 3];
-let rmvec = &mut vec;
-for _ in &*rmvec {}
-for _ in &mut *rmvec {}
-```
 
-**Default Value:** `false`
+## `type-complexity-threshold`
+The maximum complexity a type can have
+
+**Default Value:** `250`
 
 ---
 **Affected lints:**
-* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop)
+* [`type_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity)
 
 
-## `check-private-items`
-Whether to also run the listed lints on private items.
+## `unnecessary-box-size`
+The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
 
-**Default Value:** `false`
+**Default Value:** `128`
 
 ---
 **Affected lints:**
-* [`missing_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc)
-* [`unnecessary_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc)
-* [`missing_panics_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc)
-* [`missing_errors_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc)
+* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
 
 
-## `pub-underscore-fields-behavior`
-Lint "public" fields in a struct that are prefixed with an underscore based on their
-exported visibility, or whether they are marked as "pub".
+## `unreadable-literal-lint-fractions`
+Should the fraction of a decimal be linted to include separators.
 
-**Default Value:** `"PubliclyExported"`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
+* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal)
 
 
-## `allow-comparison-to-zero`
-Don't lint when comparing the result of a modulo operation to zero.
+## `upper-case-acronyms-aggressive`
+Enables verbose mode. Triggers if there is more than one uppercase char next to each other
 
-**Default Value:** `true`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic)
+* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
 
 
-## `allowed-wildcard-imports`
-List of path segments allowed to have wildcard imports.
+## `vec-box-size-threshold`
+The size of the boxed type in bytes, where boxing in a `Vec` is allowed
 
-#### Example
+**Default Value:** `4096`
 
-```toml
-allowed-wildcard-imports = [ "utils", "common" ]
-```
+---
+**Affected lints:**
+* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
 
-#### Noteworthy
 
-1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
-2. Paths with any segment that containing the word 'prelude'
-are already allowed by default.
+## `verbose-bit-mask-threshold`
+The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
 
-**Default Value:** `[]`
+**Default Value:** `1`
+
+---
+**Affected lints:**
+* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask)
+
+
+## `warn-on-all-wildcard-imports`
+Whether to allow certain wildcard imports (prelude, super in tests).
+
+**Default Value:** `false`
 
 ---
 **Affected lints:**
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index b781259ad96..673b6328b39 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -193,7 +193,7 @@ macro_rules! define_Conf {
         }
 
         pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
-            vec![
+            let mut sorted = vec![
                 $(
                     {
                         let deprecation_reason = wrap_option!($($dep)?);
@@ -206,7 +206,9 @@ macro_rules! define_Conf {
                         )
                     },
                 )+
-            ]
+            ];
+            sorted.sort_by(|a, b| a.name.cmp(&b.name));
+            sorted
         }
     };
 }
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index 3d5002f1780..01e2aa6e0a6 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -5,7 +5,7 @@
     clippy::must_use_candidate,
     clippy::missing_panics_doc,
     rustc::diagnostic_outside_of_impl,
-    rustc::untranslatable_diagnostic,
+    rustc::untranslatable_diagnostic
 )]
 
 extern crate rustc_ast;
diff --git a/src/tools/clippy/clippy_config/src/metadata.rs b/src/tools/clippy/clippy_config/src/metadata.rs
index 3ba2796e18d..400887185e8 100644
--- a/src/tools/clippy/clippy_config/src/metadata.rs
+++ b/src/tools/clippy/clippy_config/src/metadata.rs
@@ -26,9 +26,11 @@ impl ClippyConfiguration {
         doc_comment: &'static str,
         deprecation_reason: Option<&'static str>,
     ) -> Self {
-        let (lints, doc) = parse_config_field_doc(doc_comment)
+        let (mut lints, doc) = parse_config_field_doc(doc_comment)
             .unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
 
+        lints.sort();
+
         Self {
             name: to_kebab(name),
             lints,
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index f4389db627d..a8a32f7ed20 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -24,6 +24,7 @@ msrv_aliases! {
     1,68,0 { PATH_MAIN_SEPARATOR_STR }
     1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
     1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE }
+    1,59,0 { THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST }
     1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY }
     1,55,0 { SEEK_REWIND }
     1,54,0 { INTO_KEYS }
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
new file mode 100644
index 00000000000..b1c552c7a8d
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -0,0 +1,322 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::macros::HirNode;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{is_trait_method, path_to_local};
+use rustc_errors::Applicability;
+use rustc_hir::{self as hir, Expr, ExprKind, Node};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{self, Instance, Mutability};
+use rustc_session::declare_lint_pass;
+use rustc_span::def_id::DefId;
+use rustc_span::symbol::sym;
+use rustc_span::ExpnKind;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for code like `foo = bar.clone();`
+    ///
+    /// ### Why is this bad?
+    /// Custom `Clone::clone_from()` or `ToOwned::clone_into` implementations allow the objects
+    /// to share resources and therefore avoid allocations.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct Thing;
+    ///
+    /// impl Clone for Thing {
+    ///     fn clone(&self) -> Self { todo!() }
+    ///     fn clone_from(&mut self, other: &Self) { todo!() }
+    /// }
+    ///
+    /// pub fn assign_to_ref(a: &mut Thing, b: Thing) {
+    ///     *a = b.clone();
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// struct Thing;
+    /// impl Clone for Thing {
+    ///     fn clone(&self) -> Self { todo!() }
+    ///     fn clone_from(&mut self, other: &Self) { todo!() }
+    /// }
+    ///
+    /// pub fn assign_to_ref(a: &mut Thing, b: Thing) {
+    ///     a.clone_from(&b);
+    /// }
+    /// ```
+    #[clippy::version = "1.77.0"]
+    pub ASSIGNING_CLONES,
+    perf,
+    "assigning the result of cloning may be inefficient"
+}
+declare_lint_pass!(AssigningClones => [ASSIGNING_CLONES]);
+
+impl<'tcx> LateLintPass<'tcx> for AssigningClones {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, assign_expr: &'tcx hir::Expr<'_>) {
+        // Do not fire the lint in macros
+        let expn_data = assign_expr.span().ctxt().outer_expn_data();
+        match expn_data.kind {
+            ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) | ExpnKind::Macro(..) => return,
+            ExpnKind::Root => {},
+        }
+
+        let ExprKind::Assign(lhs, rhs, _span) = assign_expr.kind else {
+            return;
+        };
+
+        let Some(call) = extract_call(cx, rhs) else {
+            return;
+        };
+
+        if is_ok_to_suggest(cx, lhs, &call) {
+            suggest(cx, assign_expr, lhs, &call);
+        }
+    }
+}
+
+// Try to resolve the call to `Clone::clone` or `ToOwned::to_owned`.
+fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<CallCandidate<'tcx>> {
+    let fn_def_id = clippy_utils::fn_def_id(cx, expr)?;
+
+    // Fast paths to only check method calls without arguments or function calls with a single argument
+    let (target, kind, resolved_method) = match expr.kind {
+        ExprKind::MethodCall(path, receiver, [], _span) => {
+            let args = cx.typeck_results().node_args(expr.hir_id);
+
+            // If we could not resolve the method, don't apply the lint
+            let Ok(Some(resolved_method)) = Instance::resolve(cx.tcx, cx.param_env, fn_def_id, args) else {
+                return None;
+            };
+            if is_trait_method(cx, expr, sym::Clone) && path.ident.name == sym::clone {
+                (TargetTrait::Clone, CallKind::MethodCall { receiver }, resolved_method)
+            } else if is_trait_method(cx, expr, sym::ToOwned) && path.ident.name.as_str() == "to_owned" {
+                (TargetTrait::ToOwned, CallKind::MethodCall { receiver }, resolved_method)
+            } else {
+                return None;
+            }
+        },
+        ExprKind::Call(function, [arg]) => {
+            let kind = cx.typeck_results().node_type(function.hir_id).kind();
+
+            // If we could not resolve the method, don't apply the lint
+            let Ok(Some(resolved_method)) = (match kind {
+                ty::FnDef(_, args) => Instance::resolve(cx.tcx, cx.param_env, fn_def_id, args),
+                _ => Ok(None),
+            }) else {
+                return None;
+            };
+            if cx.tcx.is_diagnostic_item(sym::to_owned_method, fn_def_id) {
+                (
+                    TargetTrait::ToOwned,
+                    CallKind::FunctionCall { self_arg: arg },
+                    resolved_method,
+                )
+            } else if let Some(trait_did) = cx.tcx.trait_of_item(fn_def_id)
+                && cx.tcx.is_diagnostic_item(sym::Clone, trait_did)
+            {
+                (
+                    TargetTrait::Clone,
+                    CallKind::FunctionCall { self_arg: arg },
+                    resolved_method,
+                )
+            } else {
+                return None;
+            }
+        },
+        _ => return None,
+    };
+
+    Some(CallCandidate {
+        target,
+        kind,
+        method_def_id: resolved_method.def_id(),
+    })
+}
+
+// Return true if we find that the called method has a custom implementation and isn't derived or
+// provided by default by the corresponding trait.
+fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>) -> bool {
+    // If the left-hand side is a local variable, it might be uninitialized at this point.
+    // In that case we do not want to suggest the lint.
+    if let Some(local) = path_to_local(lhs) {
+        // TODO: This check currently bails if the local variable has no initializer.
+        // That is overly conservative - the lint should fire even if there was no initializer,
+        // but the variable has been initialized before `lhs` was evaluated.
+        if let Some(Node::Local(local)) = cx.tcx.hir().parent_id_iter(local).next().map(|p| cx.tcx.hir_node(p))
+            && local.init.is_none()
+        {
+            return false;
+        }
+    }
+
+    let Some(impl_block) = cx.tcx.impl_of_method(call.method_def_id) else {
+        return false;
+    };
+
+    // If the method implementation comes from #[derive(Clone)], then don't suggest the lint.
+    // Automatically generated Clone impls do not currently override `clone_from`.
+    // See e.g. https://github.com/rust-lang/rust/pull/98445#issuecomment-1190681305 for more details.
+    if cx.tcx.is_builtin_derived(impl_block) {
+        return false;
+    }
+
+    // Find the function for which we want to check that it is implemented.
+    let provided_fn = match call.target {
+        TargetTrait::Clone => cx.tcx.get_diagnostic_item(sym::Clone).and_then(|clone| {
+            cx.tcx
+                .provided_trait_methods(clone)
+                .find(|item| item.name == sym::clone_from)
+        }),
+        TargetTrait::ToOwned => cx.tcx.get_diagnostic_item(sym::ToOwned).and_then(|to_owned| {
+            cx.tcx
+                .provided_trait_methods(to_owned)
+                .find(|item| item.name.as_str() == "clone_into")
+        }),
+    };
+    let Some(provided_fn) = provided_fn else {
+        return false;
+    };
+
+    // Now take a look if the impl block defines an implementation for the method that we're interested
+    // in. If not, then we're using a default implementation, which is not interesting, so we will
+    // not suggest the lint.
+    let implemented_fns = cx.tcx.impl_item_implementor_ids(impl_block);
+    implemented_fns.contains_key(&provided_fn.def_id)
+}
+
+fn suggest<'tcx>(
+    cx: &LateContext<'tcx>,
+    assign_expr: &hir::Expr<'tcx>,
+    lhs: &hir::Expr<'tcx>,
+    call: &CallCandidate<'tcx>,
+) {
+    span_lint_and_then(cx, ASSIGNING_CLONES, assign_expr.span, call.message(), |diag| {
+        let mut applicability = Applicability::MachineApplicable;
+
+        diag.span_suggestion(
+            assign_expr.span,
+            call.suggestion_msg(),
+            call.suggested_replacement(cx, lhs, &mut applicability),
+            applicability,
+        );
+    });
+}
+
+#[derive(Copy, Clone, Debug)]
+enum CallKind<'tcx> {
+    MethodCall { receiver: &'tcx Expr<'tcx> },
+    FunctionCall { self_arg: &'tcx Expr<'tcx> },
+}
+
+#[derive(Copy, Clone, Debug)]
+enum TargetTrait {
+    Clone,
+    ToOwned,
+}
+
+#[derive(Debug)]
+struct CallCandidate<'tcx> {
+    target: TargetTrait,
+    kind: CallKind<'tcx>,
+    // DefId of the called method from an impl block that implements the target trait
+    method_def_id: DefId,
+}
+
+impl<'tcx> CallCandidate<'tcx> {
+    #[inline]
+    fn message(&self) -> &'static str {
+        match self.target {
+            TargetTrait::Clone => "assigning the result of `Clone::clone()` may be inefficient",
+            TargetTrait::ToOwned => "assigning the result of `ToOwned::to_owned()` may be inefficient",
+        }
+    }
+
+    #[inline]
+    fn suggestion_msg(&self) -> &'static str {
+        match self.target {
+            TargetTrait::Clone => "use `clone_from()`",
+            TargetTrait::ToOwned => "use `clone_into()`",
+        }
+    }
+
+    fn suggested_replacement(
+        &self,
+        cx: &LateContext<'tcx>,
+        lhs: &hir::Expr<'tcx>,
+        applicability: &mut Applicability,
+    ) -> String {
+        match self.target {
+            TargetTrait::Clone => {
+                match self.kind {
+                    CallKind::MethodCall { receiver } => {
+                        let receiver_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
+                            // `*lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`
+                            Sugg::hir_with_applicability(cx, ref_expr, "_", applicability)
+                        } else {
+                            // `lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`
+                            Sugg::hir_with_applicability(cx, lhs, "_", applicability)
+                        }
+                        .maybe_par();
+
+                        // Determine whether we need to reference the argument to clone_from().
+                        let clone_receiver_type = cx.typeck_results().expr_ty(receiver);
+                        let clone_receiver_adj_type = cx.typeck_results().expr_ty_adjusted(receiver);
+                        let mut arg_sugg = Sugg::hir_with_applicability(cx, receiver, "_", applicability);
+                        if clone_receiver_type != clone_receiver_adj_type {
+                            // The receiver may have been a value type, so we need to add an `&` to
+                            // be sure the argument to clone_from will be a reference.
+                            arg_sugg = arg_sugg.addr();
+                        };
+
+                        format!("{receiver_sugg}.clone_from({arg_sugg})")
+                    },
+                    CallKind::FunctionCall { self_arg, .. } => {
+                        let self_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
+                            // `*lhs = Clone::clone(self_expr);` -> `Clone::clone_from(lhs, self_expr)`
+                            Sugg::hir_with_applicability(cx, ref_expr, "_", applicability)
+                        } else {
+                            // `lhs = Clone::clone(self_expr);` -> `Clone::clone_from(&mut lhs, self_expr)`
+                            Sugg::hir_with_applicability(cx, lhs, "_", applicability).mut_addr()
+                        };
+                        // The RHS had to be exactly correct before the call, there is no auto-deref for function calls.
+                        let rhs_sugg = Sugg::hir_with_applicability(cx, self_arg, "_", applicability);
+
+                        format!("Clone::clone_from({self_sugg}, {rhs_sugg})")
+                    },
+                }
+            },
+            TargetTrait::ToOwned => {
+                let rhs_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
+                    // `*lhs = rhs.to_owned()` -> `rhs.clone_into(lhs)`
+                    // `*lhs = ToOwned::to_owned(rhs)` -> `ToOwned::clone_into(rhs, lhs)`
+                    let sugg = Sugg::hir_with_applicability(cx, ref_expr, "_", applicability).maybe_par();
+                    let inner_type = cx.typeck_results().expr_ty(ref_expr);
+                    // If after unwrapping the dereference, the type is not a mutable reference, we add &mut to make it
+                    // deref to a mutable reference.
+                    if matches!(inner_type.kind(), ty::Ref(_, _, Mutability::Mut)) {
+                        sugg
+                    } else {
+                        sugg.mut_addr()
+                    }
+                } else {
+                    // `lhs = rhs.to_owned()` -> `rhs.clone_into(&mut lhs)`
+                    // `lhs = ToOwned::to_owned(rhs)` -> `ToOwned::clone_into(rhs, &mut lhs)`
+                    Sugg::hir_with_applicability(cx, lhs, "_", applicability)
+                        .maybe_par()
+                        .mut_addr()
+                };
+
+                match self.kind {
+                    CallKind::MethodCall { receiver } => {
+                        let receiver_sugg = Sugg::hir_with_applicability(cx, receiver, "_", applicability);
+                        format!("{receiver_sugg}.clone_into({rhs_sugg})")
+                    },
+                    CallKind::FunctionCall { self_arg, .. } => {
+                        let self_sugg = Sugg::hir_with_applicability(cx, self_arg, "_", applicability);
+                        format!("ToOwned::clone_into({self_sugg}, {rhs_sugg})")
+                    },
+                }
+            },
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
deleted file mode 100644
index f2937d51340..00000000000
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ /dev/null
@@ -1,1210 +0,0 @@
-//! checks for attributes
-
-use clippy_config::msrvs::{self, Msrv};
-use clippy_utils::diagnostics::{
-    span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
-};
-use clippy_utils::is_from_proc_macro;
-use clippy_utils::macros::{is_panic, macro_backtrace};
-use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
-use rustc_ast::token::{Token, TokenKind};
-use rustc_ast::tokenstream::TokenTree;
-use rustc_ast::{
-    AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem,
-};
-use rustc_errors::Applicability;
-use rustc_hir::{
-    Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
-};
-use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext};
-use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, impl_lint_pass};
-use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span, DUMMY_SP};
-use semver::Version;
-
-static UNIX_SYSTEMS: &[&str] = &[
-    "android",
-    "dragonfly",
-    "emscripten",
-    "freebsd",
-    "fuchsia",
-    "haiku",
-    "illumos",
-    "ios",
-    "l4re",
-    "linux",
-    "macos",
-    "netbsd",
-    "openbsd",
-    "redox",
-    "solaris",
-    "vxworks",
-];
-
-// NOTE: windows is excluded from the list because it's also a valid target family.
-static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"];
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for items annotated with `#[inline(always)]`,
-    /// unless the annotated function is empty or simply panics.
-    ///
-    /// ### Why is this bad?
-    /// While there are valid uses of this annotation (and once
-    /// you know when to use it, by all means `allow` this lint), it's a common
-    /// newbie-mistake to pepper one's code with it.
-    ///
-    /// As a rule of thumb, before slapping `#[inline(always)]` on a function,
-    /// measure if that additional function call really affects your runtime profile
-    /// sufficiently to make up for the increase in compile time.
-    ///
-    /// ### Known problems
-    /// False positives, big time. This lint is meant to be
-    /// deactivated by everyone doing serious performance work. This means having
-    /// done the measurement.
-    ///
-    /// ### Example
-    /// ```ignore
-    /// #[inline(always)]
-    /// fn not_quite_hot_code(..) { ... }
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub INLINE_ALWAYS,
-    pedantic,
-    "use of `#[inline(always)]`"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `extern crate` and `use` items annotated with
-    /// lint attributes.
-    ///
-    /// This lint permits lint attributes for lints emitted on the items themself.
-    /// For `use` items these lints are:
-    /// * deprecated
-    /// * unreachable_pub
-    /// * unused_imports
-    /// * clippy::enum_glob_use
-    /// * clippy::macro_use_imports
-    /// * clippy::wildcard_imports
-    ///
-    /// For `extern crate` items these lints are:
-    /// * `unused_imports` on items with `#[macro_use]`
-    ///
-    /// ### Why is this bad?
-    /// Lint attributes have no effect on crate imports. Most
-    /// likely a `!` was forgotten.
-    ///
-    /// ### Example
-    /// ```ignore
-    /// #[deny(dead_code)]
-    /// extern crate foo;
-    /// #[forbid(dead_code)]
-    /// use foo::bar;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```rust,ignore
-    /// #[allow(unused_imports)]
-    /// use foo::baz;
-    /// #[allow(unused_imports)]
-    /// #[macro_use]
-    /// extern crate baz;
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub USELESS_ATTRIBUTE,
-    correctness,
-    "use of lint attributes on `extern crate` items"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[deprecated]` annotations with a `since`
-    /// field that is not a valid semantic version. Also allows "TBD" to signal
-    /// future deprecation.
-    ///
-    /// ### Why is this bad?
-    /// For checking the version of the deprecation, it must be
-    /// a valid semver. Failing that, the contained information is useless.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[deprecated(since = "forever")]
-    /// fn something_else() { /* ... */ }
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub DEPRECATED_SEMVER,
-    correctness,
-    "use of `#[deprecated(since = \"x\")]` where x is not semver"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for empty lines after outer attributes
-    ///
-    /// ### Why is this bad?
-    /// Most likely the attribute was meant to be an inner attribute using a '!'.
-    /// If it was meant to be an outer attribute, then the following item
-    /// should not be separated by empty lines.
-    ///
-    /// ### Known problems
-    /// Can cause false positives.
-    ///
-    /// From the clippy side it's difficult to detect empty lines between an attributes and the
-    /// following item because empty lines and comments are not part of the AST. The parsing
-    /// currently works for basic cases but is not perfect.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[allow(dead_code)]
-    ///
-    /// fn not_quite_good_code() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// // Good (as inner attribute)
-    /// #![allow(dead_code)]
-    ///
-    /// fn this_is_fine() { }
-    ///
-    /// // or
-    ///
-    /// // Good (as outer attribute)
-    /// #[allow(dead_code)]
-    /// fn this_is_fine_too() { }
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub EMPTY_LINE_AFTER_OUTER_ATTR,
-    nursery,
-    "empty line after outer attribute"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for empty lines after documentation comments.
-    ///
-    /// ### Why is this bad?
-    /// The documentation comment was most likely meant to be an inner attribute or regular comment.
-    /// If it was intended to be a documentation comment, then the empty line should be removed to
-    /// be more idiomatic.
-    ///
-    /// ### Known problems
-    /// Only detects empty lines immediately following the documentation. If the doc comment is followed
-    /// by an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr`
-    /// in combination with this lint to detect both cases.
-    ///
-    /// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
-    ///
-    /// ### Example
-    /// ```no_run
-    /// /// Some doc comment with a blank line after it.
-    ///
-    /// fn not_quite_good_code() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// /// Good (no blank line)
-    /// fn this_is_fine() { }
-    /// ```
-    ///
-    /// ```no_run
-    /// // Good (convert to a regular comment)
-    ///
-    /// fn this_is_fine_too() { }
-    /// ```
-    ///
-    /// ```no_run
-    /// //! Good (convert to a comment on an inner attribute)
-    ///
-    /// fn this_is_fine_as_well() { }
-    /// ```
-    #[clippy::version = "1.70.0"]
-    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
-    nursery,
-    "empty line after documentation comments"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
-    ///
-    /// ### Why is this bad?
-    /// Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
-    /// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #![deny(clippy::restriction)]
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #![deny(clippy::as_conversions)]
-    /// ```
-    #[clippy::version = "1.47.0"]
-    pub BLANKET_CLIPPY_RESTRICTION_LINTS,
-    suspicious,
-    "enabling the complete restriction group"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
-    /// with `#[rustfmt::skip]`.
-    ///
-    /// ### Why is this bad?
-    /// Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
-    /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
-    ///
-    /// ### Known problems
-    /// This lint doesn't detect crate level inner attributes, because they get
-    /// processed before the PreExpansionPass lints get executed. See
-    /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg_attr(rustfmt, rustfmt_skip)]
-    /// fn main() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[rustfmt::skip]
-    /// fn main() { }
-    /// ```
-    #[clippy::version = "1.32.0"]
-    pub DEPRECATED_CFG_ATTR,
-    complexity,
-    "usage of `cfg_attr(rustfmt)` instead of tool attributes"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for cfg attributes having operating systems used in target family position.
-    ///
-    /// ### Why is this bad?
-    /// The configuration option will not be recognised and the related item will not be included
-    /// by the conditional compilation engine.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(linux)]
-    /// fn conditional() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// # mod hidden {
-    /// #[cfg(target_os = "linux")]
-    /// fn conditional() { }
-    /// # }
-    ///
-    /// // or
-    ///
-    /// #[cfg(unix)]
-    /// fn conditional() { }
-    /// ```
-    /// Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details.
-    #[clippy::version = "1.45.0"]
-    pub MISMATCHED_TARGET_OS,
-    correctness,
-    "usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for attributes that allow lints without a reason.
-    ///
-    /// (This requires the `lint_reasons` feature)
-    ///
-    /// ### Why is this bad?
-    /// Allowing a lint should always have a reason. This reason should be documented to
-    /// ensure that others understand the reasoning
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #![feature(lint_reasons)]
-    ///
-    /// #![allow(clippy::some_lint)]
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #![feature(lint_reasons)]
-    ///
-    /// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
-    /// ```
-    #[clippy::version = "1.61.0"]
-    pub ALLOW_ATTRIBUTES_WITHOUT_REASON,
-    restriction,
-    "ensures that all `allow` and `expect` attributes have a reason"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[should_panic]` attributes without specifying the expected panic message.
-    ///
-    /// ### Why is this bad?
-    /// The expected panic message should be specified to ensure that the test is actually
-    /// panicking with the expected message, and not another unrelated panic.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// fn random() -> i32 { 0 }
-    ///
-    /// #[should_panic]
-    /// #[test]
-    /// fn my_test() {
-    ///     let _ = 1 / random();
-    /// }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// fn random() -> i32 { 0 }
-    ///
-    /// #[should_panic = "attempt to divide by zero"]
-    /// #[test]
-    /// fn my_test() {
-    ///     let _ = 1 / random();
-    /// }
-    /// ```
-    #[clippy::version = "1.74.0"]
-    pub SHOULD_PANIC_WITHOUT_EXPECT,
-    pedantic,
-    "ensures that all `should_panic` attributes specify its expected panic message"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `any` and `all` combinators in `cfg` with only one condition.
-    ///
-    /// ### Why is this bad?
-    /// If there is only one condition, no need to wrap it into `any` or `all` combinators.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(any(unix))]
-    /// pub struct Bar;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[cfg(unix)]
-    /// pub struct Bar;
-    /// ```
-    #[clippy::version = "1.71.0"]
-    pub NON_MINIMAL_CFG,
-    style,
-    "ensure that all `cfg(any())` and `cfg(all())` have more than one condition"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg(features = "...")]` and suggests to replace it with
-    /// `#[cfg(feature = "...")]`.
-    ///
-    /// It also checks if `cfg(test)` was misspelled.
-    ///
-    /// ### Why is this bad?
-    /// Misspelling `feature` as `features` or `test` as `tests` can be sometimes hard to spot. It
-    /// may cause conditional compilation not work quietly.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(features = "some-feature")]
-    /// fn conditional() { }
-    /// #[cfg(tests)]
-    /// mod tests { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[cfg(feature = "some-feature")]
-    /// fn conditional() { }
-    /// #[cfg(test)]
-    /// mod tests { }
-    /// ```
-    #[clippy::version = "1.69.0"]
-    pub MAYBE_MISUSED_CFG,
-    suspicious,
-    "prevent from misusing the wrong attr name"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg_attr(feature = "cargo-clippy", ...)]` and for
-    /// `#[cfg(feature = "cargo-clippy")]` and suggests to replace it with
-    /// `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`.
-    ///
-    /// ### Why is this bad?
-    /// This feature has been deprecated for years and shouldn't be used anymore.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(feature = "cargo-clippy")]
-    /// struct Bar;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[cfg(clippy)]
-    /// struct Bar;
-    /// ```
-    #[clippy::version = "1.78.0"]
-    pub DEPRECATED_CLIPPY_CFG_ATTR,
-    suspicious,
-    "usage of `cfg(feature = \"cargo-clippy\")` instead of `cfg(clippy)`"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg_attr(clippy, allow(clippy::lint))]`
-    /// and suggests to replace it with `#[allow(clippy::lint)]`.
-    ///
-    /// ### Why is this bad?
-    /// There is no reason to put clippy attributes behind a clippy `cfg` as they are not
-    /// run by anything else than clippy.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #![cfg_attr(clippy, allow(clippy::deprecated_cfg_attr))]
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #![allow(clippy::deprecated_cfg_attr)]
-    /// ```
-    #[clippy::version = "1.78.0"]
-    pub UNNECESSARY_CLIPPY_CFG,
-    suspicious,
-    "usage of `cfg_attr(clippy, allow(clippy::lint))` instead of `allow(clippy::lint)`"
-}
-
-declare_lint_pass!(Attributes => [
-    ALLOW_ATTRIBUTES_WITHOUT_REASON,
-    INLINE_ALWAYS,
-    DEPRECATED_SEMVER,
-    USELESS_ATTRIBUTE,
-    BLANKET_CLIPPY_RESTRICTION_LINTS,
-    SHOULD_PANIC_WITHOUT_EXPECT,
-]);
-
-impl<'tcx> LateLintPass<'tcx> for Attributes {
-    fn check_crate(&mut self, cx: &LateContext<'tcx>) {
-        for (name, level) in &cx.sess().opts.lint_opts {
-            if name == "clippy::restriction" && *level > Level::Allow {
-                span_lint_and_then(
-                    cx,
-                    BLANKET_CLIPPY_RESTRICTION_LINTS,
-                    DUMMY_SP,
-                    "`clippy::restriction` is not meant to be enabled as a group",
-                    |diag| {
-                        diag.note(format!(
-                            "because of the command line `--{} clippy::restriction`",
-                            level.as_str()
-                        ));
-                        diag.help("enable the restriction lints you need individually");
-                    },
-                );
-            }
-        }
-    }
-
-    fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
-        if let Some(items) = &attr.meta_item_list() {
-            if let Some(ident) = attr.ident() {
-                if is_lint_level(ident.name) {
-                    check_clippy_lint_names(cx, ident.name, items);
-                }
-                if matches!(ident.name, sym::allow | sym::expect) {
-                    check_lint_reason(cx, ident.name, items, attr);
-                }
-                if items.is_empty() || !attr.has_name(sym::deprecated) {
-                    return;
-                }
-                for item in items {
-                    if let NestedMetaItem::MetaItem(mi) = &item
-                        && let MetaItemKind::NameValue(lit) = &mi.kind
-                        && mi.has_name(sym::since)
-                    {
-                        check_deprecated_since(cx, item.span(), lit);
-                    }
-                }
-            }
-        }
-        if attr.has_name(sym::should_panic) {
-            check_should_panic_reason(cx, attr);
-        }
-    }
-
-    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
-        let attrs = cx.tcx.hir().attrs(item.hir_id());
-        if is_relevant_item(cx, item) {
-            check_attrs(cx, item.span, item.ident.name, attrs);
-        }
-        match item.kind {
-            ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
-                let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
-
-                for attr in attrs {
-                    if in_external_macro(cx.sess(), attr.span) {
-                        return;
-                    }
-                    if let Some(lint_list) = &attr.meta_item_list() {
-                        if attr.ident().map_or(false, |ident| is_lint_level(ident.name)) {
-                            for lint in lint_list {
-                                match item.kind {
-                                    ItemKind::Use(..) => {
-                                        if is_word(lint, sym::unused_imports)
-                                            || is_word(lint, sym::deprecated)
-                                            || is_word(lint, sym!(unreachable_pub))
-                                            || is_word(lint, sym!(unused))
-                                            || is_word(lint, sym!(unused_import_braces))
-                                            || extract_clippy_lint(lint).map_or(false, |s| {
-                                                matches!(
-                                                    s.as_str(),
-                                                    "wildcard_imports"
-                                                        | "enum_glob_use"
-                                                        | "redundant_pub_crate"
-                                                        | "macro_use_imports"
-                                                        | "unsafe_removed_from_name"
-                                                        | "module_name_repetitions"
-                                                        | "single_component_path_imports"
-                                                )
-                                            })
-                                        {
-                                            return;
-                                        }
-                                    },
-                                    ItemKind::ExternCrate(..) => {
-                                        if is_word(lint, sym::unused_imports) && skip_unused_imports {
-                                            return;
-                                        }
-                                        if is_word(lint, sym!(unused_extern_crates)) {
-                                            return;
-                                        }
-                                    },
-                                    _ => {},
-                                }
-                            }
-                            let line_span = first_line_of_span(cx, attr.span);
-
-                            if let Some(mut sugg) = snippet_opt(cx, line_span) {
-                                if sugg.contains("#[") {
-                                    span_lint_and_then(
-                                        cx,
-                                        USELESS_ATTRIBUTE,
-                                        line_span,
-                                        "useless lint attribute",
-                                        |diag| {
-                                            sugg = sugg.replacen("#[", "#![", 1);
-                                            diag.span_suggestion(
-                                                line_span,
-                                                "if you just forgot a `!`, use",
-                                                sugg,
-                                                Applicability::MaybeIncorrect,
-                                            );
-                                        },
-                                    );
-                                }
-                            }
-                        }
-                    }
-                }
-            },
-            _ => {},
-        }
-    }
-
-    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
-        if is_relevant_impl(cx, item) {
-            check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
-        }
-    }
-
-    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
-        if is_relevant_trait(cx, item) {
-            check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
-        }
-    }
-}
-
-/// Returns the lint name if it is clippy lint.
-fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
-    if let Some(meta_item) = lint.meta_item()
-        && meta_item.path.segments.len() > 1
-        && let tool_name = meta_item.path.segments[0].ident
-        && tool_name.name == sym::clippy
-    {
-        let lint_name = meta_item.path.segments.last().unwrap().ident.name;
-        return Some(lint_name);
-    }
-    None
-}
-
-fn check_should_panic_reason(cx: &LateContext<'_>, attr: &Attribute) {
-    if let AttrKind::Normal(normal_attr) = &attr.kind {
-        if let AttrArgs::Eq(_, AttrArgsEq::Hir(_)) = &normal_attr.item.args {
-            // `#[should_panic = ".."]` found, good
-            return;
-        }
-
-        if let AttrArgs::Delimited(args) = &normal_attr.item.args
-            && let mut tt_iter = args.tokens.trees()
-            && let Some(TokenTree::Token(
-                Token {
-                    kind: TokenKind::Ident(sym::expected, _),
-                    ..
-                },
-                _,
-            )) = tt_iter.next()
-            && let Some(TokenTree::Token(
-                Token {
-                    kind: TokenKind::Eq, ..
-                },
-                _,
-            )) = tt_iter.next()
-            && let Some(TokenTree::Token(
-                Token {
-                    kind: TokenKind::Literal(_),
-                    ..
-                },
-                _,
-            )) = tt_iter.next()
-        {
-            // `#[should_panic(expected = "..")]` found, good
-            return;
-        }
-
-        span_lint_and_sugg(
-            cx,
-            SHOULD_PANIC_WITHOUT_EXPECT,
-            attr.span,
-            "#[should_panic] attribute without a reason",
-            "consider specifying the expected panic",
-            "#[should_panic(expected = /* panic message */)]".into(),
-            Applicability::HasPlaceholders,
-        );
-    }
-}
-
-fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
-    for lint in items {
-        if let Some(lint_name) = extract_clippy_lint(lint) {
-            if lint_name.as_str() == "restriction" && name != sym::allow {
-                span_lint_and_help(
-                    cx,
-                    BLANKET_CLIPPY_RESTRICTION_LINTS,
-                    lint.span(),
-                    "`clippy::restriction` is not meant to be enabled as a group",
-                    None,
-                    "enable the restriction lints you need individually",
-                );
-            }
-        }
-    }
-}
-
-fn check_lint_reason<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) {
-    // Check for the feature
-    if !cx.tcx.features().lint_reasons {
-        return;
-    }
-
-    // Check if the reason is present
-    if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
-        && let MetaItemKind::NameValue(_) = &item.kind
-        && item.path == sym::reason
-    {
-        return;
-    }
-
-    // Check if the attribute is in an external macro and therefore out of the developer's control
-    if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &attr) {
-        return;
-    }
-
-    span_lint_and_help(
-        cx,
-        ALLOW_ATTRIBUTES_WITHOUT_REASON,
-        attr.span,
-        &format!("`{}` attribute without specifying a reason", name.as_str()),
-        None,
-        "try adding a reason at the end with `, reason = \"..\"`",
-    );
-}
-
-fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
-    if let ItemKind::Fn(_, _, eid) = item.kind {
-        is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
-    } else {
-        true
-    }
-}
-
-fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool {
-    match item.kind {
-        ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value),
-        _ => false,
-    }
-}
-
-fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool {
-    match item.kind {
-        TraitItemKind::Fn(_, TraitFn::Required(_)) => true,
-        TraitItemKind::Fn(_, TraitFn::Provided(eid)) => {
-            is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
-        },
-        _ => false,
-    }
-}
-
-fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, block: &Block<'_>) -> bool {
-    block.stmts.first().map_or(
-        block
-            .expr
-            .as_ref()
-            .map_or(false, |e| is_relevant_expr(cx, typeck_results, e)),
-        |stmt| match &stmt.kind {
-            StmtKind::Local(_) => true,
-            StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
-            StmtKind::Item(_) => false,
-        },
-    )
-}
-
-fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, expr: &Expr<'_>) -> bool {
-    if macro_backtrace(expr.span).last().map_or(false, |macro_call| {
-        is_panic(cx, macro_call.def_id) || cx.tcx.item_name(macro_call.def_id) == sym::unreachable
-    }) {
-        return false;
-    }
-    match &expr.kind {
-        ExprKind::Block(block, _) => is_relevant_block(cx, typeck_results, block),
-        ExprKind::Ret(Some(e)) => is_relevant_expr(cx, typeck_results, e),
-        ExprKind::Ret(None) | ExprKind::Break(_, None) => false,
-        _ => true,
-    }
-}
-
-fn check_attrs(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
-    if span.from_expansion() {
-        return;
-    }
-
-    for attr in attrs {
-        if let Some(values) = attr.meta_item_list() {
-            if values.len() != 1 || !attr.has_name(sym::inline) {
-                continue;
-            }
-            if is_word(&values[0], sym::always) {
-                span_lint(
-                    cx,
-                    INLINE_ALWAYS,
-                    attr.span,
-                    &format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
-                );
-            }
-        }
-    }
-}
-
-fn check_deprecated_since(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
-    if let LitKind::Str(is, _) = lit.kind {
-        if is.as_str() == "TBD" || Version::parse(is.as_str()).is_ok() {
-            return;
-        }
-    }
-    span_lint(
-        cx,
-        DEPRECATED_SEMVER,
-        span,
-        "the since field must contain a semver-compliant version",
-    );
-}
-
-fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
-    if let NestedMetaItem::MetaItem(mi) = &nmi {
-        mi.is_word() && mi.has_name(expected)
-    } else {
-        false
-    }
-}
-
-pub struct EarlyAttributes {
-    pub msrv: Msrv,
-}
-
-impl_lint_pass!(EarlyAttributes => [
-    DEPRECATED_CFG_ATTR,
-    MISMATCHED_TARGET_OS,
-    EMPTY_LINE_AFTER_OUTER_ATTR,
-    EMPTY_LINE_AFTER_DOC_COMMENTS,
-    NON_MINIMAL_CFG,
-    MAYBE_MISUSED_CFG,
-    DEPRECATED_CLIPPY_CFG_ATTR,
-    UNNECESSARY_CLIPPY_CFG,
-]);
-
-impl EarlyLintPass for EarlyAttributes {
-    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
-        check_empty_line_after_outer_attr(cx, item);
-    }
-
-    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
-        check_deprecated_cfg_attr(cx, attr, &self.msrv);
-        check_deprecated_cfg(cx, attr);
-        check_mismatched_target_os(cx, attr);
-        check_minimal_cfg_condition(cx, attr);
-        check_misused_cfg(cx, attr);
-    }
-
-    extract_msrv_attr!(EarlyContext);
-}
-
-/// Check for empty lines after outer attributes.
-///
-/// Attributes and documentation comments are both considered outer attributes
-/// by the AST. However, the average user likely considers them to be different.
-/// Checking for empty lines after each of these attributes is split into two different
-/// lints but can share the same logic.
-fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
-    let mut iter = item.attrs.iter().peekable();
-    while let Some(attr) = iter.next() {
-        if (matches!(attr.kind, AttrKind::Normal(..)) || matches!(attr.kind, AttrKind::DocComment(..)))
-            && attr.style == AttrStyle::Outer
-            && is_present_in_source(cx, attr.span)
-        {
-            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
-            let end_of_attr_to_next_attr_or_item = Span::new(
-                attr.span.hi(),
-                iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
-                item.span.ctxt(),
-                item.span.parent(),
-            );
-
-            if let Some(snippet) = snippet_opt(cx, end_of_attr_to_next_attr_or_item) {
-                let lines = snippet.split('\n').collect::<Vec<_>>();
-                let lines = without_block_comments(lines);
-
-                if lines.iter().filter(|l| l.trim().is_empty()).count() > 2 {
-                    let (lint_msg, lint_type) = match attr.kind {
-                        AttrKind::DocComment(..) => (
-                            "found an empty line after a doc comment. \
-                            Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?",
-                            EMPTY_LINE_AFTER_DOC_COMMENTS,
-                        ),
-                        AttrKind::Normal(..) => (
-                            "found an empty line after an outer attribute. \
-                            Perhaps you forgot to add a `!` to make it an inner attribute?",
-                            EMPTY_LINE_AFTER_OUTER_ATTR,
-                        ),
-                    };
-
-                    span_lint(cx, lint_type, begin_of_attr_to_item, lint_msg);
-                }
-            }
-        }
-    }
-}
-
-fn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {
-    if item.has_name(sym::feature) && item.value_str().is_some_and(|v| v.as_str() == "cargo-clippy") {
-        span_lint_and_sugg(
-            cx,
-            DEPRECATED_CLIPPY_CFG_ATTR,
-            item.span,
-            "`feature = \"cargo-clippy\"` was replaced by `clippy`",
-            "replace with",
-            "clippy".to_string(),
-            Applicability::MachineApplicable,
-        );
-    }
-}
-
-fn check_deprecated_cfg_recursively(cx: &EarlyContext<'_>, attr: &rustc_ast::MetaItem) {
-    if let Some(ident) = attr.ident() {
-        if ["any", "all", "not"].contains(&ident.name.as_str()) {
-            let Some(list) = attr.meta_item_list() else { return };
-            for item in list.iter().filter_map(|item| item.meta_item()) {
-                check_deprecated_cfg_recursively(cx, item);
-            }
-        } else {
-            check_cargo_clippy_attr(cx, attr);
-        }
-    }
-}
-
-fn check_deprecated_cfg(cx: &EarlyContext<'_>, attr: &Attribute) {
-    if attr.has_name(sym::cfg)
-        && let Some(list) = attr.meta_item_list()
-    {
-        for item in list.iter().filter_map(|item| item.meta_item()) {
-            check_deprecated_cfg_recursively(cx, item);
-        }
-    }
-}
-
-fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) {
-    // check cfg_attr
-    if attr.has_name(sym::cfg_attr)
-        && let Some(items) = attr.meta_item_list()
-        && items.len() == 2
-        && let Some(feature_item) = items[0].meta_item()
-    {
-        // check for `rustfmt`
-        if feature_item.has_name(sym::rustfmt)
-            && msrv.meets(msrvs::TOOL_ATTRIBUTES)
-            // check for `rustfmt_skip` and `rustfmt::skip`
-            && let Some(skip_item) = &items[1].meta_item()
-            && (skip_item.has_name(sym!(rustfmt_skip))
-                || skip_item
-                    .path
-                    .segments
-                    .last()
-                    .expect("empty path in attribute")
-                    .ident
-                    .name
-                    == sym::skip)
-            // Only lint outer attributes, because custom inner attributes are unstable
-            // Tracking issue: https://github.com/rust-lang/rust/issues/54726
-            && attr.style == AttrStyle::Outer
-        {
-            span_lint_and_sugg(
-                cx,
-                DEPRECATED_CFG_ATTR,
-                attr.span,
-                "`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes",
-                "use",
-                "#[rustfmt::skip]".to_string(),
-                Applicability::MachineApplicable,
-            );
-        } else {
-            check_deprecated_cfg_recursively(cx, feature_item);
-            if let Some(behind_cfg_attr) = items[1].meta_item() {
-                check_clippy_cfg_attr(cx, feature_item, behind_cfg_attr, attr);
-            }
-        }
-    }
-}
-
-fn check_clippy_cfg_attr(
-    cx: &EarlyContext<'_>,
-    cfg_attr: &rustc_ast::MetaItem,
-    behind_cfg_attr: &rustc_ast::MetaItem,
-    attr: &Attribute,
-) {
-    if cfg_attr.has_name(sym::clippy)
-        && let Some(ident) = behind_cfg_attr.ident()
-        && Level::from_symbol(ident.name, Some(attr.id)).is_some()
-        && let Some(items) = behind_cfg_attr.meta_item_list()
-    {
-        let nb_items = items.len();
-        let mut clippy_lints = Vec::with_capacity(items.len());
-        for item in items {
-            if let Some(meta_item) = item.meta_item()
-                && let [part1, _] = meta_item.path.segments.as_slice()
-                && part1.ident.name == sym::clippy
-            {
-                clippy_lints.push(item.span());
-            }
-        }
-        if clippy_lints.is_empty() {
-            return;
-        }
-        if nb_items == clippy_lints.len() {
-            if let Some(snippet) = snippet_opt(cx, behind_cfg_attr.span) {
-                span_lint_and_sugg(
-                    cx,
-                    UNNECESSARY_CLIPPY_CFG,
-                    attr.span,
-                    "no need to put clippy lints behind a `clippy` cfg",
-                    "replace with",
-                    format!(
-                        "#{}[{}]",
-                        if attr.style == AttrStyle::Inner { "!" } else { "" },
-                        snippet
-                    ),
-                    Applicability::MachineApplicable,
-                );
-            }
-        } else {
-            let snippet = clippy_lints
-                .iter()
-                .filter_map(|sp| snippet_opt(cx, *sp))
-                .collect::<Vec<_>>()
-                .join(",");
-            span_lint_and_note(
-                cx,
-                UNNECESSARY_CLIPPY_CFG,
-                clippy_lints,
-                "no need to put clippy lints behind a `clippy` cfg",
-                None,
-                &format!(
-                    "write instead: `#{}[{}({})]`",
-                    if attr.style == AttrStyle::Inner { "!" } else { "" },
-                    ident.name,
-                    snippet
-                ),
-            );
-        }
-    }
-}
-
-fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
-    for item in items {
-        if let NestedMetaItem::MetaItem(meta) = item {
-            if !meta.has_name(sym::any) && !meta.has_name(sym::all) {
-                continue;
-            }
-            if let MetaItemKind::List(list) = &meta.kind {
-                check_nested_cfg(cx, list);
-                if list.len() == 1 {
-                    span_lint_and_then(
-                        cx,
-                        NON_MINIMAL_CFG,
-                        meta.span,
-                        "unneeded sub `cfg` when there is only one condition",
-                        |diag| {
-                            if let Some(snippet) = snippet_opt(cx, list[0].span()) {
-                                diag.span_suggestion(meta.span, "try", snippet, Applicability::MaybeIncorrect);
-                            }
-                        },
-                    );
-                } else if list.is_empty() && meta.has_name(sym::all) {
-                    span_lint_and_then(
-                        cx,
-                        NON_MINIMAL_CFG,
-                        meta.span,
-                        "unneeded sub `cfg` when there is no condition",
-                        |_| {},
-                    );
-                }
-            }
-        }
-    }
-}
-
-fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
-    for item in items {
-        if let NestedMetaItem::MetaItem(meta) = item {
-            if let Some(ident) = meta.ident()
-                && ident.name.as_str() == "features"
-                && let Some(val) = meta.value_str()
-            {
-                span_lint_and_sugg(
-                    cx,
-                    MAYBE_MISUSED_CFG,
-                    meta.span,
-                    "'feature' may be misspelled as 'features'",
-                    "did you mean",
-                    format!("feature = \"{val}\""),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            if let MetaItemKind::List(list) = &meta.kind {
-                check_nested_misused_cfg(cx, list);
-            // If this is not a list, then we check for `cfg(test)`.
-            } else if let Some(ident) = meta.ident()
-                && matches!(ident.name.as_str(), "tests" | "Test")
-            {
-                span_lint_and_sugg(
-                    cx,
-                    MAYBE_MISUSED_CFG,
-                    meta.span,
-                    &format!("'test' may be misspelled as '{}'", ident.name.as_str()),
-                    "did you mean",
-                    "test".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-        }
-    }
-}
-
-fn check_minimal_cfg_condition(cx: &EarlyContext<'_>, attr: &Attribute) {
-    if attr.has_name(sym::cfg)
-        && let Some(items) = attr.meta_item_list()
-    {
-        check_nested_cfg(cx, &items);
-    }
-}
-
-fn check_misused_cfg(cx: &EarlyContext<'_>, attr: &Attribute) {
-    if attr.has_name(sym::cfg)
-        && let Some(items) = attr.meta_item_list()
-    {
-        check_nested_misused_cfg(cx, &items);
-    }
-}
-
-fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) {
-    fn find_os(name: &str) -> Option<&'static str> {
-        UNIX_SYSTEMS
-            .iter()
-            .chain(NON_UNIX_SYSTEMS.iter())
-            .find(|&&os| os == name)
-            .copied()
-    }
-
-    fn is_unix(name: &str) -> bool {
-        UNIX_SYSTEMS.iter().any(|&os| os == name)
-    }
-
-    fn find_mismatched_target_os(items: &[NestedMetaItem]) -> Vec<(&str, Span)> {
-        let mut mismatched = Vec::new();
-
-        for item in items {
-            if let NestedMetaItem::MetaItem(meta) = item {
-                match &meta.kind {
-                    MetaItemKind::List(list) => {
-                        mismatched.extend(find_mismatched_target_os(list));
-                    },
-                    MetaItemKind::Word => {
-                        if let Some(ident) = meta.ident()
-                            && let Some(os) = find_os(ident.name.as_str())
-                        {
-                            mismatched.push((os, ident.span));
-                        }
-                    },
-                    MetaItemKind::NameValue(..) => {},
-                }
-            }
-        }
-
-        mismatched
-    }
-
-    if attr.has_name(sym::cfg)
-        && let Some(list) = attr.meta_item_list()
-        && let mismatched = find_mismatched_target_os(&list)
-        && !mismatched.is_empty()
-    {
-        let mess = "operating system used in target family position";
-
-        span_lint_and_then(cx, MISMATCHED_TARGET_OS, attr.span, mess, |diag| {
-            // Avoid showing the unix suggestion multiple times in case
-            // we have more than one mismatch for unix-like systems
-            let mut unix_suggested = false;
-
-            for (os, span) in mismatched {
-                let sugg = format!("target_os = \"{os}\"");
-                diag.span_suggestion(span, "try", sugg, Applicability::MaybeIncorrect);
-
-                if !unix_suggested && is_unix(os) {
-                    diag.help("did you mean `unix`?");
-                    unix_suggested = true;
-                }
-            }
-        });
-    }
-}
-
-fn is_lint_level(symbol: Symbol) -> bool {
-    matches!(symbol, sym::allow | sym::expect | sym::warn | sym::deny | sym::forbid)
-}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
new file mode 100644
index 00000000000..df00f23e37e
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
@@ -0,0 +1,37 @@
+use super::{Attribute, ALLOW_ATTRIBUTES_WITHOUT_REASON};
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::is_from_proc_macro;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_lint::{LateContext, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_span::sym;
+use rustc_span::symbol::Symbol;
+
+pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) {
+    // Check for the feature
+    if !cx.tcx.features().lint_reasons {
+        return;
+    }
+
+    // Check if the reason is present
+    if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
+        && let MetaItemKind::NameValue(_) = &item.kind
+        && item.path == sym::reason
+    {
+        return;
+    }
+
+    // Check if the attribute is in an external macro and therefore out of the developer's control
+    if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &attr) {
+        return;
+    }
+
+    span_lint_and_help(
+        cx,
+        ALLOW_ATTRIBUTES_WITHOUT_REASON,
+        attr.span,
+        &format!("`{}` attribute without specifying a reason", name.as_str()),
+        None,
+        "try adding a reason at the end with `, reason = \"..\"`",
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs b/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
new file mode 100644
index 00000000000..9b08fd6d654
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
@@ -0,0 +1,44 @@
+use super::utils::extract_clippy_lint;
+use super::BLANKET_CLIPPY_RESTRICTION_LINTS;
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
+use rustc_ast::NestedMetaItem;
+use rustc_lint::{LateContext, Level, LintContext};
+use rustc_span::symbol::Symbol;
+use rustc_span::{sym, DUMMY_SP};
+
+pub(super) fn check(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
+    for lint in items {
+        if let Some(lint_name) = extract_clippy_lint(lint) {
+            if lint_name.as_str() == "restriction" && name != sym::allow {
+                span_lint_and_help(
+                    cx,
+                    BLANKET_CLIPPY_RESTRICTION_LINTS,
+                    lint.span(),
+                    "`clippy::restriction` is not meant to be enabled as a group",
+                    None,
+                    "enable the restriction lints you need individually",
+                );
+            }
+        }
+    }
+}
+
+pub(super) fn check_command_line(cx: &LateContext<'_>) {
+    for (name, level) in &cx.sess().opts.lint_opts {
+        if name == "clippy::restriction" && *level > Level::Allow {
+            span_lint_and_then(
+                cx,
+                BLANKET_CLIPPY_RESTRICTION_LINTS,
+                DUMMY_SP,
+                "`clippy::restriction` is not meant to be enabled as a group",
+                |diag| {
+                    diag.note(format!(
+                        "because of the command line `--{} clippy::restriction`",
+                        level.as_str()
+                    ));
+                    diag.help("enable the restriction lints you need individually");
+                },
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
new file mode 100644
index 00000000000..e872ab6b4b5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
@@ -0,0 +1,87 @@
+use super::{unnecessary_clippy_cfg, Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR};
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::AttrStyle;
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) {
+    // check cfg_attr
+    if attr.has_name(sym::cfg_attr)
+        && let Some(items) = attr.meta_item_list()
+        && items.len() == 2
+        && let Some(feature_item) = items[0].meta_item()
+    {
+        // check for `rustfmt`
+        if feature_item.has_name(sym::rustfmt)
+            && msrv.meets(msrvs::TOOL_ATTRIBUTES)
+            // check for `rustfmt_skip` and `rustfmt::skip`
+            && let Some(skip_item) = &items[1].meta_item()
+            && (skip_item.has_name(sym!(rustfmt_skip))
+                || skip_item
+                    .path
+                    .segments
+                    .last()
+                    .expect("empty path in attribute")
+                    .ident
+                    .name
+                    == sym::skip)
+            // Only lint outer attributes, because custom inner attributes are unstable
+            // Tracking issue: https://github.com/rust-lang/rust/issues/54726
+            && attr.style == AttrStyle::Outer
+        {
+            span_lint_and_sugg(
+                cx,
+                DEPRECATED_CFG_ATTR,
+                attr.span,
+                "`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes",
+                "use",
+                "#[rustfmt::skip]".to_string(),
+                Applicability::MachineApplicable,
+            );
+        } else {
+            check_deprecated_cfg_recursively(cx, feature_item);
+            if let Some(behind_cfg_attr) = items[1].meta_item() {
+                unnecessary_clippy_cfg::check(cx, feature_item, behind_cfg_attr, attr);
+            }
+        }
+    }
+}
+
+pub(super) fn check_clippy(cx: &EarlyContext<'_>, attr: &Attribute) {
+    if attr.has_name(sym::cfg)
+        && let Some(list) = attr.meta_item_list()
+    {
+        for item in list.iter().filter_map(|item| item.meta_item()) {
+            check_deprecated_cfg_recursively(cx, item);
+        }
+    }
+}
+
+fn check_deprecated_cfg_recursively(cx: &EarlyContext<'_>, attr: &rustc_ast::MetaItem) {
+    if let Some(ident) = attr.ident() {
+        if ["any", "all", "not"].contains(&ident.name.as_str()) {
+            let Some(list) = attr.meta_item_list() else { return };
+            for item in list.iter().filter_map(|item| item.meta_item()) {
+                check_deprecated_cfg_recursively(cx, item);
+            }
+        } else {
+            check_cargo_clippy_attr(cx, attr);
+        }
+    }
+}
+
+fn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {
+    if item.has_name(sym::feature) && item.value_str().is_some_and(|v| v.as_str() == "cargo-clippy") {
+        span_lint_and_sugg(
+            cx,
+            DEPRECATED_CLIPPY_CFG_ATTR,
+            item.span,
+            "`feature = \"cargo-clippy\"` was replaced by `clippy`",
+            "replace with",
+            "clippy".to_string(),
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs
new file mode 100644
index 00000000000..1898c145c76
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs
@@ -0,0 +1,20 @@
+use super::DEPRECATED_SEMVER;
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::{LitKind, MetaItemLit};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+use semver::Version;
+
+pub(super) fn check(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
+    if let LitKind::Str(is, _) = lit.kind {
+        if is.as_str() == "TBD" || Version::parse(is.as_str()).is_ok() {
+            return;
+        }
+    }
+    span_lint(
+        cx,
+        DEPRECATED_SEMVER,
+        span,
+        "the since field must contain a semver-compliant version",
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
new file mode 100644
index 00000000000..ca43e76ac57
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
@@ -0,0 +1,52 @@
+use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::source::{is_present_in_source, snippet_opt, without_block_comments};
+use rustc_ast::{AttrKind, AttrStyle};
+use rustc_lint::EarlyContext;
+use rustc_span::Span;
+
+/// Check for empty lines after outer attributes.
+///
+/// Attributes and documentation comments are both considered outer attributes
+/// by the AST. However, the average user likely considers them to be different.
+/// Checking for empty lines after each of these attributes is split into two different
+/// lints but can share the same logic.
+pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
+    let mut iter = item.attrs.iter().peekable();
+    while let Some(attr) = iter.next() {
+        if (matches!(attr.kind, AttrKind::Normal(..)) || matches!(attr.kind, AttrKind::DocComment(..)))
+            && attr.style == AttrStyle::Outer
+            && is_present_in_source(cx, attr.span)
+        {
+            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
+            let end_of_attr_to_next_attr_or_item = Span::new(
+                attr.span.hi(),
+                iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
+                item.span.ctxt(),
+                item.span.parent(),
+            );
+
+            if let Some(snippet) = snippet_opt(cx, end_of_attr_to_next_attr_or_item) {
+                let lines = snippet.split('\n').collect::<Vec<_>>();
+                let lines = without_block_comments(lines);
+
+                if lines.iter().filter(|l| l.trim().is_empty()).count() > 2 {
+                    let (lint_msg, lint_type) = match attr.kind {
+                        AttrKind::DocComment(..) => (
+                            "found an empty line after a doc comment. \
+                            Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?",
+                            EMPTY_LINE_AFTER_DOC_COMMENTS,
+                        ),
+                        AttrKind::Normal(..) => (
+                            "found an empty line after an outer attribute. \
+                            Perhaps you forgot to add a `!` to make it an inner attribute?",
+                            EMPTY_LINE_AFTER_OUTER_ATTR,
+                        ),
+                    };
+
+                    span_lint(cx, lint_type, begin_of_attr_to_item, lint_msg);
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
new file mode 100644
index 00000000000..cfcd2cc6a00
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
@@ -0,0 +1,29 @@
+use super::utils::is_word;
+use super::INLINE_ALWAYS;
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::Attribute;
+use rustc_lint::LateContext;
+use rustc_span::symbol::Symbol;
+use rustc_span::{sym, Span};
+
+pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
+    if span.from_expansion() {
+        return;
+    }
+
+    for attr in attrs {
+        if let Some(values) = attr.meta_item_list() {
+            if values.len() != 1 || !attr.has_name(sym::inline) {
+                continue;
+            }
+            if is_word(&values[0], sym::always) {
+                span_lint(
+                    cx,
+                    INLINE_ALWAYS,
+                    attr.span,
+                    &format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs
new file mode 100644
index 00000000000..5a70866eda5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs
@@ -0,0 +1,51 @@
+use super::{Attribute, MAYBE_MISUSED_CFG};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
+    if attr.has_name(sym::cfg)
+        && let Some(items) = attr.meta_item_list()
+    {
+        check_nested_misused_cfg(cx, &items);
+    }
+}
+
+fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
+    for item in items {
+        if let NestedMetaItem::MetaItem(meta) = item {
+            if let Some(ident) = meta.ident()
+                && ident.name.as_str() == "features"
+                && let Some(val) = meta.value_str()
+            {
+                span_lint_and_sugg(
+                    cx,
+                    MAYBE_MISUSED_CFG,
+                    meta.span,
+                    "'feature' may be misspelled as 'features'",
+                    "did you mean",
+                    format!("feature = \"{val}\""),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            if let MetaItemKind::List(list) = &meta.kind {
+                check_nested_misused_cfg(cx, list);
+            // If this is not a list, then we check for `cfg(test)`.
+            } else if let Some(ident) = meta.ident()
+                && matches!(ident.name.as_str(), "tests" | "Test")
+            {
+                span_lint_and_sugg(
+                    cx,
+                    MAYBE_MISUSED_CFG,
+                    meta.span,
+                    &format!("'test' may be misspelled as '{}'", ident.name.as_str()),
+                    "did you mean",
+                    "test".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs b/src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs
new file mode 100644
index 00000000000..b1cc0a763c5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs
@@ -0,0 +1,90 @@
+use super::{Attribute, MISMATCHED_TARGET_OS};
+use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::{sym, Span};
+
+static UNIX_SYSTEMS: &[&str] = &[
+    "android",
+    "dragonfly",
+    "emscripten",
+    "freebsd",
+    "fuchsia",
+    "haiku",
+    "illumos",
+    "ios",
+    "l4re",
+    "linux",
+    "macos",
+    "netbsd",
+    "openbsd",
+    "redox",
+    "solaris",
+    "vxworks",
+];
+
+// NOTE: windows is excluded from the list because it's also a valid target family.
+static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"];
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
+    fn find_os(name: &str) -> Option<&'static str> {
+        UNIX_SYSTEMS
+            .iter()
+            .chain(NON_UNIX_SYSTEMS.iter())
+            .find(|&&os| os == name)
+            .copied()
+    }
+
+    fn is_unix(name: &str) -> bool {
+        UNIX_SYSTEMS.iter().any(|&os| os == name)
+    }
+
+    fn find_mismatched_target_os(items: &[NestedMetaItem]) -> Vec<(&str, Span)> {
+        let mut mismatched = Vec::new();
+
+        for item in items {
+            if let NestedMetaItem::MetaItem(meta) = item {
+                match &meta.kind {
+                    MetaItemKind::List(list) => {
+                        mismatched.extend(find_mismatched_target_os(list));
+                    },
+                    MetaItemKind::Word => {
+                        if let Some(ident) = meta.ident()
+                            && let Some(os) = find_os(ident.name.as_str())
+                        {
+                            mismatched.push((os, ident.span));
+                        }
+                    },
+                    MetaItemKind::NameValue(..) => {},
+                }
+            }
+        }
+
+        mismatched
+    }
+
+    if attr.has_name(sym::cfg)
+        && let Some(list) = attr.meta_item_list()
+        && let mismatched = find_mismatched_target_os(&list)
+        && !mismatched.is_empty()
+    {
+        let mess = "operating system used in target family position";
+
+        span_lint_and_then(cx, MISMATCHED_TARGET_OS, attr.span, mess, |diag| {
+            // Avoid showing the unix suggestion multiple times in case
+            // we have more than one mismatch for unix-like systems
+            let mut unix_suggested = false;
+
+            for (os, span) in mismatched {
+                let sugg = format!("target_os = \"{os}\"");
+                diag.span_suggestion(span, "try", sugg, Applicability::MaybeIncorrect);
+
+                if !unix_suggested && is_unix(os) {
+                    diag.help("did you mean `unix`?");
+                    unix_suggested = true;
+                }
+            }
+        });
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
new file mode 100644
index 00000000000..c2e21cfd330
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
@@ -0,0 +1,30 @@
+use super::MIXED_ATTRIBUTES_STYLE;
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::AttrStyle;
+use rustc_lint::EarlyContext;
+
+pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
+    let mut has_outer = false;
+    let mut has_inner = false;
+
+    for attr in &item.attrs {
+        if attr.span.from_expansion() {
+            continue;
+        }
+        match attr.style {
+            AttrStyle::Inner => has_inner = true,
+            AttrStyle::Outer => has_outer = true,
+        }
+    }
+    if !has_outer || !has_inner {
+        return;
+    }
+    let mut attrs_iter = item.attrs.iter().filter(|attr| !attr.span.from_expansion());
+    let span = attrs_iter.next().unwrap().span;
+    span_lint(
+        cx,
+        MIXED_ATTRIBUTES_STYLE,
+        span.with_hi(attrs_iter.last().unwrap().span.hi()),
+        "item has both inner and outer attributes",
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
new file mode 100644
index 00000000000..c4c65d3248a
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -0,0 +1,588 @@
+//! checks for attributes
+
+mod allow_attributes_without_reason;
+mod blanket_clippy_restriction_lints;
+mod deprecated_cfg_attr;
+mod deprecated_semver;
+mod empty_line_after;
+mod inline_always;
+mod maybe_misused_cfg;
+mod mismatched_target_os;
+mod mixed_attributes_style;
+mod non_minimal_cfg;
+mod should_panic_without_expect;
+mod unnecessary_clippy_cfg;
+mod useless_attribute;
+mod utils;
+
+use clippy_config::msrvs::Msrv;
+use rustc_ast::{Attribute, MetaItemKind, NestedMetaItem};
+use rustc_hir::{ImplItem, Item, ItemKind, TraitItem};
+use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, impl_lint_pass};
+use rustc_span::sym;
+use utils::{is_lint_level, is_relevant_impl, is_relevant_item, is_relevant_trait};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for items annotated with `#[inline(always)]`,
+    /// unless the annotated function is empty or simply panics.
+    ///
+    /// ### Why is this bad?
+    /// While there are valid uses of this annotation (and once
+    /// you know when to use it, by all means `allow` this lint), it's a common
+    /// newbie-mistake to pepper one's code with it.
+    ///
+    /// As a rule of thumb, before slapping `#[inline(always)]` on a function,
+    /// measure if that additional function call really affects your runtime profile
+    /// sufficiently to make up for the increase in compile time.
+    ///
+    /// ### Known problems
+    /// False positives, big time. This lint is meant to be
+    /// deactivated by everyone doing serious performance work. This means having
+    /// done the measurement.
+    ///
+    /// ### Example
+    /// ```ignore
+    /// #[inline(always)]
+    /// fn not_quite_hot_code(..) { ... }
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub INLINE_ALWAYS,
+    pedantic,
+    "use of `#[inline(always)]`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `extern crate` and `use` items annotated with
+    /// lint attributes.
+    ///
+    /// This lint permits lint attributes for lints emitted on the items themself.
+    /// For `use` items these lints are:
+    /// * deprecated
+    /// * unreachable_pub
+    /// * unused_imports
+    /// * clippy::enum_glob_use
+    /// * clippy::macro_use_imports
+    /// * clippy::wildcard_imports
+    ///
+    /// For `extern crate` items these lints are:
+    /// * `unused_imports` on items with `#[macro_use]`
+    ///
+    /// ### Why is this bad?
+    /// Lint attributes have no effect on crate imports. Most
+    /// likely a `!` was forgotten.
+    ///
+    /// ### Example
+    /// ```ignore
+    /// #[deny(dead_code)]
+    /// extern crate foo;
+    /// #[forbid(dead_code)]
+    /// use foo::bar;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust,ignore
+    /// #[allow(unused_imports)]
+    /// use foo::baz;
+    /// #[allow(unused_imports)]
+    /// #[macro_use]
+    /// extern crate baz;
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub USELESS_ATTRIBUTE,
+    correctness,
+    "use of lint attributes on `extern crate` items"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[deprecated]` annotations with a `since`
+    /// field that is not a valid semantic version. Also allows "TBD" to signal
+    /// future deprecation.
+    ///
+    /// ### Why is this bad?
+    /// For checking the version of the deprecation, it must be
+    /// a valid semver. Failing that, the contained information is useless.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[deprecated(since = "forever")]
+    /// fn something_else() { /* ... */ }
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub DEPRECATED_SEMVER,
+    correctness,
+    "use of `#[deprecated(since = \"x\")]` where x is not semver"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after outer attributes
+    ///
+    /// ### Why is this bad?
+    /// Most likely the attribute was meant to be an inner attribute using a '!'.
+    /// If it was meant to be an outer attribute, then the following item
+    /// should not be separated by empty lines.
+    ///
+    /// ### Known problems
+    /// Can cause false positives.
+    ///
+    /// From the clippy side it's difficult to detect empty lines between an attributes and the
+    /// following item because empty lines and comments are not part of the AST. The parsing
+    /// currently works for basic cases but is not perfect.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[allow(dead_code)]
+    ///
+    /// fn not_quite_good_code() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// // Good (as inner attribute)
+    /// #![allow(dead_code)]
+    ///
+    /// fn this_is_fine() { }
+    ///
+    /// // or
+    ///
+    /// // Good (as outer attribute)
+    /// #[allow(dead_code)]
+    /// fn this_is_fine_too() { }
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub EMPTY_LINE_AFTER_OUTER_ATTR,
+    nursery,
+    "empty line after outer attribute"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after documentation comments.
+    ///
+    /// ### Why is this bad?
+    /// The documentation comment was most likely meant to be an inner attribute or regular comment.
+    /// If it was intended to be a documentation comment, then the empty line should be removed to
+    /// be more idiomatic.
+    ///
+    /// ### Known problems
+    /// Only detects empty lines immediately following the documentation. If the doc comment is followed
+    /// by an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr`
+    /// in combination with this lint to detect both cases.
+    ///
+    /// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
+    ///
+    /// ### Example
+    /// ```no_run
+    /// /// Some doc comment with a blank line after it.
+    ///
+    /// fn not_quite_good_code() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// /// Good (no blank line)
+    /// fn this_is_fine() { }
+    /// ```
+    ///
+    /// ```no_run
+    /// // Good (convert to a regular comment)
+    ///
+    /// fn this_is_fine_too() { }
+    /// ```
+    ///
+    /// ```no_run
+    /// //! Good (convert to a comment on an inner attribute)
+    ///
+    /// fn this_is_fine_as_well() { }
+    /// ```
+    #[clippy::version = "1.70.0"]
+    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
+    nursery,
+    "empty line after documentation comments"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
+    ///
+    /// ### Why is this bad?
+    /// Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
+    /// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #![deny(clippy::restriction)]
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #![deny(clippy::as_conversions)]
+    /// ```
+    #[clippy::version = "1.47.0"]
+    pub BLANKET_CLIPPY_RESTRICTION_LINTS,
+    suspicious,
+    "enabling the complete restriction group"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
+    /// with `#[rustfmt::skip]`.
+    ///
+    /// ### Why is this bad?
+    /// Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
+    /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
+    ///
+    /// ### Known problems
+    /// This lint doesn't detect crate level inner attributes, because they get
+    /// processed before the PreExpansionPass lints get executed. See
+    /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg_attr(rustfmt, rustfmt_skip)]
+    /// fn main() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[rustfmt::skip]
+    /// fn main() { }
+    /// ```
+    #[clippy::version = "1.32.0"]
+    pub DEPRECATED_CFG_ATTR,
+    complexity,
+    "usage of `cfg_attr(rustfmt)` instead of tool attributes"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for cfg attributes having operating systems used in target family position.
+    ///
+    /// ### Why is this bad?
+    /// The configuration option will not be recognised and the related item will not be included
+    /// by the conditional compilation engine.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(linux)]
+    /// fn conditional() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// # mod hidden {
+    /// #[cfg(target_os = "linux")]
+    /// fn conditional() { }
+    /// # }
+    ///
+    /// // or
+    ///
+    /// #[cfg(unix)]
+    /// fn conditional() { }
+    /// ```
+    /// Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details.
+    #[clippy::version = "1.45.0"]
+    pub MISMATCHED_TARGET_OS,
+    correctness,
+    "usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for attributes that allow lints without a reason.
+    ///
+    /// (This requires the `lint_reasons` feature)
+    ///
+    /// ### Why is this bad?
+    /// Allowing a lint should always have a reason. This reason should be documented to
+    /// ensure that others understand the reasoning
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #![feature(lint_reasons)]
+    ///
+    /// #![allow(clippy::some_lint)]
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #![feature(lint_reasons)]
+    ///
+    /// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
+    /// ```
+    #[clippy::version = "1.61.0"]
+    pub ALLOW_ATTRIBUTES_WITHOUT_REASON,
+    restriction,
+    "ensures that all `allow` and `expect` attributes have a reason"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[should_panic]` attributes without specifying the expected panic message.
+    ///
+    /// ### Why is this bad?
+    /// The expected panic message should be specified to ensure that the test is actually
+    /// panicking with the expected message, and not another unrelated panic.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// fn random() -> i32 { 0 }
+    ///
+    /// #[should_panic]
+    /// #[test]
+    /// fn my_test() {
+    ///     let _ = 1 / random();
+    /// }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// fn random() -> i32 { 0 }
+    ///
+    /// #[should_panic = "attempt to divide by zero"]
+    /// #[test]
+    /// fn my_test() {
+    ///     let _ = 1 / random();
+    /// }
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub SHOULD_PANIC_WITHOUT_EXPECT,
+    pedantic,
+    "ensures that all `should_panic` attributes specify its expected panic message"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `any` and `all` combinators in `cfg` with only one condition.
+    ///
+    /// ### Why is this bad?
+    /// If there is only one condition, no need to wrap it into `any` or `all` combinators.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(any(unix))]
+    /// pub struct Bar;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(unix)]
+    /// pub struct Bar;
+    /// ```
+    #[clippy::version = "1.71.0"]
+    pub NON_MINIMAL_CFG,
+    style,
+    "ensure that all `cfg(any())` and `cfg(all())` have more than one condition"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg(features = "...")]` and suggests to replace it with
+    /// `#[cfg(feature = "...")]`.
+    ///
+    /// It also checks if `cfg(test)` was misspelled.
+    ///
+    /// ### Why is this bad?
+    /// Misspelling `feature` as `features` or `test` as `tests` can be sometimes hard to spot. It
+    /// may cause conditional compilation not work quietly.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(features = "some-feature")]
+    /// fn conditional() { }
+    /// #[cfg(tests)]
+    /// mod tests { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(feature = "some-feature")]
+    /// fn conditional() { }
+    /// #[cfg(test)]
+    /// mod tests { }
+    /// ```
+    #[clippy::version = "1.69.0"]
+    pub MAYBE_MISUSED_CFG,
+    suspicious,
+    "prevent from misusing the wrong attr name"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg_attr(feature = "cargo-clippy", ...)]` and for
+    /// `#[cfg(feature = "cargo-clippy")]` and suggests to replace it with
+    /// `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`.
+    ///
+    /// ### Why is this bad?
+    /// This feature has been deprecated for years and shouldn't be used anymore.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(feature = "cargo-clippy")]
+    /// struct Bar;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(clippy)]
+    /// struct Bar;
+    /// ```
+    #[clippy::version = "1.78.0"]
+    pub DEPRECATED_CLIPPY_CFG_ATTR,
+    suspicious,
+    "usage of `cfg(feature = \"cargo-clippy\")` instead of `cfg(clippy)`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg_attr(clippy, allow(clippy::lint))]`
+    /// and suggests to replace it with `#[allow(clippy::lint)]`.
+    ///
+    /// ### Why is this bad?
+    /// There is no reason to put clippy attributes behind a clippy `cfg` as they are not
+    /// run by anything else than clippy.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #![cfg_attr(clippy, allow(clippy::deprecated_cfg_attr))]
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #![allow(clippy::deprecated_cfg_attr)]
+    /// ```
+    #[clippy::version = "1.78.0"]
+    pub UNNECESSARY_CLIPPY_CFG,
+    suspicious,
+    "usage of `cfg_attr(clippy, allow(clippy::lint))` instead of `allow(clippy::lint)`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks that an item has only one kind of attributes.
+    ///
+    /// ### Why is this bad?
+    /// Having both kinds of attributes makes it more complicated to read code.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(linux)]
+    /// pub fn foo() {
+    ///     #![cfg(windows)]
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(linux)]
+    /// #[cfg(windows)]
+    /// pub fn foo() {
+    /// }
+    /// ```
+    #[clippy::version = "1.78.0"]
+    pub MIXED_ATTRIBUTES_STYLE,
+    suspicious,
+    "item has both inner and outer attributes"
+}
+
+declare_lint_pass!(Attributes => [
+    ALLOW_ATTRIBUTES_WITHOUT_REASON,
+    INLINE_ALWAYS,
+    DEPRECATED_SEMVER,
+    USELESS_ATTRIBUTE,
+    BLANKET_CLIPPY_RESTRICTION_LINTS,
+    SHOULD_PANIC_WITHOUT_EXPECT,
+]);
+
+impl<'tcx> LateLintPass<'tcx> for Attributes {
+    fn check_crate(&mut self, cx: &LateContext<'tcx>) {
+        blanket_clippy_restriction_lints::check_command_line(cx);
+    }
+
+    fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
+        if let Some(items) = &attr.meta_item_list() {
+            if let Some(ident) = attr.ident() {
+                if is_lint_level(ident.name, attr.id) {
+                    blanket_clippy_restriction_lints::check(cx, ident.name, items);
+                }
+                if matches!(ident.name, sym::allow | sym::expect) {
+                    allow_attributes_without_reason::check(cx, ident.name, items, attr);
+                }
+                if items.is_empty() || !attr.has_name(sym::deprecated) {
+                    return;
+                }
+                for item in items {
+                    if let NestedMetaItem::MetaItem(mi) = &item
+                        && let MetaItemKind::NameValue(lit) = &mi.kind
+                        && mi.has_name(sym::since)
+                    {
+                        deprecated_semver::check(cx, item.span(), lit);
+                    }
+                }
+            }
+        }
+        if attr.has_name(sym::should_panic) {
+            should_panic_without_expect::check(cx, attr);
+        }
+    }
+
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
+        let attrs = cx.tcx.hir().attrs(item.hir_id());
+        if is_relevant_item(cx, item) {
+            inline_always::check(cx, item.span, item.ident.name, attrs);
+        }
+        match item.kind {
+            ItemKind::ExternCrate(..) | ItemKind::Use(..) => useless_attribute::check(cx, item, attrs),
+            _ => {},
+        }
+    }
+
+    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
+        if is_relevant_impl(cx, item) {
+            inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
+        }
+    }
+
+    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
+        if is_relevant_trait(cx, item) {
+            inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
+        }
+    }
+}
+
+pub struct EarlyAttributes {
+    pub msrv: Msrv,
+}
+
+impl_lint_pass!(EarlyAttributes => [
+    DEPRECATED_CFG_ATTR,
+    MISMATCHED_TARGET_OS,
+    EMPTY_LINE_AFTER_OUTER_ATTR,
+    EMPTY_LINE_AFTER_DOC_COMMENTS,
+    NON_MINIMAL_CFG,
+    MAYBE_MISUSED_CFG,
+    DEPRECATED_CLIPPY_CFG_ATTR,
+    UNNECESSARY_CLIPPY_CFG,
+    MIXED_ATTRIBUTES_STYLE,
+]);
+
+impl EarlyLintPass for EarlyAttributes {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
+        empty_line_after::check(cx, item);
+        mixed_attributes_style::check(cx, item);
+    }
+
+    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
+        deprecated_cfg_attr::check(cx, attr, &self.msrv);
+        deprecated_cfg_attr::check_clippy(cx, attr);
+        mismatched_target_os::check(cx, attr);
+        non_minimal_cfg::check(cx, attr);
+        maybe_misused_cfg::check(cx, attr);
+    }
+
+    extract_msrv_attr!(EarlyContext);
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
new file mode 100644
index 00000000000..3fde7061585
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
@@ -0,0 +1,49 @@
+use super::{Attribute, NON_MINIMAL_CFG};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet_opt;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
+    if attr.has_name(sym::cfg)
+        && let Some(items) = attr.meta_item_list()
+    {
+        check_nested_cfg(cx, &items);
+    }
+}
+
+fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
+    for item in items {
+        if let NestedMetaItem::MetaItem(meta) = item {
+            if !meta.has_name(sym::any) && !meta.has_name(sym::all) {
+                continue;
+            }
+            if let MetaItemKind::List(list) = &meta.kind {
+                check_nested_cfg(cx, list);
+                if list.len() == 1 {
+                    span_lint_and_then(
+                        cx,
+                        NON_MINIMAL_CFG,
+                        meta.span,
+                        "unneeded sub `cfg` when there is only one condition",
+                        |diag| {
+                            if let Some(snippet) = snippet_opt(cx, list[0].span()) {
+                                diag.span_suggestion(meta.span, "try", snippet, Applicability::MaybeIncorrect);
+                            }
+                        },
+                    );
+                } else if list.is_empty() && meta.has_name(sym::all) {
+                    span_lint_and_then(
+                        cx,
+                        NON_MINIMAL_CFG,
+                        meta.span,
+                        "unneeded sub `cfg` when there is no condition",
+                        |_| {},
+                    );
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs
new file mode 100644
index 00000000000..2d45cbbf621
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs
@@ -0,0 +1,54 @@
+use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::token::{Token, TokenKind};
+use rustc_ast::tokenstream::TokenTree;
+use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind};
+use rustc_errors::Applicability;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &LateContext<'_>, attr: &Attribute) {
+    if let AttrKind::Normal(normal_attr) = &attr.kind {
+        if let AttrArgs::Eq(_, AttrArgsEq::Hir(_)) = &normal_attr.item.args {
+            // `#[should_panic = ".."]` found, good
+            return;
+        }
+
+        if let AttrArgs::Delimited(args) = &normal_attr.item.args
+            && let mut tt_iter = args.tokens.trees()
+            && let Some(TokenTree::Token(
+                Token {
+                    kind: TokenKind::Ident(sym::expected, _),
+                    ..
+                },
+                _,
+            )) = tt_iter.next()
+            && let Some(TokenTree::Token(
+                Token {
+                    kind: TokenKind::Eq, ..
+                },
+                _,
+            )) = tt_iter.next()
+            && let Some(TokenTree::Token(
+                Token {
+                    kind: TokenKind::Literal(_),
+                    ..
+                },
+                _,
+            )) = tt_iter.next()
+        {
+            // `#[should_panic(expected = "..")]` found, good
+            return;
+        }
+
+        span_lint_and_sugg(
+            cx,
+            SHOULD_PANIC_WITHOUT_EXPECT,
+            attr.span,
+            "#[should_panic] attribute without a reason",
+            "consider specifying the expected panic",
+            "#[should_panic(expected = /* panic message */)]".into(),
+            Applicability::HasPlaceholders,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
new file mode 100644
index 00000000000..05da69636c6
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
@@ -0,0 +1,70 @@
+use super::{Attribute, UNNECESSARY_CLIPPY_CFG};
+use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
+use clippy_utils::source::snippet_opt;
+use rustc_ast::AttrStyle;
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, Level};
+use rustc_span::sym;
+
+pub(super) fn check(
+    cx: &EarlyContext<'_>,
+    cfg_attr: &rustc_ast::MetaItem,
+    behind_cfg_attr: &rustc_ast::MetaItem,
+    attr: &Attribute,
+) {
+    if cfg_attr.has_name(sym::clippy)
+        && let Some(ident) = behind_cfg_attr.ident()
+        && Level::from_symbol(ident.name, Some(attr.id)).is_some()
+        && let Some(items) = behind_cfg_attr.meta_item_list()
+    {
+        let nb_items = items.len();
+        let mut clippy_lints = Vec::with_capacity(items.len());
+        for item in items {
+            if let Some(meta_item) = item.meta_item()
+                && let [part1, _] = meta_item.path.segments.as_slice()
+                && part1.ident.name == sym::clippy
+            {
+                clippy_lints.push(item.span());
+            }
+        }
+        if clippy_lints.is_empty() {
+            return;
+        }
+        if nb_items == clippy_lints.len() {
+            if let Some(snippet) = snippet_opt(cx, behind_cfg_attr.span) {
+                span_lint_and_sugg(
+                    cx,
+                    UNNECESSARY_CLIPPY_CFG,
+                    attr.span,
+                    "no need to put clippy lints behind a `clippy` cfg",
+                    "replace with",
+                    format!(
+                        "#{}[{}]",
+                        if attr.style == AttrStyle::Inner { "!" } else { "" },
+                        snippet
+                    ),
+                    Applicability::MachineApplicable,
+                );
+            }
+        } else {
+            let snippet = clippy_lints
+                .iter()
+                .filter_map(|sp| snippet_opt(cx, *sp))
+                .collect::<Vec<_>>()
+                .join(",");
+            span_lint_and_note(
+                cx,
+                UNNECESSARY_CLIPPY_CFG,
+                clippy_lints,
+                "no need to put clippy lints behind a `clippy` cfg",
+                None,
+                &format!(
+                    "write instead: `#{}[{}({})]`",
+                    if attr.style == AttrStyle::Inner { "!" } else { "" },
+                    ident.name,
+                    snippet
+                ),
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
new file mode 100644
index 00000000000..7575f502a7c
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -0,0 +1,73 @@
+use super::utils::{extract_clippy_lint, is_lint_level, is_word};
+use super::{Attribute, USELESS_ATTRIBUTE};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::{first_line_of_span, snippet_opt};
+use rustc_errors::Applicability;
+use rustc_hir::{Item, ItemKind};
+use rustc_lint::{LateContext, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute]) {
+    let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
+
+    for attr in attrs {
+        if in_external_macro(cx.sess(), attr.span) {
+            return;
+        }
+        if let Some(lint_list) = &attr.meta_item_list() {
+            if attr.ident().map_or(false, |ident| is_lint_level(ident.name, attr.id)) {
+                for lint in lint_list {
+                    match item.kind {
+                        ItemKind::Use(..) => {
+                            if is_word(lint, sym::unused_imports)
+                                || is_word(lint, sym::deprecated)
+                                || is_word(lint, sym!(unreachable_pub))
+                                || is_word(lint, sym!(unused))
+                                || is_word(lint, sym!(unused_import_braces))
+                                || extract_clippy_lint(lint).map_or(false, |s| {
+                                    matches!(
+                                        s.as_str(),
+                                        "wildcard_imports"
+                                            | "enum_glob_use"
+                                            | "redundant_pub_crate"
+                                            | "macro_use_imports"
+                                            | "unsafe_removed_from_name"
+                                            | "module_name_repetitions"
+                                            | "single_component_path_imports"
+                                    )
+                                })
+                            {
+                                return;
+                            }
+                        },
+                        ItemKind::ExternCrate(..) => {
+                            if is_word(lint, sym::unused_imports) && skip_unused_imports {
+                                return;
+                            }
+                            if is_word(lint, sym!(unused_extern_crates)) {
+                                return;
+                            }
+                        },
+                        _ => {},
+                    }
+                }
+                let line_span = first_line_of_span(cx, attr.span);
+
+                if let Some(mut sugg) = snippet_opt(cx, line_span) {
+                    if sugg.contains("#[") {
+                        span_lint_and_then(cx, USELESS_ATTRIBUTE, line_span, "useless lint attribute", |diag| {
+                            sugg = sugg.replacen("#[", "#![", 1);
+                            diag.span_suggestion(
+                                line_span,
+                                "if you just forgot a `!`, use",
+                                sugg,
+                                Applicability::MaybeIncorrect,
+                            );
+                        });
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/utils.rs b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
new file mode 100644
index 00000000000..9b36cc00444
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
@@ -0,0 +1,87 @@
+use clippy_utils::macros::{is_panic, macro_backtrace};
+use rustc_ast::{AttrId, NestedMetaItem};
+use rustc_hir::{
+    Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
+};
+use rustc_lint::{LateContext, Level};
+use rustc_middle::ty;
+use rustc_span::sym;
+use rustc_span::symbol::Symbol;
+
+pub(super) fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
+    if let NestedMetaItem::MetaItem(mi) = &nmi {
+        mi.is_word() && mi.has_name(expected)
+    } else {
+        false
+    }
+}
+
+pub(super) fn is_lint_level(symbol: Symbol, attr_id: AttrId) -> bool {
+    Level::from_symbol(symbol, Some(attr_id)).is_some()
+}
+
+pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
+    if let ItemKind::Fn(_, _, eid) = item.kind {
+        is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
+    } else {
+        true
+    }
+}
+
+pub(super) fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool {
+    match item.kind {
+        ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value),
+        _ => false,
+    }
+}
+
+pub(super) fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool {
+    match item.kind {
+        TraitItemKind::Fn(_, TraitFn::Required(_)) => true,
+        TraitItemKind::Fn(_, TraitFn::Provided(eid)) => {
+            is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
+        },
+        _ => false,
+    }
+}
+
+fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, block: &Block<'_>) -> bool {
+    block.stmts.first().map_or(
+        block
+            .expr
+            .as_ref()
+            .map_or(false, |e| is_relevant_expr(cx, typeck_results, e)),
+        |stmt| match &stmt.kind {
+            StmtKind::Local(_) => true,
+            StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
+            StmtKind::Item(_) => false,
+        },
+    )
+}
+
+fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, expr: &Expr<'_>) -> bool {
+    if macro_backtrace(expr.span).last().map_or(false, |macro_call| {
+        is_panic(cx, macro_call.def_id) || cx.tcx.item_name(macro_call.def_id) == sym::unreachable
+    }) {
+        return false;
+    }
+    match &expr.kind {
+        ExprKind::Block(block, _) => is_relevant_block(cx, typeck_results, block),
+        ExprKind::Ret(Some(e)) => is_relevant_expr(cx, typeck_results, e),
+        ExprKind::Ret(None) | ExprKind::Break(_, None) => false,
+        _ => true,
+    }
+}
+
+/// Returns the lint name if it is clippy lint.
+pub(super) fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
+    if let Some(meta_item) = lint.meta_item()
+        && meta_item.path.segments.len() > 1
+        && let tool_name = meta_item.path.segments[0].ident
+        && tool_name.name == sym::clippy
+    {
+        let lint_name = meta_item.path.segments.last().unwrap().ident.name;
+        return Some(lint_name);
+    }
+    None
+}
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 0d66f2d644d..a474356608f 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -88,7 +88,6 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         match expr.kind {
-            ExprKind::Unary(UnOp::Not, sub) => check_inverted_condition(cx, expr.span, sub),
             // This check the case where an element in a boolean comparison is inverted, like:
             //
             // ```
@@ -119,27 +118,6 @@ fn bin_op_eq_str(op: BinOpKind) -> Option<&'static str> {
     }
 }
 
-fn check_inverted_condition(cx: &LateContext<'_>, expr_span: Span, sub_expr: &Expr<'_>) {
-    if !expr_span.from_expansion()
-        && let ExprKind::Binary(op, left, right) = sub_expr.kind
-        && let Some(left) = snippet_opt(cx, left.span)
-        && let Some(right) = snippet_opt(cx, right.span)
-    {
-        let Some(op) = inverted_bin_op_eq_str(op.node) else {
-            return;
-        };
-        span_lint_and_sugg(
-            cx,
-            NONMINIMAL_BOOL,
-            expr_span,
-            "this boolean expression can be simplified",
-            "try",
-            format!("{left} {op} {right}",),
-            Applicability::MachineApplicable,
-        );
-    }
-}
-
 fn check_inverted_bool_in_condition(
     cx: &LateContext<'_>,
     expr_span: Span,
@@ -148,8 +126,8 @@ fn check_inverted_bool_in_condition(
     right: &Expr<'_>,
 ) {
     if expr_span.from_expansion()
-        && (!cx.typeck_results().node_types()[left.hir_id].is_bool()
-            || !cx.typeck_results().node_types()[right.hir_id].is_bool())
+        || !cx.typeck_results().node_types()[left.hir_id].is_bool()
+        || !cx.typeck_results().node_types()[right.hir_id].is_bool()
     {
         return;
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index cc513d46bf4..08341ff32f3 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -151,13 +151,24 @@ pub(super) fn check<'tcx>(
             return false;
         }
 
+        // If the whole cast expression is a unary expression (`(*x as T)`) or an addressof
+        // expression (`(&x as T)`), then not surrounding the suggestion into a block risks us
+        // changing the precedence of operators if the cast expression is followed by an operation
+        // with higher precedence than the unary operator (`(*x as T).foo()` would become
+        // `*x.foo()`, which changes what the `*` applies on).
+        // The same is true if the expression encompassing the cast expression is a unary
+        // expression or an addressof expression.
+        let needs_block = matches!(cast_expr.kind, ExprKind::Unary(..) | ExprKind::AddrOf(..))
+            || get_parent_expr(cx, expr)
+                .map_or(false, |e| matches!(e.kind, ExprKind::Unary(..) | ExprKind::AddrOf(..)));
+
         span_lint_and_sugg(
             cx,
             UNNECESSARY_CAST,
             expr.span,
             &format!("casting to the same type is unnecessary (`{cast_from}` -> `{cast_to}`)"),
             "try",
-            if get_parent_expr(cx, expr).map_or(false, |e| matches!(e.kind, ExprKind::AddrOf(..))) {
+            if needs_block {
                 format!("{{ {cast_str} }}")
             } else {
                 cast_str
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index fb3ae2457e3..2b324f5f96e 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -47,6 +47,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX_INFO,
     crate::assertions_on_constants::ASSERTIONS_ON_CONSTANTS_INFO,
     crate::assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES_INFO,
+    crate::assigning_clones::ASSIGNING_CLONES_INFO,
     crate::async_yields_async::ASYNC_YIELDS_ASYNC_INFO,
     crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO,
     crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO,
@@ -58,6 +59,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::attrs::INLINE_ALWAYS_INFO,
     crate::attrs::MAYBE_MISUSED_CFG_INFO,
     crate::attrs::MISMATCHED_TARGET_OS_INFO,
+    crate::attrs::MIXED_ATTRIBUTES_STYLE_INFO,
     crate::attrs::NON_MINIMAL_CFG_INFO,
     crate::attrs::SHOULD_PANIC_WITHOUT_EXPECT_INFO,
     crate::attrs::UNNECESSARY_CLIPPY_CFG_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 6144ec7b3ca..f0f2c7d6658 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -451,8 +451,8 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
         && let Some(def_id) = trait_ref.trait_def_id()
         && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
         && !has_non_exhaustive_attr(cx.tcx, *adt)
+        && !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)
         && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
-        && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
         // If all of our fields implement `Eq`, we can implement `Eq` too
         && adt
             .all_fields()
@@ -471,6 +471,10 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
     }
 }
 
+fn ty_implements_eq_trait<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, eq_trait_id: DefId) -> bool {
+    tcx.non_blanket_impls_for_ty(eq_trait_id, ty).next().is_some()
+}
+
 /// Creates the `ParamEnv` used for the give type's derived `Eq` impl.
 fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ParamEnv<'_> {
     // Initial map from generic index to param def.
diff --git a/src/tools/clippy/clippy_lints/src/doc/markdown.rs b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
index a58219c2946..d2f14756591 100644
--- a/src/tools/clippy/clippy_lints/src/doc/markdown.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
@@ -8,7 +8,7 @@ use url::Url;
 
 use crate::doc::DOC_MARKDOWN;
 
-pub fn check(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span) {
+pub fn check(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span, code_level: isize) {
     for orig_word in text.split(|c: char| c.is_whitespace() || c == '\'') {
         // Trim punctuation as in `some comment (see foo::bar).`
         //                                                   ^^
@@ -46,11 +46,11 @@ pub fn check(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str,
             span.parent(),
         );
 
-        check_word(cx, word, span);
+        check_word(cx, word, span, code_level);
     }
 }
 
-fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
+fn check_word(cx: &LateContext<'_>, word: &str, span: Span, code_level: isize) {
     /// Checks if a string is upper-camel-case, i.e., starts with an uppercase and
     /// contains at least two uppercase letters (`Clippy` is ok) and one lower-case
     /// letter (`NASA` is ok).
@@ -60,7 +60,14 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
             return false;
         }
 
-        let s = s.strip_suffix('s').unwrap_or(s);
+        let s = if let Some(prefix) = s.strip_suffix("es")
+            && prefix.chars().all(|c| c.is_ascii_uppercase())
+            && matches!(prefix.chars().last(), Some('S' | 'X'))
+        {
+            prefix
+        } else {
+            s.strip_suffix('s').unwrap_or(s)
+        };
 
         s.chars().all(char::is_alphanumeric)
             && s.chars().filter(|&c| c.is_uppercase()).take(2).count() > 1
@@ -90,7 +97,7 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
     }
 
     // We assume that mixed-case words are not meant to be put inside backticks. (Issue #2343)
-    if has_underscore(word) && has_hyphen(word) {
+    if code_level > 0 || (has_underscore(word) && has_hyphen(word)) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 9af34c3a7bf..003d26b7b89 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -599,10 +599,19 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     let mut ignore = false;
     let mut edition = None;
     let mut ticks_unbalanced = false;
-    let mut text_to_check: Vec<(CowStr<'_>, Range<usize>)> = Vec::new();
+    let mut text_to_check: Vec<(CowStr<'_>, Range<usize>, isize)> = Vec::new();
     let mut paragraph_range = 0..0;
+    let mut code_level = 0;
+
     for (event, range) in events {
         match event {
+            Html(tag) => {
+                if tag.starts_with("<code") {
+                    code_level += 1;
+                } else if tag.starts_with("</code") {
+                    code_level -= 1;
+                }
+            },
             Start(CodeBlock(ref kind)) => {
                 in_code = true;
                 if let CodeBlockKind::Fenced(lang) = kind {
@@ -652,16 +661,15 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                         "a backtick may be missing a pair",
                     );
                 } else {
-                    for (text, range) in text_to_check {
+                    for (text, range, assoc_code_level) in text_to_check {
                         if let Some(span) = fragments.span(cx, range) {
-                            markdown::check(cx, valid_idents, &text, span);
+                            markdown::check(cx, valid_idents, &text, span, assoc_code_level);
                         }
                     }
                 }
                 text_to_check = Vec::new();
             },
             Start(_tag) | End(_tag) => (), // We don't care about other tags
-            Html(_html) => (),             // HTML is weird, just ignore it
             SoftBreak | HardBreak | TaskListMarker(_) | Code(_) | Rule => (),
             FootnoteReference(text) | Text(text) => {
                 paragraph_range.end = range.end;
@@ -694,7 +702,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                         // Don't check the text associated with external URLs
                         continue;
                     }
-                    text_to_check.push((text, range));
+                    text_to_check.push((text, range, code_level));
                 }
             },
         }
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index 0b4bc375df0..de6073c2723 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -214,12 +214,31 @@ impl MapType {
     }
 }
 
+/// Details on an expression checking whether a map contains a key.
+///
+/// For instance, with the following:
+/// ```ignore
+/// !!!self.the_map.contains_key("the_key")
+/// ```
+///
+/// - `negated` will be set to `true` (the 3 `!` negate the condition)
+/// - `map` will be the `self.the_map` expression
+/// - `key` will be the `"the_key"` expression
 struct ContainsExpr<'tcx> {
+    /// Whether the check for `contains_key` was negated.
     negated: bool,
+    /// The map on which the check is performed.
     map: &'tcx Expr<'tcx>,
+    /// The key that is checked to be contained.
     key: &'tcx Expr<'tcx>,
+    /// The context of the whole condition expression.
     call_ctxt: SyntaxContext,
 }
+
+/// Inspect the given expression and return details about the `contains_key` check.
+///
+/// If the given expression is not a `contains_key` check against a `BTreeMap` or a `HashMap`,
+/// return `None`.
 fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Option<(MapType, ContainsExpr<'tcx>)> {
     let mut negated = false;
     let expr = peel_hir_expr_while(expr, |e| match e.kind {
@@ -229,6 +248,7 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
         },
         _ => None,
     });
+
     match expr.kind {
         ExprKind::MethodCall(
             _,
@@ -261,11 +281,28 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
     }
 }
 
+/// Details on an expression inserting a key into a map.
+///
+/// For instance, on the following:
+/// ```ignore
+/// self.the_map.insert("the_key", 3 + 4);
+/// ```
+///
+/// - `map` will be the `self.the_map` expression
+/// - `key` will be the `"the_key"` expression
+/// - `value` will be the `3 + 4` expression
 struct InsertExpr<'tcx> {
+    /// The map into which the insertion is performed.
     map: &'tcx Expr<'tcx>,
+    /// The key at which to insert.
     key: &'tcx Expr<'tcx>,
+    /// The value to insert.
     value: &'tcx Expr<'tcx>,
 }
+
+/// Inspect the given expression and return details about the `insert` call.
+///
+/// If the given expression is not an `insert` call into a `BTreeMap` or a `HashMap`, return `None`.
 fn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {
     if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {
         let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
@@ -298,7 +335,7 @@ struct Insertion<'tcx> {
     value: &'tcx Expr<'tcx>,
 }
 
-/// This visitor needs to do a multiple things:
+/// This visitor needs to do multiple things:
 /// * Find all usages of the map. An insertion can only be made before any other usages of the map.
 /// * Determine if there's an insertion using the same key. There's no need for the entry api
 ///   otherwise.
@@ -346,7 +383,7 @@ impl<'tcx> InsertSearcher<'_, 'tcx> {
         res
     }
 
-    /// Visits an expression which is not itself in a tail position, but other sibling expressions
+    /// Visit an expression which is not itself in a tail position, but other sibling expressions
     /// may be. e.g. if conditions
     fn visit_non_tail_expr(&mut self, e: &'tcx Expr<'_>) {
         let in_tail_pos = self.in_tail_pos;
@@ -354,6 +391,19 @@ impl<'tcx> InsertSearcher<'_, 'tcx> {
         self.visit_expr(e);
         self.in_tail_pos = in_tail_pos;
     }
+
+    /// Visit the key and value expression of an insert expression.
+    /// There may not be uses of the map in either of those two either.
+    fn visit_insert_expr_arguments(&mut self, e: &InsertExpr<'tcx>) {
+        let in_tail_pos = self.in_tail_pos;
+        let allow_insert_closure = self.allow_insert_closure;
+        let is_single_insert = self.is_single_insert;
+        walk_expr(self, e.key);
+        walk_expr(self, e.value);
+        self.in_tail_pos = in_tail_pos;
+        self.allow_insert_closure = allow_insert_closure;
+        self.is_single_insert = is_single_insert;
+    }
 }
 impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
     fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
@@ -425,6 +475,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
 
         match try_parse_insert(self.cx, expr) {
             Some(insert_expr) if SpanlessEq::new(self.cx).eq_expr(self.map, insert_expr.map) => {
+                self.visit_insert_expr_arguments(&insert_expr);
                 // Multiple inserts, inserts with a different key, and inserts from a macro can't use the entry api.
                 if self.is_map_used
                     || !SpanlessEq::new(self.cx).eq_expr(self.key, insert_expr.key)
diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs
index 606c2ed72be..0ea53c39280 100644
--- a/src/tools/clippy/clippy_lints/src/let_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
 use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
-use rustc_hir::{Local, PatKind};
+use rustc_hir::{Local, LocalSource, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{GenericArgKind, IsSuggestable};
@@ -139,7 +139,8 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
 
 impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) {
-        if !in_external_macro(cx.tcx.sess, local.span)
+        if matches!(local.source, LocalSource::Normal)
+            && !in_external_macro(cx.tcx.sess, local.span)
             && let PatKind::Wild = local.pat.kind
             && let Some(init) = local.init
         {
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 76e75968314..b930175c4d8 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -80,6 +80,7 @@ mod as_conversions;
 mod asm_syntax;
 mod assertions_on_constants;
 mod assertions_on_result_states;
+mod assigning_clones;
 mod async_yields_async;
 mod attrs;
 mod await_holding_invalid;
@@ -1118,6 +1119,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| Box::new(incompatible_msrv::IncompatibleMsrv::new(msrv())));
     store.register_late_pass(|_| Box::new(to_string_trait_impl::ToStringTraitImpl));
     store.register_early_pass(|| Box::new(multiple_bound_locations::MultipleBoundLocations));
+    store.register_late_pass(|_| Box::new(assigning_clones::AssigningClones));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index 58f713d8187..18f799e875a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -3,6 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_copy;
+use clippy_utils::usage::local_used_in;
 use clippy_utils::{get_enclosing_block, higher, path_to_local, sugg};
 use rustc_ast::ast;
 use rustc_errors::Applicability;
@@ -63,8 +64,9 @@ pub(super) fn check<'tcx>(
                             && get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some()
                             && let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts)
                             && let Some((start_right, offset_right)) = get_details_from_idx(cx, idx_right, &starts)
-
-                            // Source and destination must be different
+                            && !local_used_in(cx, canonical_id, base_left)
+                            && !local_used_in(cx, canonical_id, base_right)
+							// Source and destination must be different
                             && path_to_local(base_left) != path_to_local(base_right)
                         {
                             Some((
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 69f86836775..b770ad0ddb5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -37,12 +37,7 @@ pub(super) fn check<'tcx>(
     }
 }
 
-fn set_diagnostic<'tcx>(
-    diag: &mut Diag<'_, ()>,
-    cx: &LateContext<'tcx>,
-    expr: &'tcx Expr<'tcx>,
-    found: FoundSigDrop,
-) {
+fn set_diagnostic<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, found: FoundSigDrop) {
     if found.lint_suggestion == LintSuggestion::MoveAndClone {
         // If our suggestion is to move and clone, then we want to leave it to the user to
         // decide how to address this lint, since it may be that cloning is inappropriate.
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index adb696ad509..8a24ccea3a1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -3875,6 +3875,7 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// ### What it does
     /// Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type.
     ///
     /// ### Why is this bad?
@@ -3981,6 +3982,7 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// ### What it does
     /// Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either
     /// through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()`
     /// on a (byte) string literal with a hardcoded `\0` byte at the end.
diff --git a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
index f671517c134..0879dcd9bcd 100644
--- a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
@@ -42,7 +42,7 @@ pub(crate) fn check<'tcx>(
 
     match op {
         BinOpKind::Add | BinOpKind::BitOr | BinOpKind::BitXor => {
-            check_op(
+            let _ = check_op(
                 cx,
                 left,
                 0,
@@ -50,8 +50,7 @@ pub(crate) fn check<'tcx>(
                 peeled_right_span,
                 needs_parenthesis(cx, expr, right),
                 right_is_coerced_to_value,
-            );
-            check_op(
+            ) || check_op(
                 cx,
                 right,
                 0,
@@ -62,7 +61,7 @@ pub(crate) fn check<'tcx>(
             );
         },
         BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Sub => {
-            check_op(
+            let _ = check_op(
                 cx,
                 right,
                 0,
@@ -73,7 +72,7 @@ pub(crate) fn check<'tcx>(
             );
         },
         BinOpKind::Mul => {
-            check_op(
+            let _ = check_op(
                 cx,
                 left,
                 1,
@@ -81,8 +80,18 @@ pub(crate) fn check<'tcx>(
                 peeled_right_span,
                 needs_parenthesis(cx, expr, right),
                 right_is_coerced_to_value,
+            ) || check_op(
+                cx,
+                right,
+                1,
+                expr.span,
+                peeled_left_span,
+                Parens::Unneeded,
+                left_is_coerced_to_value,
             );
-            check_op(
+        },
+        BinOpKind::Div => {
+            let _ = check_op(
                 cx,
                 right,
                 1,
@@ -92,17 +101,8 @@ pub(crate) fn check<'tcx>(
                 left_is_coerced_to_value,
             );
         },
-        BinOpKind::Div => check_op(
-            cx,
-            right,
-            1,
-            expr.span,
-            peeled_left_span,
-            Parens::Unneeded,
-            left_is_coerced_to_value,
-        ),
         BinOpKind::BitAnd => {
-            check_op(
+            let _ = check_op(
                 cx,
                 left,
                 -1,
@@ -110,8 +110,7 @@ pub(crate) fn check<'tcx>(
                 peeled_right_span,
                 needs_parenthesis(cx, expr, right),
                 right_is_coerced_to_value,
-            );
-            check_op(
+            ) || check_op(
                 cx,
                 right,
                 -1,
@@ -201,12 +200,12 @@ fn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span
     }
 }
 
-fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, parens: Parens, is_erased: bool) {
+fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, parens: Parens, is_erased: bool) -> bool {
     if let Some(Constant::Int(v)) = constant_simple(cx, cx.typeck_results(), e).map(Constant::peel_refs) {
         let check = match *cx.typeck_results().expr_ty(e).peel_refs().kind() {
             ty::Int(ity) => unsext(cx.tcx, -1_i128, ity),
             ty::Uint(uty) => clip(cx.tcx, !0, uty),
-            _ => return,
+            _ => return false,
         };
         if match m {
             0 => v == 0,
@@ -215,8 +214,10 @@ fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, pa
             _ => unreachable!(),
         } {
             span_ineffective_operation(cx, span, arg, parens, is_erased);
+            return true;
         }
     }
+    false
 }
 
 fn span_ineffective_operation(
diff --git a/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs b/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
index fecc5a8578e..311cbd050a1 100644
--- a/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
@@ -21,9 +21,8 @@ pub(super) fn check<'tcx>(
         // lhs op= l op r
         if eq_expr_value(cx, lhs, l) {
             lint_misrefactored_assign_op(cx, expr, op, rhs, lhs, r);
-        }
-        // lhs op= l commutative_op r
-        if is_commutative(op) && eq_expr_value(cx, lhs, r) {
+        } else if is_commutative(op) && eq_expr_value(cx, lhs, r) {
+            // lhs op= l commutative_op r
             lint_misrefactored_assign_op(cx, expr, op, rhs, lhs, l);
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index 1df2d5e4602..cf7f730140c 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -203,108 +203,106 @@ fn expr_return_none_or_err(
     }
 }
 
-impl QuestionMark {
-    fn inside_try_block(&self) -> bool {
-        self.try_block_depth_stack.last() > Some(&0)
-    }
-
-    /// Checks if the given expression on the given context matches the following structure:
-    ///
-    /// ```ignore
-    /// if option.is_none() {
-    ///    return None;
-    /// }
-    /// ```
-    ///
-    /// ```ignore
-    /// if result.is_err() {
-    ///     return result;
-    /// }
-    /// ```
-    ///
-    /// If it matches, it will suggest to use the question mark operator instead
-    fn check_is_none_or_err_and_early_return<'tcx>(&self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
-        if !self.inside_try_block()
-            && let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr)
-            && !is_else_clause(cx.tcx, expr)
-            && let ExprKind::MethodCall(segment, caller, ..) = &cond.kind
-            && let caller_ty = cx.typeck_results().expr_ty(caller)
-            && let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then)
-            && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block))
-        {
-            let mut applicability = Applicability::MachineApplicable;
-            let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
-            let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
-                && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
-            let sugg = if let Some(else_inner) = r#else {
-                if eq_expr_value(cx, caller, peel_blocks(else_inner)) {
-                    format!("Some({receiver_str}?)")
-                } else {
-                    return;
-                }
+/// Checks if the given expression on the given context matches the following structure:
+///
+/// ```ignore
+/// if option.is_none() {
+///    return None;
+/// }
+/// ```
+///
+/// ```ignore
+/// if result.is_err() {
+///     return result;
+/// }
+/// ```
+///
+/// If it matches, it will suggest to use the question mark operator instead
+fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
+    if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr)
+        && !is_else_clause(cx.tcx, expr)
+        && let ExprKind::MethodCall(segment, caller, ..) = &cond.kind
+        && let caller_ty = cx.typeck_results().expr_ty(caller)
+        && let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then)
+        && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block))
+    {
+        let mut applicability = Applicability::MachineApplicable;
+        let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
+        let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
+            && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
+        let sugg = if let Some(else_inner) = r#else {
+            if eq_expr_value(cx, caller, peel_blocks(else_inner)) {
+                format!("Some({receiver_str}?)")
             } else {
-                format!("{receiver_str}{}?;", if by_ref { ".as_ref()" } else { "" })
-            };
+                return;
+            }
+        } else {
+            format!("{receiver_str}{}?;", if by_ref { ".as_ref()" } else { "" })
+        };
 
-            span_lint_and_sugg(
-                cx,
-                QUESTION_MARK,
-                expr.span,
-                "this block may be rewritten with the `?` operator",
-                "replace it with",
-                sugg,
-                applicability,
-            );
-        }
+        span_lint_and_sugg(
+            cx,
+            QUESTION_MARK,
+            expr.span,
+            "this block may be rewritten with the `?` operator",
+            "replace it with",
+            sugg,
+            applicability,
+        );
     }
+}
 
-    fn check_if_let_some_or_err_and_early_return<'tcx>(&self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
-        if !self.inside_try_block()
-            && let Some(higher::IfLet {
-                let_pat,
-                let_expr,
-                if_then,
-                if_else,
-                ..
-            }) = higher::IfLet::hir(cx, expr)
-            && !is_else_clause(cx.tcx, expr)
-            && let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind
-            && ddpos.as_opt_usize().is_none()
-            && let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind
-            && let caller_ty = cx.typeck_results().expr_ty(let_expr)
-            && let if_block = IfBlockType::IfLet(
-                cx.qpath_res(path1, let_pat.hir_id),
-                caller_ty,
-                ident.name,
-                let_expr,
-                if_then,
-                if_else,
-            )
-            && ((is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id))
-                || is_early_return(sym::Result, cx, &if_block))
-            && if_else
-                .map(|e| eq_expr_value(cx, let_expr, peel_blocks(e)))
-                .filter(|e| *e)
-                .is_none()
-        {
-            let mut applicability = Applicability::MachineApplicable;
-            let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
-            let requires_semi = matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(_));
-            let sugg = format!(
-                "{receiver_str}{}?{}",
-                if by_ref == ByRef::Yes { ".as_ref()" } else { "" },
-                if requires_semi { ";" } else { "" }
-            );
-            span_lint_and_sugg(
-                cx,
-                QUESTION_MARK,
-                expr.span,
-                "this block may be rewritten with the `?` operator",
-                "replace it with",
-                sugg,
-                applicability,
-            );
-        }
+fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
+    if let Some(higher::IfLet {
+        let_pat,
+        let_expr,
+        if_then,
+        if_else,
+        ..
+    }) = higher::IfLet::hir(cx, expr)
+        && !is_else_clause(cx.tcx, expr)
+        && let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind
+        && ddpos.as_opt_usize().is_none()
+        && let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind
+        && let caller_ty = cx.typeck_results().expr_ty(let_expr)
+        && let if_block = IfBlockType::IfLet(
+            cx.qpath_res(path1, let_pat.hir_id),
+            caller_ty,
+            ident.name,
+            let_expr,
+            if_then,
+            if_else,
+        )
+        && ((is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id))
+            || is_early_return(sym::Result, cx, &if_block))
+        && if_else
+            .map(|e| eq_expr_value(cx, let_expr, peel_blocks(e)))
+            .filter(|e| *e)
+            .is_none()
+    {
+        let mut applicability = Applicability::MachineApplicable;
+        let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
+        let requires_semi = matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(_));
+        let sugg = format!(
+            "{receiver_str}{}?{}",
+            if by_ref == ByRef::Yes { ".as_ref()" } else { "" },
+            if requires_semi { ";" } else { "" }
+        );
+        span_lint_and_sugg(
+            cx,
+            QUESTION_MARK,
+            expr.span,
+            "this block may be rewritten with the `?` operator",
+            "replace it with",
+            sugg,
+            applicability,
+        );
+    }
+}
+
+impl QuestionMark {
+    fn inside_try_block(&self) -> bool {
+        self.try_block_depth_stack.last() > Some(&0)
     }
 }
 
@@ -324,15 +322,18 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
             return;
         }
 
-        if !in_constant(cx, stmt.hir_id) {
+        if !self.inside_try_block() && !in_constant(cx, stmt.hir_id) {
             check_let_some_else_return_none(cx, stmt);
         }
         self.check_manual_let_else(cx, stmt);
     }
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if !in_constant(cx, expr.hir_id) && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id) {
-            self.check_is_none_or_err_and_early_return(cx, expr);
-            self.check_if_let_some_or_err_and_early_return(cx, expr);
+        if !self.inside_try_block()
+            && !in_constant(cx, expr.hir_id)
+            && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)
+        {
+            check_is_none_or_err_and_early_return(cx, expr);
+            check_if_let_some_or_err_and_early_return(cx, expr);
         }
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index e3f0ce2a922..f61527cc0a9 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -159,6 +159,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
             //           ^^  we only want to lint for this call (but we walk up the calls to consider both calls).
             // without this check, we'd end up linting twice.
             && !matches!(recv.kind, hir::ExprKind::Call(..))
+            // Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is
+            // the same as the one the call is in.
+            // For instance, let's assume `x!()` returns a closure:
+            //    B ---v
+            //      x!()()
+            //          ^- A
+            // The call happens in the expansion `A`, while the closure originates from the expansion `B`.
+            // We don't want to suggest replacing `x!()()` with `x!()`.
+            && recv.span.ctxt().outer_expn() == expr.span.ctxt().outer_expn()
             && let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
             && let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
             // outside macros we lint properly. Inside macros, we lint only ||() style closures.
diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
index fb000cd7184..17b031d5f01 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -59,24 +59,22 @@ impl EarlyLintPass for RedundantFieldNames {
         }
         if let ExprKind::Struct(ref se) = expr.kind {
             for field in &se.fields {
-                if field.is_shorthand {
-                    continue;
-                }
-                if let ExprKind::Path(None, path) = &field.expr.kind {
-                    if path.segments.len() == 1
-                        && path.segments[0].ident == field.ident
-                        && path.segments[0].args.is_none()
-                    {
-                        span_lint_and_sugg(
-                            cx,
-                            REDUNDANT_FIELD_NAMES,
-                            field.span,
-                            "redundant field names in struct initialization",
-                            "replace it with",
-                            field.ident.to_string(),
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                if !field.is_shorthand
+                    && let ExprKind::Path(None, path) = &field.expr.kind
+                    && let [segment] = path.segments.as_slice()
+                    && segment.args.is_none()
+                    && segment.ident == field.ident
+                    && field.span.eq_ctxt(field.ident.span)
+                {
+                    span_lint_and_sugg(
+                        cx,
+                        REDUNDANT_FIELD_NAMES,
+                        field.span,
+                        "redundant field names in struct initialization",
+                        "replace it with",
+                        field.ident.to_string(),
+                        Applicability::MachineApplicable,
+                    );
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 38fd54a0f1e..c0e4f3c368a 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -109,7 +109,6 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     sym::core => (STD_INSTEAD_OF_CORE, "std", "core"),
                     sym::alloc => (STD_INSTEAD_OF_ALLOC, "std", "alloc"),
                     _ => {
-                        self.prev_span = path.span;
                         return;
                     },
                 },
@@ -117,13 +116,12 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     if cx.tcx.crate_name(def_id.krate) == sym::core {
                         (ALLOC_INSTEAD_OF_CORE, "alloc", "core")
                     } else {
-                        self.prev_span = path.span;
                         return;
                     }
                 },
                 _ => return,
             };
-            if path.span != self.prev_span {
+            if first_segment.ident.span != self.prev_span {
                 span_lint_and_sugg(
                     cx,
                     lint,
@@ -133,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     replace_with.to_string(),
                     Applicability::MachineApplicable,
                 );
-                self.prev_span = path.span;
+                self.prev_span = first_segment.ident.span;
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
index 9fee4c06200..1af3733ebfa 100644
--- a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
+++ b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
@@ -1,12 +1,11 @@
-use clippy_config::msrvs::Msrv;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::fn_has_unsatisfiable_preds;
 use clippy_utils::qualify_min_const_fn::is_min_const_fn;
 use clippy_utils::source::snippet;
+use clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::{intravisit, ExprKind};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym::thread_local_macro;
 
@@ -57,6 +56,31 @@ impl ThreadLocalInitializerCanBeMadeConst {
 
 impl_lint_pass!(ThreadLocalInitializerCanBeMadeConst => [THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST]);
 
+#[inline]
+fn is_thread_local_initializer(
+    cx: &LateContext<'_>,
+    fn_kind: rustc_hir::intravisit::FnKind<'_>,
+    span: rustc_span::Span,
+) -> Option<bool> {
+    let macro_def_id = span.source_callee()?.macro_def_id?;
+    Some(
+        cx.tcx.is_diagnostic_item(thread_local_macro, macro_def_id)
+            && matches!(fn_kind, intravisit::FnKind::ItemFn(..)),
+    )
+}
+
+#[inline]
+fn initializer_can_be_made_const(cx: &LateContext<'_>, defid: rustc_span::def_id::DefId, msrv: &Msrv) -> bool {
+    // Building MIR for `fn`s with unsatisfiable preds results in ICE.
+    if !fn_has_unsatisfiable_preds(cx, defid)
+        && let mir = cx.tcx.optimized_mir(defid)
+        && let Ok(()) = is_min_const_fn(cx.tcx, mir, msrv)
+    {
+        return true;
+    }
+    false
+}
+
 impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst {
     fn check_fn(
         &mut self,
@@ -65,31 +89,32 @@ impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst {
         _: &'tcx rustc_hir::FnDecl<'tcx>,
         body: &'tcx rustc_hir::Body<'tcx>,
         span: rustc_span::Span,
-        defid: rustc_span::def_id::LocalDefId,
+        local_defid: rustc_span::def_id::LocalDefId,
     ) {
-        if in_external_macro(cx.sess(), span)
-            && let Some(callee) = span.source_callee()
-            && let Some(macro_def_id) = callee.macro_def_id
-            && cx.tcx.is_diagnostic_item(thread_local_macro, macro_def_id)
-            && let intravisit::FnKind::ItemFn(..) = fn_kind
-            // Building MIR for `fn`s with unsatisfiable preds results in ICE.
-            && !fn_has_unsatisfiable_preds(cx, defid.to_def_id())
-            && let mir = cx.tcx.optimized_mir(defid.to_def_id())
-            && let Ok(()) = is_min_const_fn(cx.tcx, mir, &self.msrv)
-            // this is the `__init` function emitted by the `thread_local!` macro
-            // when the `const` keyword is not used. We avoid checking the `__init` directly
-            // as that is not a public API.
-            // we know that the function is const-qualifiable, so now we need only to get the
-            // initializer expression to span-lint it.
+        let defid = local_defid.to_def_id();
+        if self.msrv.meets(msrvs::THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST)
+            && is_thread_local_initializer(cx, fn_kind, span).unwrap_or(false)
+            // Some implementations of `thread_local!` include an initializer fn.
+            // In the case of a const initializer, the init fn is also const,
+            // so we can skip the lint in that case. This occurs only on some
+            // backends due to conditional compilation:
+            // https://doc.rust-lang.org/src/std/sys/common/thread_local/mod.rs.html
+            // for details on this issue, see:
+            // https://github.com/rust-lang/rust-clippy/pull/12276
+            && !cx.tcx.is_const_fn(defid)
+            && initializer_can_be_made_const(cx, defid, &self.msrv)
+            // we know that the function is const-qualifiable, so now
+            // we need only to get the initializer expression to span-lint it.
             && let ExprKind::Block(block, _) = body.value.kind
-            && let Some(ret_expr) = block.expr
+            && let Some(unpeeled) = block.expr
+            && let ret_expr = peel_blocks(unpeeled)
             && let initializer_snippet = snippet(cx, ret_expr.span, "thread_local! { ... }")
             && initializer_snippet != "thread_local! { ... }"
         {
             span_lint_and_sugg(
                 cx,
                 THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST,
-                ret_expr.span,
+                unpeeled.span,
                 "initializer for `thread_local` value can be made `const`",
                 "replace with",
                 format!("const {{ {initializer_snippet} }}"),
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 06de7a11031..e47b14bf63b 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -592,7 +592,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 | (eager_transmute::check(cx, e, arg, from_ty, to_ty));
 
             if !linted {
-                transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, from_ty_adjusted, to_ty, arg);
+                transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, from_ty_adjusted, to_ty, arg, const_context);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index bbecc39a813..043c9c88601 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -18,10 +18,12 @@ pub(super) fn check<'tcx>(
     from_ty_adjusted: bool,
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
+    const_context: bool,
 ) -> bool {
     use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast};
     let mut app = Applicability::MachineApplicable;
     let mut sugg = match check_cast(cx, e, from_ty, to_ty) {
+        Some(FnPtrAddrCast | PtrAddrCast) if const_context => return false,
         Some(PtrPtrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) => {
             Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut app)
                 .as_ty(to_ty.to_string())
diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
index a285f771f1b..7926738d68f 100644
--- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
@@ -1,10 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::paths::ALLOCATOR_GLOBAL;
+use clippy_utils::last_path_segment;
 use clippy_utils::source::snippet;
-use clippy_utils::{last_path_segment, match_def_path};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{self as hir, GenericArg, QPath, TyKind};
+use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::LateContext;
 use rustc_middle::ty::layout::LayoutOf;
@@ -50,7 +49,7 @@ pub(super) fn check<'tcx>(
                 (None, Some(GenericArg::Type(inner))) | (Some(GenericArg::Type(inner)), None) => {
                     if let TyKind::Path(path) = inner.kind
                         && let Some(did) = cx.qpath_res(&path, inner.hir_id).opt_def_id() {
-                        match_def_path(cx, did, &ALLOCATOR_GLOBAL)
+                        cx.tcx.lang_items().get(LangItem::GlobalAlloc) == Some(did)
                     } else {
                         false
                     }
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 2f728b62754..987f28192a8 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -115,4 +115,3 @@ pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"];
 pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"];
 #[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so
 pub const BOOL_THEN: [&str; 4] = ["core", "bool", "<impl bool>", "then"];
-pub const ALLOCATOR_GLOBAL: [&str; 3] = ["alloc", "alloc", "Global"];
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index e74621a0fbb..5090d0bd98b 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -995,7 +995,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
                         // no adjustment needed here, as field projections are handled by the compiler
                         ProjectionKind::Field(..) => match cmt.place.ty_before_projection(i).kind() {
                             ty::Adt(..) | ty::Tuple(_) => {
-                                replacement_str = ident_str_with_proj.clone();
+                                replacement_str.clone_from(&ident_str_with_proj);
                                 projections_handled = true;
                             },
                             _ => (),
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index fb038b617df..070b62887d5 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-02-22"
+channel = "nightly-2024-03-07"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index dffa854177b..30beaae34d2 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -174,8 +174,13 @@ To allow or deny a lint from the command line you can use <cyan,bold>cargo clipp
 You can use tool lints to allow or deny lints from your code, e.g.:
 
     <yellow,bold>#[allow(clippy::needless_lifetimes)]</>
-"
-    )
+
+<green,bold>Manifest Options:</>
+    <cyan,bold>--manifest-path</> <cyan><<PATH>></>  Path to Cargo.toml
+    <cyan,bold>--frozen</>                Require Cargo.lock and cache are up to date
+    <cyan,bold>--locked</>                Require Cargo.lock is up to date
+    <cyan,bold>--offline</>               Run without accessing the network
+")
 }
 #[cfg(test)]
 mod tests {
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index a088896b6b0..a0c8bf9334c 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -138,6 +138,7 @@ fn base_config(test_dir: &str) -> (Config, Args) {
             "-Aunused",
             "-Ainternal_features",
             "-Zui-testing",
+            "-Zdeduplicate-diagnostics=no",
             "-Dwarnings",
             &format!("-Ldependency={}", deps_path.display()),
         ]
diff --git a/src/tools/clippy/tests/missing-test-files.rs b/src/tools/clippy/tests/missing-test-files.rs
index 0d35a22cd9a..141c11ddb47 100644
--- a/src/tools/clippy/tests/missing-test-files.rs
+++ b/src/tools/clippy/tests/missing-test-files.rs
@@ -54,7 +54,7 @@ fn explore_directory(dir: &Path) -> Vec<String> {
             let file_prefix = path.file_prefix().unwrap().to_str().unwrap().to_string();
             if let Some(ext) = path.extension() {
                 match ext.to_str().unwrap() {
-                    "rs" | "toml" => current_file = file_prefix.clone(),
+                    "rs" | "toml" => current_file.clone_from(&file_prefix),
                     "stderr" | "stdout" => {
                         if file_prefix != current_file {
                             missing_files.push(path.to_str().unwrap().to_string());
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
index 9b0db660c99..400bfd5d975 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
@@ -5,6 +5,7 @@
 //@normalize-stderr-test: "'rustc'" -> "'<unnamed>'"
 //@normalize-stderr-test: "rustc 1\.\d+.* running on .*" -> "rustc <version> running on <target>"
 //@normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> ""
+//@normalize-stderr-test: "this compiler `.*` is outdated" -> "this compiler <version> is outdated"
 
 #![deny(clippy::internal)]
 #![allow(clippy::missing_clippy_version_attribute)]
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
index d8b158816c9..b84f4e87e07 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
@@ -4,11 +4,14 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 error: the compiler unexpectedly panicked. this is a bug.
 
-note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml
+note: it seems that this compiler <version> is outdated, a newer nightly should have been released in the mean time
+  |
+  = note: please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists
+  = note: if the problem still persists, we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml
 
 note: rustc <version> running on <target>
 
-note: compiler flags: -Z ui-testing
+note: compiler flags: -Z ui-testing -Z deduplicate-diagnostics=no
 
 note: Clippy version: foo
 
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
index c5029bbd9a4..5a2a868ed3e 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
@@ -10,22 +10,11 @@ use rustc_hir::hir_id::HirId;
 use rustc_lint::{Lint, LintContext};
 use rustc_middle::ty::TyCtxt;
 
-pub fn a(
-    cx: impl LintContext,
-    lint: &'static Lint,
-    span: impl Into<MultiSpan>,
-    msg: impl Into<DiagMessage>)
-{
+pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
     cx.span_lint(lint, span, msg, |_| {});
 }
 
-pub fn b(
-    tcx: TyCtxt<'_>,
-    lint: &'static Lint,
-    hir_id: HirId,
-    span: impl Into<MultiSpan>,
-    msg: impl Into<DiagMessage>,
-) {
+pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
     tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
 }
 
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
index 1a1ad26290c..ae5d6843406 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
@@ -8,7 +8,7 @@ LL |     cx.span_lint(lint, span, msg, |_| {});
    = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
 
 error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`
-  --> tests/ui-internal/disallow_span_lint.rs:24:5
+  --> tests/ui-internal/disallow_span_lint.rs:18:5
    |
 LL |     tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index 87f84d8f7dd..37d69055737 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:266:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:271: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:29
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:48
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:18
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:37
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:292: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:298: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:302: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:8
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:317:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:322: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:325:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:330: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:339:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:344: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:20
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:348: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:350:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:355: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:357:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:362: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:411:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:417:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:422: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:463:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:468: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:472: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:474:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:481: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:483:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:488: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:492:1
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:497: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:505:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -291,13 +291,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:504:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:12
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:511: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:23
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:514:23
    |
 LL |             let bar = unsafe {};
    |                       ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index 5ffe73f5a2f..400fde997e9 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:266:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:271: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:29
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:48
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:18
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:37
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:292: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:298: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:302: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:8
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:317:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:322: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:325:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:330: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:339:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:344: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:20
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:348: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:350:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:355: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:357:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:362: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:411:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:417:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:422: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:463:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:468: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:472: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:474:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:481: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:483:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:488: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:492:1
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:497: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:502:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:507: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:505:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -299,13 +299,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:504:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:12
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:511: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:23
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:514: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:527:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:532: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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:531:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:536:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -337,7 +337,7 @@ 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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:535:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:540:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -345,7 +345,7 @@ 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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:541:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:546:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -353,7 +353,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:550:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -361,7 +361,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:552:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:557:9
    |
 LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -369,7 +369,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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:557:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:562:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -377,7 +377,7 @@ 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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:563:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:568:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -385,7 +385,7 @@ 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
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:568:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:573:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
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 8997073c8a5..e5ef9d35fb6 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
@@ -4,7 +4,12 @@
 //@[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, non_local_definitions, clippy::let_unit_value, clippy::missing_safety_doc)]
+#![allow(
+    deref_nullptr,
+    non_local_definitions,
+    clippy::let_unit_value,
+    clippy::missing_safety_doc
+)]
 #![feature(lint_reasons)]
 
 extern crate proc_macro_unsafe;
diff --git a/src/tools/clippy/tests/ui/assigning_clones.fixed b/src/tools/clippy/tests/ui/assigning_clones.fixed
new file mode 100644
index 00000000000..c66e0c1f602
--- /dev/null
+++ b/src/tools/clippy/tests/ui/assigning_clones.fixed
@@ -0,0 +1,222 @@
+#![allow(unused)]
+#![allow(clippy::redundant_clone)]
+#![allow(clippy::ptr_arg)] // https://github.com/rust-lang/rust-clippy/issues/10612
+#![allow(clippy::needless_late_init)]
+#![allow(clippy::box_collection)]
+#![warn(clippy::assigning_clones)]
+
+use std::borrow::ToOwned;
+use std::ops::{Add, Deref, DerefMut};
+
+// Clone
+pub struct HasCloneFrom;
+
+impl Clone for HasCloneFrom {
+    fn clone(&self) -> Self {
+        Self
+    }
+    fn clone_from(&mut self, source: &Self) {
+        *self = HasCloneFrom;
+    }
+}
+
+fn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) {
+    mut_thing.clone_from(&value_thing);
+}
+
+fn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing.clone_from(ref_thing);
+}
+
+fn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing.clone_from(ref_thing);
+}
+
+fn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(&mut mut_thing, ref_thing);
+}
+
+fn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be kept as necessary for a receiver
+    (mut_thing + &mut HasCloneFrom).clone_from(ref_thing);
+}
+
+fn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be removed since they are not needed in a function argument
+    mut_thing.clone_from(ref_thing + ref_thing);
+}
+
+fn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom {
+    let mut a = HasCloneFrom;
+    for _ in 1..10 {
+        a.clone_from(&b);
+    }
+    a
+}
+
+fn assign_to_late_init_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = HasCloneFrom;
+    a = b.clone();
+}
+
+fn assign_to_uninit_var(b: HasCloneFrom) {
+    let a;
+    a = b.clone();
+}
+
+fn assign_to_uninit_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = b.clone();
+}
+
+#[derive(Clone)]
+pub struct HasDeriveClone;
+
+fn ignore_derive_clone(a: &mut HasDeriveClone, b: &HasDeriveClone) {
+    // Should not be linted, since the Clone impl is derived
+    *a = b.clone();
+}
+
+pub struct HasCloneImpl;
+
+impl Clone for HasCloneImpl {
+    fn clone(&self) -> Self {
+        Self
+    }
+}
+
+fn ignore_missing_clone_from(a: &mut HasCloneImpl, b: &HasCloneImpl) {
+    // Should not be linted, since the Clone impl doesn't override clone_from
+    *a = b.clone();
+}
+
+struct FakeClone;
+
+impl FakeClone {
+    /// This looks just like `Clone::clone`
+    fn clone(&self) -> Self {
+        FakeClone
+    }
+}
+
+fn ignore_fake_clone() {
+    let mut a = FakeClone;
+    let b = FakeClone;
+    // Should not be linted, since the Clone impl doesn't come from std
+    a = b.clone();
+}
+
+fn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {
+    // Should not be linted, since we don't know the actual clone impl
+    *a = b.clone();
+}
+
+macro_rules! clone_inside {
+    ($a:expr, $b: expr) => {
+        $a = $b.clone();
+    };
+}
+
+fn clone_inside_macro() {
+    let mut a = String::new();
+    let b = String::new();
+    clone_inside!(a, b);
+}
+
+// ToOwned
+fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {
+    ref_str.clone_into(mut_string);
+}
+
+fn owned_method_val(mut mut_string: String, ref_str: &str) {
+    ref_str.clone_into(&mut mut_string);
+}
+
+struct HasDeref {
+    a: String,
+}
+
+impl Deref for HasDeref {
+    type Target = String;
+    fn deref(&self) -> &Self::Target {
+        &self.a
+    }
+}
+
+impl DerefMut for HasDeref {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.a
+    }
+}
+
+fn owned_method_box(mut_box_string: &mut Box<String>, ref_str: &str) {
+    ref_str.clone_into(&mut (*mut_box_string));
+}
+
+fn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) {
+    ref_str.clone_into(&mut (*mut_box_string));
+}
+
+fn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) {
+    ToOwned::clone_into(ref_str, mut_thing);
+}
+
+fn owned_function_val(mut mut_thing: String, ref_str: &str) {
+    ToOwned::clone_into(ref_str, &mut mut_thing);
+}
+
+struct FakeToOwned;
+impl FakeToOwned {
+    /// This looks just like `ToOwned::to_owned`
+    fn to_owned(&self) -> Self {
+        FakeToOwned
+    }
+}
+
+fn fake_to_owned() {
+    let mut a = FakeToOwned;
+    let b = FakeToOwned;
+    // Should not be linted, since the ToOwned impl doesn't come from std
+    a = b.to_owned();
+}
+
+fn main() {}
+
+/// Trait implementation to allow producing a `Thing` with a low-precedence expression.
+impl Add for HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&Thing` with a low-precedence expression.
+impl<'a> Add for &'a HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&mut Thing` with a low-precedence expression.
+impl<'a> Add for &'a mut HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a mut HasCloneFrom) -> Self {
+        self
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assigning_clones.rs b/src/tools/clippy/tests/ui/assigning_clones.rs
new file mode 100644
index 00000000000..b9f994d3e03
--- /dev/null
+++ b/src/tools/clippy/tests/ui/assigning_clones.rs
@@ -0,0 +1,222 @@
+#![allow(unused)]
+#![allow(clippy::redundant_clone)]
+#![allow(clippy::ptr_arg)] // https://github.com/rust-lang/rust-clippy/issues/10612
+#![allow(clippy::needless_late_init)]
+#![allow(clippy::box_collection)]
+#![warn(clippy::assigning_clones)]
+
+use std::borrow::ToOwned;
+use std::ops::{Add, Deref, DerefMut};
+
+// Clone
+pub struct HasCloneFrom;
+
+impl Clone for HasCloneFrom {
+    fn clone(&self) -> Self {
+        Self
+    }
+    fn clone_from(&mut self, source: &Self) {
+        *self = HasCloneFrom;
+    }
+}
+
+fn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) {
+    *mut_thing = value_thing.clone();
+}
+
+fn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = ref_thing.clone();
+}
+
+fn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing = ref_thing.clone();
+}
+
+fn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = Clone::clone(ref_thing);
+}
+
+fn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing = Clone::clone(ref_thing);
+}
+
+fn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = Clone::clone(ref_thing);
+}
+
+fn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = HasCloneFrom::clone(ref_thing);
+}
+
+fn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = <HasCloneFrom as Clone>::clone(ref_thing);
+}
+
+fn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be kept as necessary for a receiver
+    *(mut_thing + &mut HasCloneFrom) = ref_thing.clone();
+}
+
+fn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be removed since they are not needed in a function argument
+    *mut_thing = (ref_thing + ref_thing).clone();
+}
+
+fn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom {
+    let mut a = HasCloneFrom;
+    for _ in 1..10 {
+        a = b.clone();
+    }
+    a
+}
+
+fn assign_to_late_init_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = HasCloneFrom;
+    a = b.clone();
+}
+
+fn assign_to_uninit_var(b: HasCloneFrom) {
+    let a;
+    a = b.clone();
+}
+
+fn assign_to_uninit_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = b.clone();
+}
+
+#[derive(Clone)]
+pub struct HasDeriveClone;
+
+fn ignore_derive_clone(a: &mut HasDeriveClone, b: &HasDeriveClone) {
+    // Should not be linted, since the Clone impl is derived
+    *a = b.clone();
+}
+
+pub struct HasCloneImpl;
+
+impl Clone for HasCloneImpl {
+    fn clone(&self) -> Self {
+        Self
+    }
+}
+
+fn ignore_missing_clone_from(a: &mut HasCloneImpl, b: &HasCloneImpl) {
+    // Should not be linted, since the Clone impl doesn't override clone_from
+    *a = b.clone();
+}
+
+struct FakeClone;
+
+impl FakeClone {
+    /// This looks just like `Clone::clone`
+    fn clone(&self) -> Self {
+        FakeClone
+    }
+}
+
+fn ignore_fake_clone() {
+    let mut a = FakeClone;
+    let b = FakeClone;
+    // Should not be linted, since the Clone impl doesn't come from std
+    a = b.clone();
+}
+
+fn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {
+    // Should not be linted, since we don't know the actual clone impl
+    *a = b.clone();
+}
+
+macro_rules! clone_inside {
+    ($a:expr, $b: expr) => {
+        $a = $b.clone();
+    };
+}
+
+fn clone_inside_macro() {
+    let mut a = String::new();
+    let b = String::new();
+    clone_inside!(a, b);
+}
+
+// ToOwned
+fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {
+    *mut_string = ref_str.to_owned();
+}
+
+fn owned_method_val(mut mut_string: String, ref_str: &str) {
+    mut_string = ref_str.to_owned();
+}
+
+struct HasDeref {
+    a: String,
+}
+
+impl Deref for HasDeref {
+    type Target = String;
+    fn deref(&self) -> &Self::Target {
+        &self.a
+    }
+}
+
+impl DerefMut for HasDeref {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.a
+    }
+}
+
+fn owned_method_box(mut_box_string: &mut Box<String>, ref_str: &str) {
+    **mut_box_string = ref_str.to_owned();
+}
+
+fn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) {
+    **mut_box_string = ref_str.to_owned();
+}
+
+fn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) {
+    *mut_thing = ToOwned::to_owned(ref_str);
+}
+
+fn owned_function_val(mut mut_thing: String, ref_str: &str) {
+    mut_thing = ToOwned::to_owned(ref_str);
+}
+
+struct FakeToOwned;
+impl FakeToOwned {
+    /// This looks just like `ToOwned::to_owned`
+    fn to_owned(&self) -> Self {
+        FakeToOwned
+    }
+}
+
+fn fake_to_owned() {
+    let mut a = FakeToOwned;
+    let b = FakeToOwned;
+    // Should not be linted, since the ToOwned impl doesn't come from std
+    a = b.to_owned();
+}
+
+fn main() {}
+
+/// Trait implementation to allow producing a `Thing` with a low-precedence expression.
+impl Add for HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&Thing` with a low-precedence expression.
+impl<'a> Add for &'a HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&mut Thing` with a low-precedence expression.
+impl<'a> Add for &'a mut HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a mut HasCloneFrom) -> Self {
+        self
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assigning_clones.stderr b/src/tools/clippy/tests/ui/assigning_clones.stderr
new file mode 100644
index 00000000000..b76323f3606
--- /dev/null
+++ b/src/tools/clippy/tests/ui/assigning_clones.stderr
@@ -0,0 +1,107 @@
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:24:5
+   |
+LL |     *mut_thing = value_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(&value_thing)`
+   |
+   = note: `-D clippy::assigning-clones` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::assigning_clones)]`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:28:5
+   |
+LL |     *mut_thing = ref_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:32:5
+   |
+LL |     mut_thing = ref_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:36:5
+   |
+LL |     *mut_thing = Clone::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:40:5
+   |
+LL |     mut_thing = Clone::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:44:5
+   |
+LL |     *mut_thing = Clone::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:48:5
+   |
+LL |     *mut_thing = HasCloneFrom::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:52:5
+   |
+LL |     *mut_thing = <HasCloneFrom as Clone>::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:57:5
+   |
+LL |     *(mut_thing + &mut HasCloneFrom) = ref_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `(mut_thing + &mut HasCloneFrom).clone_from(ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:62:5
+   |
+LL |     *mut_thing = (ref_thing + ref_thing).clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing + ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:68:9
+   |
+LL |         a = b.clone();
+   |         ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:145:5
+   |
+LL |     *mut_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(mut_string)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:149:5
+   |
+LL |     mut_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut mut_string)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:170:5
+   |
+LL |     **mut_box_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:174:5
+   |
+LL |     **mut_box_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:178:5
+   |
+LL |     *mut_thing = ToOwned::to_owned(ref_str);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, mut_thing)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:182:5
+   |
+LL |     mut_thing = ToOwned::to_owned(ref_str);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, &mut mut_thing)`
+
+error: aborting due to 17 previous errors
+
diff --git a/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs b/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs
index b56abccbd41..e920e58d6ec 100644
--- a/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs
+++ b/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs
@@ -3,6 +3,6 @@ struct Foo(isize, isize, isize, isize);
 pub fn main() {
     let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5);
     match [5, 5, 5, 5] {
-        [..] => { }
+        [..] => {},
     }
 }
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
index aa7a95405e0..6f42487bbf4 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
@@ -153,4 +153,30 @@ pub enum MissingEqNonExhaustive3 {
     Bar,
 }
 
+mod struct_gen {
+    // issue 9413
+    pub trait Group {
+        type Element: Eq + PartialEq;
+    }
+
+    pub trait Suite {
+        type Group: Group;
+    }
+
+    #[derive(PartialEq, Eq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Foo<C: Suite>(<C::Group as Group>::Element);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
+
+    // issue 9319
+    #[derive(PartialEq, Eq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Oof<T: Fn()>(T);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Rab<T: Fn()>(T);
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
index 90ac7a7989e..24f687c6c9d 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
@@ -153,4 +153,30 @@ pub enum MissingEqNonExhaustive3 {
     Bar,
 }
 
+mod struct_gen {
+    // issue 9413
+    pub trait Group {
+        type Element: Eq + PartialEq;
+    }
+
+    pub trait Suite {
+        type Group: Group;
+    }
+
+    #[derive(PartialEq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Foo<C: Suite>(<C::Group as Group>::Element);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
+
+    // issue 9319
+    #[derive(PartialEq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Oof<T: Fn()>(T);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Rab<T: Fn()>(T);
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
index 42b9895121f..3d92112dc36 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
@@ -67,5 +67,17 @@ error: you are deriving `PartialEq` and can implement `Eq`
 LL |     #[derive(PartialEq)]
    |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
 
-error: aborting due to 11 previous errors
+error: you are deriving `PartialEq` and can implement `Eq`
+  --> tests/ui/derive_partial_eq_without_eq.rs:166:14
+   |
+LL |     #[derive(PartialEq)]
+   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
+
+error: you are deriving `PartialEq` and can implement `Eq`
+  --> tests/ui/derive_partial_eq_without_eq.rs:174:14
+   |
+LL |     #[derive(PartialEq)]
+   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index 16f7bafd44b..178d4a1aa2b 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -230,3 +230,8 @@ fn issue_11568() {}
 
 /// There is no try (`do()` or `do_not()`).
 fn parenthesized_word() {}
+
+/// `ABes`
+/// OSes
+/// UXes
+fn plural_acronym_test() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 4058b2bad74..01edb44c64c 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -230,3 +230,8 @@ fn issue_11568() {}
 
 /// There is no try (do() or do_not()).
 fn parenthesized_word() {}
+
+/// ABes
+/// OSes
+/// UXes
+fn plural_acronym_test() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
index 7db9ff2b83b..ac876306b39 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
@@ -341,5 +341,16 @@ help: try
 LL | /// There is no try (do() or `do_not()`).
    |                              ~~~~~~~~~~
 
-error: aborting due to 31 previous errors
+error: item in documentation is missing backticks
+  --> tests/ui/doc/doc-fixable.rs:234:5
+   |
+LL | /// ABes
+   |     ^^^^
+   |
+help: try
+   |
+LL | /// `ABes`
+   |     ~~~~~~
+
+error: aborting due to 32 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.fixed b/src/tools/clippy/tests/ui/doc/issue_9473.fixed
new file mode 100644
index 00000000000..276ce7620ca
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/issue_9473.fixed
@@ -0,0 +1,9 @@
+#![warn(clippy::doc_markdown)]
+
+// Should not warn!
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>.
+pub struct Foo(u32);
+
+// Should warn.
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].
+pub struct FooBar(u32);
diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.rs b/src/tools/clippy/tests/ui/doc/issue_9473.rs
new file mode 100644
index 00000000000..52527f7106d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/issue_9473.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::doc_markdown)]
+
+// Should not warn!
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>.
+pub struct Foo(u32);
+
+// Should warn.
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].
+pub struct FooBar(u32);
diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.stderr b/src/tools/clippy/tests/ui/doc/issue_9473.stderr
new file mode 100644
index 00000000000..35aa2884cc1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/issue_9473.stderr
@@ -0,0 +1,15 @@
+error: item in documentation is missing backticks
+  --> tests/ui/doc/issue_9473.rs:8:58
+   |
+LL | /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].
+   |                                                          ^^^^^^
+   |
+   = note: `-D clippy::doc-markdown` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
+help: try
+   |
+LL | /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].
+   |                                                          ~~~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/else_if_without_else.rs b/src/tools/clippy/tests/ui/else_if_without_else.rs
index eb5e2266540..e7786f7dd27 100644
--- a/src/tools/clippy/tests/ui/else_if_without_else.rs
+++ b/src/tools/clippy/tests/ui/else_if_without_else.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::all)]
 #![warn(clippy::else_if_without_else)]
 
diff --git a/src/tools/clippy/tests/ui/else_if_without_else.stderr b/src/tools/clippy/tests/ui/else_if_without_else.stderr
index 80355cb2dba..3bb840f39e7 100644
--- a/src/tools/clippy/tests/ui/else_if_without_else.stderr
+++ b/src/tools/clippy/tests/ui/else_if_without_else.stderr
@@ -1,5 +1,5 @@
 error: `if` expression with an `else if`, but without a final `else`
-  --> tests/ui/else_if_without_else.rs:45:12
+  --> tests/ui/else_if_without_else.rs:47:12
    |
 LL |       } else if bla2() {
    |  ____________^
@@ -13,7 +13,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::else_if_without_else)]`
 
 error: `if` expression with an `else if`, but without a final `else`
-  --> tests/ui/else_if_without_else.rs:54:12
+  --> tests/ui/else_if_without_else.rs:56:12
    |
 LL |       } else if bla3() {
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/empty_docs.rs b/src/tools/clippy/tests/ui/empty_docs.rs
index c47a603e71b..272fab7d5ca 100644
--- a/src/tools/clippy/tests/ui/empty_docs.rs
+++ b/src/tools/clippy/tests/ui/empty_docs.rs
@@ -1,5 +1,7 @@
 #![allow(unused)]
 #![warn(clippy::empty_docs)]
+#![allow(clippy::mixed_attributes_style)]
+
 mod outer {
     //!
 
diff --git a/src/tools/clippy/tests/ui/empty_docs.stderr b/src/tools/clippy/tests/ui/empty_docs.stderr
index 3f1d071fb13..f12aead6aa7 100644
--- a/src/tools/clippy/tests/ui/empty_docs.stderr
+++ b/src/tools/clippy/tests/ui/empty_docs.stderr
@@ -1,5 +1,5 @@
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:4:5
+  --> tests/ui/empty_docs.rs:6:5
    |
 LL |     //!
    |     ^^^
@@ -9,7 +9,7 @@ LL |     //!
    = help: to override `-D warnings` add `#[allow(clippy::empty_docs)]`
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:12:5
+  --> tests/ui/empty_docs.rs:14:5
    |
 LL |     ///
    |     ^^^
@@ -17,7 +17,7 @@ LL |     ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:14:9
+  --> tests/ui/empty_docs.rs:16:9
    |
 LL |         ///
    |         ^^^
@@ -25,7 +25,7 @@ LL |         ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:25:5
+  --> tests/ui/empty_docs.rs:27:5
    |
 LL |     #[doc = ""]
    |     ^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     #[doc = ""]
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:28:5
+  --> tests/ui/empty_docs.rs:30:5
    |
 LL | /     #[doc = ""]
 LL | |     #[doc = ""]
@@ -42,7 +42,7 @@ LL | |     #[doc = ""]
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:35:5
+  --> tests/ui/empty_docs.rs:37:5
    |
 LL |     ///
    |     ^^^
@@ -50,7 +50,7 @@ LL |     ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:48:13
+  --> tests/ui/empty_docs.rs:50:13
    |
 LL |             /*! */
    |             ^^^^^^
@@ -58,7 +58,7 @@ LL |             /*! */
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:56:13
+  --> tests/ui/empty_docs.rs:58:13
    |
 LL |             ///
    |             ^^^
@@ -66,7 +66,7 @@ LL |             ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:64:9
+  --> tests/ui/empty_docs.rs:66:9
    |
 LL |         ///
    |         ^^^
diff --git a/src/tools/clippy/tests/ui/entry.fixed b/src/tools/clippy/tests/ui/entry.fixed
index 4099fe7e139..71ec13f4610 100644
--- a/src/tools/clippy/tests/ui/entry.fixed
+++ b/src/tools/clippy/tests/ui/entry.fixed
@@ -165,4 +165,15 @@ pub fn issue_10331() {
     }
 }
 
+/// Issue 11935
+/// Do not suggest using entries if the map is used inside the `insert` expression.
+pub fn issue_11935() {
+    let mut counts: HashMap<u64, u64> = HashMap::new();
+    if !counts.contains_key(&1) {
+        counts.insert(1, 1);
+    } else {
+        counts.insert(1, counts.get(&1).unwrap() + 1);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/entry.rs b/src/tools/clippy/tests/ui/entry.rs
index 409be0aa060..86092b7c055 100644
--- a/src/tools/clippy/tests/ui/entry.rs
+++ b/src/tools/clippy/tests/ui/entry.rs
@@ -169,4 +169,15 @@ pub fn issue_10331() {
     }
 }
 
+/// Issue 11935
+/// Do not suggest using entries if the map is used inside the `insert` expression.
+pub fn issue_11935() {
+    let mut counts: HashMap<u64, u64> = HashMap::new();
+    if !counts.contains_key(&1) {
+        counts.insert(1, 1);
+    } else {
+        counts.insert(1, counts.get(&1).unwrap() + 1);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
index 06229a52a18..f38b34c5a7c 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
@@ -6,7 +6,7 @@
     clippy::deref_addrof,
     clippy::unnecessary_mut_passed,
     dead_code,
-    non_local_definitions,
+    non_local_definitions
 )]
 
 use core::slice;
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
index c2bf45ab2e9..2e701ada5ac 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
@@ -6,7 +6,7 @@
     clippy::deref_addrof,
     clippy::unnecessary_mut_passed,
     dead_code,
-    non_local_definitions,
+    non_local_definitions
 )]
 
 use core::slice;
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.rs b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
index 2045b1eebcd..620cffb4f04 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.rs
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
@@ -2,6 +2,7 @@
 //@aux-build:proc_macros.rs
 
 #![warn(clippy::field_reassign_with_default)]
+#![allow(clippy::assigning_clones)]
 
 #[macro_use]
 extern crate proc_macro_derive;
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
index bc032834920..ae909475c6f 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
@@ -1,11 +1,11 @@
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:56:5
+  --> tests/ui/field_reassign_with_default.rs:57:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:55:5
+  --> tests/ui/field_reassign_with_default.rs:56:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,121 +13,121 @@ LL |     let mut a: A = Default::default();
    = help: to override `-D warnings` add `#[allow(clippy::field_reassign_with_default)]`
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:96:5
+  --> tests/ui/field_reassign_with_default.rs:97:5
    |
 LL |     a.j = 43;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:95:5
+  --> tests/ui/field_reassign_with_default.rs:96:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:101:5
+  --> tests/ui/field_reassign_with_default.rs:102:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:100:5
+  --> tests/ui/field_reassign_with_default.rs:101:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:107:5
+  --> tests/ui/field_reassign_with_default.rs:108:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:106:5
+  --> tests/ui/field_reassign_with_default.rs:107:5
    |
 LL |     let mut a = A::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:117:5
+  --> tests/ui/field_reassign_with_default.rs:118:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:116:5
+  --> tests/ui/field_reassign_with_default.rs:117:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:121:5
+  --> tests/ui/field_reassign_with_default.rs:122:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:120:5
+  --> tests/ui/field_reassign_with_default.rs:121:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:143:5
+  --> tests/ui/field_reassign_with_default.rs:144:5
    |
 LL |     a.i = vec![1];
    |     ^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:142:5
+  --> tests/ui/field_reassign_with_default.rs:143:5
    |
 LL |     let mut a: C = C::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:161:5
+  --> tests/ui/field_reassign_with_default.rs:162:5
    |
 LL |     a.i = true;
    |     ^^^^^^^^^^^
    |
 note: consider initializing the variable with `Wrapper::<bool> { i: true }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:160:5
+  --> tests/ui/field_reassign_with_default.rs:161:5
    |
 LL |     let mut a: Wrapper<bool> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:164:5
+  --> tests/ui/field_reassign_with_default.rs:165:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `WrapperMulti::<i32, i64> { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:163:5
+  --> tests/ui/field_reassign_with_default.rs:164:5
    |
 LL |     let mut a: WrapperMulti<i32, i64> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:235:13
+  --> tests/ui/field_reassign_with_default.rs:236:13
    |
 LL |             f.name = name.len();
    |             ^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:234:13
+  --> tests/ui/field_reassign_with_default.rs:235:13
    |
 LL |             let mut f = ImplDropAllCopy::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:251:13
+  --> tests/ui/field_reassign_with_default.rs:252:13
    |
 LL |             f.name = name.len();
    |             ^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:250:13
+  --> tests/ui/field_reassign_with_default.rs:251:13
    |
 LL |             let mut f = NoDropAllCopy::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed
index 660e9a21b18..b18d8560f6f 100644
--- a/src/tools/clippy/tests/ui/identity_op.fixed
+++ b/src/tools/clippy/tests/ui/identity_op.fixed
@@ -134,7 +134,7 @@ fn main() {
     //~^ ERROR: this operation has no effect
     f(if b { 1 } else { 2 } + 3);
     //~^ ERROR: this operation has no effect
-    
+
     const _: i32 = { 2 * 4 } + 3;
     //~^ ERROR: this operation has no effect
     const _: i32 = { 1 + 2 * 3 } + 3;
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index bbef531e9dc..f1f01b42447 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -134,7 +134,7 @@ fn main() {
     //~^ ERROR: this operation has no effect
     f(0 + if b { 1 } else { 2 } + 3);
     //~^ ERROR: this operation has no effect
-    
+
     const _: i32 = { 2 * 4 } + 0 + 3;
     //~^ ERROR: this operation has no effect
     const _: i32 = 0 + { 1 + 2 * 3 } + 3;
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
index 2ababad7fc7..27ee2f91594 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![feature(inline_const)]
 #![warn(clippy::indexing_slicing)]
 // We also check the out_of_bounds_indexing lint here, because it lints similar things and
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index 06a4defcb93..5f62ec9b556 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -1,5 +1,5 @@
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:14:20
+  --> tests/ui/indexing_slicing_index.rs:16:20
    |
 LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
    |                    ^^^^^^^^^^
@@ -10,19 +10,19 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re
    = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
 
 error[E0080]: evaluation of `main::{constant#3}` failed
-  --> tests/ui/indexing_slicing_index.rs:46:14
+  --> tests/ui/indexing_slicing_index.rs:48:14
    |
 LL |     const { &ARR[idx4()] };
    |              ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
 
 note: erroneous constant encountered
-  --> tests/ui/indexing_slicing_index.rs:46:5
+  --> tests/ui/indexing_slicing_index.rs:48:5
    |
 LL |     const { &ARR[idx4()] };
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:27:5
+  --> tests/ui/indexing_slicing_index.rs:29:5
    |
 LL |     x[index];
    |     ^^^^^^^^
@@ -30,7 +30,7 @@ LL |     x[index];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:30:5
+  --> tests/ui/indexing_slicing_index.rs:32:5
    |
 LL |     x[4];
    |     ^^^^
@@ -39,13 +39,13 @@ LL |     x[4];
    = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:32:5
+  --> tests/ui/indexing_slicing_index.rs:34:5
    |
 LL |     x[1 << 3];
    |     ^^^^^^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:43:14
+  --> tests/ui/indexing_slicing_index.rs:45:14
    |
 LL |     const { &ARR[idx()] };
    |              ^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     const { &ARR[idx()] };
    = note: the suggestion might not be applicable in constant blocks
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:46:14
+  --> tests/ui/indexing_slicing_index.rs:48:14
    |
 LL |     const { &ARR[idx4()] };
    |              ^^^^^^^^^^^
@@ -63,13 +63,13 @@ LL |     const { &ARR[idx4()] };
    = note: the suggestion might not be applicable in constant blocks
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:53:5
+  --> tests/ui/indexing_slicing_index.rs:55:5
    |
 LL |     y[4];
    |     ^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:56:5
+  --> tests/ui/indexing_slicing_index.rs:58:5
    |
 LL |     v[0];
    |     ^^^^
@@ -77,7 +77,7 @@ LL |     v[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:58:5
+  --> tests/ui/indexing_slicing_index.rs:60:5
    |
 LL |     v[10];
    |     ^^^^^
@@ -85,7 +85,7 @@ LL |     v[10];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:60:5
+  --> tests/ui/indexing_slicing_index.rs:62:5
    |
 LL |     v[1 << 3];
    |     ^^^^^^^^^
@@ -93,13 +93,13 @@ LL |     v[1 << 3];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:68:5
+  --> tests/ui/indexing_slicing_index.rs:70:5
    |
 LL |     x[N];
    |     ^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:71:5
+  --> tests/ui/indexing_slicing_index.rs:73:5
    |
 LL |     v[N];
    |     ^^^^
@@ -107,7 +107,7 @@ LL |     v[N];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:73:5
+  --> tests/ui/indexing_slicing_index.rs:75:5
    |
 LL |     v[M];
    |     ^^^^
@@ -115,7 +115,7 @@ LL |     v[M];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:77:13
+  --> tests/ui/indexing_slicing_index.rs:79:13
    |
 LL |     let _ = x[4];
    |             ^^^^
diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.rs b/src/tools/clippy/tests/ui/let_underscore_untyped.rs
index bd94a3ada18..6275b6f970a 100644
--- a/src/tools/clippy/tests/ui/let_underscore_untyped.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_untyped.rs
@@ -73,3 +73,5 @@ fn main() {
     #[allow(clippy::let_underscore_untyped)]
     let _ = a();
 }
+
+async fn dont_lint_async_prototype(_: u8) {}
diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs
index 5d94660ec89..1fb252e3f97 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else.rs
@@ -1,3 +1,4 @@
+#![feature(try_blocks)]
 #![allow(unused_braces, unused_variables, dead_code)]
 #![allow(
     clippy::collapsible_else_if,
@@ -446,3 +447,12 @@ struct U<T> {
     w: T,
     x: T,
 }
+
+fn issue12337() {
+    // We want to generally silence question_mark lints within try blocks, since `?` has different
+    // behavior to `return`, and question_mark calls into manual_let_else logic, so make sure that
+    // we still emit a lint for manual_let_else
+    let _: Option<()> = try {
+        let v = if let Some(v_some) = g() { v_some } else { return };
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr
index b6433fc460c..7012c6b8891 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else.stderr
@@ -1,5 +1,5 @@
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:27:5
+  --> tests/ui/manual_let_else.rs:28:5
    |
 LL |     let v = if let Some(v_some) = g() { v_some } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
@@ -8,7 +8,7 @@ LL |     let v = if let Some(v_some) = g() { v_some } else { return };
    = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:30:5
+  --> tests/ui/manual_let_else.rs:31:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -26,7 +26,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:37:5
+  --> tests/ui/manual_let_else.rs:38:5
    |
 LL | /     let v = if let Some(v) = g() {
 LL | |
@@ -47,25 +47,25 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:49:9
+  --> tests/ui/manual_let_else.rs:50:9
    |
 LL |         let v = if let Some(v_some) = g() { v_some } else { continue };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:51:9
+  --> tests/ui/manual_let_else.rs:52:9
    |
 LL |         let v = if let Some(v_some) = g() { v_some } else { break };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:56:5
+  --> tests/ui/manual_let_else.rs:57:5
    |
 LL |     let v = if let Some(v_some) = g() { v_some } else { panic!() };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:60:5
+  --> tests/ui/manual_let_else.rs:61:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -83,7 +83,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:68:5
+  --> tests/ui/manual_let_else.rs:69:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -101,7 +101,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:76:5
+  --> tests/ui/manual_let_else.rs:77:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -121,7 +121,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:85:5
+  --> tests/ui/manual_let_else.rs:86:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -141,7 +141,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:94:5
+  --> tests/ui/manual_let_else.rs:95:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -168,7 +168,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:110:5
+  --> tests/ui/manual_let_else.rs:111:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -190,7 +190,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:121:5
+  --> tests/ui/manual_let_else.rs:122:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -217,7 +217,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:137:5
+  --> tests/ui/manual_let_else.rs:138:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -239,7 +239,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:148:5
+  --> tests/ui/manual_let_else.rs:149:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -257,7 +257,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:156:5
+  --> tests/ui/manual_let_else.rs:157:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -278,7 +278,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:166:5
+  --> tests/ui/manual_let_else.rs:167:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -299,7 +299,7 @@ LL +     } };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:176:5
+  --> tests/ui/manual_let_else.rs:177:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -328,7 +328,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:194:5
+  --> tests/ui/manual_let_else.rs:195:5
    |
 LL | /     let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {
 LL | |
@@ -346,7 +346,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:202:5
+  --> tests/ui/manual_let_else.rs:203:5
    |
 LL | /     let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) {
 LL | |
@@ -364,7 +364,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:212:13
+  --> tests/ui/manual_let_else.rs:213:13
    |
 LL |             let $n = if let Some(v) = $e { v } else { return };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };`
@@ -375,19 +375,19 @@ LL |     create_binding_if_some!(w, g());
    = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:221:5
+  --> tests/ui/manual_let_else.rs:222:5
    |
 LL |     let v = if let Variant::A(a, 0) = e() { a } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:225:5
+  --> tests/ui/manual_let_else.rs:226:5
    |
 LL |     let mut v = if let Variant::B(b) = e() { b } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:230:5
+  --> tests/ui/manual_let_else.rs:231:5
    |
 LL | /     let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested {
 LL | |
@@ -405,19 +405,19 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:237:5
+  --> tests/ui/manual_let_else.rs:238:5
    |
 LL |     let v = if let Variant::A(.., a) = e() { a } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:241:5
+  --> tests/ui/manual_let_else.rs:242:5
    |
 LL |     let w = if let (Some(v), ()) = (g(), ()) { v } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:245:5
+  --> tests/ui/manual_let_else.rs:246:5
    |
 LL | /     let w = if let Some(S { v: x }) = Some(S { v: 0 }) {
 LL | |
@@ -435,7 +435,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:253:5
+  --> tests/ui/manual_let_else.rs:254:5
    |
 LL | /     let v = if let Some(S { v: x }) = Some(S { v: 0 }) {
 LL | |
@@ -453,7 +453,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:261:5
+  --> tests/ui/manual_let_else.rs:262:5
    |
 LL | /     let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> {
 LL | |
@@ -471,7 +471,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:378:5
+  --> tests/ui/manual_let_else.rs:379:5
    |
 LL | /     let _ = match ff {
 LL | |
@@ -480,5 +480,11 @@ LL | |         _ => macro_call!(),
 LL | |     };
    | |______^ help: consider writing: `let Some(_) = ff else { macro_call!() };`
 
-error: aborting due to 30 previous errors
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else.rs:456:9
+   |
+LL |         let v = if let Some(v_some) = g() { v_some } else { return };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
index 8146091a2bb..c917fa7f2d0 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
@@ -1,5 +1,6 @@
-#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]
-#![allow(clippy::useless_vec)]
+#![warn(clippy::manual_memcpy)]
+#![allow(clippy::assigning_clones, clippy::useless_vec, clippy::needless_range_loop)]
+
 //@no-rustfix
 const LOOP_OFFSET: usize = 5000;
 
@@ -158,6 +159,59 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
         //~^ ERROR: it looks like you're manually copying between slices
         dst[i] = src[i];
     }
+
+    // Don't trigger lint for following multi-dimensional arrays
+    let src = [[0; 5]; 5];
+    for i in 0..4 {
+        dst[i] = src[i + 1][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][3];
+    }
+
+    let src = [0; 5];
+    let mut dst = [[0; 5]; 5];
+    for i in 0..5 {
+        dst[i][i] = src[i];
+    }
+
+    let src = [[[0; 5]; 5]; 5];
+    let mut dst = [0; 5];
+    for i in 0..5 {
+        dst[i] = src[i][i][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][i][0];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][0][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[0][i][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[0][i][1];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][0][1];
+    }
+
+    // Trigger lint
+    let src = [[0; 5]; 5];
+    let mut dst = [0; 5];
+    for i in 0..5 {
+        //~^ ERROR: it looks like you're manually copying between slices
+        dst[i] = src[0][i];
+    }
+
+    let src = [[[0; 5]; 5]; 5];
+    for i in 0..5 {
+        //~^ ERROR: it looks like you're manually copying between slices
+        dst[i] = src[0][1][i];
+    }
 }
 
 #[warn(clippy::needless_range_loop, clippy::manual_memcpy)]
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
index 55cca1fb584..803053b2db2 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
@@ -1,5 +1,5 @@
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:8:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:9:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -12,7 +12,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:15:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:16:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -21,7 +21,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:21:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:22:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -30,7 +30,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:27:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:28:5
    |
 LL | /     for i in 11..src.len() {
 LL | |
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:33:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:34:5
    |
 LL | /     for i in 0..dst.len() {
 LL | |
@@ -48,7 +48,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:47:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:48:5
    |
 LL | /     for i in 10..256 {
 LL | |
@@ -64,7 +64,7 @@ LL +     dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]);
    |
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:60:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:61:5
    |
 LL | /     for i in 10..LOOP_OFFSET {
 LL | |
@@ -73,7 +73,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:74:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:75:5
    |
 LL | /     for i in 0..src_vec.len() {
 LL | |
@@ -82,7 +82,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:104:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:105:5
    |
 LL | /     for i in from..from + src.len() {
 LL | |
@@ -91,7 +91,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:109:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:110:5
    |
 LL | /     for i in from..from + 3 {
 LL | |
@@ -100,7 +100,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:115:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:116:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -109,7 +109,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:121:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:122:5
    |
 LL | /     for i in 0..0 {
 LL | |
@@ -118,7 +118,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:145:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:146:5
    |
 LL | /     for i in 0..4 {
 LL | |
@@ -127,7 +127,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:151:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:152:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -136,7 +136,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:157:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:158:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -145,7 +145,25 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:165:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:205:5
+   |
+LL | /     for i in 0..5 {
+LL | |
+LL | |         dst[i] = src[0][i];
+LL | |     }
+   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);`
+
+error: it looks like you're manually copying between slices
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:211:5
+   |
+LL | /     for i in 0..5 {
+LL | |
+LL | |         dst[i] = src[0][1][i];
+LL | |     }
+   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);`
+
+error: it looks like you're manually copying between slices
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:219:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -153,5 +171,5 @@ LL | |         dst[i] = src[i].clone();
 LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..]);`
 
-error: aborting due to 16 previous errors
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_retain.fixed b/src/tools/clippy/tests/ui/manual_retain.fixed
index 5540029bf6b..e359dfbb98c 100644
--- a/src/tools/clippy/tests/ui/manual_retain.fixed
+++ b/src/tools/clippy/tests/ui/manual_retain.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::manual_retain)]
 #![allow(unused, clippy::redundant_clone)]
 use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
diff --git a/src/tools/clippy/tests/ui/manual_retain.rs b/src/tools/clippy/tests/ui/manual_retain.rs
index cee641d9d65..931814f08b7 100644
--- a/src/tools/clippy/tests/ui/manual_retain.rs
+++ b/src/tools/clippy/tests/ui/manual_retain.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::manual_retain)]
 #![allow(unused, clippy::redundant_clone)]
 use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
diff --git a/src/tools/clippy/tests/ui/manual_retain.stderr b/src/tools/clippy/tests/ui/manual_retain.stderr
index c25c804df75..fdbbc53e4df 100644
--- a/src/tools/clippy/tests/ui/manual_retain.stderr
+++ b/src/tools/clippy/tests/ui/manual_retain.stderr
@@ -1,5 +1,5 @@
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:25:5
+  --> tests/ui/manual_retain.rs:27:5
    |
 LL |     binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
@@ -8,43 +8,43 @@ LL |     binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
    = help: to override `-D warnings` add `#[allow(clippy::manual_retain)]`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:26:5
+  --> tests/ui/manual_retain.rs:28:5
    |
 LL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:27:5
+  --> tests/ui/manual_retain.rs:29:5
    |
 LL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:31:5
+  --> tests/ui/manual_retain.rs:33:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:32:5
+  --> tests/ui/manual_retain.rs:34:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:62:5
+  --> tests/ui/manual_retain.rs:64:5
    |
 LL |     btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:63:5
+  --> tests/ui/manual_retain.rs:65:5
    |
 LL |     btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:64:5
+  --> tests/ui/manual_retain.rs:66:5
    |
 LL | /     btree_map = btree_map
 LL | |         .into_iter()
@@ -53,49 +53,49 @@ LL | |         .collect();
    | |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:89:5
+  --> tests/ui/manual_retain.rs:91:5
    |
 LL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:90:5
+  --> tests/ui/manual_retain.rs:92:5
    |
 LL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:91:5
+  --> tests/ui/manual_retain.rs:93:5
    |
 LL |     btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:95:5
+  --> tests/ui/manual_retain.rs:97:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:96:5
+  --> tests/ui/manual_retain.rs:98:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:126:5
+  --> tests/ui/manual_retain.rs:128:5
    |
 LL |     hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:127:5
+  --> tests/ui/manual_retain.rs:129:5
    |
 LL |     hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:128:5
+  --> tests/ui/manual_retain.rs:130:5
    |
 LL | /     hash_map = hash_map
 LL | |         .into_iter()
@@ -104,133 +104,133 @@ LL | |         .collect();
    | |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:152:5
+  --> tests/ui/manual_retain.rs:154:5
    |
 LL |     hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:153:5
+  --> tests/ui/manual_retain.rs:155:5
    |
 LL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:154:5
+  --> tests/ui/manual_retain.rs:156:5
    |
 LL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:158:5
+  --> tests/ui/manual_retain.rs:160:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:159:5
+  --> tests/ui/manual_retain.rs:161:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:188:5
+  --> tests/ui/manual_retain.rs:190:5
    |
 LL |     s = s.chars().filter(|&c| c != 'o').to_owned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:200:5
+  --> tests/ui/manual_retain.rs:202:5
    |
 LL |     vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:201:5
+  --> tests/ui/manual_retain.rs:203:5
    |
 LL |     vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:202:5
+  --> tests/ui/manual_retain.rs:204:5
    |
 LL |     vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:206:5
+  --> tests/ui/manual_retain.rs:208:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:207:5
+  --> tests/ui/manual_retain.rs:209:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:229:5
+  --> tests/ui/manual_retain.rs:231:5
    |
 LL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:230:5
+  --> tests/ui/manual_retain.rs:232:5
    |
 LL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:231:5
+  --> tests/ui/manual_retain.rs:233:5
    |
 LL |     vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:288:5
+  --> tests/ui/manual_retain.rs:290:5
    |
 LL |     vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:292:5
+  --> tests/ui/manual_retain.rs:294:5
    |
 LL |     tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(_, n)| *n > 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:309:5
+  --> tests/ui/manual_retain.rs:311:5
    |
 LL |     vec = vec.iter().filter(|&&x| x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:310:5
+  --> tests/ui/manual_retain.rs:312:5
    |
 LL |     vec = vec.iter().filter(|&&x| x == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:311:5
+  --> tests/ui/manual_retain.rs:313:5
    |
 LL |     vec = vec.into_iter().filter(|&x| x == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:314:5
+  --> tests/ui/manual_retain.rs:316:5
    |
 LL |     vec = vec.iter().filter(|&x| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:315:5
+  --> tests/ui/manual_retain.rs:317:5
    |
 LL |     vec = vec.iter().filter(|&x| *x == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:316:5
+  --> tests/ui/manual_retain.rs:318:5
    |
 LL |     vec = vec.into_iter().filter(|x| *x == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
diff --git a/src/tools/clippy/tests/ui/many_single_char_names.rs b/src/tools/clippy/tests/ui/many_single_char_names.rs
index 68578340d90..2af45eaab8a 100644
--- a/src/tools/clippy/tests/ui/many_single_char_names.rs
+++ b/src/tools/clippy/tests/ui/many_single_char_names.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![allow(clippy::too_many_arguments, clippy::diverging_sub_expression)]
 #![warn(clippy::many_single_char_names)]
 
diff --git a/src/tools/clippy/tests/ui/many_single_char_names.stderr b/src/tools/clippy/tests/ui/many_single_char_names.stderr
index 131836ef7c8..3b2460b5c07 100644
--- a/src/tools/clippy/tests/ui/many_single_char_names.stderr
+++ b/src/tools/clippy/tests/ui/many_single_char_names.stderr
@@ -1,5 +1,5 @@
 error: 5 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:5:9
+  --> tests/ui/many_single_char_names.rs:7:9
    |
 LL |     let a: i32;
    |         ^
@@ -14,7 +14,7 @@ LL |             let e: i32;
    = help: to override `-D warnings` add `#[allow(clippy::many_single_char_names)]`
 
 error: 6 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:5:9
+  --> tests/ui/many_single_char_names.rs:7:9
    |
 LL |     let a: i32;
    |         ^
@@ -28,7 +28,7 @@ LL |             let f: i32;
    |                 ^
 
 error: 5 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:5:9
+  --> tests/ui/many_single_char_names.rs:7:9
    |
 LL |     let a: i32;
    |         ^
@@ -40,13 +40,13 @@ LL |             e => panic!(),
    |             ^
 
 error: 8 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:34:13
+  --> tests/ui/many_single_char_names.rs:36:13
    |
 LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
    |             ^       ^       ^       ^       ^       ^       ^       ^
 
 error: 8 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:38:10
+  --> tests/ui/many_single_char_names.rs:40:10
    |
 LL |     let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();
    |          ^  ^  ^  ^  ^  ^  ^  ^
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
index 3917bb9e03d..2dccadd9fce 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![feature(custom_inner_attributes)]
 #![clippy::msrv = "invalid.version"]
 //~^ ERROR: `invalid.version` is not a valid Rust version
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
index cf0d08a5d21..b4cb1b5713f 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
@@ -1,35 +1,35 @@
 error: `invalid.version` is not a valid Rust version
-  --> tests/ui/min_rust_version_invalid_attr.rs:2:1
+  --> tests/ui/min_rust_version_invalid_attr.rs:4:1
    |
 LL | #![clippy::msrv = "invalid.version"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `invalid.version` is not a valid Rust version
-  --> tests/ui/min_rust_version_invalid_attr.rs:7:1
+  --> tests/ui/min_rust_version_invalid_attr.rs:9:1
    |
 LL | #[clippy::msrv = "invalid.version"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `clippy::msrv` is defined multiple times
-  --> tests/ui/min_rust_version_invalid_attr.rs:14:5
+  --> tests/ui/min_rust_version_invalid_attr.rs:16:5
    |
 LL |     #![clippy::msrv = "1.10.1"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first definition found here
-  --> tests/ui/min_rust_version_invalid_attr.rs:12:5
+  --> tests/ui/min_rust_version_invalid_attr.rs:14:5
    |
 LL |     #![clippy::msrv = "1.40"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `clippy::msrv` is defined multiple times
-  --> tests/ui/min_rust_version_invalid_attr.rs:19:9
+  --> tests/ui/min_rust_version_invalid_attr.rs:21:9
    |
 LL |         #![clippy::msrv = "1.0.0"]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first definition found here
-  --> tests/ui/min_rust_version_invalid_attr.rs:18:9
+  --> tests/ui/min_rust_version_invalid_attr.rs:20:9
    |
 LL |         #![clippy::msrv = "1"]
    |         ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.rs b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
new file mode 100644
index 00000000000..ad93e3019fa
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
@@ -0,0 +1,39 @@
+#![warn(clippy::mixed_attributes_style)]
+
+#[allow(unused)] //~ ERROR: item has both inner and outer attributes
+fn foo1() {
+    #![allow(unused)]
+}
+
+#[allow(unused)]
+#[allow(unused)]
+fn foo2() {}
+
+fn foo3() {
+    #![allow(unused)]
+    #![allow(unused)]
+}
+
+/// linux
+//~^ ERROR: item has both inner and outer attributes
+fn foo4() {
+    //! windows
+}
+
+/// linux
+/// windows
+fn foo5() {}
+
+fn foo6() {
+    //! linux
+    //! windows
+}
+
+#[allow(unused)] //~ ERROR: item has both inner and outer attributes
+mod bar {
+    #![allow(unused)]
+}
+
+fn main() {
+    // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.stderr b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
new file mode 100644
index 00000000000..d1d5cd3f47f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
@@ -0,0 +1,30 @@
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:3:1
+   |
+LL | / #[allow(unused)]
+LL | | fn foo1() {
+LL | |     #![allow(unused)]
+   | |_____________________^
+   |
+   = note: `-D clippy::mixed-attributes-style` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]`
+
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:17:1
+   |
+LL | / /// linux
+LL | |
+LL | | fn foo4() {
+LL | |     //! windows
+   | |_______________^
+
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:32:1
+   |
+LL | / #[allow(unused)]
+LL | | mod bar {
+LL | |     #![allow(unused)]
+   | |_____________________^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/mut_mut.rs b/src/tools/clippy/tests/ui/mut_mut.rs
index 72a171119f3..288b003405d 100644
--- a/src/tools/clippy/tests/ui/mut_mut.rs
+++ b/src/tools/clippy/tests/ui/mut_mut.rs
@@ -1,4 +1,6 @@
 //@aux-build:proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::mut_mut)]
 #![allow(unused)]
 #![allow(
diff --git a/src/tools/clippy/tests/ui/mut_mut.stderr b/src/tools/clippy/tests/ui/mut_mut.stderr
index 810c0c96743..73f2410a252 100644
--- a/src/tools/clippy/tests/ui/mut_mut.stderr
+++ b/src/tools/clippy/tests/ui/mut_mut.stderr
@@ -1,5 +1,5 @@
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:14:11
+  --> tests/ui/mut_mut.rs:16:11
    |
 LL | fn fun(x: &mut &mut u32) -> bool {
    |           ^^^^^^^^^^^^^
@@ -8,13 +8,13 @@ LL | fn fun(x: &mut &mut u32) -> bool {
    = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]`
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:31:17
+  --> tests/ui/mut_mut.rs:33:17
    |
 LL |     let mut x = &mut &mut 1u32;
    |                 ^^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:46:25
+  --> tests/ui/mut_mut.rs:48:25
    |
 LL |     let mut z = inline!(&mut $(&mut 3u32));
    |                         ^
@@ -22,37 +22,37 @@ LL |     let mut z = inline!(&mut $(&mut 3u32));
    = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this expression mutably borrows a mutable reference. Consider reborrowing
-  --> tests/ui/mut_mut.rs:33:21
+  --> tests/ui/mut_mut.rs:35:21
    |
 LL |         let mut y = &mut x;
    |                     ^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:37:32
+  --> tests/ui/mut_mut.rs:39:32
    |
 LL |         let y: &mut &mut u32 = &mut &mut 2;
    |                                ^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:37:16
+  --> tests/ui/mut_mut.rs:39:16
    |
 LL |         let y: &mut &mut u32 = &mut &mut 2;
    |                ^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:42:37
+  --> tests/ui/mut_mut.rs:44:37
    |
 LL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;
    |                                     ^^^^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:42:16
+  --> tests/ui/mut_mut.rs:44:16
    |
 LL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;
    |                ^^^^^^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:42:21
+  --> tests/ui/mut_mut.rs:44:21
    |
 LL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;
    |                     ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/no_effect_replace.rs b/src/tools/clippy/tests/ui/no_effect_replace.rs
index e4fd5caae2a..2a940d87fb9 100644
--- a/src/tools/clippy/tests/ui/no_effect_replace.rs
+++ b/src/tools/clippy/tests/ui/no_effect_replace.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::no_effect_replace)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/no_effect_replace.stderr b/src/tools/clippy/tests/ui/no_effect_replace.stderr
index ded86c5c5b8..ad2dcd2cc9b 100644
--- a/src/tools/clippy/tests/ui/no_effect_replace.stderr
+++ b/src/tools/clippy/tests/ui/no_effect_replace.stderr
@@ -1,5 +1,5 @@
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:4:13
+  --> tests/ui/no_effect_replace.rs:6:13
    |
 LL |     let _ = "12345".replace('1', "1");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,43 +8,43 @@ LL |     let _ = "12345".replace('1', "1");
    = help: to override `-D warnings` add `#[allow(clippy::no_effect_replace)]`
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:7:13
+  --> tests/ui/no_effect_replace.rs:9:13
    |
 LL |     let _ = "12345".replace("12", "12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:9:13
+  --> tests/ui/no_effect_replace.rs:11:13
    |
 LL |     let _ = String::new().replace("12", "12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:12:13
+  --> tests/ui/no_effect_replace.rs:14:13
    |
 LL |     let _ = "12345".replacen('1', "1", 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:14:13
+  --> tests/ui/no_effect_replace.rs:16:13
    |
 LL |     let _ = "12345".replacen("12", "12", 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:16:13
+  --> tests/ui/no_effect_replace.rs:18:13
    |
 LL |     let _ = String::new().replacen("12", "12", 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:23:13
+  --> tests/ui/no_effect_replace.rs:25:13
    |
 LL |     let _ = "hello".replace(&x.f(), &x.f());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:27:13
+  --> tests/ui/no_effect_replace.rs:29:13
    |
 LL |     let _ = "hello".replace(&y(), &y());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed b/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
index 165702b3041..7d1be412e54 100644
--- a/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
@@ -1,4 +1,5 @@
 #![allow(clippy::clone_on_copy, unused)]
+#![allow(clippy::assigning_clones)]
 #![no_main]
 
 // lint
diff --git a/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs b/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
index 3b07dd5ce62..beae05efb2f 100644
--- a/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
@@ -1,4 +1,5 @@
 #![allow(clippy::clone_on_copy, unused)]
+#![allow(clippy::assigning_clones)]
 #![no_main]
 
 // lint
diff --git a/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr b/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
index 8eff322fa2d..6bfc99d988b 100644
--- a/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
@@ -1,5 +1,5 @@
 error: non-canonical implementation of `clone` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:9:29
+  --> tests/ui/non_canonical_clone_impl.rs:10:29
    |
 LL |       fn clone(&self) -> Self {
    |  _____________________________^
@@ -11,7 +11,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]`
 
 error: unnecessary implementation of `clone_from` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:13:5
+  --> tests/ui/non_canonical_clone_impl.rs:14:5
    |
 LL | /     fn clone_from(&mut self, source: &Self) {
 LL | |         source.clone();
@@ -20,7 +20,7 @@ LL | |     }
    | |_____^ help: remove it
 
 error: non-canonical implementation of `clone` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:80:29
+  --> tests/ui/non_canonical_clone_impl.rs:81:29
    |
 LL |       fn clone(&self) -> Self {
    |  _____________________________^
@@ -29,7 +29,7 @@ LL | |     }
    | |_____^ help: change this to: `{ *self }`
 
 error: unnecessary implementation of `clone_from` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:84:5
+  --> tests/ui/non_canonical_clone_impl.rs:85:5
    |
 LL | /     fn clone_from(&mut self, source: &Self) {
 LL | |         source.clone();
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs
index 908ef6cb2a0..38157116e91 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs
@@ -1,4 +1,5 @@
 //@no-rustfix: overlapping suggestions
+
 #![feature(lint_reasons)]
 #![allow(
     unused,
@@ -173,3 +174,8 @@ fn issue_5794() {
     if !b == !c {} //~ ERROR: this boolean expression can be simplified
     if !b != !c {} //~ ERROR: this boolean expression can be simplified
 }
+
+fn issue_12371(x: usize) -> bool {
+    // Should not warn!
+    !x != 0
+}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
index 954e2345266..b6af06d845a 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
@@ -1,5 +1,5 @@
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:18:13
+  --> tests/ui/nonminimal_bool.rs:19:13
    |
 LL |     let _ = !true;
    |             ^^^^^ help: try: `false`
@@ -8,43 +8,43 @@ LL |     let _ = !true;
    = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:21:13
+  --> tests/ui/nonminimal_bool.rs:22:13
    |
 LL |     let _ = !false;
    |             ^^^^^^ help: try: `true`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:23:13
+  --> tests/ui/nonminimal_bool.rs:24:13
    |
 LL |     let _ = !!a;
    |             ^^^ help: try: `a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:25:13
+  --> tests/ui/nonminimal_bool.rs:26:13
    |
 LL |     let _ = false || a;
    |             ^^^^^^^^^^ help: try: `a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:30:13
+  --> tests/ui/nonminimal_bool.rs:31:13
    |
 LL |     let _ = !(!a && b);
    |             ^^^^^^^^^^ help: try: `a || !b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:32:13
+  --> tests/ui/nonminimal_bool.rs:33:13
    |
 LL |     let _ = !(!a || b);
    |             ^^^^^^^^^^ help: try: `a && !b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:34:13
+  --> tests/ui/nonminimal_bool.rs:35:13
    |
 LL |     let _ = !a && !(b && c);
    |             ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:43:13
+  --> tests/ui/nonminimal_bool.rs:44:13
    |
 LL |     let _ = a == b && c == 5 && a == b;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = a == b && c == 5;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:45:13
+  --> tests/ui/nonminimal_bool.rs:46:13
    |
 LL |     let _ = a == b || c == 5 || a == b;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     let _ = a == b || c == 5;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:47:13
+  --> tests/ui/nonminimal_bool.rs:48:13
    |
 LL |     let _ = a == b && c == 5 && b == a;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     let _ = a == b && c == 5;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:49:13
+  --> tests/ui/nonminimal_bool.rs:50:13
    |
 LL |     let _ = a != b || !(a != b || c == d);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL |     let _ = a != b || c != d;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:51:13
+  --> tests/ui/nonminimal_bool.rs:52:13
    |
 LL |     let _ = a != b && !(a != b && c == d);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -109,43 +109,43 @@ LL |     let _ = a != b && c != d;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:82:8
+  --> tests/ui/nonminimal_bool.rs:83:8
    |
 LL |     if matches!(true, true) && true {
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:162:8
+  --> tests/ui/nonminimal_bool.rs:163:8
    |
 LL |     if !(12 == a) {}
    |        ^^^^^^^^^^ help: try: `12 != a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:163:8
+  --> tests/ui/nonminimal_bool.rs:164:8
    |
 LL |     if !(a == 12) {}
    |        ^^^^^^^^^^ help: try: `a != 12`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:164:8
+  --> tests/ui/nonminimal_bool.rs:165:8
    |
 LL |     if !(12 != a) {}
    |        ^^^^^^^^^^ help: try: `12 == a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:165:8
+  --> tests/ui/nonminimal_bool.rs:166:8
    |
 LL |     if !(a != 12) {}
    |        ^^^^^^^^^^ help: try: `a == 12`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:169:8
+  --> tests/ui/nonminimal_bool.rs:170:8
    |
 LL |     if !b == true {}
    |        ^^^^^^^^^^ help: try: `b != true`
 
 error: this comparison might be written more concisely
-  --> tests/ui/nonminimal_bool.rs:169:8
+  --> tests/ui/nonminimal_bool.rs:170:8
    |
 LL |     if !b == true {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `b != true`
@@ -154,61 +154,61 @@ LL |     if !b == true {}
    = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
 
 error: equality checks against true are unnecessary
-  --> tests/ui/nonminimal_bool.rs:169:8
+  --> tests/ui/nonminimal_bool.rs:170:8
    |
 LL |     if !b == true {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:170:8
+  --> tests/ui/nonminimal_bool.rs:171:8
    |
 LL |     if !b != true {}
    |        ^^^^^^^^^^ help: try: `b == true`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/nonminimal_bool.rs:170:8
+  --> tests/ui/nonminimal_bool.rs:171:8
    |
 LL |     if !b != true {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:171:8
+  --> tests/ui/nonminimal_bool.rs:172:8
    |
 LL |     if true == !b {}
    |        ^^^^^^^^^^ help: try: `true != b`
 
 error: this comparison might be written more concisely
-  --> tests/ui/nonminimal_bool.rs:171:8
+  --> tests/ui/nonminimal_bool.rs:172:8
    |
 LL |     if true == !b {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `true != b`
 
 error: equality checks against true are unnecessary
-  --> tests/ui/nonminimal_bool.rs:171:8
+  --> tests/ui/nonminimal_bool.rs:172:8
    |
 LL |     if true == !b {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:172:8
+  --> tests/ui/nonminimal_bool.rs:173:8
    |
 LL |     if true != !b {}
    |        ^^^^^^^^^^ help: try: `true == b`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/nonminimal_bool.rs:172:8
+  --> tests/ui/nonminimal_bool.rs:173:8
    |
 LL |     if true != !b {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:173:8
+  --> tests/ui/nonminimal_bool.rs:174:8
    |
 LL |     if !b == !c {}
    |        ^^^^^^^^ help: try: `b == c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:174:8
+  --> tests/ui/nonminimal_bool.rs:175:8
    |
 LL |     if !b != !c {}
    |        ^^^^^^^^ help: try: `b != c`
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
index e27c0350d49..bd4be3e5a44 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
 #![warn(clippy::nonminimal_bool)]
 
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
index 040a6e920a1..4523c7385df 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
 #![warn(clippy::nonminimal_bool)]
 
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
index ede88ba529c..e32c8dacd2f 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
@@ -1,5 +1,5 @@
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:8:13
+  --> tests/ui/nonminimal_bool_methods.rs:10:13
    |
 LL |     let _ = !a.is_some();
    |             ^^^^^^^^^^^^ help: try: `a.is_none()`
@@ -8,73 +8,73 @@ LL |     let _ = !a.is_some();
    = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:10:13
+  --> tests/ui/nonminimal_bool_methods.rs:12:13
    |
 LL |     let _ = !a.is_none();
    |             ^^^^^^^^^^^^ help: try: `a.is_some()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:12:13
+  --> tests/ui/nonminimal_bool_methods.rs:14:13
    |
 LL |     let _ = !b.is_err();
    |             ^^^^^^^^^^^ help: try: `b.is_ok()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:14:13
+  --> tests/ui/nonminimal_bool_methods.rs:16:13
    |
 LL |     let _ = !b.is_ok();
    |             ^^^^^^^^^^ help: try: `b.is_err()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:16:13
+  --> tests/ui/nonminimal_bool_methods.rs:18:13
    |
 LL |     let _ = !(a.is_some() && !c);
    |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:17:13
+  --> tests/ui/nonminimal_bool_methods.rs:19:13
    |
 LL |     let _ = !(a.is_some() || !c);
    |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:18:26
+  --> tests/ui/nonminimal_bool_methods.rs:20:26
    |
 LL |     let _ = !(!c ^ c) || !a.is_some();
    |                          ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:19:25
+  --> tests/ui/nonminimal_bool_methods.rs:21:25
    |
 LL |     let _ = (!c ^ c) || !a.is_some();
    |                         ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:20:23
+  --> tests/ui/nonminimal_bool_methods.rs:22:23
    |
 LL |     let _ = !c ^ c || !a.is_some();
    |                       ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:92:8
+  --> tests/ui/nonminimal_bool_methods.rs:94:8
    |
 LL |     if !res.is_ok() {}
    |        ^^^^^^^^^^^^ help: try: `res.is_err()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:93:8
+  --> tests/ui/nonminimal_bool_methods.rs:95:8
    |
 LL |     if !res.is_err() {}
    |        ^^^^^^^^^^^^^ help: try: `res.is_ok()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:96:8
+  --> tests/ui/nonminimal_bool_methods.rs:98:8
    |
 LL |     if !res.is_some() {}
    |        ^^^^^^^^^^^^^^ help: try: `res.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:97:8
+  --> tests/ui/nonminimal_bool_methods.rs:99:8
    |
 LL |     if !res.is_none() {}
    |        ^^^^^^^^^^^^^^ help: try: `res.is_some()`
diff --git a/src/tools/clippy/tests/ui/option_option.rs b/src/tools/clippy/tests/ui/option_option.rs
index 9bbdd3aaacc..2f6e4d76145 100644
--- a/src/tools/clippy/tests/ui/option_option.rs
+++ b/src/tools/clippy/tests/ui/option_option.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![deny(clippy::option_option)]
 #![allow(clippy::unnecessary_wraps)]
 
diff --git a/src/tools/clippy/tests/ui/option_option.stderr b/src/tools/clippy/tests/ui/option_option.stderr
index 0cd048e400e..76cb9ae944c 100644
--- a/src/tools/clippy/tests/ui/option_option.stderr
+++ b/src/tools/clippy/tests/ui/option_option.stderr
@@ -1,77 +1,77 @@
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:4:10
+  --> tests/ui/option_option.rs:6:10
    |
 LL | const C: Option<Option<i32>> = None;
    |          ^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> tests/ui/option_option.rs:1:9
+  --> tests/ui/option_option.rs:3:9
    |
 LL | #![deny(clippy::option_option)]
    |         ^^^^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:6:11
+  --> tests/ui/option_option.rs:8:11
    |
 LL | static S: Option<Option<i32>> = None;
    |           ^^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:9:13
+  --> tests/ui/option_option.rs:11:13
    |
 LL | fn input(_: Option<Option<u8>>) {}
    |             ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:12:16
+  --> tests/ui/option_option.rs:14:16
    |
 LL | fn output() -> Option<Option<u8>> {
    |                ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:17:27
+  --> tests/ui/option_option.rs:19:27
    |
 LL | fn output_nested() -> Vec<Option<Option<u8>>> {
    |                           ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:23:30
+  --> tests/ui/option_option.rs:25:30
    |
 LL | fn output_nested_nested() -> Option<Option<Option<u8>>> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:29:8
+  --> tests/ui/option_option.rs:31:8
    |
 LL |     x: Option<Option<u8>>,
    |        ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:34:23
+  --> tests/ui/option_option.rs:36:23
    |
 LL |     fn struct_fn() -> Option<Option<u8>> {
    |                       ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:41:22
+  --> tests/ui/option_option.rs:43:22
    |
 LL |     fn trait_fn() -> Option<Option<u8>>;
    |                      ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:46:11
+  --> tests/ui/option_option.rs:48:11
    |
 LL |     Tuple(Option<Option<u8>>),
    |           ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:48:17
+  --> tests/ui/option_option.rs:50:17
    |
 LL |     Struct { x: Option<Option<u8>> },
    |                 ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:90:14
+  --> tests/ui/option_option.rs:92:14
    |
 LL |         foo: Option<Option<Cow<'a, str>>>,
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
index fa15c323540..61d37b8ba3a 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
 
 #![warn(clippy::ptr_as_ptr)]
 
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
index 7ab52e63da5..8f2068cd268 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
 
 #![warn(clippy::ptr_as_ptr)]
 
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
index e162f35baf5..e6cd697c7ba 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
@@ -1,5 +1,5 @@
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:18:33
+  --> tests/ui/ptr_as_ptr.rs:19:33
    |
 LL |         *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()`
@@ -8,37 +8,37 @@ LL |         *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::i
    = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:27:13
+  --> tests/ui/ptr_as_ptr.rs:28:13
    |
 LL |     let _ = ptr as *const i32;
    |             ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:28:13
+  --> tests/ui/ptr_as_ptr.rs:29:13
    |
 LL |     let _ = mut_ptr as *mut i32;
    |             ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:33:17
+  --> tests/ui/ptr_as_ptr.rs:34:17
    |
 LL |         let _ = *ptr_ptr as *const i32;
    |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:46:25
+  --> tests/ui/ptr_as_ptr.rs:47:25
    |
 LL |     let _: *const i32 = ptr as *const _;
    |                         ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:47:23
+  --> tests/ui/ptr_as_ptr.rs:48:23
    |
 LL |     let _: *mut i32 = mut_ptr as _;
    |                       ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:50:21
+  --> tests/ui/ptr_as_ptr.rs:51:21
    |
 LL |     let _ = inline!($ptr as *const i32);
    |                     ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
@@ -46,157 +46,157 @@ LL |     let _ = inline!($ptr as *const i32);
    = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:71:13
+  --> tests/ui/ptr_as_ptr.rs:72:13
    |
 LL |     let _ = ptr as *const i32;
    |             ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:72:13
+  --> tests/ui/ptr_as_ptr.rs:73:13
    |
 LL |     let _ = mut_ptr as *mut i32;
    |             ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:79:9
+  --> tests/ui/ptr_as_ptr.rs:80:9
    |
 LL |         ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:83:9
+  --> tests/ui/ptr_as_ptr.rs:84:9
    |
 LL |         std::ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:88:9
+  --> tests/ui/ptr_as_ptr.rs:89:9
    |
 LL |         ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:92:9
+  --> tests/ui/ptr_as_ptr.rs:93:9
    |
 LL |         core::ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:97:9
+  --> tests/ui/ptr_as_ptr.rs:98:9
    |
 LL |         ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:101:9
+  --> tests/ui/ptr_as_ptr.rs:102:9
    |
 LL |         std::ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:106:9
+  --> tests/ui/ptr_as_ptr.rs:107:9
    |
 LL |         ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:110:9
+  --> tests/ui/ptr_as_ptr.rs:111:9
    |
 LL |         core::ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:117:9
+  --> tests/ui/ptr_as_ptr.rs:118:9
    |
 LL |         ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:121:9
+  --> tests/ui/ptr_as_ptr.rs:122:9
    |
 LL |         std::ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:126:9
+  --> tests/ui/ptr_as_ptr.rs:127:9
    |
 LL |         ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:130:9
+  --> tests/ui/ptr_as_ptr.rs:131:9
    |
 LL |         core::ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:135:9
+  --> tests/ui/ptr_as_ptr.rs:136:9
    |
 LL |         ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:139:9
+  --> tests/ui/ptr_as_ptr.rs:140:9
    |
 LL |         std::ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:144:9
+  --> tests/ui/ptr_as_ptr.rs:145:9
    |
 LL |         ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:148:9
+  --> tests/ui/ptr_as_ptr.rs:149:9
    |
 LL |         core::ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:155:9
+  --> tests/ui/ptr_as_ptr.rs:156:9
    |
 LL |         ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:159:9
+  --> tests/ui/ptr_as_ptr.rs:160:9
    |
 LL |         std::ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:164:9
+  --> tests/ui/ptr_as_ptr.rs:165:9
    |
 LL |         ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:168:9
+  --> tests/ui/ptr_as_ptr.rs:169:9
    |
 LL |         core::ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:173:9
+  --> tests/ui/ptr_as_ptr.rs:174:9
    |
 LL |         ptr::null() as _
    |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:177:9
+  --> tests/ui/ptr_as_ptr.rs:178:9
    |
 LL |         std::ptr::null() as _
    |         ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:182:9
+  --> tests/ui/ptr_as_ptr.rs:183:9
    |
 LL |         ptr::null() as _
    |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:186:9
+  --> tests/ui/ptr_as_ptr.rs:187:9
    |
 LL |         core::ptr::null() as _
    |         ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 2ef006c1419..567472a8af2 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -273,3 +273,13 @@ const fn issue9175(option: Option<()>) -> Option<()> {
     //stuff
     Some(())
 }
+
+fn issue12337() -> Option<i32> {
+    let _: Option<i32> = try {
+        let Some(_) = Some(42) else {
+            return None;
+        };
+        123
+    };
+    Some(42)
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index c170669823f..abf8c270de8 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -313,3 +313,13 @@ const fn issue9175(option: Option<()>) -> Option<()> {
     //stuff
     Some(())
 }
+
+fn issue12337() -> Option<i32> {
+    let _: Option<i32> = try {
+        let Some(_) = Some(42) else {
+            return None;
+        };
+        123
+    };
+    Some(42)
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index ce5c7f2600b..191f7719904 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -111,3 +111,20 @@ fn fp_11274() {
     }
     m!(|x| println!("{x}"));
 }
+
+// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
+// triggers the lint.
+fn issue_12358() {
+    macro_rules! make_closure {
+        () => {
+            (|| || {})
+        };
+        (x) => {
+            make_closure!()()
+        };
+    }
+
+    // The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
+    // different.
+    make_closure!(x)();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
index ac09390e6ea..33a3b90f9cf 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -111,3 +111,20 @@ fn fp_11274() {
     }
     m!(|x| println!("{x}"));
 }
+
+// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
+// triggers the lint.
+fn issue_12358() {
+    macro_rules! make_closure {
+        () => {
+            (|| || {})
+        };
+        (x) => {
+            make_closure!()()
+        };
+    }
+
+    // The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
+    // different.
+    make_closure!(x)();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed
index c578e786426..72fc4cb7333 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.fixed
+++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed
@@ -20,7 +20,7 @@ struct Person {
 }
 
 pub struct S {
-    v: String,
+    v: usize,
 }
 
 fn main() {
@@ -59,11 +59,22 @@ fn main() {
     let _ = RangeToInclusive { end };
 
     external! {
-        let v = String::new();
+        let v = 1;
         let _ = S {
             v: v
         };
     }
+
+    let v = 2;
+    macro_rules! internal {
+        ($i:ident) => {
+            let _ = S { v };
+            let _ = S { $i: v };
+            let _ = S { v: $i };
+            let _ = S { $i: $i };
+        };
+    }
+    internal!(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 d8c2286d5ad..2617d7e7283 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.rs
+++ b/src/tools/clippy/tests/ui/redundant_field_names.rs
@@ -20,7 +20,7 @@ struct Person {
 }
 
 pub struct S {
-    v: String,
+    v: usize,
 }
 
 fn main() {
@@ -59,11 +59,22 @@ fn main() {
     let _ = RangeToInclusive { end: end };
 
     external! {
-        let v = String::new();
+        let v = 1;
         let _ = S {
             v: v
         };
     }
+
+    let v = 2;
+    macro_rules! internal {
+        ($i:ident) => {
+            let _ = S { v: v };
+            let _ = S { $i: v };
+            let _ = S { v: $i };
+            let _ = S { $i: $i };
+        };
+    }
+    internal!(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 53234736207..38c021fdba3 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.stderr
+++ b/src/tools/clippy/tests/ui/redundant_field_names.stderr
@@ -44,10 +44,21 @@ LL |     let _ = RangeToInclusive { end: end };
    |                                ^^^^^^^^ help: replace it with: `end`
 
 error: redundant field names in struct initialization
-  --> tests/ui/redundant_field_names.rs:88:25
+  --> tests/ui/redundant_field_names.rs:71:25
+   |
+LL |             let _ = S { v: v };
+   |                         ^^^^ help: replace it with: `v`
+...
+LL |     internal!(v);
+   |     ------------ in this macro invocation
+   |
+   = note: this error originates in the macro `internal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: redundant field names in struct initialization
+  --> tests/ui/redundant_field_names.rs:99:25
    |
 LL |     let _ = RangeFrom { start: start };
    |                         ^^^^^^^^^^^^ help: replace it with: `start`
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
index bc055215708..aebf8712dd9 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
@@ -1,2 +1,4 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #[clippy::cognitive_complexity = "1"]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
index fdb425363e8..6c18151195f 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
@@ -1,2 +1,4 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #[clippy::cyclomatic_complexity = "1"]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
index f9108d169c7..fb51313dab6 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
@@ -1,5 +1,5 @@
 error: usage of deprecated attribute
-  --> tests/ui/renamed_builtin_attr.rs:1:11
+  --> tests/ui/renamed_builtin_attr.rs:3:11
    |
 LL | #[clippy::cyclomatic_complexity = "1"]
    |           ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity`
diff --git a/src/tools/clippy/tests/ui/single_match.fixed b/src/tools/clippy/tests/ui/single_match.fixed
index 0a49be2dc4f..6df64eb4053 100644
--- a/src/tools/clippy/tests/ui/single_match.fixed
+++ b/src/tools/clippy/tests/ui/single_match.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match)]
 #![allow(
     unused,
diff --git a/src/tools/clippy/tests/ui/single_match.rs b/src/tools/clippy/tests/ui/single_match.rs
index 4e35d265acb..4f005f4e04f 100644
--- a/src/tools/clippy/tests/ui/single_match.rs
+++ b/src/tools/clippy/tests/ui/single_match.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match)]
 #![allow(
     unused,
diff --git a/src/tools/clippy/tests/ui/single_match.stderr b/src/tools/clippy/tests/ui/single_match.stderr
index 40af38879ae..651d0b4911d 100644
--- a/src/tools/clippy/tests/ui/single_match.stderr
+++ b/src/tools/clippy/tests/ui/single_match.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:14:5
+  --> tests/ui/single_match.rs:16:5
    |
 LL | /     match x {
 LL | |         Some(y) => {
@@ -19,7 +19,7 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:22:5
+  --> tests/ui/single_match.rs:24:5
    |
 LL | /     match x {
 LL | |         // Note the missing block braces.
@@ -31,7 +31,7 @@ LL | |     }
    | |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:31:5
+  --> tests/ui/single_match.rs:33:5
    |
 LL | /     match z {
 LL | |         (2..=3, 7..=9) => dummy(),
@@ -40,7 +40,7 @@ LL | |     };
    | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:60:5
+  --> tests/ui/single_match.rs:62:5
    |
 LL | /     match x {
 LL | |         Some(y) => dummy(),
@@ -49,7 +49,7 @@ LL | |     };
    | |_____^ help: try: `if let Some(y) = x { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:65:5
+  --> tests/ui/single_match.rs:67:5
    |
 LL | /     match y {
 LL | |         Ok(y) => dummy(),
@@ -58,7 +58,7 @@ LL | |     };
    | |_____^ help: try: `if let Ok(y) = y { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:72:5
+  --> tests/ui/single_match.rs:74:5
    |
 LL | /     match c {
 LL | |         Cow::Borrowed(..) => dummy(),
@@ -67,7 +67,7 @@ LL | |     };
    | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:93:5
+  --> tests/ui/single_match.rs:95:5
    |
 LL | /     match x {
 LL | |         "test" => println!(),
@@ -76,7 +76,7 @@ LL | |     }
    | |_____^ help: try: `if x == "test" { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:106:5
+  --> tests/ui/single_match.rs:108:5
    |
 LL | /     match x {
 LL | |         Foo::A => println!(),
@@ -85,7 +85,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:112:5
+  --> tests/ui/single_match.rs:114:5
    |
 LL | /     match x {
 LL | |         FOO_C => println!(),
@@ -94,7 +94,7 @@ LL | |     }
    | |_____^ help: try: `if x == FOO_C { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:117:5
+  --> tests/ui/single_match.rs:119:5
    |
 LL | /     match &&x {
 LL | |         Foo::A => println!(),
@@ -103,7 +103,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:123:5
+  --> tests/ui/single_match.rs:125:5
    |
 LL | /     match &x {
 LL | |         Foo::A => println!(),
@@ -112,7 +112,7 @@ LL | |     }
    | |_____^ help: try: `if x == &Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:140:5
+  --> tests/ui/single_match.rs:142:5
    |
 LL | /     match x {
 LL | |         Bar::A => println!(),
@@ -121,7 +121,7 @@ LL | |     }
    | |_____^ help: try: `if let Bar::A = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:148:5
+  --> tests/ui/single_match.rs:150:5
    |
 LL | /     match x {
 LL | |         None => println!(),
@@ -130,7 +130,7 @@ LL | |     };
    | |_____^ help: try: `if let None = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:170:5
+  --> tests/ui/single_match.rs:172:5
    |
 LL | /     match x {
 LL | |         (Some(_), _) => {},
@@ -139,7 +139,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(_), _) = x {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:176:5
+  --> tests/ui/single_match.rs:178:5
    |
 LL | /     match x {
 LL | |         (Some(E::V), _) => todo!(),
@@ -148,7 +148,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:182:5
+  --> tests/ui/single_match.rs:184:5
    |
 LL | /     match (Some(42), Some(E::V), Some(42)) {
 LL | |         (.., Some(E::V), _) => {},
@@ -157,7 +157,7 @@ LL | |     }
    | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:254:5
+  --> tests/ui/single_match.rs:256:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -177,7 +177,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:262:5
+  --> tests/ui/single_match.rs:264:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed
index f3b1de3b44f..2970f5485fa 100644
--- a/src/tools/clippy/tests/ui/single_match_else.fixed
+++ b/src/tools/clippy/tests/ui/single_match_else.fixed
@@ -1,4 +1,6 @@
 //@aux-build: proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs
index ddee2e42ec2..26974b2a48a 100644
--- a/src/tools/clippy/tests/ui/single_match_else.rs
+++ b/src/tools/clippy/tests/ui/single_match_else.rs
@@ -1,4 +1,6 @@
 //@aux-build: proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index 63c733e9a7a..48c74c0caea 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:16:13
+  --> tests/ui/single_match_else.rs:18:13
    |
 LL |       let _ = match ExprNode::Butterflies {
    |  _____________^
@@ -22,7 +22,7 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:81:5
+  --> tests/ui/single_match_else.rs:83:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -42,7 +42,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:90:5
+  --> tests/ui/single_match_else.rs:92:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -62,7 +62,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:100:5
+  --> tests/ui/single_match_else.rs:102:5
    |
 LL | /     match Result::<i32, Infallible>::Ok(1) {
 LL | |         Ok(a) => println!("${:?}", a),
@@ -82,7 +82,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:109:5
+  --> tests/ui/single_match_else.rs:111:5
    |
 LL | /     match Cow::from("moo") {
 LL | |         Cow::Owned(a) => println!("${:?}", a),
@@ -102,7 +102,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:119:5
+  --> tests/ui/single_match_else.rs:121:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -125,7 +125,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:130:5
+  --> tests/ui/single_match_else.rs:132:5
    |
 LL | /     match bar {
 LL | |         Some(v) => {
@@ -149,7 +149,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:142:5
+  --> tests/ui/single_match_else.rs:144:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -173,7 +173,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:154:5
+  --> tests/ui/single_match_else.rs:156:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.fixed b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
index a7555704fbe..0a734a65d29 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.fixed
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
@@ -1,4 +1,5 @@
 //@aux-build:proc_macro_derive.rs
+
 #![warn(clippy::std_instead_of_core)]
 #![allow(unused_imports)]
 
@@ -16,12 +17,20 @@ fn std_instead_of_core() {
     use ::core::hash::Hash;
     //~^ ERROR: used import from `std` instead of `core`
     // Don't lint on `env` macro
-    use std::env;
+    use core::env;
 
     // Multiple imports
     use core::fmt::{Debug, Result};
     //~^ ERROR: used import from `std` instead of `core`
 
+    // Multiple imports multiline
+    #[rustfmt::skip]
+    use core::{
+        //~^ ERROR: used import from `std` instead of `core`
+        fmt::Write as _,
+        ptr::read_unaligned,
+    };
+
     // Function calls
     let ptr = core::ptr::null::<u32>();
     //~^ ERROR: used import from `std` instead of `core`
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.rs b/src/tools/clippy/tests/ui/std_instead_of_core.rs
index af7f3399f49..c12c459c7eb 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.rs
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs
@@ -1,4 +1,5 @@
 //@aux-build:proc_macro_derive.rs
+
 #![warn(clippy::std_instead_of_core)]
 #![allow(unused_imports)]
 
@@ -22,6 +23,14 @@ fn std_instead_of_core() {
     use std::fmt::{Debug, Result};
     //~^ ERROR: used import from `std` instead of `core`
 
+    // Multiple imports multiline
+    #[rustfmt::skip]
+    use std::{
+        //~^ ERROR: used import from `std` instead of `core`
+        fmt::Write as _,
+        ptr::read_unaligned,
+    };
+
     // Function calls
     let ptr = std::ptr::null::<u32>();
     //~^ ERROR: used import from `std` instead of `core`
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
index 30dd49dc268..ee42b474a32 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
@@ -1,5 +1,5 @@
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:13:9
+  --> tests/ui/std_instead_of_core.rs:14:9
    |
 LL |     use std::hash::Hasher;
    |         ^^^ help: consider importing the item from `core`: `core`
@@ -8,49 +8,61 @@ LL |     use std::hash::Hasher;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:16:11
+  --> tests/ui/std_instead_of_core.rs:17:11
    |
 LL |     use ::std::hash::Hash;
    |           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:22:9
+  --> tests/ui/std_instead_of_core.rs:20:9
+   |
+LL |     use std::env;
+   |         ^^^ help: consider importing the item from `core`: `core`
+
+error: used import from `std` instead of `core`
+  --> tests/ui/std_instead_of_core.rs:23:9
    |
 LL |     use std::fmt::{Debug, Result};
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:26:15
+  --> tests/ui/std_instead_of_core.rs:28:9
+   |
+LL |     use std::{
+   |         ^^^ help: consider importing the item from `core`: `core`
+
+error: used import from `std` instead of `core`
+  --> tests/ui/std_instead_of_core.rs:35:15
    |
 LL |     let ptr = std::ptr::null::<u32>();
    |               ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:28:21
+  --> tests/ui/std_instead_of_core.rs:37:21
    |
 LL |     let ptr_mut = ::std::ptr::null_mut::<usize>();
    |                     ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:32:16
+  --> tests/ui/std_instead_of_core.rs:41:16
    |
 LL |     let cell = std::cell::Cell::new(8u32);
    |                ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:34:27
+  --> tests/ui/std_instead_of_core.rs:43:27
    |
 LL |     let cell_absolute = ::std::cell::Cell::new(8u32);
    |                           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:43:9
+  --> tests/ui/std_instead_of_core.rs:52:9
    |
 LL |     use std::iter::Iterator;
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `alloc`
-  --> tests/ui/std_instead_of_core.rs:50:9
+  --> tests/ui/std_instead_of_core.rs:59:9
    |
 LL |     use std::vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
@@ -59,13 +71,13 @@ LL |     use std::vec;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`
 
 error: used import from `std` instead of `alloc`
-  --> tests/ui/std_instead_of_core.rs:52:9
+  --> tests/ui/std_instead_of_core.rs:61:9
    |
 LL |     use std::vec::Vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
 
 error: used import from `alloc` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:58:9
+  --> tests/ui/std_instead_of_core.rs:67:9
    |
 LL |     use alloc::slice::from_ref;
    |         ^^^^^ help: consider importing the item from `core`: `core`
@@ -73,5 +85,5 @@ LL |     use alloc::slice::from_ref;
    = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`
 
-error: aborting due to 11 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
index 9d9732307c8..60fde6e22cb 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::suspicious_operation_groupings)]
 #![allow(dead_code, unused_parens, clippy::eq_op)]
 
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
index 201b8e657f4..ce37148a853 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::suspicious_operation_groupings)]
 #![allow(dead_code, unused_parens, clippy::eq_op)]
 
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr b/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
index 9d1d8a1f34f..7cb066d57e7 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
@@ -1,5 +1,5 @@
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:15:9
+  --> tests/ui/suspicious_operation_groupings.rs:17:9
    |
 LL |         self.x == other.y && self.y == other.y && self.z == other.z
    |         ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x`
@@ -8,151 +8,151 @@ LL |         self.x == other.y && self.y == other.y && self.z == other.z
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_operation_groupings)]`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:28:20
+  --> tests/ui/suspicious_operation_groupings.rs:30:20
    |
 LL |     s1.a < s2.a && s1.a < s2.b
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:76:33
+  --> tests/ui/suspicious_operation_groupings.rs:78:33
    |
 LL |     s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d
    |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:81:19
+  --> tests/ui/suspicious_operation_groupings.rs:83:19
    |
 LL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:81:19
+  --> tests/ui/suspicious_operation_groupings.rs:83:19
    |
 LL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:86:19
+  --> tests/ui/suspicious_operation_groupings.rs:88:19
    |
 LL |     s1.a * s2.a + s2.b * s2.b + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:91:19
+  --> tests/ui/suspicious_operation_groupings.rs:93:19
    |
 LL |     s1.a * s2.a + s1.b * s1.b + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:96:5
+  --> tests/ui/suspicious_operation_groupings.rs:98:5
    |
 LL |     s1.a * s1.a + s1.b * s2.b + s1.c * s2.c
    |     ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:101:33
+  --> tests/ui/suspicious_operation_groupings.rs:103:33
    |
 LL |     s1.a * s2.a + s1.b * s2.b + s1.c * s1.c
    |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:114:20
+  --> tests/ui/suspicious_operation_groupings.rs:116:20
    |
 LL |     (s1.a * s2.a + s1.b * s1.b)
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:119:34
+  --> tests/ui/suspicious_operation_groupings.rs:121:34
    |
 LL |     (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d)
    |                                  ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:124:38
+  --> tests/ui/suspicious_operation_groupings.rs:126:38
    |
 LL |     (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)
    |                                      ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:129:39
+  --> tests/ui/suspicious_operation_groupings.rs:131:39
    |
 LL |     ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))
    |                                       ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:134:42
+  --> tests/ui/suspicious_operation_groupings.rs:136:42
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
    |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:134:42
+  --> tests/ui/suspicious_operation_groupings.rs:136:42
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
    |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:139:40
+  --> tests/ui/suspicious_operation_groupings.rs:141:40
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d))
    |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:144:40
+  --> tests/ui/suspicious_operation_groupings.rs:146:40
    |
 LL |     ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)))
    |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:149:20
+  --> tests/ui/suspicious_operation_groupings.rs:151:20
    |
 LL |     (s1.a * s2.a + s2.b * s2.b) / 2
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:154:35
+  --> tests/ui/suspicious_operation_groupings.rs:156:35
    |
 LL |     i32::swap_bytes(s1.a * s2.a + s2.b * s2.b)
    |                                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:159:29
+  --> tests/ui/suspicious_operation_groupings.rs:161:29
    |
 LL |     s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d
    |                             ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:164:17
+  --> tests/ui/suspicious_operation_groupings.rs:166:17
    |
 LL |     s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d
    |                 ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:173:77
+  --> tests/ui/suspicious_operation_groupings.rs:175:77
    |
 LL |     (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0
    |                                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:187:25
+  --> tests/ui/suspicious_operation_groupings.rs:189:25
    |
 LL |         s1.a <= s2.a && s1.a <= s2.b
    |                         ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:193:23
+  --> tests/ui/suspicious_operation_groupings.rs:195:23
    |
 LL |     if s1.a < s2.a && s1.a < s2.b {
    |                       ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:200:48
+  --> tests/ui/suspicious_operation_groupings.rs:202:48
    |
 LL |     -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d)))
    |                                                ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:205:27
+  --> tests/ui/suspicious_operation_groupings.rs:207:27
    |
 LL |     -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a })
    |                           ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b`
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
index bbde25b0a88..a6ed59d49c5 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
@@ -27,4 +27,18 @@ fn main() {
     }
     //~^^^^ ERROR: initializer for `thread_local` value can be made `const`
     //~^^^ ERROR: initializer for `thread_local` value can be made `const`
+
+    thread_local! {
+        static PEEL_ME: i32 = const { 1 };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+        static PEEL_ME_MANY: i32 = const { { let x = 1; x * x } };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+    }
+}
+
+#[clippy::msrv = "1.58"]
+fn f() {
+    thread_local! {
+        static TLS: i32 = 1;
+    }
 }
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
index 3d7aacf2f09..3f0159c5806 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
@@ -27,4 +27,18 @@ fn main() {
     }
     //~^^^^ ERROR: initializer for `thread_local` value can be made `const`
     //~^^^ ERROR: initializer for `thread_local` value can be made `const`
+
+    thread_local! {
+        static PEEL_ME: i32 = { 1 };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+        static PEEL_ME_MANY: i32 = { let x = 1; x * x };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+    }
+}
+
+#[clippy::msrv = "1.58"]
+fn f() {
+    thread_local! {
+        static TLS: i32 = 1;
+    }
 }
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr
index 9ee52fbbb31..b4f8bd822b0 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr
@@ -25,5 +25,17 @@ error: initializer for `thread_local` value can be made `const`
 LL |         static BUF_4_CAN_BE_MADE_CONST: RefCell<String> = RefCell::new(String::new());
    |                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }`
 
-error: aborting due to 4 previous errors
+error: initializer for `thread_local` value can be made `const`
+  --> tests/ui/thread_local_initializer_can_be_made_const.rs:32:31
+   |
+LL |         static PEEL_ME: i32 = { 1 };
+   |                               ^^^^^ help: replace with: `const { 1 }`
+
+error: initializer for `thread_local` value can be made `const`
+  --> tests/ui/thread_local_initializer_can_be_made_const.rs:34:36
+   |
+LL |         static PEEL_ME_MANY: i32 = { let x = 1; x * x };
+   |                                    ^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { { let x = 1; x * x } }`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
index 08b8e786611..2365695d691 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
@@ -82,3 +82,10 @@ fn issue_10449() {
 
     let _x: u8 = unsafe { *(f as *const u8) };
 }
+
+// Pointers cannot be cast to integers in const contexts
+const fn issue_12402<P>(ptr: *const P) {
+    unsafe { transmute::<*const i32, usize>(&42i32) };
+    unsafe { transmute::<fn(*const P), usize>(issue_12402) };
+    let _ = unsafe { transmute::<_, usize>(ptr) };
+}
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
index 92eb765e5f9..cd1607b4c19 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
@@ -82,3 +82,10 @@ fn issue_10449() {
 
     let _x: u8 = unsafe { *std::mem::transmute::<fn(), *const u8>(f) };
 }
+
+// Pointers cannot be cast to integers in const contexts
+const fn issue_12402<P>(ptr: *const P) {
+    unsafe { transmute::<*const i32, usize>(&42i32) };
+    unsafe { transmute::<fn(*const P), usize>(issue_12402) };
+    let _ = unsafe { transmute::<_, usize>(ptr) };
+}
diff --git a/src/tools/clippy/tests/ui/type_complexity.rs b/src/tools/clippy/tests/ui/type_complexity.rs
index be28ee2da0c..b057dc4e89f 100644
--- a/src/tools/clippy/tests/ui/type_complexity.rs
+++ b/src/tools/clippy/tests/ui/type_complexity.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::all)]
 #![allow(unused, clippy::needless_pass_by_value, clippy::vec_box, clippy::useless_vec)]
 #![feature(associated_type_defaults)]
diff --git a/src/tools/clippy/tests/ui/type_complexity.stderr b/src/tools/clippy/tests/ui/type_complexity.stderr
index 9e27899e4f9..bfbab8647e8 100644
--- a/src/tools/clippy/tests/ui/type_complexity.stderr
+++ b/src/tools/clippy/tests/ui/type_complexity.stderr
@@ -1,5 +1,5 @@
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:7:12
+  --> tests/ui/type_complexity.rs:9:12
    |
 LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,85 +8,85 @@ LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:10:12
+  --> tests/ui/type_complexity.rs:12:12
    |
 LL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:14:8
+  --> tests/ui/type_complexity.rs:16:8
    |
 LL |     f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:18:11
+  --> tests/ui/type_complexity.rs:20:11
    |
 LL | struct Ts(Vec<Vec<Box<(u32, u32, u32, u32)>>>);
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:22:11
+  --> tests/ui/type_complexity.rs:24:11
    |
 LL |     Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:24:17
+  --> tests/ui/type_complexity.rs:26:17
    |
 LL |     Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:29:14
+  --> tests/ui/type_complexity.rs:31:14
    |
 LL |     const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:31:30
+  --> tests/ui/type_complexity.rs:33:30
    |
 LL |     fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:36:14
+  --> tests/ui/type_complexity.rs:38:14
    |
 LL |     const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:38:14
+  --> tests/ui/type_complexity.rs:40:14
    |
 LL |     type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:40:25
+  --> tests/ui/type_complexity.rs:42:25
    |
 LL |     fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:42:29
+  --> tests/ui/type_complexity.rs:44:29
    |
 LL |     fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:55:15
+  --> tests/ui/type_complexity.rs:57:15
    |
 LL | fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:60:14
+  --> tests/ui/type_complexity.rs:62:14
    |
 LL | fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:64:13
+  --> tests/ui/type_complexity.rs:66:13
    |
 LL |     let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unknown_attribute.rs b/src/tools/clippy/tests/ui/unknown_attribute.rs
index 932f284d5b7..3241742b5d4 100644
--- a/src/tools/clippy/tests/ui/unknown_attribute.rs
+++ b/src/tools/clippy/tests/ui/unknown_attribute.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #[clippy::unknown]
 //~^ ERROR: usage of unknown attribute
 #[clippy::cognitive_complexity = "1"]
diff --git a/src/tools/clippy/tests/ui/unknown_attribute.stderr b/src/tools/clippy/tests/ui/unknown_attribute.stderr
index d1f8eeb51ae..b306abe0a9d 100644
--- a/src/tools/clippy/tests/ui/unknown_attribute.stderr
+++ b/src/tools/clippy/tests/ui/unknown_attribute.stderr
@@ -1,5 +1,5 @@
 error: usage of unknown attribute
-  --> tests/ui/unknown_attribute.rs:1:11
+  --> tests/ui/unknown_attribute.rs:3:11
    |
 LL | #[clippy::unknown]
    |           ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.fixed b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
index f52d3250339..288541362cd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
@@ -221,4 +221,10 @@ mod fixable {
     fn issue_9603() {
         let _: f32 = -0x400 as f32;
     }
+
+    // Issue #11968: The suggestion for this lint removes the parentheses and leave the code as
+    // `*x.pow(2)` which tries to dereference the return value rather than `x`.
+    fn issue_11968(x: &usize) -> usize {
+        { *x }.pow(2)
+    }
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs
index dfd8b454e6c..eef3a42e351 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs
@@ -221,4 +221,10 @@ mod fixable {
     fn issue_9603() {
         let _: f32 = -0x400 as f32;
     }
+
+    // Issue #11968: The suggestion for this lint removes the parentheses and leave the code as
+    // `*x.pow(2)` which tries to dereference the return value rather than `x`.
+    fn issue_11968(x: &usize) -> usize {
+        (*x as usize).pow(2)
+    }
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.stderr b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
index 935bb71da32..80fd5c13d81 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
@@ -241,5 +241,11 @@ error: casting to the same type is unnecessary (`f32` -> `f32`)
 LL |         let _num = foo() as f32;
    |                    ^^^^^^^^^^^^ help: try: `foo()`
 
-error: aborting due to 40 previous errors
+error: casting to the same type is unnecessary (`usize` -> `usize`)
+  --> tests/ui/unnecessary_cast.rs:228:9
+   |
+LL |         (*x as usize).pow(2)
+   |         ^^^^^^^^^^^^^ help: try: `{ *x }`
+
+error: aborting due to 41 previous errors
 
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 8c50bcd5b61..06d8f099c33 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -451,6 +451,15 @@ impl Config {
         self.target_cfg().panic == PanicStrategy::Unwind
     }
 
+    pub fn has_threads(&self) -> bool {
+        // Wasm targets don't have threads unless `-threads` is in the target
+        // name, such as `wasm32-wasip1-threads`.
+        if self.target.starts_with("wasm") {
+            return self.target.contains("threads");
+        }
+        true
+    }
+
     pub fn has_asm_support(&self) -> bool {
         static ASM_SUPPORTED_ARCHS: &[&str] = &[
             "x86", "x86_64", "arm", "aarch64", "riscv32",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 6de445a5783..f15761354f7 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -787,6 +787,7 @@ const DIAGNOSTICS_DIRECTIVE_NAMES: &[&str] = &[
     "needs-sanitizer-shadow-call-stack",
     "needs-sanitizer-support",
     "needs-sanitizer-thread",
+    "needs-threads",
     "needs-unwind",
     "needs-xray",
     "no-prefer-dynamic",
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 39786588150..d7c74038aea 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -85,6 +85,11 @@ pub(super) fn handle_needs(
             ignore_reason: "ignored when running the resulting test binaries is disabled",
         },
         Need {
+            name: "needs-threads",
+            condition: config.has_threads(),
+            ignore_reason: "ignored on targets without threading support",
+        },
+        Need {
             name: "needs-unwind",
             condition: config.can_unwind(),
             ignore_reason: "ignored on targets without unwinding support",
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index eff76a38d2e..815ac3839df 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -592,3 +592,23 @@ fn ignore_mode() {
         assert!(!check_ignore(&config, &format!("//@ ignore-mode-{other}")));
     }
 }
+
+#[test]
+fn threads_support() {
+    let threads = [
+        ("x86_64-unknown-linux-gnu", true),
+        ("aarch64-apple-darwin", true),
+        ("wasm32-unknown-unknown", false),
+        ("wasm64-unknown-unknown", false),
+        #[cfg(not(bootstrap))]
+        ("wasm32-wasip1", false),
+        #[cfg(not(bootstrap))]
+        ("wasm32-wasip1-threads", true),
+        ("wasm32-wasi-preview1-threads", true),
+    ];
+    for (target, has_threads) in threads {
+        let config = cfg().target(target).build();
+        assert_eq!(config.has_threads(), has_threads);
+        assert_eq!(check_ignore(&config, "//@ needs-threads"), !has_threads)
+    }
+}
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index bfce11a730e..a54e33ae528 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-bfe762e0ed2e95041cc12c02c5565c4368f2cc9f
+79d246112dc95bbd67848f7546f3fd1aca516b82
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 8341fd7648b..805c0580b2f 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -890,7 +890,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             instance,
             start_abi,
             &[*func_arg],
-            Some(&ret_place.into()),
+            Some(&ret_place),
             StackPopCleanup::Root { cleanup: true },
         )?;
 
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 4e080f0cc3b..f7edbdb9c5e 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -391,7 +391,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
                     argv,
                     Scalar::from_u8(sigpipe).into(),
                 ],
-                Some(&ret_place.into()),
+                Some(&ret_place),
                 StackPopCleanup::Root { cleanup: true },
             )?;
         }
@@ -400,7 +400,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
                 entry_instance,
                 Abi::Rust,
                 &[argc.into(), argv],
-                Some(&ret_place.into()),
+                Some(&ret_place),
                 StackPopCleanup::Root { cleanup: true },
             )?;
         }
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index ddefecca597..5e9de3ffb80 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -383,7 +383,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         f: ty::Instance<'tcx>,
         caller_abi: Abi,
         args: &[Immediate<Provenance>],
-        dest: Option<&PlaceTy<'tcx, Provenance>>,
+        dest: Option<&MPlaceTy<'tcx, Provenance>>,
         stack_pop: StackPopCleanup,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
@@ -401,7 +401,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let mir = this.load_mir(f.def, None)?;
         let dest = match dest {
             Some(dest) => dest.clone(),
-            None => MPlaceTy::fake_alloc_zst(this.layout_of(mir.return_ty())?).into(),
+            None => MPlaceTy::fake_alloc_zst(this.layout_of(mir.return_ty())?),
         };
         this.push_stack_frame(f, mir, &dest, stack_pop)?;
 
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index f226354200f..490fa6f5535 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -945,7 +945,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         instance: ty::Instance<'tcx>,
         abi: Abi,
         args: &[FnArg<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ret: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@@ -972,7 +972,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         fn_val: DynSym,
         abi: Abi,
         args: &[FnArg<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ret: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
@@ -985,7 +985,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
         ecx: &mut MiriInterpCx<'mir, 'tcx>,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ret: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index 48dafc40c62..abfa7143a73 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -12,7 +12,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         abi: Abi,
         link_name: Symbol,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         let [flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
@@ -32,7 +32,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         abi: Abi,
         link_name: Symbol,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         let tcx = this.tcx;
@@ -145,7 +145,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         abi: Abi,
         link_name: Symbol,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         let [ptr, flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
@@ -174,7 +174,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // `lo.col` is 0-based - add 1 to make it 1-based for the caller.
         let colno: u32 = u32::try_from(lo.col.0.saturating_add(1)).unwrap_or(0);
 
-        let dest = this.force_allocation(dest)?;
         if let ty::Adt(adt, _) = dest.layout.ty.kind() {
             if !adt.repr().c() {
                 throw_ub_format!(
@@ -191,29 +190,29 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let filename_alloc =
                     this.allocate_str(&filename, MiriMemoryKind::Rust.into(), Mutability::Mut)?;
 
-                this.write_immediate(name_alloc.to_ref(this), &this.project_field(&dest, 0)?)?;
-                this.write_immediate(filename_alloc.to_ref(this), &this.project_field(&dest, 1)?)?;
+                this.write_immediate(name_alloc.to_ref(this), &this.project_field(dest, 0)?)?;
+                this.write_immediate(filename_alloc.to_ref(this), &this.project_field(dest, 1)?)?;
             }
             1 => {
                 this.write_scalar(
                     Scalar::from_target_usize(name.len().try_into().unwrap(), this),
-                    &this.project_field(&dest, 0)?,
+                    &this.project_field(dest, 0)?,
                 )?;
                 this.write_scalar(
                     Scalar::from_target_usize(filename.len().try_into().unwrap(), this),
-                    &this.project_field(&dest, 1)?,
+                    &this.project_field(dest, 1)?,
                 )?;
             }
             _ => throw_unsup_format!("unknown `miri_resolve_frame` flags {}", flags),
         }
 
-        this.write_scalar(Scalar::from_u32(lineno), &this.project_field(&dest, 2)?)?;
-        this.write_scalar(Scalar::from_u32(colno), &this.project_field(&dest, 3)?)?;
+        this.write_scalar(Scalar::from_u32(lineno), &this.project_field(dest, 2)?)?;
+        this.write_scalar(Scalar::from_u32(colno), &this.project_field(dest, 3)?)?;
 
         // Support a 4-field struct for now - this is deprecated
         // and slated for removal.
         if num_fields == 5 {
-            this.write_pointer(fn_ptr, &this.project_field(&dest, 4)?)?;
+            this.write_pointer(fn_ptr, &this.project_field(dest, 4)?)?;
         }
 
         Ok(())
diff --git a/src/tools/miri/src/shims/ffi_support.rs b/src/tools/miri/src/shims/ffi_support.rs
index e628c44a867..6da119e5fa8 100644
--- a/src/tools/miri/src/shims/ffi_support.rs
+++ b/src/tools/miri/src/shims/ffi_support.rs
@@ -70,7 +70,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn call_external_c_and_store_return<'a>(
         &mut self,
         link_name: Symbol,
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ptr: CodePtr,
         libffi_args: Vec<libffi::high::Arg<'a>>,
     ) -> InterpResult<'tcx, ()> {
@@ -205,7 +205,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn call_external_c_fct(
         &mut self,
         link_name: Symbol,
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         args: &[OpTy<'tcx, Provenance>],
     ) -> InterpResult<'tcx, bool> {
         // Get the pointer to the function in the shared object file if it exists.
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 4ae607e98da..a25d377f3a7 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -57,7 +57,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ret: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@@ -123,7 +123,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // Second: functions that return immediately.
         match this.emulate_foreign_item_inner(link_name, abi, args, dest)? {
             EmulateForeignItemResult::NeedsJumping => {
-                trace!("{:?}", this.dump_place(dest));
+                trace!("{:?}", this.dump_place(&dest.clone().into()));
                 this.go_to_block(ret);
             }
             EmulateForeignItemResult::AlreadyJumped => (),
@@ -149,7 +149,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         sym: DynSym,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ret: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
@@ -401,7 +401,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
 
@@ -1085,7 +1085,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
                 let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, op_len);
 
diff --git a/src/tools/miri/src/shims/intrinsics/atomic.rs b/src/tools/miri/src/shims/intrinsics/atomic.rs
index 4d7f6a6b4e0..865886a7fc1 100644
--- a/src/tools/miri/src/shims/intrinsics/atomic.rs
+++ b/src/tools/miri/src/shims/intrinsics/atomic.rs
@@ -18,7 +18,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         &mut self,
         intrinsic_name: &str,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
@@ -124,7 +124,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
     fn atomic_load(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         atomic: AtomicReadOrd,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
@@ -181,7 +181,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
     fn atomic_rmw_op(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         atomic_op: AtomicOp,
         atomic: AtomicRwOrd,
     ) -> InterpResult<'tcx> {
@@ -223,7 +223,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
     fn atomic_exchange(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         atomic: AtomicRwOrd,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
@@ -240,7 +240,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
     fn atomic_compare_exchange_impl(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         success: AtomicRwOrd,
         fail: AtomicReadOrd,
         can_fail_spuriously: bool,
@@ -269,7 +269,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
     fn atomic_compare_exchange(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         success: AtomicRwOrd,
         fail: AtomicReadOrd,
     ) -> InterpResult<'tcx> {
@@ -279,7 +279,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
     fn atomic_compare_exchange_weak(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         success: AtomicRwOrd,
         fail: AtomicReadOrd,
     ) -> InterpResult<'tcx> {
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index d4905c22a6a..b388f70bef2 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -23,7 +23,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         &mut self,
         instance: ty::Instance<'tcx>,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ret: Option<mir::BasicBlock>,
         _unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
@@ -61,7 +61,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // The rest jumps to `ret` immediately.
         this.emulate_intrinsic_by_name(intrinsic_name, instance.args, args, dest)?;
 
-        trace!("{:?}", this.dump_place(dest));
+        trace!("{:?}", this.dump_place(&dest.clone().into()));
         this.go_to_block(ret);
         Ok(())
     }
@@ -72,7 +72,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         intrinsic_name: &str,
         generic_args: ty::GenericArgsRef<'tcx>,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index bb18fba5c98..ddddcdcebd2 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -21,7 +21,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         intrinsic_name: &str,
         generic_args: ty::GenericArgsRef<'tcx>,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
         match intrinsic_name {
@@ -40,7 +40,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             => {
                 let [op] = check_arg_count(args)?;
                 let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, op_len);
 
@@ -167,7 +167,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [left, right] = check_arg_count(args)?;
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
@@ -255,7 +255,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let (a, a_len) = this.operand_to_simd(a)?;
                 let (b, b_len) = this.operand_to_simd(b)?;
                 let (c, c_len) = this.operand_to_simd(c)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, a_len);
                 assert_eq!(dest_len, b_len);
@@ -390,7 +390,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let (mask, mask_len) = this.operand_to_simd(mask)?;
                 let (yes, yes_len) = this.operand_to_simd(yes)?;
                 let (no, no_len) = this.operand_to_simd(no)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, mask_len);
                 assert_eq!(dest_len, yes_len);
@@ -411,7 +411,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [mask, yes, no] = check_arg_count(args)?;
                 let (yes, yes_len) = this.operand_to_simd(yes)?;
                 let (no, no_len) = this.operand_to_simd(no)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
                 let bitmask_len = dest_len.next_multiple_of(8);
 
                 // The mask must be an integer or an array.
@@ -487,7 +487,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "cast" | "as" | "cast_ptr" | "expose_addr" | "from_exposed_addr" => {
                 let [op] = check_arg_count(args)?;
                 let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, op_len);
 
@@ -545,7 +545,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [left, right] = check_arg_count(args)?;
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 let index = generic_args[2]
                     .expect_const()
@@ -582,7 +582,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let [left, right, index] = check_arg_count(args)?;
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 // `index` is an array, not a SIMD type
                 let ty::Array(_, index_len) = index.layout.ty.kind() else {
@@ -623,7 +623,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let (passthru, passthru_len) = this.operand_to_simd(passthru)?;
                 let (ptrs, ptrs_len) = this.operand_to_simd(ptrs)?;
                 let (mask, mask_len) = this.operand_to_simd(mask)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, passthru_len);
                 assert_eq!(dest_len, ptrs_len);
@@ -669,7 +669,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let (mask, mask_len) = this.operand_to_simd(mask)?;
                 let ptr = this.read_pointer(ptr)?;
                 let (default, default_len) = this.operand_to_simd(default)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, mask_len);
                 assert_eq!(dest_len, default_len);
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 65b5838cd14..34b6481dd38 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -28,7 +28,7 @@ pub struct CatchUnwindData<'tcx> {
     /// The `data` argument for that callback.
     data: Scalar<Provenance>,
     /// The return place from the original call to `try`.
-    dest: PlaceTy<'tcx, Provenance>,
+    dest: MPlaceTy<'tcx, Provenance>,
     /// The return block from the original call to `try`.
     ret: mir::BasicBlock,
 }
@@ -72,7 +72,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn handle_catch_unwind(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
         ret: mir::BasicBlock,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index b5cd18396a2..4ceda809350 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -44,7 +44,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
 
diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
index 64094ac307d..6814e0d4283 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -17,7 +17,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         match link_name.as_str() {
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index b9215129674..d13ada0f4cf 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -24,7 +24,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
 
@@ -228,7 +228,7 @@ fn getrandom<'tcx>(
     ptr: &OpTy<'tcx, Provenance>,
     len: &OpTy<'tcx, Provenance>,
     flags: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx> {
     let ptr = this.read_pointer(ptr)?;
     let len = this.read_target_usize(len)?;
diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs
index 66105391c47..ed27066aa6a 100644
--- a/src/tools/miri/src/shims/unix/linux/sync.rs
+++ b/src/tools/miri/src/shims/unix/linux/sync.rs
@@ -8,7 +8,7 @@ use crate::*;
 pub fn futex<'tcx>(
     this: &mut MiriInterpCx<'_, 'tcx>,
     args: &[OpTy<'tcx, Provenance>],
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx> {
     // The amount of arguments used depends on the type of futex operation.
     // The full futex syscall takes six arguments (excluding the syscall
@@ -179,7 +179,7 @@ pub fn futex<'tcx>(
                     struct Callback<'tcx> {
                         thread: ThreadId,
                         addr_usize: u64,
-                        dest: PlaceTy<'tcx, Provenance>,
+                        dest: MPlaceTy<'tcx, Provenance>,
                     }
 
                     impl<'tcx> VisitProvenance for Callback<'tcx> {
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index ecc07e28a29..3af01eb44d8 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -17,7 +17,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
 
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index 054e9719b34..dd301f9ee6d 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -843,7 +843,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         cond_op: &OpTy<'tcx, Provenance>,
         mutex_op: &OpTy<'tcx, Provenance>,
         abstime_op: &OpTy<'tcx, Provenance>,
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
@@ -883,7 +883,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             active_thread: ThreadId,
             mutex_id: MutexId,
             id: CondvarId,
-            dest: PlaceTy<'tcx, Provenance>,
+            dest: MPlaceTy<'tcx, Provenance>,
         }
 
         impl<'tcx> VisitProvenance for Callback<'tcx> {
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index f56ea06dbe3..9e0baf86cbc 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -27,7 +27,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
 
diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs
index 1ce385aaaba..5edc18af482 100644
--- a/src/tools/miri/src/shims/windows/sync.rs
+++ b/src/tools/miri/src/shims/windows/sync.rs
@@ -179,7 +179,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         let id = this.init_once_get_id(init_once_op)?;
         let flags = this.read_scalar(flags_op)?.to_u32()?;
-        let pending_place = this.deref_pointer(pending_op)?.into();
+        let pending_place = this.deref_pointer(pending_op)?;
         let context = this.read_pointer(context_op)?;
 
         if flags != 0 {
@@ -201,7 +201,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 // When we are woken up, set the `pending` flag accordingly.
                 struct Callback<'tcx> {
                     init_once_id: InitOnceId,
-                    pending_place: PlaceTy<'tcx, Provenance>,
+                    pending_place: MPlaceTy<'tcx, Provenance>,
                 }
 
                 impl<'tcx> VisitProvenance for Callback<'tcx> {
@@ -290,7 +290,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         compare_op: &OpTy<'tcx, Provenance>,
         size_op: &OpTy<'tcx, Provenance>,
         timeout_op: &OpTy<'tcx, Provenance>,
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
@@ -334,7 +334,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 struct Callback<'tcx> {
                     thread: ThreadId,
                     addr: u64,
-                    dest: PlaceTy<'tcx, Provenance>,
+                    dest: MPlaceTy<'tcx, Provenance>,
                 }
 
                 impl<'tcx> VisitProvenance for Callback<'tcx> {
@@ -406,7 +406,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         lock_op: &OpTy<'tcx, Provenance>,
         timeout_op: &OpTy<'tcx, Provenance>,
         flags_op: &OpTy<'tcx, Provenance>,
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, Scalar<Provenance>> {
         let this = self.eval_context_mut();
 
@@ -453,7 +453,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 condvar_id: CondvarId,
                 lock_id: RwLockId,
                 mode: RwLockMode,
-                dest: PlaceTy<'tcx, Provenance>,
+                dest: MPlaceTy<'tcx, Provenance>,
             }
 
             impl<'tcx> VisitProvenance for Callback<'tcx> {
diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs
index fb0b7015127..6c090d877ea 100644
--- a/src/tools/miri/src/shims/x86/aesni.rs
+++ b/src/tools/miri/src/shims/x86/aesni.rs
@@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         this.expect_target_feature_for_intrinsic(link_name, "aes")?;
@@ -138,7 +138,7 @@ fn aes_round<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     state: &OpTy<'tcx, Provenance>,
     key: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
     f: impl Fn(u128, u128) -> u128,
 ) -> InterpResult<'tcx, ()> {
     assert_eq!(dest.layout.size, state.layout.size);
diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs
index 65de1607595..23c78647b9c 100644
--- a/src/tools/miri/src/shims/x86/avx.rs
+++ b/src/tools/miri/src/shims/x86/avx.rs
@@ -21,7 +21,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         this.expect_target_feature_for_intrinsic(link_name, "avx")?;
@@ -164,7 +164,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (data, data_len) = this.operand_to_simd(data)?;
                 let (control, control_len) = this.operand_to_simd(control)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, data_len);
                 assert_eq!(dest_len, control_len);
@@ -199,7 +199,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (data, data_len) = this.operand_to_simd(data)?;
                 let (control, control_len) = this.operand_to_simd(control)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, data_len);
                 assert_eq!(dest_len, control_len);
@@ -354,10 +354,10 @@ fn mask_load<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     ptr: &OpTy<'tcx, Provenance>,
     mask: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (mask, mask_len) = this.operand_to_simd(mask)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, mask_len);
 
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index 9cfee20014f..7cd397625dc 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -29,7 +29,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         // Prefix should have already been checked.
@@ -286,11 +286,11 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>(
     which: FloatBinOp,
     left: &OpTy<'tcx, Provenance>,
     right: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (left, left_len) = this.operand_to_simd(left)?;
     let (right, right_len) = this.operand_to_simd(right)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, left_len);
     assert_eq!(dest_len, right_len);
@@ -317,11 +317,11 @@ fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>(
     which: FloatBinOp,
     left: &OpTy<'tcx, Provenance>,
     right: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (left, left_len) = this.operand_to_simd(left)?;
     let (right, right_len) = this.operand_to_simd(right)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, left_len);
     assert_eq!(dest_len, right_len);
@@ -414,10 +414,10 @@ fn unary_op_ss<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     which: FloatUnaryOp,
     op: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (op, op_len) = this.operand_to_simd(op)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, op_len);
 
@@ -437,10 +437,10 @@ fn unary_op_ps<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     which: FloatUnaryOp,
     op: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (op, op_len) = this.operand_to_simd(op)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, op_len);
 
@@ -462,11 +462,11 @@ fn round_first<'tcx, F: rustc_apfloat::Float>(
     left: &OpTy<'tcx, Provenance>,
     right: &OpTy<'tcx, Provenance>,
     rounding: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (left, left_len) = this.operand_to_simd(left)?;
     let (right, right_len) = this.operand_to_simd(right)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, left_len);
     assert_eq!(dest_len, right_len);
@@ -492,10 +492,10 @@ fn round_all<'tcx, F: rustc_apfloat::Float>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     op: &OpTy<'tcx, Provenance>,
     rounding: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (op, op_len) = this.operand_to_simd(op)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, op_len);
 
@@ -544,10 +544,10 @@ fn convert_float_to_int<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     op: &OpTy<'tcx, Provenance>,
     rnd: rustc_apfloat::Round,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (op, op_len) = this.operand_to_simd(op)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     // Output must be *signed* integers.
     assert!(matches!(dest.layout.field(this, 0).ty.kind(), ty::Int(_)));
@@ -587,7 +587,7 @@ fn split_simd_to_128bit_chunks<'tcx>(
     this: &mut crate::MiriInterpCx<'_, 'tcx>,
     left: &OpTy<'tcx, Provenance>,
     right: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<
     'tcx,
     (u64, u64, MPlaceTy<'tcx, Provenance>, MPlaceTy<'tcx, Provenance>, MPlaceTy<'tcx, Provenance>),
@@ -597,7 +597,7 @@ fn split_simd_to_128bit_chunks<'tcx>(
 
     let (left, left_len) = this.operand_to_simd(left)?;
     let (right, right_len) = this.operand_to_simd(right)?;
-    let (dest, dest_len) = this.place_to_simd(dest)?;
+    let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
     assert_eq!(dest_len, left_len);
     assert_eq!(dest_len, right_len);
@@ -636,7 +636,7 @@ fn horizontal_bin_op<'tcx>(
     saturating: bool,
     left: &OpTy<'tcx, Provenance>,
     right: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (num_chunks, items_per_chunk, left, right, dest) =
         split_simd_to_128bit_chunks(this, left, right, dest)?;
@@ -684,7 +684,7 @@ fn conditional_dot_product<'tcx>(
     left: &OpTy<'tcx, Provenance>,
     right: &OpTy<'tcx, Provenance>,
     imm: &OpTy<'tcx, Provenance>,
-    dest: &PlaceTy<'tcx, Provenance>,
+    dest: &MPlaceTy<'tcx, Provenance>,
 ) -> InterpResult<'tcx, ()> {
     let (num_chunks, items_per_chunk, left, right, dest) =
         split_simd_to_128bit_chunks(this, left, right, dest)?;
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index da0db92738f..b8c0dfb1c7f 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -19,7 +19,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         this.expect_target_feature_for_intrinsic(link_name, "sse")?;
@@ -198,7 +198,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.operand_to_simd(left)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
 
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index b34b93e3739..18ff5d809e3 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -17,7 +17,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         this.expect_target_feature_for_intrinsic(link_name, "sse2")?;
@@ -46,7 +46,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(left_len, right_len);
                 assert_eq!(dest_len.checked_mul(2).unwrap(), left_len);
@@ -85,7 +85,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 // left and right are u8x16, dest is u64x2
                 assert_eq!(left_len, right_len);
@@ -122,7 +122,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
@@ -172,7 +172,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
@@ -223,7 +223,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
@@ -306,7 +306,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 // left and right are i16x8, dest is i8x16
                 assert_eq!(left_len, 8);
@@ -337,7 +337,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 // left and right are i16x8, dest is u8x16
                 assert_eq!(left_len, 8);
@@ -367,7 +367,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 // left and right are i32x4, dest is i16x8
                 assert_eq!(left_len, 4);
@@ -430,7 +430,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
                 let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, op_len);
 
@@ -449,7 +449,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
                 let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, op_len);
 
@@ -563,7 +563,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, _) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
 
diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs
index 99a7a4f2f88..5ac30dca79a 100644
--- a/src/tools/miri/src/shims/x86/sse3.rs
+++ b/src/tools/miri/src/shims/x86/sse3.rs
@@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         this.expect_target_feature_for_intrinsic(link_name, "sse3")?;
diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs
index 32b1fe43c58..16a82eed99b 100644
--- a/src/tools/miri/src/shims/x86/sse41.rs
+++ b/src/tools/miri/src/shims/x86/sse41.rs
@@ -14,7 +14,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         this.expect_target_feature_for_intrinsic(link_name, "sse4.1")?;
@@ -34,7 +34,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
@@ -70,7 +70,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(left_len, right_len);
                 assert_eq!(dest_len, left_len.checked_mul(2).unwrap());
@@ -142,7 +142,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
                 let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 // Find minimum
                 let mut min_value = u16::MAX;
@@ -178,7 +178,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(left_len, right_len);
                 assert_eq!(left_len, dest_len.checked_mul(2).unwrap());
diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs
index 724150fd2fe..dd5d064b20f 100644
--- a/src/tools/miri/src/shims/x86/ssse3.rs
+++ b/src/tools/miri/src/shims/x86/ssse3.rs
@@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
         link_name: Symbol,
         abi: Abi,
         args: &[OpTy<'tcx, Provenance>],
-        dest: &PlaceTy<'tcx, Provenance>,
+        dest: &MPlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx, EmulateForeignItemResult> {
         let this = self.eval_context_mut();
         this.expect_target_feature_for_intrinsic(link_name, "ssse3")?;
@@ -29,7 +29,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                 let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
 
                 let (op, op_len) = this.operand_to_simd(op)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(op_len, dest_len);
 
@@ -52,7 +52,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
@@ -102,7 +102,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(left_len, right_len);
                 assert_eq!(dest_len.checked_mul(2).unwrap(), left_len);
@@ -138,7 +138,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
@@ -172,7 +172,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
 
                 let (left, left_len) = this.operand_to_simd(left)?;
                 let (right, right_len) = this.operand_to_simd(right)?;
-                let (dest, dest_len) = this.place_to_simd(dest)?;
+                let (dest, dest_len) = this.mplace_to_simd(dest)?;
 
                 assert_eq!(dest_len, left_len);
                 assert_eq!(dest_len, right_len);
diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs
index 9f467724565..db0768848fd 100644
--- a/src/tools/miri/tests/compiletest.rs
+++ b/src/tools/miri/tests/compiletest.rs
@@ -81,8 +81,10 @@ fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
 
     // Add a test env var to do environment communication tests.
     program.envs.push(("MIRI_ENV_VAR_TEST".into(), Some("0".into())));
+
     // Let the tests know where to store temp files (they might run for a different target, which can make this hard to find).
-    program.envs.push(("MIRI_TEMP".into(), Some(env::temp_dir().into())));
+    let miri_temp = env::var_os("MIRI_TEMP").unwrap_or_else(|| env::temp_dir().into());
+    program.envs.push(("MIRI_TEMP".into(), Some(miri_temp)));
 
     let mut config = Config {
         target: Some(target.to_owned()),
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index 6ba39c1f563..304a178dc34 100644
--- a/src/tools/miri/tests/pass/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -1,6 +1,10 @@
 //@ignore-target-windows: File handling is not implemented yet
 //@compile-flags: -Zmiri-disable-isolation
 
+// If this test is failing for you locally, you can try
+// 1. Deleting the files `/tmp/miri_*`
+// 2. Setting `MIRI_TEMP` or `TMPDIR` to a different directory, without the `miri_*` files
+
 #![feature(io_error_more)]
 #![feature(io_error_uncategorized)]
 
diff --git a/src/tools/opt-dist/src/utils/artifact_size.rs b/src/tools/opt-dist/src/utils/artifact_size.rs
index eb1f6bcf21d..b6c453fb40b 100644
--- a/src/tools/opt-dist/src/utils/artifact_size.rs
+++ b/src/tools/opt-dist/src/utils/artifact_size.rs
@@ -16,7 +16,7 @@ pub fn print_binary_sizes(env: &Environment) -> anyhow::Result<()> {
     let root = env.build_artifacts().join("stage2");
 
     let mut files = get_files_from_dir(&root.join("bin"), None)?;
-    files.extend(get_files_from_dir(&root.join("lib"), Some(".so"))?);
+    files.extend(get_files_from_dir(&root.join("lib"), None)?);
     files.sort_unstable();
 
     let items: Vec<_> = files
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index b4540f14627..b4ccddda0d8 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -190,7 +190,11 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) {
         let blessed_issues_path = tidy_src.join("issues_blessed.txt");
         let mut blessed_issues_txt = fs::File::create(&blessed_issues_path).unwrap();
         blessed_issues_txt.write(issues_txt_header.as_bytes()).unwrap();
-        for filename in allowed_issue_names.difference(&remaining_issue_names) {
+        // If we changed paths to use the OS separator, reassert Unix chauvinism for blessing.
+        for filename in allowed_issue_names
+            .difference(&remaining_issue_names)
+            .map(|s| s.replace(std::path::MAIN_SEPARATOR_STR, "/"))
+        {
             write!(blessed_issues_txt, "\"{filename}\",\n").unwrap();
         }
         write!(blessed_issues_txt, "]\n").unwrap();
diff --git a/tests/assembly/targets/targets-pe.rs b/tests/assembly/targets/targets-pe.rs
index 63b07ee4d1a..6415aee6fae 100644
--- a/tests/assembly/targets/targets-pe.rs
+++ b/tests/assembly/targets/targets-pe.rs
@@ -12,6 +12,9 @@
 //@ revisions: aarch64_uwp_windows_msvc
 //@ [aarch64_uwp_windows_msvc] compile-flags: --target aarch64-uwp-windows-msvc
 //@ [aarch64_uwp_windows_msvc] needs-llvm-components: aarch64
+//@ revisions: arm64ec_pc_windows_msvc
+//@ [arm64ec_pc_windows_msvc] compile-flags: --target arm64ec-pc-windows-msvc
+//@ [arm64ec_pc_windows_msvc] needs-llvm-components: aarch64
 //@ revisions: avr_unknown_gnu_atmega328
 //@ [avr_unknown_gnu_atmega328] compile-flags: --target avr-unknown-gnu-atmega328
 //@ [avr_unknown_gnu_atmega328] needs-llvm-components: avr
diff --git a/tests/codegen/cffi/c-variadic.rs b/tests/codegen/cffi/c-variadic.rs
index 74aed36a8a1..914d1623ed2 100644
--- a/tests/codegen/cffi/c-variadic.rs
+++ b/tests/codegen/cffi/c-variadic.rs
@@ -1,4 +1,4 @@
-//@ ignore-wasm32-bare compiled with panic=abort by default
+//@ needs-unwind
 //@ compile-flags: -C no-prepopulate-passes -Copt-level=0
 //
 
diff --git a/tests/codegen/dst-offset.rs b/tests/codegen/dst-offset.rs
new file mode 100644
index 00000000000..f0157e5a106
--- /dev/null
+++ b/tests/codegen/dst-offset.rs
@@ -0,0 +1,84 @@
+//! This file tests that we correctly generate GEP instructions for DST
+//! field offsets.
+//@ compile-flags: -C no-prepopulate-passes -Copt-level=0
+
+#![crate_type = "lib"]
+
+#![feature(extern_types)]
+
+use std::ptr::addr_of;
+
+// Hack to get the correct type for usize
+// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
+#[no_mangle]
+pub fn helper(_: usize) {
+}
+
+struct Dst<T: ?Sized> {
+    x: u32,
+    y: u8,
+    z: T,
+}
+
+// CHECK: @dst_dyn_trait_offset(ptr align {{[0-9]+}} [[DATA_PTR:%.+]], ptr align {{[0-9]+}} [[VTABLE_PTR:%.+]])
+#[no_mangle]
+pub fn dst_dyn_trait_offset(s: &Dst<dyn Drop>) -> &dyn Drop {
+// The alignment of dyn trait is unknown, so we compute the offset based on align from the vtable.
+
+// CHECK: [[SIZE_PTR:%[0-9]+]] = getelementptr inbounds {{.+}} [[VTABLE_PTR]]
+// CHECK: load [[USIZE]], ptr [[SIZE_PTR]]
+// CHECK: [[ALIGN_PTR:%[0-9]+]] = getelementptr inbounds {{.+}} [[VTABLE_PTR]]
+// CHECK: load [[USIZE]], ptr [[ALIGN_PTR]]
+
+// CHECK: getelementptr inbounds i8, ptr [[DATA_PTR]]
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: ret
+    &s.z
+}
+
+// CHECK-LABEL: @dst_slice_offset
+#[no_mangle]
+pub fn dst_slice_offset(s: &Dst<[u16]>) -> &[u16] {
+// The alignment of [u16] is known, so we generate a GEP directly.
+
+// CHECK: start:
+// CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 6
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: ret
+    &s.z
+}
+
+#[repr(packed)]
+struct PackedDstSlice {
+    x: u32,
+    y: u8,
+    z: [u16],
+}
+
+// CHECK-LABEL: @packed_dst_slice_offset
+#[no_mangle]
+pub fn packed_dst_slice_offset(s: &PackedDstSlice) -> *const [u16] {
+// The alignment of [u16] is known, so we generate a GEP directly.
+
+// CHECK: start:
+// CHECK-NEXT: getelementptr inbounds i8, {{.+}}, [[USIZE]] 5
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: ret
+    addr_of!(s.z)
+}
+
+extern {
+    pub type Extern;
+}
+
+// CHECK-LABEL: @dst_extern
+#[no_mangle]
+pub fn dst_extern(s: &Dst<Extern>) -> &Extern {
+// Computing the alignment of an extern type is currently unsupported and just panics.
+
+// CHECK: call void @{{.+}}panic
+    &s.z
+}
diff --git a/tests/codegen/zst-offset.rs b/tests/codegen/zst-offset.rs
index 65d9cf39c4c..b623d492d9d 100644
--- a/tests/codegen/zst-offset.rs
+++ b/tests/codegen/zst-offset.rs
@@ -13,7 +13,7 @@ pub fn helper(_: usize) {
 // CHECK-LABEL: @scalar_layout
 #[no_mangle]
 pub fn scalar_layout(s: &(u64, ())) {
-// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 8
+// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 8
     let x = &s.1;
     witness(&x); // keep variable in an alloca
 }
@@ -22,7 +22,7 @@ pub fn scalar_layout(s: &(u64, ())) {
 // CHECK-LABEL: @scalarpair_layout
 #[no_mangle]
 pub fn scalarpair_layout(s: &(u64, u32, ())) {
-// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 12
+// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 12
     let x = &s.2;
     witness(&x); // keep variable in an alloca
 }
@@ -34,7 +34,7 @@ pub struct U64x4(u64, u64, u64, u64);
 // CHECK-LABEL: @vector_layout
 #[no_mangle]
 pub fn vector_layout(s: &(U64x4, ())) {
-// CHECK: getelementptr i8, {{.+}}, [[USIZE]] 32
+// CHECK: getelementptr inbounds i8, {{.+}}, [[USIZE]] 32
     let x = &s.1;
     witness(&x); // keep variable in an alloca
 }
diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs
index 16e2c7d60b8..9f7d6db5d26 100644
--- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs
+++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.rs
@@ -12,7 +12,7 @@ struct DefaultAllocator;
 // `<DefaultAllocator as Allocator>::Buffer` to be ambiguous,
 // which caused an ICE with `-Znormalize-docs`.
 impl<T> Allocator for DefaultAllocator {
-    //~^ ERROR: type annotations needed
+    //~^ ERROR: the type parameter `T` is not constrained
     type Buffer = ();
 }
 
diff --git a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr
index 01034018e22..55ab144b924 100644
--- a/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr
+++ b/tests/rustdoc-ui/not-wf-ambiguous-normalization.stderr
@@ -1,9 +1,9 @@
-error[E0282]: type annotations needed
-  --> $DIR/not-wf-ambiguous-normalization.rs:14:23
+error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
+  --> $DIR/not-wf-ambiguous-normalization.rs:14:6
    |
 LL | impl<T> Allocator for DefaultAllocator {
-   |                       ^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
+   |      ^ unconstrained type parameter
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0282`.
+For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index a4f60ea2684..3ee4542810c 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -39,7 +39,7 @@
 //@ revisions: loongarch64
 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
 //@[loongarch64] needs-llvm-components: loongarch
-//@[loongarch64] min-llvm-version: 17
+//@[loongarch64] min-llvm-version: 18
 //@ revisions: wasm
 //@[wasm] compile-flags: --target wasm32-unknown-unknown
 //@[wasm] needs-llvm-components: webassembly
diff --git a/tests/ui/abi/extern/extern-call-deep2.rs b/tests/ui/abi/extern/extern-call-deep2.rs
index 80c492e3022..c021bc22348 100644
--- a/tests/ui/abi/extern/extern-call-deep2.rs
+++ b/tests/ui/abi/extern/extern-call-deep2.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 #![feature(rustc_private)]
 
 extern crate libc;
diff --git a/tests/ui/abi/extern/extern-call-scrub.rs b/tests/ui/abi/extern/extern-call-scrub.rs
index 873f5d2e774..7edf8975ad8 100644
--- a/tests/ui/abi/extern/extern-call-scrub.rs
+++ b/tests/ui/abi/extern/extern-call-scrub.rs
@@ -4,7 +4,7 @@
 // make sure the stack pointers are maintained properly in both
 // directions
 
-//@ ignore-emscripten no threads support
+//@ needs-threads
 #![feature(rustc_private)]
 
 extern crate libc;
diff --git a/tests/ui/abi/foreign/foreign-call-no-runtime.rs b/tests/ui/abi/foreign/foreign-call-no-runtime.rs
index 7f847d55721..42d8d7b1d25 100644
--- a/tests/ui/abi/foreign/foreign-call-no-runtime.rs
+++ b/tests/ui/abi/foreign/foreign-call-no-runtime.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 #![feature(rustc_private)]
 
diff --git a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
index 2a308f83731..03d72f2ae2c 100644
--- a/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
+++ b/tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr
@@ -1,11 +1,8 @@
-error[E0191]: the value of the associated types `Item`, `Item`, `IntoIter` and `IntoIter` in `IntoIterator` must be specified
+error[E0191]: the value of the associated types `Item` and `IntoIter` in `IntoIterator` must be specified
   --> $DIR/overlaping-bound-suggestion.rs:7:13
    |
 LL |     inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |             |                  |
-   |             |                  associated types `Item`, `IntoIter` must be specified
-   |             associated types `Item`, `IntoIter` must be specified
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated types: `IntoIterator<Item: IntoIterator<Item: >, Item = Type, IntoIter = Type>`
 
 error[E0223]: ambiguous associated type
   --> $DIR/overlaping-bound-suggestion.rs:7:13
diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.rs b/tests/ui/associated-types/hr-associated-type-projection-1.rs
index 3df3f68ab1e..d7fc5d122c3 100644
--- a/tests/ui/associated-types/hr-associated-type-projection-1.rs
+++ b/tests/ui/associated-types/hr-associated-type-projection-1.rs
@@ -11,8 +11,8 @@ where
 }
 
 impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
-    //~^ type mismatch resolving `<T as Deref>::Target == T`
     type Item = T;
+    //~^ type mismatch resolving `<T as Deref>::Target == T`
 }
 
 pub fn main() {
diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.stderr b/tests/ui/associated-types/hr-associated-type-projection-1.stderr
index 65221718ee6..b871bb51ae3 100644
--- a/tests/ui/associated-types/hr-associated-type-projection-1.stderr
+++ b/tests/ui/associated-types/hr-associated-type-projection-1.stderr
@@ -1,10 +1,10 @@
 error[E0271]: type mismatch resolving `<T as Deref>::Target == T`
-  --> $DIR/hr-associated-type-projection-1.rs:13:33
+  --> $DIR/hr-associated-type-projection-1.rs:14:17
    |
 LL | impl<T: Copy + std::ops::Deref> UnsafeCopy<'_, T> for T {
-   |      -                          ^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
-   |      |
-   |      expected this type parameter
+   |      - expected this type parameter
+LL |     type Item = T;
+   |                 ^ expected type parameter `T`, found associated type
    |
    = note: expected type parameter `T`
              found associated type `<T as Deref>::Target`
diff --git a/tests/ui/associated-types/issue-38821.stderr b/tests/ui/associated-types/issue-38821.stderr
index acf6bb2810c..f1c8f83e30c 100644
--- a/tests/ui/associated-types/issue-38821.stderr
+++ b/tests/ui/associated-types/issue-38821.stderr
@@ -1,23 +1,4 @@
 error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
-  --> $DIR/issue-38821.rs:23:17
-   |
-LL | #[derive(Debug, Copy, Clone)]
-   |                 ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
-   |
-note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
-  --> $DIR/issue-38821.rs:9:18
-   |
-LL | impl<T: NotNull> IntoNullable for T {
-   |         -------  ^^^^^^^^^^^^     ^
-   |         |
-   |         unsatisfied trait bound introduced here
-   = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
-help: consider further restricting the associated type
-   |
-LL |     Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
-   |                                                                       +++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
   --> $DIR/issue-38821.rs:40:1
    |
 LL | pub enum ColumnInsertValue<Col, Expr> where
@@ -142,6 +123,25 @@ LL | impl<T: NotNull> IntoNullable for T {
    |         -------  ^^^^^^^^^^^^     ^
    |         |
    |         unsatisfied trait bound introduced here
+   = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider further restricting the associated type
+   |
+LL |     Expr: Expression<SqlType=<Col::SqlType as IntoNullable>::Nullable>, <Col as Expression>::SqlType: NotNull,
+   |                                                                       +++++++++++++++++++++++++++++++++++++++
+
+error[E0277]: the trait bound `<Col as Expression>::SqlType: NotNull` is not satisfied
+  --> $DIR/issue-38821.rs:23:17
+   |
+LL | #[derive(Debug, Copy, Clone)]
+   |                 ^^^^ the trait `NotNull` is not implemented for `<Col as Expression>::SqlType`, which is required by `<Col as Expression>::SqlType: IntoNullable`
+   |
+note: required for `<Col as Expression>::SqlType` to implement `IntoNullable`
+  --> $DIR/issue-38821.rs:9:18
+   |
+LL | impl<T: NotNull> IntoNullable for T {
+   |         -------  ^^^^^^^^^^^^     ^
+   |         |
+   |         unsatisfied trait bound introduced here
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider further restricting the associated type
diff --git a/tests/ui/box/unit/unique-send-2.rs b/tests/ui/box/unit/unique-send-2.rs
index 20474fee4d8..d3cbeefab37 100644
--- a/tests/ui/box/unit/unique-send-2.rs
+++ b/tests/ui/box/unit/unique-send-2.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
diff --git a/tests/ui/check-cfg/mix.stderr b/tests/ui/check-cfg/mix.stderr
index 93333e5ef2a..007f9de0331 100644
--- a/tests/ui/check-cfg/mix.stderr
+++ b/tests/ui/check-cfg/mix.stderr
@@ -251,7 +251,7 @@ warning: unexpected `cfg` condition value: `zebra`
 LL |     cfg!(target_feature = "zebra");
    |          ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 186 more
+   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2` and 187 more
    = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 27 warnings emitted
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index 86df829fe72..cf18503b74b 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -118,7 +118,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_arch = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_arch` are: `aarch64`, `arm`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`
+   = note: expected values for `target_arch` are: `aarch64`, `arm`, `arm64ec`, `avr`, `bpf`, `csky`, `hexagon`, `loongarch64`, `m68k`, `mips`, `mips32r6`, `mips64`, `mips64r6`, `msp430`, `nvptx64`, `powerpc`, `powerpc64`, `riscv32`, `riscv64`, `s390x`, `sparc`, `sparc64`, `wasm32`, `wasm64`, `x86`, `x86_64`
    = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -154,7 +154,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_feature = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt`
+   = note: expected values for `target_feature` are: `10e60`, `2e3`, `3e3r1`, `3e3r2`, `3e3r3`, `3e7`, `7e10`, `a`, `aclass`, `adx`, `aes`, `altivec`, `alu32`, `atomics`, `avx`, `avx2`, `avx512bf16`, `avx512bitalg`, `avx512bw`, `avx512cd`, `avx512dq`, `avx512er`, `avx512f`, `avx512fp16`, `avx512ifma`, `avx512pf`, `avx512vbmi`, `avx512vbmi2`, `avx512vl`, `avx512vnni`, `avx512vp2intersect`, `avx512vpopcntdq`, `bf16`, `bmi1`, `bmi2`, `bti`, `bulk-memory`, `c`, `cache`, `cmpxchg16b`, `crc`, `crt-static`, `d`, `d32`, `dit`, `doloop`, `dotprod`, `dpb`, `dpb2`, `dsp`, `dsp1e2`, `dspe60`, `e`, `e1`, `e2`, `edsp`, `elrw`, `ermsb`, `exception-handling`, `f`, `f16c`, `f32mm`, `f64mm`, `fast-unaligned-access`, `fcma`, `fdivdu`, `fhm`, `flagm`, `float1e2`, `float1e3`, `float3e4`, `float7e60`, `floate1`, `fma`, `fp-armv8`, `fp16`, `fp64`, `fpuv2_df`, `fpuv2_sf`, `fpuv3_df`, `fpuv3_hf`, `fpuv3_hi`, `fpuv3_sf`, `frecipe`, `frintts`, `fxsr`, `gfni`, `hard-float`, `hard-float-abi`, `hard-tp`, `high-registers`, `hvx`, `hvx-length128b`, `hwdiv`, `i8mm`, `jsconv`, `lahfsahf`, `lasx`, `lbt`, `lor`, `lse`, `lsx`, `lvz`, `lzcnt`, `m`, `mclass`, `movbe`, `mp`, `mp1e2`, `msa`, `mte`, `multivalue`, `mutable-globals`, `neon`, `nontrapping-fptoint`, `nvic`, `paca`, `pacg`, `pan`, `pclmulqdq`, `pmuv3`, `popcnt`, `power10-vector`, `power8-altivec`, `power8-vector`, `power9-altivec`, `power9-vector`, `prfchw`, `rand`, `ras`, `rclass`, `rcpc`, `rcpc2`, `rdm`, `rdrand`, `rdseed`, `reference-types`, `relax`, `relaxed-simd`, `rtm`, `sb`, `sha`, `sha2`, `sha3`, `sign-ext`, `simd128`, `sm4`, `spe`, `ssbs`, `sse`, `sse2`, `sse3`, `sse4.1`, `sse4.2`, `sse4a`, `ssse3`, `sve`, `sve2`, `sve2-aes`, `sve2-bitperm`, `sve2-sha3`, `sve2-sm4`, `tbm`, `thumb-mode`, `thumb2`, `tme`, `trust`, `trustzone`, `ual`, `v`, `v5te`, `v6`, `v6k`, `v6t2`, `v7`, `v8`, `v8.1a`, `v8.2a`, `v8.3a`, `v8.4a`, `v8.5a`, `v8.6a`, `v8.7a`, `vaes`, `vdsp2e60f`, `vdspv1`, `vdspv2`, `vfp2`, `vfp3`, `vfp4`, `vh`, `virt`, `virtualization`, `vpclmulqdq`, `vsx`, `xsave`, `xsavec`, `xsaveopt`, `xsaves`, `zba`, `zbb`, `zbc`, `zbkb`, `zbkc`, `zbkx`, `zbs`, `zdinx`, `zfh`, `zfhmin`, `zfinx`, `zhinx`, `zhinxmin`, `zk`, `zkn`, `zknd`, `zkne`, `zknh`, `zkr`, `zks`, `zksed`, `zksh`, `zkt`
    = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
diff --git a/tests/ui/codegen/init-large-type.rs b/tests/ui/codegen/init-large-type.rs
index 34b40693ab1..b9fc6612e16 100644
--- a/tests/ui/codegen/init-large-type.rs
+++ b/tests/ui/codegen/init-large-type.rs
@@ -7,8 +7,7 @@
 // optimisation.
 
 //@ pretty-expanded FIXME #23616
-//@ ignore-emscripten no threads support
-
+//@ needs-threads
 #![feature(intrinsics)]
 
 use std::{mem, thread};
diff --git a/tests/ui/codegen/issue-28950.rs b/tests/ui/codegen/issue-28950.rs
index 8e55172af6d..0a706c588d5 100644
--- a/tests/ui/codegen/issue-28950.rs
+++ b/tests/ui/codegen/issue-28950.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads
+//@ needs-threads
 //@ compile-flags: -O
 
 // Tests that the `vec!` macro does not overflow the stack when it is
diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr
index b1bb75bfe51..48843f7cd18 100644
--- a/tests/ui/coherence/coherence-orphan.stderr
+++ b/tests/ui/coherence/coherence-orphan.stderr
@@ -10,17 +10,6 @@ LL | impl TheTrait<usize> for isize {}
    |
    = note: define and implement a trait or new type instead
 
-error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
-  --> $DIR/coherence-orphan.rs:20:1
-   |
-LL | impl !Send for Vec<isize> {}
-   | ^^^^^^^^^^^^^^^----------
-   | |              |
-   | |              `Vec` is not defined in the current crate
-   | impl doesn't use only types from inside the current crate
-   |
-   = note: define and implement a trait or new type instead
-
 error[E0046]: not all trait items implemented, missing: `the_fn`
   --> $DIR/coherence-orphan.rs:10:1
    |
@@ -45,6 +34,17 @@ LL | impl TheTrait<isize> for TheType {}
    |
    = help: implement the missing item: `fn the_fn(&self) { todo!() }`
 
+error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
+  --> $DIR/coherence-orphan.rs:20:1
+   |
+LL | impl !Send for Vec<isize> {}
+   | ^^^^^^^^^^^^^^^----------
+   | |              |
+   | |              `Vec` is not defined in the current crate
+   | impl doesn't use only types from inside the current crate
+   |
+   = note: define and implement a trait or new type instead
+
 error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0046, E0117.
diff --git a/tests/ui/const-generics/issues/issue-68366.full.stderr b/tests/ui/const-generics/issues/issue-68366.full.stderr
index ca9eb801dfc..dc20af77310 100644
--- a/tests/ui/const-generics/issues/issue-68366.full.stderr
+++ b/tests/ui/const-generics/issues/issue-68366.full.stderr
@@ -1,5 +1,14 @@
+error: `Option<usize>` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-68366.rs:9:25
+   |
+LL | struct Collatz<const N: Option<usize>>;
+   |                         ^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:11:7
+  --> $DIR/issue-68366.rs:12:7
    |
 LL | impl <const N: usize> Collatz<{Some(N)}> {}
    |       ^^^^^^^^^^^^^^ unconstrained const parameter
@@ -8,7 +17,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
    = note: proving the result of expressions other than the parameter are unique is not supported
 
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:17:6
+  --> $DIR/issue-68366.rs:19:6
    |
 LL | impl<const N: usize> Foo {}
    |      ^^^^^^^^^^^^^^ unconstrained const parameter
@@ -16,6 +25,17 @@ LL | impl<const N: usize> Foo {}
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
 
-error: aborting due to 2 previous errors
+error: overly complex generic constant
+  --> $DIR/issue-68366.rs:12:31
+   |
+LL | impl <const N: usize> Collatz<{Some(N)}> {}
+   |                               ^-------^
+   |                                |
+   |                                struct/enum construction is not supported in generic constants
+   |
+   = help: consider moving this anonymous constant into a `const` function
+   = note: this operation may be supported in the future
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/const-generics/issues/issue-68366.min.stderr b/tests/ui/const-generics/issues/issue-68366.min.stderr
index ecf24a356de..78e49f46e1a 100644
--- a/tests/ui/const-generics/issues/issue-68366.min.stderr
+++ b/tests/ui/const-generics/issues/issue-68366.min.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/issue-68366.rs:11:37
+  --> $DIR/issue-68366.rs:12:37
    |
 LL | impl <const N: usize> Collatz<{Some(N)}> {}
    |                                     ^ cannot perform const operation using `N`
@@ -7,8 +7,17 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
    = help: const parameters may only be used as standalone arguments, i.e. `N`
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
+error: `Option<usize>` is forbidden as the type of a const generic parameter
+  --> $DIR/issue-68366.rs:9:25
+   |
+LL | struct Collatz<const N: Option<usize>>;
+   |                         ^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:11:7
+  --> $DIR/issue-68366.rs:12:7
    |
 LL | impl <const N: usize> Collatz<{Some(N)}> {}
    |       ^^^^^^^^^^^^^^ unconstrained const parameter
@@ -17,7 +26,7 @@ LL | impl <const N: usize> Collatz<{Some(N)}> {}
    = note: proving the result of expressions other than the parameter are unique is not supported
 
 error[E0207]: the const parameter `N` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/issue-68366.rs:17:6
+  --> $DIR/issue-68366.rs:19:6
    |
 LL | impl<const N: usize> Foo {}
    |      ^^^^^^^^^^^^^^ unconstrained const parameter
@@ -25,6 +34,6 @@ LL | impl<const N: usize> Foo {}
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0207`.
diff --git a/tests/ui/const-generics/issues/issue-68366.rs b/tests/ui/const-generics/issues/issue-68366.rs
index d3e57a021a6..d9d5e21857b 100644
--- a/tests/ui/const-generics/issues/issue-68366.rs
+++ b/tests/ui/const-generics/issues/issue-68366.rs
@@ -7,10 +7,12 @@
 #![cfg_attr(full, allow(incomplete_features))]
 
 struct Collatz<const N: Option<usize>>;
+//~^ ERROR: `Option<usize>` is forbidden
 
 impl <const N: usize> Collatz<{Some(N)}> {}
 //~^ ERROR the const parameter
 //[min]~^^ generic parameters may not be used in const operations
+//[full]~^^^ ERROR overly complex
 
 struct Foo;
 
diff --git a/tests/ui/coroutine/smoke.rs b/tests/ui/coroutine/smoke.rs
index 0ed56982c9b..17d98a52a1c 100644
--- a/tests/ui/coroutine/smoke.rs
+++ b/tests/ui/coroutine/smoke.rs
@@ -3,7 +3,7 @@
 //@ revisions: default nomiropt
 //@[nomiropt]compile-flags: -Z mir-opt-level=0
 
-//@ ignore-emscripten no threads support
+//@ needs-threads
 //@ compile-flags: --test
 
 #![feature(coroutines, coroutine_trait)]
diff --git a/tests/ui/crate-loading/missing-std.stderr b/tests/ui/crate-loading/missing-std.stderr
index 70bcae1e0ed..3eb6c2946d3 100644
--- a/tests/ui/crate-loading/missing-std.stderr
+++ b/tests/ui/crate-loading/missing-std.stderr
@@ -8,8 +8,6 @@ LL | extern crate core;
    = help: consider downloading the target with `rustup target add x86_64-unknown-uefi`
    = help: consider building the standard library from source with `cargo build -Zbuild-std`
 
-error: requires `sized` lang_item
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0463`.
diff --git a/tests/ui/cross-crate/cci_capture_clause.rs b/tests/ui/cross-crate/cci_capture_clause.rs
index 99736ad185d..73e1020d7cf 100644
--- a/tests/ui/cross-crate/cci_capture_clause.rs
+++ b/tests/ui/cross-crate/cci_capture_clause.rs
@@ -5,7 +5,7 @@
 // that use capture clauses.
 
 //@ pretty-expanded FIXME #23616
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 extern crate cci_capture_clause;
 
diff --git a/tests/ui/diagnostic_namespace/existing_proc_macros.rs b/tests/ui/diagnostic_namespace/existing_proc_macros.rs
index 2bc58aea8fc..014ec46f1b9 100644
--- a/tests/ui/diagnostic_namespace/existing_proc_macros.rs
+++ b/tests/ui/diagnostic_namespace/existing_proc_macros.rs
@@ -1,4 +1,3 @@
-#![feature(diagnostic_namespace)]
 //@ check-pass
 //@ aux-build:proc-macro-helper.rs
 
diff --git a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs b/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs
deleted file mode 100644
index b08e291621f..00000000000
--- a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-#[diagnostic::non_existing_attribute]
-//~^ERROR `#[diagnostic]` attribute name space is experimental [E0658]
-//~|WARNING unknown diagnostic attribute [unknown_or_malformed_diagnostic_attributes]
-pub trait Bar {
-}
-
-#[diagnostic::non_existing_attribute(with_option = "foo")]
-//~^ERROR `#[diagnostic]` attribute name space is experimental [E0658]
-//~|WARNING unknown diagnostic attribute [unknown_or_malformed_diagnostic_attributes]
-struct Foo;
-
-fn main() {
-}
diff --git a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr b/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr
deleted file mode 100644
index 38424c13d86..00000000000
--- a/tests/ui/diagnostic_namespace/feature-gate-diagnostic_namespace.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error[E0658]: `#[diagnostic]` attribute name space is experimental
-  --> $DIR/feature-gate-diagnostic_namespace.rs:1:3
-   |
-LL | #[diagnostic::non_existing_attribute]
-   |   ^^^^^^^^^^
-   |
-   = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information
-   = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error[E0658]: `#[diagnostic]` attribute name space is experimental
-  --> $DIR/feature-gate-diagnostic_namespace.rs:7:3
-   |
-LL | #[diagnostic::non_existing_attribute(with_option = "foo")]
-   |   ^^^^^^^^^^
-   |
-   = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information
-   = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-warning: unknown diagnostic attribute
-  --> $DIR/feature-gate-diagnostic_namespace.rs:1:15
-   |
-LL | #[diagnostic::non_existing_attribute]
-   |               ^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
-
-warning: unknown diagnostic attribute
-  --> $DIR/feature-gate-diagnostic_namespace.rs:7:15
-   |
-LL | #[diagnostic::non_existing_attribute(with_option = "foo")]
-   |               ^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors; 2 warnings emitted
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs
index 95465701bf8..f6957b1448d 100644
--- a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs
+++ b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.rs
@@ -1,4 +1,3 @@
-#![feature(diagnostic_namespace)]
 //@ check-pass
 #[diagnostic::non_existing_attribute]
 //~^WARN unknown diagnostic attribute
diff --git a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr
index 753077b365e..c073ec9b103 100644
--- a/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr
+++ b/tests/ui/diagnostic_namespace/non_existing_attributes_accepted.stderr
@@ -1,5 +1,5 @@
 warning: unknown diagnostic attribute
-  --> $DIR/non_existing_attributes_accepted.rs:3:15
+  --> $DIR/non_existing_attributes_accepted.rs:2:15
    |
 LL | #[diagnostic::non_existing_attribute]
    |               ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::non_existing_attribute]
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: unknown diagnostic attribute
-  --> $DIR/non_existing_attributes_accepted.rs:8:15
+  --> $DIR/non_existing_attributes_accepted.rs:7:15
    |
 LL | #[diagnostic::non_existing_attribute(with_option = "foo")]
    |               ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/auxiliary/other.rs b/tests/ui/diagnostic_namespace/on_unimplemented/auxiliary/other.rs
index 884bab2800a..512ef6330e5 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/auxiliary/other.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/auxiliary/other.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic::on_unimplemented(
     message = "Message",
     note = "Note",
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs
index eb985c062f3..30a85ff2199 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic::on_unimplemented(
     on(_Self = "&str"),
     //~^WARN malformed `on_unimplemented` attribute
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr
index 75a701f0b5f..e34b917f67e 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_accept_options_of_the_internal_rustc_attribute.stderr
@@ -1,5 +1,5 @@
 warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:24:1
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:22:1
    |
 LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::on_unimplemented(message = "Not allowed to apply it on a impl
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:4:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:2:5
    |
 LL |     on(_Self = "&str"),
    |     ^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -15,7 +15,7 @@ LL |     on(_Self = "&str"),
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:10:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:8:5
    |
 LL |     parent_label = "in this scope",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -23,7 +23,7 @@ LL |     parent_label = "in this scope",
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:13:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:11:5
    |
 LL |     append_const_msg
    |     ^^^^^^^^^^^^^^^^ invalid option found here
@@ -31,7 +31,7 @@ LL |     append_const_msg
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:19:32
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:17:32
    |
 LL | #[diagnostic::on_unimplemented = "Message"]
    |                                ^^^^^^^^^^^ invalid option found here
@@ -39,7 +39,7 @@ LL | #[diagnostic::on_unimplemented = "Message"]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: there is no parameter `from_desugaring` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `direct` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +55,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `cause` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `integral` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,7 +71,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `integer` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -79,7 +79,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `float` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `_Self` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -95,7 +95,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `crate_local` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -103,7 +103,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `Trait` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -111,7 +111,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: there is no parameter `ItemContext` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -119,7 +119,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:4:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:2:5
    |
 LL |     on(_Self = "&str"),
    |     ^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -128,7 +128,7 @@ LL |     on(_Self = "&str"),
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:10:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:8:5
    |
 LL |     parent_label = "in this scope",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -137,7 +137,7 @@ LL |     parent_label = "in this scope",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:13:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:11:5
    |
 LL |     append_const_msg
    |     ^^^^^^^^^^^^^^^^ invalid option found here
@@ -146,7 +146,7 @@ LL |     append_const_msg
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: trait has `()` and `i32` as params
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:61:15
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:59:15
    |
 LL |     takes_foo(());
    |     --------- ^^ trait has `()` and `i32` as params
@@ -156,18 +156,18 @@ LL |     takes_foo(());
    = help: the trait `Foo<i32>` is not implemented for `()`
    = note: trait has `()` and `i32` as params
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:17:1
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:15:1
    |
 LL | trait Foo<T> {}
    | ^^^^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:56:22
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:54:22
    |
 LL | fn takes_foo(_: impl Foo<i32>) {}
    |                      ^^^^^^^^ required by this bound in `takes_foo`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:19:32
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:17:32
    |
 LL | #[diagnostic::on_unimplemented = "Message"]
    |                                ^^^^^^^^^^^ invalid option found here
@@ -176,7 +176,7 @@ LL | #[diagnostic::on_unimplemented = "Message"]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: the trait bound `(): Bar` is not satisfied
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:63:15
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:61:15
    |
 LL |     takes_bar(());
    |     --------- ^^ the trait `Bar` is not implemented for `()`
@@ -185,13 +185,13 @@ LL |     takes_bar(());
    |
    = help: the trait `Bar` is implemented for `i32`
 note: required by a bound in `takes_bar`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:57:22
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:55:22
    |
 LL | fn takes_bar(_: impl Bar) {}
    |                      ^^^ required by this bound in `takes_bar`
 
 warning: there is no parameter `from_desugaring` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -200,7 +200,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `direct` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `cause` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -218,7 +218,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `integral` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -227,7 +227,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `integer` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:31:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:29:5
    |
 LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -236,7 +236,7 @@ LL |     message = "{from_desugaring}{direct}{cause}{integral}{integer}",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `float` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -245,7 +245,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `_Self` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -254,7 +254,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `crate_local` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `Trait` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -272,7 +272,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: there is no parameter `ItemContext` on trait `Baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:42:5
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:40:5
    |
 LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -281,7 +281,7 @@ LL |     label = "{float}{_Self}{crate_local}{Trait}{ItemContext}"
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: {from_desugaring}{direct}{cause}{integral}{integer}
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:65:15
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:63:15
    |
 LL |     takes_baz(());
    |     --------- ^^ {float}{_Self}{crate_local}{Trait}{ItemContext}
@@ -290,12 +290,12 @@ LL |     takes_baz(());
    |
    = help: the trait `Baz` is not implemented for `()`
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:54:1
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:52:1
    |
 LL | trait Baz {}
    | ^^^^^^^^^
 note: required by a bound in `takes_baz`
-  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:58:22
+  --> $DIR/do_not_accept_options_of_the_internal_rustc_attribute.rs:56:22
    |
 LL | fn takes_baz(_: impl Baz) {}
    |                      ^^^ required by this bound in `takes_baz`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs
index 12fe988170a..b4234066bb1 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic::on_unimplemented(unsupported = "foo")]
 //~^WARN malformed `on_unimplemented` attribute
 //~|WARN malformed `on_unimplemented` attribute
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr
index 11263580b15..dc0c1948236 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/do_not_fail_parsing_on_invalid_options_1.stderr
@@ -1,5 +1,5 @@
 warning: `#[diagnostic::on_unimplemented]` can only be applied to trait definitions
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:8:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:6:1
    |
 LL | #[diagnostic::on_unimplemented(message = "Baz")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL | #[diagnostic::on_unimplemented(message = "Baz")]
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:1:32
    |
 LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    |                                ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -15,7 +15,7 @@ LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:10:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    |                                                  ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -23,7 +23,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:15:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
    |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -31,7 +31,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:22:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:20:32
    |
 LL | #[diagnostic::on_unimplemented = "boom"]
    |                                ^^^^^^^^ invalid option found here
@@ -39,7 +39,7 @@ LL | #[diagnostic::on_unimplemented = "boom"]
    = help: only `message`, `note` and `label` are allowed as options
 
 warning: missing options for `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:24:1
    |
 LL | #[diagnostic::on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +47,7 @@ LL | #[diagnostic::on_unimplemented]
    = help: at least one of the `message`, `note` and `label` options are expected
 
 warning: there is no parameter `DoesNotExist` on trait `Test`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:29:32
    |
 LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -55,7 +55,7 @@ LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    = help: expect either a generic argument name or `{Self}` as format argument
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:3:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:1:32
    |
 LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    |                                ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -64,7 +64,7 @@ LL | #[diagnostic::on_unimplemented(unsupported = "foo")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: the trait bound `i32: Foo` is not satisfied
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:43:14
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:41:14
    |
 LL |     take_foo(1_i32);
    |     -------- ^^^^^ the trait `Foo` is not implemented for `i32`
@@ -72,18 +72,18 @@ LL |     take_foo(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:6:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:4:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `take_foo`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:36:21
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:34:21
    |
 LL | fn take_foo(_: impl Foo) {}
    |                     ^^^ required by this bound in `take_foo`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:12:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:10:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    |                                                  ^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -92,7 +92,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", unsupported = "Bar")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Boom
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:45:14
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:43:14
    |
 LL |     take_baz(1_i32);
    |     -------- ^^^^^ the trait `Baz` is not implemented for `i32`
@@ -100,18 +100,18 @@ LL |     take_baz(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:15:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:13:1
    |
 LL | trait Baz {}
    | ^^^^^^^^^
 note: required by a bound in `take_baz`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:37:21
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:35:21
    |
 LL | fn take_baz(_: impl Baz) {}
    |                     ^^^ required by this bound in `take_baz`
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:17:50
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:15:50
    |
 LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message = "whatever"))]
    |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ invalid option found here
@@ -120,7 +120,7 @@ LL | #[diagnostic::on_unimplemented(message = "Boom", on(_Self = "i32", message
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: Boom
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:47:15
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:45:15
    |
 LL |     take_boom(1_i32);
    |     --------- ^^^^^ the trait `Boom` is not implemented for `i32`
@@ -128,18 +128,18 @@ LL |     take_boom(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:20:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:18:1
    |
 LL | trait Boom {}
    | ^^^^^^^^^^
 note: required by a bound in `take_boom`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:38:22
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:36:22
    |
 LL | fn take_boom(_: impl Boom) {}
    |                      ^^^^ required by this bound in `take_boom`
 
 warning: missing options for `on_unimplemented` attribute
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:26:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:24:1
    |
 LL | #[diagnostic::on_unimplemented]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -148,7 +148,7 @@ LL | #[diagnostic::on_unimplemented]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: the trait bound `i32: Whatever` is not satisfied
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:49:19
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:47:19
    |
 LL |     take_whatever(1_i32);
    |     ------------- ^^^^^ the trait `Whatever` is not implemented for `i32`
@@ -156,18 +156,18 @@ LL |     take_whatever(1_i32);
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:29:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:27:1
    |
 LL | trait Whatever {}
    | ^^^^^^^^^^^^^^
 note: required by a bound in `take_whatever`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:39:26
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:37:26
    |
 LL | fn take_whatever(_: impl Whatever) {}
    |                          ^^^^^^^^ required by this bound in `take_whatever`
 
 warning: there is no parameter `DoesNotExist` on trait `Test`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:31:32
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:29:32
    |
 LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -176,7 +176,7 @@ LL | #[diagnostic::on_unimplemented(message = "{DoesNotExist}")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: {DoesNotExist}
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:51:15
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:49:15
    |
 LL |     take_test(());
    |     --------- ^^ the trait `Test` is not implemented for `()`
@@ -184,12 +184,12 @@ LL |     take_test(());
    |     required by a bound introduced by this call
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:34:1
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:32:1
    |
 LL | trait Test {}
    | ^^^^^^^^^^
 note: required by a bound in `take_test`
-  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:40:22
+  --> $DIR/do_not_fail_parsing_on_invalid_options_1.rs:38:22
    |
 LL | fn take_test(_: impl Test) {}
    |                      ^^^^ required by this bound in `take_test`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.rs b/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.rs
deleted file mode 100644
index 609a840c118..00000000000
--- a/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#[diagnostic::on_unimplemented(message = "Foo")]
-//~^ERROR `#[diagnostic]` attribute name space is experimental [E0658]
-pub trait Bar {
-}
-
-fn main() {
-}
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.stderr
deleted file mode 100644
index 719322fa0f5..00000000000
--- a/tests/ui/diagnostic_namespace/on_unimplemented/feature-gate-diagnostic_on_unimplemented.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: `#[diagnostic]` attribute name space is experimental
-  --> $DIR/feature-gate-diagnostic_on_unimplemented.rs:1:3
-   |
-LL | #[diagnostic::on_unimplemented(message = "Foo")]
-   |   ^^^^^^^^^^
-   |
-   = note: see issue #111996 <https://github.com/rust-lang/rust/issues/111996> for more information
-   = help: add `#![feature(diagnostic_namespace)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs
index 0893f29c4a3..5b25fb234bc 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic::on_unimplemented(
     if(Self = "()"),
     //~^WARN malformed `on_unimplemented` attribute
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr
index e00846da77b..56d125e20e5 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/ignore_unsupported_options_and_continue_to_use_fallback.stderr
@@ -1,5 +1,5 @@
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:4:5
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:2:5
    |
 LL |     if(Self = "()"),
    |     ^^^^^^^^^^^^^^^ invalid option found here
@@ -8,7 +8,7 @@ LL |     if(Self = "()"),
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:10:32
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:8:32
    |
 LL |     message = "custom message",
    |     -------------------------- `message` is first declared here
@@ -17,7 +17,7 @@ LL | #[diagnostic::on_unimplemented(message = "fallback!!")]
    |                                ^^^^^^^^^^^^^^^^^^^^^^ `message` is already declared here
 
 warning: malformed `on_unimplemented` attribute
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:4:5
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:2:5
    |
 LL |     if(Self = "()"),
    |     ^^^^^^^^^^^^^^^ invalid option found here
@@ -26,7 +26,7 @@ LL |     if(Self = "()"),
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:10:32
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:8:32
    |
 LL |     message = "custom message",
    |     -------------------------- `message` is first declared here
@@ -37,7 +37,7 @@ LL | #[diagnostic::on_unimplemented(message = "fallback!!")]
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: custom message
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:20:15
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:18:15
    |
 LL |     takes_foo(());
    |     --------- ^^ fallback label
@@ -48,12 +48,12 @@ LL |     takes_foo(());
    = note: custom note
    = note: fallback note
 help: this trait has no implementations, consider adding one
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:15:1
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:13:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:17:22
+  --> $DIR/ignore_unsupported_options_and_continue_to_use_fallback.rs:15:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs
index 34cdb99c754..a5982f6492c 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic::on_unimplemented(message = "Foo", label = "Bar", note = "Baz", note = "Boom")]
 trait Foo {}
 
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr
index c72321d4617..93a0d0b3f41 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/multiple_notes.stderr
@@ -1,5 +1,5 @@
 error[E0277]: Foo
-  --> $DIR/multiple_notes.rs:14:15
+  --> $DIR/multiple_notes.rs:12:15
    |
 LL |     takes_foo(());
    |     --------- ^^ Bar
@@ -10,18 +10,18 @@ LL |     takes_foo(());
    = note: Baz
    = note: Boom
 help: this trait has no implementations, consider adding one
-  --> $DIR/multiple_notes.rs:4:1
+  --> $DIR/multiple_notes.rs:2:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/multiple_notes.rs:10:22
+  --> $DIR/multiple_notes.rs:8:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
 
 error[E0277]: Bar
-  --> $DIR/multiple_notes.rs:16:15
+  --> $DIR/multiple_notes.rs:14:15
    |
 LL |     takes_bar(());
    |     --------- ^^ Foo
@@ -32,12 +32,12 @@ LL |     takes_bar(());
    = note: Baz
    = note: Baz2
 help: this trait has no implementations, consider adding one
-  --> $DIR/multiple_notes.rs:8:1
+  --> $DIR/multiple_notes.rs:6:1
    |
 LL | trait Bar {}
    | ^^^^^^^^^
 note: required by a bound in `takes_bar`
-  --> $DIR/multiple_notes.rs:11:22
+  --> $DIR/multiple_notes.rs:9:22
    |
 LL | fn takes_bar(_: impl Bar) {}
    |                      ^^^ required by this bound in `takes_bar`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs
index 797edbc9ec5..7ca03127759 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic::on_unimplemented(message = "Foo", label = "Bar", note = "Baz")]
 trait Foo {}
 
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr
index de57f7044bf..6b17f40c6dd 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/on_unimplemented_simple.stderr
@@ -1,5 +1,5 @@
 error[E0277]: Foo
-  --> $DIR/on_unimplemented_simple.rs:9:15
+  --> $DIR/on_unimplemented_simple.rs:7:15
    |
 LL |     takes_foo(());
    |     --------- ^^ Bar
@@ -9,12 +9,12 @@ LL |     takes_foo(());
    = help: the trait `Foo` is not implemented for `()`
    = note: Baz
 help: this trait has no implementations, consider adding one
-  --> $DIR/on_unimplemented_simple.rs:4:1
+  --> $DIR/on_unimplemented_simple.rs:2:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/on_unimplemented_simple.rs:6:22
+  --> $DIR/on_unimplemented_simple.rs:4:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs
index a7becd2f88f..8c0b8150417 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic::on_unimplemented(
     message = "first message",
     label = "first label",
diff --git a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr
index d30754dcf10..43ab6bf25a1 100644
--- a/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr
+++ b/tests/ui/diagnostic_namespace/on_unimplemented/report_warning_on_duplicated_options.stderr
@@ -1,5 +1,5 @@
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/report_warning_on_duplicated_options.rs:9:5
+  --> $DIR/report_warning_on_duplicated_options.rs:7:5
    |
 LL |     message = "first message",
    |     ------------------------- `message` is first declared here
@@ -10,7 +10,7 @@ LL |     message = "second message",
    = note: `#[warn(unknown_or_malformed_diagnostic_attributes)]` on by default
 
 warning: `label` is ignored due to previous definition of `label`
-  --> $DIR/report_warning_on_duplicated_options.rs:12:5
+  --> $DIR/report_warning_on_duplicated_options.rs:10:5
    |
 LL |     label = "first label",
    |     --------------------- `label` is first declared here
@@ -19,7 +19,7 @@ LL |     label = "second label",
    |     ^^^^^^^^^^^^^^^^^^^^^^ `label` is already declared here
 
 warning: `message` is ignored due to previous definition of `message`
-  --> $DIR/report_warning_on_duplicated_options.rs:9:5
+  --> $DIR/report_warning_on_duplicated_options.rs:7:5
    |
 LL |     message = "first message",
    |     ------------------------- `message` is first declared here
@@ -30,7 +30,7 @@ LL |     message = "second message",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 warning: `label` is ignored due to previous definition of `label`
-  --> $DIR/report_warning_on_duplicated_options.rs:12:5
+  --> $DIR/report_warning_on_duplicated_options.rs:10:5
    |
 LL |     label = "first label",
    |     --------------------- `label` is first declared here
@@ -41,7 +41,7 @@ LL |     label = "second label",
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0277]: first message
-  --> $DIR/report_warning_on_duplicated_options.rs:23:15
+  --> $DIR/report_warning_on_duplicated_options.rs:21:15
    |
 LL |     takes_foo(());
    |     --------- ^^ first label
@@ -52,12 +52,12 @@ LL |     takes_foo(());
    = note: custom note
    = note: second note
 help: this trait has no implementations, consider adding one
-  --> $DIR/report_warning_on_duplicated_options.rs:17:1
+  --> $DIR/report_warning_on_duplicated_options.rs:15:1
    |
 LL | trait Foo {}
    | ^^^^^^^^^
 note: required by a bound in `takes_foo`
-  --> $DIR/report_warning_on_duplicated_options.rs:20:22
+  --> $DIR/report_warning_on_duplicated_options.rs:18:22
    |
 LL | fn takes_foo(_: impl Foo) {}
    |                      ^^^ required by this bound in `takes_foo`
diff --git a/tests/ui/diagnostic_namespace/requires_path.rs b/tests/ui/diagnostic_namespace/requires_path.rs
index e8d6ca73ad0..4f3a1319caf 100644
--- a/tests/ui/diagnostic_namespace/requires_path.rs
+++ b/tests/ui/diagnostic_namespace/requires_path.rs
@@ -1,5 +1,3 @@
-#![feature(diagnostic_namespace)]
-
 #[diagnostic]
 //~^ERROR cannot find attribute `diagnostic` in this scope
 pub struct Bar;
diff --git a/tests/ui/diagnostic_namespace/requires_path.stderr b/tests/ui/diagnostic_namespace/requires_path.stderr
index 5d07d3a22d5..e02aacac8c1 100644
--- a/tests/ui/diagnostic_namespace/requires_path.stderr
+++ b/tests/ui/diagnostic_namespace/requires_path.stderr
@@ -1,5 +1,5 @@
 error: cannot find attribute `diagnostic` in this scope
-  --> $DIR/requires_path.rs:3:3
+  --> $DIR/requires_path.rs:1:3
    |
 LL | #[diagnostic]
    |   ^^^^^^^^^^
diff --git a/tests/ui/duplicate/duplicate-type-parameter.rs b/tests/ui/duplicate/duplicate-type-parameter.rs
index 2751b3c8dc0..c2064b423f1 100644
--- a/tests/ui/duplicate/duplicate-type-parameter.rs
+++ b/tests/ui/duplicate/duplicate-type-parameter.rs
@@ -23,7 +23,6 @@ trait Qux<T,T> {}
 
 impl<T,T> Qux<T,T> for Option<T> {}
 //~^ ERROR the name `T` is already used
-//~^^ ERROR the type parameter `T` is not constrained
 
 fn main() {
 }
diff --git a/tests/ui/duplicate/duplicate-type-parameter.stderr b/tests/ui/duplicate/duplicate-type-parameter.stderr
index 628f898d5c8..f23f2460a8a 100644
--- a/tests/ui/duplicate/duplicate-type-parameter.stderr
+++ b/tests/ui/duplicate/duplicate-type-parameter.stderr
@@ -54,13 +54,6 @@ LL | impl<T,T> Qux<T,T> for Option<T> {}
    |      |
    |      first use of `T`
 
-error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/duplicate-type-parameter.rs:24:8
-   |
-LL | impl<T,T> Qux<T,T> for Option<T> {}
-   |        ^ unconstrained type parameter
-
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0207, E0403.
-For more information about an error, try `rustc --explain E0207`.
+For more information about this error, try `rustc --explain E0403`.
diff --git a/tests/ui/error-codes/E0374.stderr b/tests/ui/error-codes/E0374.stderr
index 77f351b28ef..71eec4c16fd 100644
--- a/tests/ui/error-codes/E0374.stderr
+++ b/tests/ui/error-codes/E0374.stderr
@@ -1,3 +1,11 @@
+error[E0392]: type parameter `T` is never used
+  --> $DIR/E0374.rs:4:12
+   |
+LL | struct Foo<T: ?Sized> {
+   |            ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
 error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures
   --> $DIR/E0374.rs:8:1
    |
@@ -7,14 +15,6 @@ LL | |     where T: CoerceUnsized<U> {}
    |
    = note: expected a single field to be coerced, none found
 
-error[E0392]: type parameter `T` is never used
-  --> $DIR/E0374.rs:4:12
-   |
-LL | struct Foo<T: ?Sized> {
-   |            ^ unused type parameter
-   |
-   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
-
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0374, E0392.
diff --git a/tests/ui/error-codes/E0375.stderr b/tests/ui/error-codes/E0375.stderr
index d5340022d68..af720bd40e7 100644
--- a/tests/ui/error-codes/E0375.stderr
+++ b/tests/ui/error-codes/E0375.stderr
@@ -1,12 +1,3 @@
-error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions
-  --> $DIR/E0375.rs:10:12
-   |
-LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions
-   |
-   = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
-   = note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`)
-
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/E0375.rs:6:8
    |
@@ -32,6 +23,15 @@ help: the `Box` type always has a statically known size and allocates its conten
 LL |     b: Box<T>,
    |        ++++ +
 
+error[E0375]: implementing the trait `CoerceUnsized` requires multiple coercions
+  --> $DIR/E0375.rs:10:12
+   |
+LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^ requires multiple coercions
+   |
+   = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
+   = note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`)
+
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0277, E0375.
diff --git a/tests/ui/generic-associated-types/bugs/issue-87735.stderr b/tests/ui/generic-associated-types/bugs/issue-87735.stderr
index b80e3e798bd..d8005065238 100644
--- a/tests/ui/generic-associated-types/bugs/issue-87735.stderr
+++ b/tests/ui/generic-associated-types/bugs/issue-87735.stderr
@@ -4,6 +4,91 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self
 LL | impl<'b, T, U> AsRef2 for Foo<T>
    |             ^ unconstrained type parameter
 
-error: aborting due to 1 previous error
+error[E0309]: the parameter type `U` may not live long enough
+  --> $DIR/issue-87735.rs:34:21
+   |
+LL |   type Output<'a> = FooRef<'a, U> where Self: 'a;
+   |               --    ^^^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds...
+   |               |
+   |               the parameter type `U` must be valid for the lifetime `'a` as defined here...
+   |
+note: ...that is required by this bound
+  --> $DIR/issue-87735.rs:23:22
+   |
+LL | struct FooRef<'a, U>(&'a [U]);
+   |                      ^^^^^^^
+help: consider adding an explicit lifetime bound
+   |
+LL |   type Output<'a> = FooRef<'a, U> where Self: 'a, U: 'a;
+   |                                                 +++++++
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/issue-87735.rs:31:15
+   |
+LL | impl<'b, T, U> AsRef2 for Foo<T>
+   |      -- the parameter type `T` must be valid for the lifetime `'b` as defined here...
+...
+LL |     T: AsRef2<Output<'b> = &'b [U]>,
+   |               ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/issue-87735.rs:7:31
+   |
+LL |   type Output<'a> where Self: 'a;
+   |                               ^^
+help: consider adding an explicit lifetime bound
+   |
+LL |     T: AsRef2<Output<'b> = &'b [U]> + 'b,
+   |                                     ++++
+
+error[E0309]: the parameter type `T` may not live long enough
+  --> $DIR/issue-87735.rs:36:31
+   |
+LL | impl<'b, T, U> AsRef2 for Foo<T>
+   |      -- the parameter type `T` must be valid for the lifetime `'b` as defined here...
+...
+LL |   fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
+   |                               ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
+   |
+note: ...that is required by this bound
+  --> $DIR/issue-87735.rs:7:31
+   |
+LL |   type Output<'a> where Self: 'a;
+   |                               ^^
+help: consider adding an explicit lifetime bound
+   |
+LL |     T: AsRef2<Output<'b> = &'b [U]> + 'b,
+   |                                     ++++
+
+error: lifetime may not live long enough
+  --> $DIR/issue-87735.rs:37:5
+   |
+LL | impl<'b, T, U> AsRef2 for Foo<T>
+   |      -- lifetime `'b` defined here
+...
+LL |   fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
+   |              -- lifetime `'a` defined here
+LL |     FooRef(self.0.as_ref2())
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/issue-87735.rs:37:12
+   |
+LL | impl<'b, T, U> AsRef2 for Foo<T>
+   |      -- lifetime `'b` defined here
+...
+LL |   fn as_ref2<'a>(&'a self) -> Self::Output<'a> {
+   |              -- lifetime `'a` defined here
+LL |     FooRef(self.0.as_ref2())
+   |            ^^^^^^^^^^^^^^^^ argument requires that `'a` must outlive `'b`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+help: `'b` and `'a` must be the same: replace one with the other
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0309.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-88526.stderr b/tests/ui/generic-associated-types/bugs/issue-88526.stderr
index ba87ac9185d..5da3e3ff64a 100644
--- a/tests/ui/generic-associated-types/bugs/issue-88526.stderr
+++ b/tests/ui/generic-associated-types/bugs/issue-88526.stderr
@@ -4,6 +4,20 @@ error[E0207]: the type parameter `I` is not constrained by the impl trait, self
 LL | impl<'q, Q, I, F> A for TestB<Q, F>
    |             ^ unconstrained type parameter
 
-error: aborting due to 1 previous error
+error[E0309]: the parameter type `F` may not live long enough
+  --> $DIR/issue-88526.rs:16:18
+   |
+LL |     type I<'a> = &'a F;
+   |            --    ^^^^^ ...so that the reference type `&'a F` does not outlive the data it points at
+   |            |
+   |            the parameter type `F` must be valid for the lifetime `'a` as defined here...
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     type I<'a> = &'a F where F: 'a;
+   |                        +++++++++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0309.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/hashmap/hashmap-memory.rs b/tests/ui/hashmap/hashmap-memory.rs
index 0b1e09f5344..6db5d2e7bef 100644
--- a/tests/ui/hashmap/hashmap-memory.rs
+++ b/tests/ui/hashmap/hashmap-memory.rs
@@ -4,7 +4,7 @@
 #![allow(non_camel_case_types)]
 #![allow(dead_code)]
 #![allow(unused_mut)]
-//@ ignore-emscripten No support for threads
+//@ needs-threads
 
 /**
    A somewhat reduced test case to expose some Valgrind issues.
diff --git a/tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs b/tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs
new file mode 100644
index 00000000000..882497d1015
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-cycle-in-generics-of.rs
@@ -0,0 +1,18 @@
+//@ check-pass
+
+// Check that we don't hit a query cycle when:
+// 1. Computing generics_of, which requires...
+// 2. Calling resolve_bound_vars, which requires...
+// 3. Calling associated_items, which requires...
+// 4. Calling associated_type_for_impl_trait_in_trait, which requires...
+// 5. Computing generics_of, which cycles.
+
+pub trait Foo<'a> {
+    type Assoc;
+
+    fn demo<T>(other: T) -> impl Foo<'a, Assoc = Self::Assoc>
+    where
+        T: Foo<'a, Assoc = ()>;
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/issues/issue-87340.rs b/tests/ui/impl-trait/issues/issue-87340.rs
index 705a4addcb7..b1baaaa6ba5 100644
--- a/tests/ui/impl-trait/issues/issue-87340.rs
+++ b/tests/ui/impl-trait/issues/issue-87340.rs
@@ -9,6 +9,8 @@ impl<T> X for () {
     //~^ ERROR `T` is not constrained by the impl trait, self type, or predicates
     type I = impl Sized;
     fn f() -> Self::I {}
+    //~^ ERROR type annotations needed
+    //~| ERROR type annotations needed
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/issues/issue-87340.stderr b/tests/ui/impl-trait/issues/issue-87340.stderr
index 8513cb2881e..1be4087be42 100644
--- a/tests/ui/impl-trait/issues/issue-87340.stderr
+++ b/tests/ui/impl-trait/issues/issue-87340.stderr
@@ -4,6 +4,19 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
 LL | impl<T> X for () {
    |      ^ unconstrained type parameter
 
-error: aborting due to 1 previous error
+error[E0282]: type annotations needed
+  --> $DIR/issue-87340.rs:11:23
+   |
+LL |     fn f() -> Self::I {}
+   |                       ^^ cannot infer type for type parameter `T`
+
+error[E0282]: type annotations needed
+  --> $DIR/issue-87340.rs:11:15
+   |
+LL |     fn f() -> Self::I {}
+   |               ^^^^^^^ cannot infer type for type parameter `T`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0282.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index c4bdd484fdb..e82f33ad6bc 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -361,14 +361,6 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = 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 #36887 <https://github.com/rust-lang/rust/issues/36887>
 
-error[E0118]: no nominal type found for inherent implementation
-  --> $DIR/where-allowed.rs:239:1
-   |
-LL | impl <T = impl Debug> T {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
-   |
-   = note: either implement a trait on it or create a newtype to wrap it instead
-
 error[E0283]: type annotations needed
   --> $DIR/where-allowed.rs:46:57
    |
@@ -389,6 +381,14 @@ LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { pani
            - impl<Args, F, A> Fn<Args> for Box<F, A>
              where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
 
+error[E0118]: no nominal type found for inherent implementation
+  --> $DIR/where-allowed.rs:239:1
+   |
+LL | impl <T = impl Debug> T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
+   |
+   = note: either implement a trait on it or create a newtype to wrap it instead
+
 error[E0599]: no function or associated item named `into_vec` found for slice `[_]` in the current scope
   --> $DIR/where-allowed.rs:81:5
    |
diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/impl-unused-tps.stderr
index 93215326c2f..af427cb5f3e 100644
--- a/tests/ui/impl-unused-tps.stderr
+++ b/tests/ui/impl-unused-tps.stderr
@@ -1,3 +1,25 @@
+error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
+  --> $DIR/impl-unused-tps.rs:27:1
+   |
+LL | impl<T> Foo<T> for [isize;0] {
+   | ---------------------------- first implementation here
+...
+LL | impl<T,U> Foo<T> for U {
+   | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
+
+error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`)
+note: required for `([isize; 0], _)` to implement `Bar`
+  --> $DIR/impl-unused-tps.rs:31:11
+   |
+LL | impl<T,U> Bar for T {
+   |      -    ^^^     ^
+   |      |
+   |      unsatisfied trait bound introduced here
+   = note: 126 redundant requirements hidden
+   = note: required for `([isize; 0], _)` to implement `Bar`
+
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
   --> $DIR/impl-unused-tps.rs:15:8
    |
@@ -28,28 +50,6 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self
 LL | impl<T,U,V> Foo<T> for T
    |          ^ unconstrained type parameter
 
-error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
-  --> $DIR/impl-unused-tps.rs:27:1
-   |
-LL | impl<T> Foo<T> for [isize;0] {
-   | ---------------------------- first implementation here
-...
-LL | impl<T,U> Foo<T> for U {
-   | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
-
-error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized`
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`)
-note: required for `([isize; 0], _)` to implement `Bar`
-  --> $DIR/impl-unused-tps.rs:31:11
-   |
-LL | impl<T,U> Bar for T {
-   |      -    ^^^     ^
-   |      |
-   |      unsatisfied trait bound introduced here
-   = note: 126 redundant requirements hidden
-   = note: required for `([isize; 0], _)` to implement `Bar`
-
 error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0119, E0207, E0275.
diff --git a/tests/ui/imports/auxiliary/aux-issue-121915.rs b/tests/ui/imports/auxiliary/aux-issue-121915.rs
new file mode 100644
index 00000000000..7f9f5bda79f
--- /dev/null
+++ b/tests/ui/imports/auxiliary/aux-issue-121915.rs
@@ -0,0 +1 @@
+pub fn item() {}
diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.rs b/tests/ui/imports/redundant-import-issue-121915-2015.rs
new file mode 100644
index 00000000000..d41d190bb58
--- /dev/null
+++ b/tests/ui/imports/redundant-import-issue-121915-2015.rs
@@ -0,0 +1,11 @@
+//@ compile-flags: --extern aux_issue_121915 --edition 2015
+//@ aux-build: aux-issue-121915.rs
+
+extern crate aux_issue_121915;
+
+#[deny(unused_imports)]
+fn main() {
+    use aux_issue_121915;
+    //~^ ERROR the item `aux_issue_121915` is imported redundantly
+    aux_issue_121915::item();
+}
diff --git a/tests/ui/imports/redundant-import-issue-121915-2015.stderr b/tests/ui/imports/redundant-import-issue-121915-2015.stderr
new file mode 100644
index 00000000000..174ed4fb96b
--- /dev/null
+++ b/tests/ui/imports/redundant-import-issue-121915-2015.stderr
@@ -0,0 +1,17 @@
+error: the item `aux_issue_121915` is imported redundantly
+  --> $DIR/redundant-import-issue-121915-2015.rs:8:9
+   |
+LL | extern crate aux_issue_121915;
+   | ------------------------------ the item `aux_issue_121915` is already imported here
+...
+LL |     use aux_issue_121915;
+   |         ^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/redundant-import-issue-121915-2015.rs:6:8
+   |
+LL | #[deny(unused_imports)]
+   |        ^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/imports/redundant-import-issue-121915.rs b/tests/ui/imports/redundant-import-issue-121915.rs
new file mode 100644
index 00000000000..237acc4af25
--- /dev/null
+++ b/tests/ui/imports/redundant-import-issue-121915.rs
@@ -0,0 +1,9 @@
+//@ compile-flags: --extern aux_issue_121915 --edition 2018
+//@ aux-build: aux-issue-121915.rs
+
+#[deny(unused_imports)]
+fn main() {
+    use aux_issue_121915;
+    //~^ ERROR the item `aux_issue_121915` is imported redundantly
+    aux_issue_121915::item();
+}
diff --git a/tests/ui/imports/redundant-import-issue-121915.stderr b/tests/ui/imports/redundant-import-issue-121915.stderr
new file mode 100644
index 00000000000..0047d7c3420
--- /dev/null
+++ b/tests/ui/imports/redundant-import-issue-121915.stderr
@@ -0,0 +1,14 @@
+error: the item `aux_issue_121915` is imported redundantly
+  --> $DIR/redundant-import-issue-121915.rs:6:9
+   |
+LL |     use aux_issue_121915;
+   |         ^^^^^^^^^^^^^^^^ the item `aux_issue_121915` is already defined by prelude
+   |
+note: the lint level is defined here
+  --> $DIR/redundant-import-issue-121915.rs:4:8
+   |
+LL | #[deny(unused_imports)]
+   |        ^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/imports/suggest-remove-issue-121315.rs b/tests/ui/imports/suggest-remove-issue-121315.rs
new file mode 100644
index 00000000000..63533480ec1
--- /dev/null
+++ b/tests/ui/imports/suggest-remove-issue-121315.rs
@@ -0,0 +1,40 @@
+//@ compile-flags: --edition 2021
+#![deny(unused_imports)]
+#![allow(dead_code)]
+
+fn test0() {
+    // Test remove FlatUnused
+    use std::convert::TryFrom;
+    //~^ ERROR the item `TryFrom` is imported redundantly
+    let _ = u32::try_from(5i32);
+}
+
+fn test1() {
+    // FIXME(yukang) Test remove NestedFullUnused
+    use std::convert::{TryFrom, TryInto};
+    //~^ ERROR the item `TryFrom` is imported redundantly
+    //~| ERROR the item `TryInto` is imported redundantly
+
+    let _ = u32::try_from(5i32);
+    let _a: i32 = u32::try_into(5u32).unwrap();
+}
+
+fn test2() {
+    // FIXME(yukang): Test remove both redundant and unused
+    use std::convert::{AsMut, Into};
+    //~^ ERROR unused import: `AsMut`
+    //~| ERROR the item `Into` is imported redundantly
+
+    let _a: u32 = (5u8).into();
+}
+
+fn test3() {
+    // Test remove NestedPartialUnused
+    use std::convert::{From, Infallible};
+    //~^ ERROR unused import: `From`
+
+    trait MyTrait {}
+    impl MyTrait for fn() -> Infallible {}
+}
+
+fn main() {}
diff --git a/tests/ui/imports/suggest-remove-issue-121315.stderr b/tests/ui/imports/suggest-remove-issue-121315.stderr
new file mode 100644
index 00000000000..dbd742f6c78
--- /dev/null
+++ b/tests/ui/imports/suggest-remove-issue-121315.stderr
@@ -0,0 +1,56 @@
+error: the item `TryFrom` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:7:9
+   |
+LL |     use std::convert::TryFrom;
+   |         ^^^^^^^^^^^^^^^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryFrom` is already defined here
+   |
+note: the lint level is defined here
+  --> $DIR/suggest-remove-issue-121315.rs:2:9
+   |
+LL | #![deny(unused_imports)]
+   |         ^^^^^^^^^^^^^^
+
+error: the item `TryFrom` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:14:24
+   |
+LL |     use std::convert::{TryFrom, TryInto};
+   |                        ^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryFrom` is already defined here
+
+error: the item `TryInto` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:14:33
+   |
+LL |     use std::convert::{TryFrom, TryInto};
+   |                                 ^^^^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `TryInto` is already defined here
+
+error: unused import: `AsMut`
+  --> $DIR/suggest-remove-issue-121315.rs:24:24
+   |
+LL |     use std::convert::{AsMut, Into};
+   |                        ^^^^^
+
+error: the item `Into` is imported redundantly
+  --> $DIR/suggest-remove-issue-121315.rs:24:31
+   |
+LL |     use std::convert::{AsMut, Into};
+   |                               ^^^^
+  --> $SRC_DIR/std/src/prelude/mod.rs:LL:COL
+   |
+   = note: the item `Into` is already defined here
+
+error: unused import: `From`
+  --> $DIR/suggest-remove-issue-121315.rs:33:24
+   |
+LL |     use std::convert::{From, Infallible};
+   |                        ^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/issues/issue-16560.rs b/tests/ui/issues/issue-16560.rs
index 37b536e644d..d9a7aa9101d 100644
--- a/tests/ui/issues/issue-16560.rs
+++ b/tests/ui/issues/issue-16560.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::mem;
diff --git a/tests/ui/issues/issue-21291.rs b/tests/ui/issues/issue-21291.rs
index 357d5520028..06f50ac6996 100644
--- a/tests/ui/issues/issue-21291.rs
+++ b/tests/ui/issues/issue-21291.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 // Regression test for unwrapping the result of `join`, issue #21291
 
diff --git a/tests/ui/issues/issue-22864-2.rs b/tests/ui/issues/issue-22864-2.rs
index 1b702f4f509..d98dbeda46b 100644
--- a/tests/ui/issues/issue-22864-2.rs
+++ b/tests/ui/issues/issue-22864-2.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 pub fn main() {
     let f = || || 0;
diff --git a/tests/ui/issues/issue-29861.rs b/tests/ui/issues/issue-29861.rs
index 58f8eb5362c..875c168185f 100644
--- a/tests/ui/issues/issue-29861.rs
+++ b/tests/ui/issues/issue-29861.rs
@@ -14,6 +14,7 @@ impl<'a, T: 'a> MakeRef2 for T {
 }
 
 fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") }
+//~^ ERROR temporary value dropped while borrowed
 
 fn main() {
     println!("{}", foo());
diff --git a/tests/ui/issues/issue-29861.stderr b/tests/ui/issues/issue-29861.stderr
index e7860c19eaa..a25cbf0515d 100644
--- a/tests/ui/issues/issue-29861.stderr
+++ b/tests/ui/issues/issue-29861.stderr
@@ -4,6 +4,18 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait,
 LL | impl<'a, T: 'a> MakeRef2 for T {
    |      ^^ unconstrained lifetime parameter
 
-error: aborting due to 1 previous error
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/issue-29861.rs:16:43
+   |
+LL | fn foo() -> <String as MakeRef2>::Ref2 { &String::from("foo") }
+   |                                           ^^^^^^^^^^^^^^^^^^^ -- borrow later used here
+   |                                           |                   |
+   |                                           |                   temporary value is freed at the end of this statement
+   |                                           creates a temporary value which is freed while still in use
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0716.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/issues/issue-33941.rs b/tests/ui/issues/issue-33941.rs
index 0ad7cbe8efc..7b5be30834b 100644
--- a/tests/ui/issues/issue-33941.rs
+++ b/tests/ui/issues/issue-33941.rs
@@ -5,5 +5,4 @@ use std::collections::HashMap;
 fn main() {
     for _ in HashMap::new().iter().cloned() {} //~ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
     //~^ ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
-    //~| ERROR expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
 }
diff --git a/tests/ui/issues/issue-33941.stderr b/tests/ui/issues/issue-33941.stderr
index e7f4a4fa004..f1b6b6ba17e 100644
--- a/tests/ui/issues/issue-33941.stderr
+++ b/tests/ui/issues/issue-33941.stderr
@@ -27,16 +27,6 @@ LL |     for _ in HashMap::new().iter().cloned() {}
    = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
    = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `IntoIterator`
 
-error[E0271]: expected `Iter<'_, _, _>` to be an iterator that yields `&_`, but it yields `(&_, &_)`
-  --> $DIR/issue-33941.rs:6:14
-   |
-LL |     for _ in HashMap::new().iter().cloned() {}
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `(&_, &_)`, found `&_`
-   |
-   = note:  expected tuple `(&_, &_)`
-           found reference `&_`
-   = note: required for `Cloned<std::collections::hash_map::Iter<'_, _, _>>` to implement `Iterator`
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/issues/issue-37131.stderr b/tests/ui/issues/issue-37131.stderr
index 9ecae3e7a2b..588696f3541 100644
--- a/tests/ui/issues/issue-37131.stderr
+++ b/tests/ui/issues/issue-37131.stderr
@@ -4,8 +4,6 @@ error[E0463]: can't find crate for `std`
    = help: consider downloading the target with `rustup target add thumbv6m-none-eabi`
    = help: consider building the standard library from source with `cargo build -Zbuild-std`
 
-error: requires `sized` lang_item
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0463`.
diff --git a/tests/ui/issues/issue-49851/compiler-builtins-error.rs b/tests/ui/issues/issue-49851/compiler-builtins-error.rs
index 3b62cc73f93..db45d040f79 100644
--- a/tests/ui/issues/issue-49851/compiler-builtins-error.rs
+++ b/tests/ui/issues/issue-49851/compiler-builtins-error.rs
@@ -1,5 +1,4 @@
 //~ ERROR can't find crate for `core`
-//~^ ERROR can't find crate for `compiler_builtins`
 
 //@ compile-flags: --target thumbv7em-none-eabihf
 //@ needs-llvm-components: arm
@@ -8,6 +7,5 @@
 #![no_std]
 
 extern crate cortex_m;
-//~^ ERROR can't find crate for `cortex_m`
 
 fn main() {}
diff --git a/tests/ui/issues/issue-49851/compiler-builtins-error.stderr b/tests/ui/issues/issue-49851/compiler-builtins-error.stderr
index fcfa2bf119c..1cd65a1b68c 100644
--- a/tests/ui/issues/issue-49851/compiler-builtins-error.stderr
+++ b/tests/ui/issues/issue-49851/compiler-builtins-error.stderr
@@ -4,16 +4,6 @@ error[E0463]: can't find crate for `core`
    = help: consider downloading the target with `rustup target add thumbv7em-none-eabihf`
    = help: consider building the standard library from source with `cargo build -Zbuild-std`
 
-error[E0463]: can't find crate for `compiler_builtins`
-
-error[E0463]: can't find crate for `cortex_m`
-  --> $DIR/compiler-builtins-error.rs:10:1
-   |
-LL | extern crate cortex_m;
-   | ^^^^^^^^^^^^^^^^^^^^^^ can't find crate
-
-error: requires `sized` lang_item
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0463`.
diff --git a/tests/ui/issues/issue-59020.rs b/tests/ui/issues/issue-59020.rs
index 5692afe811e..2a34ba52b88 100644
--- a/tests/ui/issues/issue-59020.rs
+++ b/tests/ui/issues/issue-59020.rs
@@ -1,6 +1,6 @@
 //@ edition:2018
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::time::Duration;
diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs
index eceefa719ec..7bc91ef426b 100644
--- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs
+++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.rs
@@ -3,6 +3,6 @@
 
 impl<T> Loop<T> {} //~ ERROR the type parameter `T` is not constrained
 
-type Loop<T> = Loop<T>;
+type Loop<T> = Loop<T>; //~ ERROR overflow
 
 fn main() {}
diff --git a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr
index b65c84226ce..bcffa02ddd4 100644
--- a/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr
+++ b/tests/ui/lazy-type-alias/unconstrained-params-in-impl-due-to-overflow.stderr
@@ -4,6 +4,15 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
 LL | impl<T> Loop<T> {}
    |      ^ unconstrained type parameter
 
-error: aborting due to 1 previous error
+error[E0275]: overflow normalizing the type alias `Loop<T>`
+  --> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:16
+   |
+LL | type Loop<T> = Loop<T>;
+   |                ^^^^^^^
+   |
+   = note: in case this is a recursive type alias, consider using a struct, enum, or union instead
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0275.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr b/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr
index 667bb3ec130..93015bb2bac 100644
--- a/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr
+++ b/tests/ui/linkage-attr/common-linkage-non-zero-init.stderr
@@ -1,3 +1,3 @@
 'common' global must have a zero initializer!
 ptr @TEST
-LLVM ERROR: Broken module found, compilation aborted!
+rustc-LLVM ERROR: Broken module found, compilation aborted!
diff --git a/tests/ui/lint/non_local_definitions.rs b/tests/ui/lint/non_local_definitions.rs
index c9aaa049346..bbcc8189871 100644
--- a/tests/ui/lint/non_local_definitions.rs
+++ b/tests/ui/lint/non_local_definitions.rs
@@ -4,6 +4,7 @@
 //@ rustc-env:CARGO=/usr/bin/cargo
 
 #![feature(inline_const)]
+#![warn(non_local_definitions)]
 
 extern crate non_local_macro;
 
diff --git a/tests/ui/lint/non_local_definitions.stderr b/tests/ui/lint/non_local_definitions.stderr
index f9f29ec63a8..b9583ae983f 100644
--- a/tests/ui/lint/non_local_definitions.stderr
+++ b/tests/ui/lint/non_local_definitions.stderr
@@ -1,5 +1,5 @@
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:36:5
+  --> $DIR/non_local_definitions.rs:37:5
    |
 LL | const Z: () = {
    |       - help: use a const-anon item to suppress this lint: `_`
@@ -11,10 +11,14 @@ LL |     impl Uto for &Test {}
    = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
-   = note: `#[warn(non_local_definitions)]` on by default
+note: the lint level is defined here
+  --> $DIR/non_local_definitions.rs:7:9
+   |
+LL | #![warn(non_local_definitions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:46:5
+  --> $DIR/non_local_definitions.rs:47:5
    |
 LL |     impl Uto for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +29,7 @@ LL |     impl Uto for *mut Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:54:9
+  --> $DIR/non_local_definitions.rs:55:9
    |
 LL |         impl Uto for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +40,7 @@ LL |         impl Uto for Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:63:5
+  --> $DIR/non_local_definitions.rs:64:5
    |
 LL |     impl Uto2 for Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -47,7 +51,7 @@ LL |     impl Uto2 for Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:71:5
+  --> $DIR/non_local_definitions.rs:72:5
    |
 LL |     impl Uto3 for Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -58,7 +62,7 @@ LL |     impl Uto3 for Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:75:5
+  --> $DIR/non_local_definitions.rs:76:5
    |
 LL |     macro_rules! m0 { () => { } };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,7 +73,7 @@ LL |     macro_rules! m0 { () => { } };
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:87:5
+  --> $DIR/non_local_definitions.rs:88:5
    |
 LL |     macro_rules! m { () => { } };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +84,7 @@ LL |     macro_rules! m { () => { } };
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:90:5
+  --> $DIR/non_local_definitions.rs:91:5
    |
 LL | /     impl Test {
 LL | |
@@ -94,7 +98,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:96:9
+  --> $DIR/non_local_definitions.rs:97:9
    |
 LL | /         impl Test {
 LL | |
@@ -108,7 +112,7 @@ LL | |         }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:105:9
+  --> $DIR/non_local_definitions.rs:106:9
    |
 LL | /         impl Test {
 LL | |
@@ -122,7 +126,7 @@ LL | |         }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:114:9
+  --> $DIR/non_local_definitions.rs:115:9
    |
 LL | /         impl Test {
 LL | |
@@ -136,7 +140,7 @@ LL | |         }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:122:5
+  --> $DIR/non_local_definitions.rs:123:5
    |
 LL | /     impl Display for Test {
 LL | |
@@ -152,7 +156,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:129:5
+  --> $DIR/non_local_definitions.rs:130:5
    |
 LL |     impl dyn Uto5 {}
    |     ^^^^^^^^^^^^^^^^
@@ -163,7 +167,7 @@ LL |     impl dyn Uto5 {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:132:5
+  --> $DIR/non_local_definitions.rs:133:5
    |
 LL |     impl<T: Uto5> Uto5 for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -174,7 +178,7 @@ LL |     impl<T: Uto5> Uto5 for Vec<T> { }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:135:5
+  --> $DIR/non_local_definitions.rs:136:5
    |
 LL |     impl Uto5 for &dyn Uto5 {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -185,7 +189,7 @@ LL |     impl Uto5 for &dyn Uto5 {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:138:5
+  --> $DIR/non_local_definitions.rs:139:5
    |
 LL |     impl Uto5 for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -196,7 +200,7 @@ LL |     impl Uto5 for *mut Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:141:5
+  --> $DIR/non_local_definitions.rs:142:5
    |
 LL |     impl Uto5 for *mut [Test] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -207,7 +211,7 @@ LL |     impl Uto5 for *mut [Test] {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:144:5
+  --> $DIR/non_local_definitions.rs:145:5
    |
 LL |     impl Uto5 for [Test; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -218,7 +222,7 @@ LL |     impl Uto5 for [Test; 8] {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:147:5
+  --> $DIR/non_local_definitions.rs:148:5
    |
 LL |     impl Uto5 for (Test,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -229,7 +233,7 @@ LL |     impl Uto5 for (Test,) {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:150:5
+  --> $DIR/non_local_definitions.rs:151:5
    |
 LL |     impl Uto5 for fn(Test) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -240,7 +244,7 @@ LL |     impl Uto5 for fn(Test) -> () {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:153:5
+  --> $DIR/non_local_definitions.rs:154:5
    |
 LL |     impl Uto5 for fn() -> Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -251,7 +255,7 @@ LL |     impl Uto5 for fn() -> Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:157:9
+  --> $DIR/non_local_definitions.rs:158:9
    |
 LL |         impl Uto5 for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^
@@ -262,7 +266,7 @@ LL |         impl Uto5 for Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:164:9
+  --> $DIR/non_local_definitions.rs:165:9
    |
 LL |         impl Uto5 for &Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^^
@@ -273,7 +277,7 @@ LL |         impl Uto5 for &Test {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:171:9
+  --> $DIR/non_local_definitions.rs:172:9
    |
 LL |         impl Uto5 for &(Test,) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -284,7 +288,7 @@ LL |         impl Uto5 for &(Test,) {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:178:9
+  --> $DIR/non_local_definitions.rs:179:9
    |
 LL |         impl Uto5 for &(Test,Test) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -295,7 +299,7 @@ LL |         impl Uto5 for &(Test,Test) {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:186:5
+  --> $DIR/non_local_definitions.rs:187:5
    |
 LL |     impl Uto5 for *mut InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -306,7 +310,7 @@ LL |     impl Uto5 for *mut InsideMain {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:188:5
+  --> $DIR/non_local_definitions.rs:189:5
    |
 LL |     impl Uto5 for *mut [InsideMain] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -317,7 +321,7 @@ LL |     impl Uto5 for *mut [InsideMain] {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:190:5
+  --> $DIR/non_local_definitions.rs:191:5
    |
 LL |     impl Uto5 for [InsideMain; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -328,7 +332,7 @@ LL |     impl Uto5 for [InsideMain; 8] {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:192:5
+  --> $DIR/non_local_definitions.rs:193:5
    |
 LL |     impl Uto5 for (InsideMain,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -339,7 +343,7 @@ LL |     impl Uto5 for (InsideMain,) {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:194:5
+  --> $DIR/non_local_definitions.rs:195:5
    |
 LL |     impl Uto5 for fn(InsideMain) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,7 +354,7 @@ LL |     impl Uto5 for fn(InsideMain) -> () {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:196:5
+  --> $DIR/non_local_definitions.rs:197:5
    |
 LL |     impl Uto5 for fn() -> InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -361,7 +365,7 @@ LL |     impl Uto5 for fn() -> InsideMain {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:210:9
+  --> $DIR/non_local_definitions.rs:211:9
    |
 LL | /         impl Display for InsideMain {
 LL | |
@@ -377,7 +381,7 @@ LL | |         }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:217:9
+  --> $DIR/non_local_definitions.rs:218:9
    |
 LL | /         impl InsideMain {
 LL | |
@@ -394,7 +398,7 @@ LL | |         }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:221:17
+  --> $DIR/non_local_definitions.rs:222:17
    |
 LL |                 macro_rules! m2 { () => { } };
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -405,7 +409,7 @@ LL |                 macro_rules! m2 { () => { } };
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:231:5
+  --> $DIR/non_local_definitions.rs:232:5
    |
 LL |     impl<T: Uto6> Uto3 for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -416,7 +420,7 @@ LL |     impl<T: Uto6> Uto3 for Vec<T> { }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:240:5
+  --> $DIR/non_local_definitions.rs:241:5
    |
 LL |     impl Uto7 for Test where Local: std::any::Any {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -427,7 +431,7 @@ LL |     impl Uto7 for Test where Local: std::any::Any {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:243:5
+  --> $DIR/non_local_definitions.rs:244:5
    |
 LL |     impl<T> Uto8 for T {}
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -438,7 +442,7 @@ LL |     impl<T> Uto8 for T {}
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:252:5
+  --> $DIR/non_local_definitions.rs:253:5
    |
 LL | /     impl Default for UwU<OwO> {
 LL | |
@@ -454,7 +458,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:263:5
+  --> $DIR/non_local_definitions.rs:264:5
    |
 LL | /     impl From<Cat> for () {
 LL | |
@@ -470,7 +474,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:272:5
+  --> $DIR/non_local_definitions.rs:273:5
    |
 LL | /     impl AsRef<Cat> for () {
 LL | |
@@ -484,7 +488,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:283:5
+  --> $DIR/non_local_definitions.rs:284:5
    |
 LL | /     impl PartialEq<B> for G {
 LL | |
@@ -500,7 +504,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:300:5
+  --> $DIR/non_local_definitions.rs:301:5
    |
 LL | /     impl PartialEq<Dog> for &Dog {
 LL | |
@@ -516,7 +520,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:307:5
+  --> $DIR/non_local_definitions.rs:308:5
    |
 LL | /     impl PartialEq<()> for Dog {
 LL | |
@@ -532,7 +536,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:314:5
+  --> $DIR/non_local_definitions.rs:315:5
    |
 LL | /     impl PartialEq<()> for &Dog {
 LL | |
@@ -548,7 +552,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:321:5
+  --> $DIR/non_local_definitions.rs:322:5
    |
 LL | /     impl PartialEq<Dog> for () {
 LL | |
@@ -564,7 +568,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:343:5
+  --> $DIR/non_local_definitions.rs:344:5
    |
 LL | /     impl From<Wrap<Wrap<Lion>>> for () {
 LL | |
@@ -580,7 +584,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:350:5
+  --> $DIR/non_local_definitions.rs:351:5
    |
 LL | /     impl From<()> for Wrap<Lion> {
 LL | |
@@ -596,7 +600,7 @@ LL | |     }
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:363:13
+  --> $DIR/non_local_definitions.rs:364:13
    |
 LL |             impl MacroTrait for OutsideStruct {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -611,7 +615,7 @@ LL | m!();
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:373:1
+  --> $DIR/non_local_definitions.rs:374:1
    |
 LL | non_local_macro::non_local_impl!(CargoUpdate);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -624,7 +628,7 @@ LL | non_local_macro::non_local_impl!(CargoUpdate);
    = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:376:1
+  --> $DIR/non_local_definitions.rs:377:1
    |
 LL | non_local_macro::non_local_macro_rules!(my_macro);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/logging-only-prints-once.rs b/tests/ui/logging-only-prints-once.rs
index 75ef0a274ee..5377d5eeae2 100644
--- a/tests/ui/logging-only-prints-once.rs
+++ b/tests/ui/logging-only-prints-once.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 //@ ignore-windows
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::cell::Cell;
 use std::fmt;
diff --git a/tests/ui/lto/lto-still-runs-thread-dtors.rs b/tests/ui/lto/lto-still-runs-thread-dtors.rs
index a93d7cf35cc..504923a93c2 100644
--- a/tests/ui/lto/lto-still-runs-thread-dtors.rs
+++ b/tests/ui/lto/lto-still-runs-thread-dtors.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 //@ compile-flags: -C lto
 //@ no-prefer-dynamic
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/macros/macro-with-braces-in-expr-position.rs b/tests/ui/macros/macro-with-braces-in-expr-position.rs
index febfa7241f2..4607349e963 100644
--- a/tests/ui/macros/macro-with-braces-in-expr-position.rs
+++ b/tests/ui/macros/macro-with-braces-in-expr-position.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr b/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr
index 92a54cff7f5..ab86df9c8a5 100644
--- a/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr
+++ b/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr
@@ -1,15 +1,3 @@
-error[E0715]: impls for marker traits cannot contain items
-  --> $DIR/override-item-on-marker-trait.rs:12:1
-   |
-LL | impl Marker for OverrideConst {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0715]: impls for marker traits cannot contain items
-  --> $DIR/override-item-on-marker-trait.rs:18:1
-   |
-LL | impl Marker for OverrideFn {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error[E0714]: marker traits cannot have associated items
   --> $DIR/override-item-on-marker-trait.rs:5:5
    |
@@ -22,6 +10,18 @@ error[E0714]: marker traits cannot have associated items
 LL |     fn do_something() {}
    |     ^^^^^^^^^^^^^^^^^
 
+error[E0715]: impls for marker traits cannot contain items
+  --> $DIR/override-item-on-marker-trait.rs:12:1
+   |
+LL | impl Marker for OverrideConst {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0715]: impls for marker traits cannot contain items
+  --> $DIR/override-item-on-marker-trait.rs:18:1
+   |
+LL | impl Marker for OverrideFn {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0714, E0715.
diff --git a/tests/ui/moves/moves-based-on-type-capture-clause.rs b/tests/ui/moves/moves-based-on-type-capture-clause.rs
index baf52ffb515..46759f66468 100644
--- a/tests/ui/moves/moves-based-on-type-capture-clause.rs
+++ b/tests/ui/moves/moves-based-on-type-capture-clause.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/panics/default-backtrace-ice.stderr b/tests/ui/panics/default-backtrace-ice.stderr
index 9d27cb22ae9..82b61e43f44 100644
--- a/tests/ui/panics/default-backtrace-ice.stderr
+++ b/tests/ui/panics/default-backtrace-ice.stderr
@@ -21,5 +21,5 @@ error: the compiler unexpectedly panicked. this is a bug.
 
 
 query stack during panic:
-#0 [resolver_for_lowering] getting the resolver for lowering
+#0 [resolver_for_lowering_raw] getting the resolver for lowering
 end of query stack
diff --git a/tests/ui/panics/panic-handler-chain.rs b/tests/ui/panics/panic-handler-chain.rs
index eb23849f3ac..fea71ad9ec4 100644
--- a/tests/ui/panics/panic-handler-chain.rs
+++ b/tests/ui/panics/panic-handler-chain.rs
@@ -1,9 +1,8 @@
 //@ run-pass
 //@ needs-unwind
+//@ needs-threads
 #![allow(stable_features)]
 
-//@ ignore-emscripten no threads support
-
 #![feature(std_panic)]
 
 use std::sync::atomic::{AtomicUsize, Ordering};
diff --git a/tests/ui/panics/panic-task-name-none.rs b/tests/ui/panics/panic-task-name-none.rs
index 7eb974bde4c..8695771ff5e 100644
--- a/tests/ui/panics/panic-task-name-none.rs
+++ b/tests/ui/panics/panic-task-name-none.rs
@@ -1,7 +1,7 @@
 //@ run-fail
 //@ error-pattern:thread '<unnamed>' panicked
 //@ error-pattern:test
-//@ ignore-emscripten Needs threads
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/panics/panic-task-name-owned.rs b/tests/ui/panics/panic-task-name-owned.rs
index 9a680676dc0..42ae33b5d35 100644
--- a/tests/ui/panics/panic-task-name-owned.rs
+++ b/tests/ui/panics/panic-task-name-owned.rs
@@ -1,7 +1,7 @@
 //@ run-fail
 //@ error-pattern:thread 'owned name' panicked
 //@ error-pattern:test
-//@ ignore-emscripten Needs threads.
+//@ needs-threads
 
 use std::thread::Builder;
 
diff --git a/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr
index 1c71cdacd89..29b0b25a564 100644
--- a/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr
+++ b/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr
@@ -82,15 +82,6 @@ LL |     type W where Self: Eq;
    = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0592]: duplicate definitions with name `W`
-  --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5
-   |
-LL |     type W: Ord where Self: Eq;
-   |     ------ other definition for `W`
-...
-LL |     type W where Self: Eq;
-   |     ^^^^^^ duplicate definitions for `W`
-
 error[E0277]: the trait bound `X: Eq` is not satisfied
   --> $DIR/impl-item-type-no-body-semantic-fail.rs:13:23
    |
@@ -119,6 +110,15 @@ LL + #[derive(Eq)]
 LL | struct X;
    |
 
+error[E0592]: duplicate definitions with name `W`
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5
+   |
+LL |     type W: Ord where Self: Eq;
+   |     ------ other definition for `W`
+...
+LL |     type W where Self: Eq;
+   |     ^^^^^^ duplicate definitions for `W`
+
 error: aborting due to 13 previous errors
 
 Some errors have detailed explanations: E0277, E0592, E0658.
diff --git a/tests/ui/parser/impls-nested-within-anon-consts-semantic.rs b/tests/ui/parser/impls-nested-within-anon-consts-semantic.rs
new file mode 100644
index 00000000000..36a7825cec8
--- /dev/null
+++ b/tests/ui/parser/impls-nested-within-anon-consts-semantic.rs
@@ -0,0 +1,35 @@
+// Regression test for issue #89342 and for part of #119924.
+//@ check-pass
+
+struct Expr<const N: u32>;
+
+trait Trait0 {
+    fn required(_: Expr<{
+        struct Type;
+
+        impl Type {
+            // This visibility qualifier used to get rejected.
+            pub fn perform() {}
+        }
+
+        0
+    }>);
+}
+
+trait Trait1 {}
+
+impl Trait1 for ()
+where
+    [(); {
+        struct Type;
+
+        impl Type {
+            // This visibility qualifier used to get rejected.
+            pub const STORE: Self = Self;
+        }
+
+        0
+    }]:
+{}
+
+fn main() {}
diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-0.rs b/tests/ui/parser/impls-nested-within-fns-semantic-0.rs
new file mode 100644
index 00000000000..107380d33c7
--- /dev/null
+++ b/tests/ui/parser/impls-nested-within-fns-semantic-0.rs
@@ -0,0 +1,15 @@
+// Regression test for #121607 and for part of issue #119924.
+//@ check-pass
+
+trait Trait {
+    fn provided() {
+        pub struct Type;
+
+        impl Type {
+            // This visibility qualifier used to get rejected.
+            pub fn perform() {}
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/parser/impls-nested-within-fns-semantic-1.rs b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs
new file mode 100644
index 00000000000..43530e41a66
--- /dev/null
+++ b/tests/ui/parser/impls-nested-within-fns-semantic-1.rs
@@ -0,0 +1,22 @@
+// Regression test for part of issue #119924.
+//@ check-pass
+
+#![feature(const_trait_impl, effects)]
+
+#[const_trait]
+trait Trait {
+    fn required();
+}
+
+impl const Trait for () {
+    fn required() {
+        pub struct Type;
+
+        impl Type {
+            // This visibility qualifier used to get rejected.
+            pub fn perform() {}
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs
index ed4de58cd23..521eb6a818b 100644
--- a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs
+++ b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.rs
@@ -1,3 +1,10 @@
+#![allow(unused)]
+
+fn test_122112() {
+    // Make sure we don't ICE if parsing in recovery fails
+    let _: std::env::temp_dir().join(&self, push: Box<usize>);  //~ ERROR expected one of
+}
+
 fn main() {
     let _: std::env::temp_dir().join("foo"); //~ ERROR expected one of
 }
diff --git a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr
index d03f3ae0283..15c27bb9451 100644
--- a/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr
+++ b/tests/ui/parser/recover/recover-colon-instead-of-eq-in-local.stderr
@@ -1,5 +1,13 @@
 error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
-  --> $DIR/recover-colon-instead-of-eq-in-local.rs:2:32
+  --> $DIR/recover-colon-instead-of-eq-in-local.rs:5:32
+   |
+LL |     let _: std::env::temp_dir().join(&self, push: Box<usize>);
+   |          -                     ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
+   |          |
+   |          while parsing the type for `_`
+
+error: expected one of `!`, `+`, `->`, `::`, `;`, or `=`, found `.`
+  --> $DIR/recover-colon-instead-of-eq-in-local.rs:9:32
    |
 LL |     let _: std::env::temp_dir().join("foo");
    |          -                     ^ expected one of `!`, `+`, `->`, `::`, `;`, or `=`
@@ -7,5 +15,5 @@ LL |     let _: std::env::temp_dir().join("foo");
    |          while parsing the type for `_`
    |          help: use `=` if you meant to assign
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/proc-macro/nested-macro-rules.rs b/tests/ui/proc-macro/nested-macro-rules.rs
index 0dce3c408c2..2f0d85c4bbf 100644
--- a/tests/ui/proc-macro/nested-macro-rules.rs
+++ b/tests/ui/proc-macro/nested-macro-rules.rs
@@ -5,6 +5,8 @@
 //@ edition:2018
 
 #![no_std] // Don't load unnecessary hygiene information from std
+#![warn(non_local_definitions)]
+
 extern crate std;
 
 extern crate nested_macro_rules;
diff --git a/tests/ui/proc-macro/nested-macro-rules.stderr b/tests/ui/proc-macro/nested-macro-rules.stderr
index 111be882771..270e9161b03 100644
--- a/tests/ui/proc-macro/nested-macro-rules.stderr
+++ b/tests/ui/proc-macro/nested-macro-rules.stderr
@@ -12,7 +12,7 @@ LL | |             }
 LL | |         }
    | |_________^
    |
-  ::: $DIR/nested-macro-rules.rs:21:5
+  ::: $DIR/nested-macro-rules.rs:23:5
    |
 LL |       nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
    |       ---------------------------------------------------------------- in this macro invocation
@@ -21,7 +21,11 @@ LL |       nested_macro_rules::outer_macro!(SecondStruct, SecondAttrStruct);
    = note: a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
-   = note: `#[warn(non_local_definitions)]` on by default
+note: the lint level is defined here
+  --> $DIR/nested-macro-rules.rs:8:9
+   |
+LL | #![warn(non_local_definitions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/proc-macro/nested-macro-rules.stdout b/tests/ui/proc-macro/nested-macro-rules.stdout
index 829cfdc0c33..5b678554b9e 100644
--- a/tests/ui/proc-macro/nested-macro-rules.stdout
+++ b/tests/ui/proc-macro/nested-macro-rules.stdout
@@ -25,7 +25,7 @@ PRINT-BANG INPUT (DISPLAY): SecondStruct
 PRINT-BANG INPUT (DEBUG): TokenStream [
     Ident {
         ident: "SecondStruct",
-        span: $DIR/nested-macro-rules.rs:21:38: 21:50 (#15),
+        span: $DIR/nested-macro-rules.rs:23:38: 23:50 (#15),
     },
 ]
 PRINT-ATTR INPUT (DISPLAY): struct SecondAttrStruct {}
@@ -36,7 +36,7 @@ PRINT-ATTR INPUT (DEBUG): TokenStream [
     },
     Ident {
         ident: "SecondAttrStruct",
-        span: $DIR/nested-macro-rules.rs:21:52: 21:68 (#15),
+        span: $DIR/nested-macro-rules.rs:23:52: 23:68 (#15),
     },
     Group {
         delimiter: Brace,
diff --git a/tests/ui/process-termination/process-termination-blocking-io.rs b/tests/ui/process-termination/process-termination-blocking-io.rs
index c21edff25cf..f725a958941 100644
--- a/tests/ui/process-termination/process-termination-blocking-io.rs
+++ b/tests/ui/process-termination/process-termination-blocking-io.rs
@@ -2,7 +2,7 @@
 // https://github.com/fortanix/rust-sgx/issues/109
 
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::{net::TcpListener, sync::mpsc, thread};
 
diff --git a/tests/ui/process-termination/process-termination-simple.rs b/tests/ui/process-termination/process-termination-simple.rs
index 63eb2c74706..8f5f185b7f9 100644
--- a/tests/ui/process-termination/process-termination-simple.rs
+++ b/tests/ui/process-termination/process-termination-simple.rs
@@ -1,7 +1,7 @@
 // program should terminate when std::process::exit is called from any thread
 
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::{process, thread};
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
index 8f374bc4d8f..9ca7b574b13 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr
@@ -37,7 +37,19 @@ error[E0207]: the const parameter `host` is not constrained by the impl trait, s
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
 
-error: aborting due to 5 previous errors
+error[E0308]: mismatched types
+  --> $DIR/derive-const-use.rs:16:14
+   |
+LL | #[derive_const(Default, PartialEq)]
+   |                         --------- in this derive macro expansion
+LL | pub struct S((), A);
+   |              ^^ expected `host`, found `true`
+   |
+   = note: expected constant `host`
+              found constant `true`
+   = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0207, E0635.
+Some errors have detailed explanations: E0207, E0308, E0635.
 For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs
index 97e89f96fe1..7bead45b35a 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.rs
@@ -8,6 +8,8 @@ impl const dyn T {
     //~^ ERROR inherent impls cannot be `const`
     //~| ERROR the const parameter `host` is not constrained by the impl trait, self type, or
     pub const fn new() -> std::sync::Mutex<dyn T> {}
+    //~^ ERROR mismatched types
+    //~| ERROR cannot be known at compilation time
 }
 
 fn main() {}
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr
index 11577d9ec1d..3ff1efb5988 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/span-bug-issue-121418.stderr
@@ -17,6 +17,29 @@ LL | impl const dyn T {
    = note: expressions using a const parameter must map each value to a distinct output value
    = note: proving the result of expressions other than the parameter are unique is not supported
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/span-bug-issue-121418.rs:10:27
+   |
+LL |     pub const fn new() -> std::sync::Mutex<dyn T> {}
+   |                  ---      ^^^^^^^^^^^^^^^^^^^^^^^ expected `Mutex<dyn T>`, found `()`
+   |                  |
+   |                  implicitly returns `()` as its body has no tail or `return` expression
+   |
+   = note: expected struct `Mutex<(dyn T + 'static)>`
+           found unit type `()`
+
+error[E0277]: the size for values of type `(dyn T + 'static)` cannot be known at compilation time
+  --> $DIR/span-bug-issue-121418.rs:10:27
+   |
+LL |     pub const fn new() -> std::sync::Mutex<dyn T> {}
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `Mutex<(dyn T + 'static)>`, the trait `Sized` is not implemented for `(dyn T + 'static)`, which is required by `Mutex<(dyn T + 'static)>: Sized`
+note: required because it appears within the type `Mutex<(dyn T + 'static)>`
+  --> $SRC_DIR/std/src/sync/mutex.rs:LL:COL
+   = note: the return type of a function must have a statically known size
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0277, E0308.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/structs-enums/ivec-tag.rs b/tests/ui/structs-enums/ivec-tag.rs
index 9185a0cbb6e..2a0b6dd1ed4 100644
--- a/tests/ui/structs-enums/ivec-tag.rs
+++ b/tests/ui/structs-enums/ivec-tag.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
diff --git a/tests/ui/test-attrs/test-filter-multiple.rs b/tests/ui/test-attrs/test-filter-multiple.rs
index 0347ce457ae..05fc022834a 100644
--- a/tests/ui/test-attrs/test-filter-multiple.rs
+++ b/tests/ui/test-attrs/test-filter-multiple.rs
@@ -3,7 +3,7 @@
 //@ run-flags: --test-threads=1 test1 test2
 //@ check-run-results
 //@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 #[test]
 fn test1() {}
diff --git a/tests/ui/test-attrs/test-type.rs b/tests/ui/test-attrs/test-type.rs
index 8f75ff309e0..7db7e31d01d 100644
--- a/tests/ui/test-attrs/test-type.rs
+++ b/tests/ui/test-attrs/test-type.rs
@@ -2,7 +2,7 @@
 //@ run-flags: --test-threads=1
 //@ check-run-results
 //@ normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
-//@ ignore-emscripten no threads support
+//@ needs-threads
 //@ run-pass
 
 #[test]
diff --git a/tests/ui/thread-local/tls.rs b/tests/ui/thread-local/tls.rs
index 17096319d23..fa6a722b291 100644
--- a/tests/ui/thread-local/tls.rs
+++ b/tests/ui/thread-local/tls.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 //@ compile-flags: -O
 //@ ignore-nto Doesn't work without emulated TLS enabled (in LLVM)
 
diff --git a/tests/ui/threads-sendsync/child-outlives-parent.rs b/tests/ui/threads-sendsync/child-outlives-parent.rs
index 2fb4a6f637a..213fd008cd3 100644
--- a/tests/ui/threads-sendsync/child-outlives-parent.rs
+++ b/tests/ui/threads-sendsync/child-outlives-parent.rs
@@ -2,7 +2,7 @@
 // Reported as issue #126, child leaks the string.
 
 //@ pretty-expanded FIXME #23616
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/clone-with-exterior.rs b/tests/ui/threads-sendsync/clone-with-exterior.rs
index 58529e4a788..67790367e27 100644
--- a/tests/ui/threads-sendsync/clone-with-exterior.rs
+++ b/tests/ui/threads-sendsync/clone-with-exterior.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/comm.rs b/tests/ui/threads-sendsync/comm.rs
index 589859e60a6..0c37fda8a39 100644
--- a/tests/ui/threads-sendsync/comm.rs
+++ b/tests/ui/threads-sendsync/comm.rs
@@ -1,13 +1,13 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
 
 pub fn main() {
     let (tx, rx) = channel();
-    let t = thread::spawn(move|| { child(&tx) });
+    let t = thread::spawn(move || { child(&tx) });
     let y = rx.recv().unwrap();
     println!("received");
     println!("{}", y);
diff --git a/tests/ui/threads-sendsync/eprint-on-tls-drop.rs b/tests/ui/threads-sendsync/eprint-on-tls-drop.rs
index 3ff9fb10f24..82abf21df3f 100644
--- a/tests/ui/threads-sendsync/eprint-on-tls-drop.rs
+++ b/tests/ui/threads-sendsync/eprint-on-tls-drop.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no processes
+//@ needs-threads
 //@ ignore-sgx no processes
 
 use std::cell::RefCell;
diff --git a/tests/ui/threads-sendsync/issue-24313.rs b/tests/ui/threads-sendsync/issue-24313.rs
index 17e027520c1..1ea862f1e7d 100644
--- a/tests/ui/threads-sendsync/issue-24313.rs
+++ b/tests/ui/threads-sendsync/issue-24313.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads
+//@ needs-threads
 //@ ignore-sgx no processes
 
 use std::thread;
diff --git a/tests/ui/threads-sendsync/issue-29488.rs b/tests/ui/threads-sendsync/issue-29488.rs
index c848e7b50bb..fbbd6b02a06 100644
--- a/tests/ui/threads-sendsync/issue-29488.rs
+++ b/tests/ui/threads-sendsync/issue-29488.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/issue-43733-2.rs b/tests/ui/threads-sendsync/issue-43733-2.rs
index 5a9ee015cb9..372ebf2cff9 100644
--- a/tests/ui/threads-sendsync/issue-43733-2.rs
+++ b/tests/ui/threads-sendsync/issue-43733-2.rs
@@ -1,4 +1,4 @@
-//@ ignore-wasm32
+//@ needs-threads
 //@ dont-check-compiler-stderr
 #![feature(cfg_target_thread_local, thread_local_internals)]
 
diff --git a/tests/ui/threads-sendsync/issue-43733.rs b/tests/ui/threads-sendsync/issue-43733.rs
index 12207f4e6aa..c90f60887cf 100644
--- a/tests/ui/threads-sendsync/issue-43733.rs
+++ b/tests/ui/threads-sendsync/issue-43733.rs
@@ -1,4 +1,4 @@
-//@ ignore-wasm32
+//@ needs-threads
 #![feature(thread_local)]
 #![feature(cfg_target_thread_local, thread_local_internals)]
 
diff --git a/tests/ui/threads-sendsync/issue-4446.rs b/tests/ui/threads-sendsync/issue-4446.rs
index b5e3a20ccde..aa2de51974b 100644
--- a/tests/ui/threads-sendsync/issue-4446.rs
+++ b/tests/ui/threads-sendsync/issue-4446.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::channel;
 use std::thread;
diff --git a/tests/ui/threads-sendsync/issue-4448.rs b/tests/ui/threads-sendsync/issue-4448.rs
index 0f3bf65c441..b8324a8c43f 100644
--- a/tests/ui/threads-sendsync/issue-4448.rs
+++ b/tests/ui/threads-sendsync/issue-4448.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::channel;
 use std::thread;
diff --git a/tests/ui/threads-sendsync/issue-8827.rs b/tests/ui/threads-sendsync/issue-8827.rs
index b7deef0f34d..fa07a4ebc7d 100644
--- a/tests/ui/threads-sendsync/issue-8827.rs
+++ b/tests/ui/threads-sendsync/issue-8827.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::{channel, Receiver};
diff --git a/tests/ui/threads-sendsync/issue-9396.rs b/tests/ui/threads-sendsync/issue-9396.rs
index 6228f4ba706..6b5907e5c1d 100644
--- a/tests/ui/threads-sendsync/issue-9396.rs
+++ b/tests/ui/threads-sendsync/issue-9396.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(deprecated)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::{TryRecvError, channel};
 use std::thread;
diff --git a/tests/ui/threads-sendsync/mpsc_stress.rs b/tests/ui/threads-sendsync/mpsc_stress.rs
index 68c40151281..f5354c60bfc 100644
--- a/tests/ui/threads-sendsync/mpsc_stress.rs
+++ b/tests/ui/threads-sendsync/mpsc_stress.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 //@ compile-flags:--test
-//@ ignore-emscripten
+//@ needs-threads
 
 use std::sync::mpsc::channel;
 use std::sync::mpsc::TryRecvError;
diff --git a/tests/ui/threads-sendsync/send-resource.rs b/tests/ui/threads-sendsync/send-resource.rs
index 32910c5f7d1..3e1532b3132 100644
--- a/tests/ui/threads-sendsync/send-resource.rs
+++ b/tests/ui/threads-sendsync/send-resource.rs
@@ -4,7 +4,7 @@
 #![allow(non_camel_case_types)]
 
 //@ pretty-expanded FIXME #23616
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::channel;
diff --git a/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs b/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs
index 5306d69a7d2..63cf3ff4049 100644
--- a/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs
+++ b/tests/ui/threads-sendsync/sendfn-spawn-with-fn-arg.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/spawn-fn.rs b/tests/ui/threads-sendsync/spawn-fn.rs
index 863c22f70d6..e4d83b53f3c 100644
--- a/tests/ui/threads-sendsync/spawn-fn.rs
+++ b/tests/ui/threads-sendsync/spawn-fn.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/spawn-types.rs b/tests/ui/threads-sendsync/spawn-types.rs
index 9c1b6550d9b..2a7a9e2f497 100644
--- a/tests/ui/threads-sendsync/spawn-types.rs
+++ b/tests/ui/threads-sendsync/spawn-types.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(non_camel_case_types)]
 
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 /*
   Make sure we can spawn tasks that take different types of
diff --git a/tests/ui/threads-sendsync/spawn.rs b/tests/ui/threads-sendsync/spawn.rs
index 2c06fc2837f..c7b344b9f75 100644
--- a/tests/ui/threads-sendsync/spawn.rs
+++ b/tests/ui/threads-sendsync/spawn.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/spawn2.rs b/tests/ui/threads-sendsync/spawn2.rs
index cfe907ea6d9..8278fec1885 100644
--- a/tests/ui/threads-sendsync/spawn2.rs
+++ b/tests/ui/threads-sendsync/spawn2.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/spawning-with-debug.rs b/tests/ui/threads-sendsync/spawning-with-debug.rs
index 58f1743527c..90a81c1e53b 100644
--- a/tests/ui/threads-sendsync/spawning-with-debug.rs
+++ b/tests/ui/threads-sendsync/spawning-with-debug.rs
@@ -3,7 +3,7 @@
 #![allow(unused_mut)]
 //@ ignore-windows
 //@ exec-env:RUST_LOG=debug
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 // regression test for issue #10405, make sure we don't call println! too soon.
 
diff --git a/tests/ui/threads-sendsync/task-comm-0.rs b/tests/ui/threads-sendsync/task-comm-0.rs
index 06ce739b8e5..50f2b591894 100644
--- a/tests/ui/threads-sendsync/task-comm-0.rs
+++ b/tests/ui/threads-sendsync/task-comm-0.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
diff --git a/tests/ui/threads-sendsync/task-comm-1.rs b/tests/ui/threads-sendsync/task-comm-1.rs
index 77ca940e947..41592bd916b 100644
--- a/tests/ui/threads-sendsync/task-comm-1.rs
+++ b/tests/ui/threads-sendsync/task-comm-1.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/task-comm-10.rs b/tests/ui/threads-sendsync/task-comm-10.rs
index 6f043b64a09..844652c0dde 100644
--- a/tests/ui/threads-sendsync/task-comm-10.rs
+++ b/tests/ui/threads-sendsync/task-comm-10.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(unused_mut)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
diff --git a/tests/ui/threads-sendsync/task-comm-11.rs b/tests/ui/threads-sendsync/task-comm-11.rs
index 51f13434435..199082fda96 100644
--- a/tests/ui/threads-sendsync/task-comm-11.rs
+++ b/tests/ui/threads-sendsync/task-comm-11.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(unused_must_use)]
 //@ pretty-expanded FIXME #23616
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
diff --git a/tests/ui/threads-sendsync/task-comm-12.rs b/tests/ui/threads-sendsync/task-comm-12.rs
index cb1fb774f10..7be7ec4c988 100644
--- a/tests/ui/threads-sendsync/task-comm-12.rs
+++ b/tests/ui/threads-sendsync/task-comm-12.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(unused_mut)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/task-comm-13.rs b/tests/ui/threads-sendsync/task-comm-13.rs
index 6b5384e3f08..414e6e0db76 100644
--- a/tests/ui/threads-sendsync/task-comm-13.rs
+++ b/tests/ui/threads-sendsync/task-comm-13.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_variables)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
diff --git a/tests/ui/threads-sendsync/task-comm-14.rs b/tests/ui/threads-sendsync/task-comm-14.rs
index 65cc750a7c3..54deb221294 100644
--- a/tests/ui/threads-sendsync/task-comm-14.rs
+++ b/tests/ui/threads-sendsync/task-comm-14.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_parens)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
diff --git a/tests/ui/threads-sendsync/task-comm-15.rs b/tests/ui/threads-sendsync/task-comm-15.rs
index 844a18b6158..f487bf3cc84 100644
--- a/tests/ui/threads-sendsync/task-comm-15.rs
+++ b/tests/ui/threads-sendsync/task-comm-15.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 //@ pretty-expanded FIXME #23616
 
 use std::sync::mpsc::{channel, Sender};
diff --git a/tests/ui/threads-sendsync/task-comm-17.rs b/tests/ui/threads-sendsync/task-comm-17.rs
index 14ef4dd3ede..687322d4dc9 100644
--- a/tests/ui/threads-sendsync/task-comm-17.rs
+++ b/tests/ui/threads-sendsync/task-comm-17.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 //@ pretty-expanded FIXME #23616
 
 // Issue #922
diff --git a/tests/ui/threads-sendsync/task-comm-3.rs b/tests/ui/threads-sendsync/task-comm-3.rs
index 1f2a6406d79..26f3eaf9dc6 100644
--- a/tests/ui/threads-sendsync/task-comm-3.rs
+++ b/tests/ui/threads-sendsync/task-comm-3.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
diff --git a/tests/ui/threads-sendsync/task-comm-7.rs b/tests/ui/threads-sendsync/task-comm-7.rs
index f6e77986e16..d9b322daa66 100644
--- a/tests/ui/threads-sendsync/task-comm-7.rs
+++ b/tests/ui/threads-sendsync/task-comm-7.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(unused_must_use)]
 #![allow(unused_assignments)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
diff --git a/tests/ui/threads-sendsync/task-comm-9.rs b/tests/ui/threads-sendsync/task-comm-9.rs
index f8fe680e5e0..3e617e4a40c 100644
--- a/tests/ui/threads-sendsync/task-comm-9.rs
+++ b/tests/ui/threads-sendsync/task-comm-9.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::{channel, Sender};
diff --git a/tests/ui/threads-sendsync/task-life-0.rs b/tests/ui/threads-sendsync/task-life-0.rs
index a4652197afc..d3eca5d371f 100644
--- a/tests/ui/threads-sendsync/task-life-0.rs
+++ b/tests/ui/threads-sendsync/task-life-0.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 //@ pretty-expanded FIXME #23616
 
 use std::thread;
diff --git a/tests/ui/threads-sendsync/task-spawn-barefn.rs b/tests/ui/threads-sendsync/task-spawn-barefn.rs
index 2c957878c95..a97e92206e2 100644
--- a/tests/ui/threads-sendsync/task-spawn-barefn.rs
+++ b/tests/ui/threads-sendsync/task-spawn-barefn.rs
@@ -1,6 +1,6 @@
 //@ run-fail
 //@ error-pattern:Ensure that the child thread runs by panicking
-//@ ignore-emscripten Needs threads.
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs b/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs
index 442955421d8..ea1c6a9b108 100644
--- a/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs
+++ b/tests/ui/threads-sendsync/task-spawn-move-and-copy.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 use std::sync::mpsc::channel;
diff --git a/tests/ui/threads-sendsync/task-stderr.rs b/tests/ui/threads-sendsync/task-stderr.rs
index 0f215a2b763..cad10c7a792 100644
--- a/tests/ui/threads-sendsync/task-stderr.rs
+++ b/tests/ui/threads-sendsync/task-stderr.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-//@ ignore-emscripten no threads support
+//@ needs-threads
 //@ needs-unwind
 
 #![feature(internal_output_capture)]
diff --git a/tests/ui/threads-sendsync/tcp-stress.rs b/tests/ui/threads-sendsync/tcp-stress.rs
index 488cab40140..429a4657314 100644
--- a/tests/ui/threads-sendsync/tcp-stress.rs
+++ b/tests/ui/threads-sendsync/tcp-stress.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 //@ ignore-android needs extra network permissions
-//@ ignore-emscripten no threads or sockets support
+//@ needs-threads
 //@ ignore-netbsd system ulimit (Too many open files)
 //@ ignore-openbsd system ulimit (Too many open files)
 
diff --git a/tests/ui/threads-sendsync/test-tasks-invalid-value.rs b/tests/ui/threads-sendsync/test-tasks-invalid-value.rs
index 4b38b9ce2c9..127086743ca 100644
--- a/tests/ui/threads-sendsync/test-tasks-invalid-value.rs
+++ b/tests/ui/threads-sendsync/test-tasks-invalid-value.rs
@@ -5,7 +5,7 @@
 //@ error-pattern:should be a positive integer
 //@ compile-flags: --test
 //@ exec-env:RUST_TEST_THREADS=foo
-//@ ignore-emscripten
+//@ needs-threads
 
 #[test]
 fn do_nothing() {}
diff --git a/tests/ui/threads-sendsync/threads.rs b/tests/ui/threads-sendsync/threads.rs
index 7b7e52abab4..f3ed7890364 100644
--- a/tests/ui/threads-sendsync/threads.rs
+++ b/tests/ui/threads-sendsync/threads.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(unused_must_use)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs b/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs
index 66fd6169db0..84176659412 100644
--- a/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs
+++ b/tests/ui/threads-sendsync/tls-dtors-are-run-in-a-static-binary.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 //@ no-prefer-dynamic
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 static mut HIT: bool = false;
 
diff --git a/tests/ui/threads-sendsync/tls-init-on-init.rs b/tests/ui/threads-sendsync/tls-init-on-init.rs
index ba5e4698e63..fd764669e7f 100644
--- a/tests/ui/threads-sendsync/tls-init-on-init.rs
+++ b/tests/ui/threads-sendsync/tls-init-on-init.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(stable_features)]
 
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 #![feature(thread_local_try_with)]
 
diff --git a/tests/ui/threads-sendsync/tls-try-with.rs b/tests/ui/threads-sendsync/tls-try-with.rs
index d9af1caf741..72cee219a0a 100644
--- a/tests/ui/threads-sendsync/tls-try-with.rs
+++ b/tests/ui/threads-sendsync/tls-try-with.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(stable_features)]
 
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 #![feature(thread_local_try_with)]
 
diff --git a/tests/ui/threads-sendsync/unwind-resource.rs b/tests/ui/threads-sendsync/unwind-resource.rs
index ea9e0c7514c..3b1ab57b46e 100644
--- a/tests/ui/threads-sendsync/unwind-resource.rs
+++ b/tests/ui/threads-sendsync/unwind-resource.rs
@@ -2,7 +2,7 @@
 //@ needs-unwind
 
 #![allow(non_camel_case_types)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::mpsc::{channel, Sender};
 use std::thread;
diff --git a/tests/ui/threads-sendsync/yield.rs b/tests/ui/threads-sendsync/yield.rs
index 4d89b10af95..99d14bd92ea 100644
--- a/tests/ui/threads-sendsync/yield.rs
+++ b/tests/ui/threads-sendsync/yield.rs
@@ -2,7 +2,7 @@
 
 #![allow(unused_must_use)]
 #![allow(unused_mut)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/threads-sendsync/yield1.rs b/tests/ui/threads-sendsync/yield1.rs
index b003a70f47e..c965d2fc303 100644
--- a/tests/ui/threads-sendsync/yield1.rs
+++ b/tests/ui/threads-sendsync/yield1.rs
@@ -2,7 +2,7 @@
 
 #![allow(unused_must_use)]
 #![allow(unused_mut)]
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::thread;
 
diff --git a/tests/ui/trait-bounds/super-assoc-mismatch.rs b/tests/ui/trait-bounds/super-assoc-mismatch.rs
new file mode 100644
index 00000000000..97dfec80e31
--- /dev/null
+++ b/tests/ui/trait-bounds/super-assoc-mismatch.rs
@@ -0,0 +1,60 @@
+trait Super {
+    type Assoc;
+}
+impl Super for () {
+    type Assoc = u8;
+}
+trait Sub: Super<Assoc = u16> {}
+
+trait BoundOnSelf: Sub {}
+impl BoundOnSelf for () {}
+//~^ ERROR the trait bound `(): Sub` is not satisfied
+
+trait BoundOnParam<T: Sub> {}
+impl BoundOnParam<()> for () {}
+//~^ ERROR the trait bound `(): Sub` is not satisfied
+
+trait BoundOnAssoc {
+    type Assoc: Sub;
+}
+impl BoundOnAssoc for () {
+    type Assoc = ();
+    //~^ ERROR the trait bound `(): Sub` is not satisfied
+}
+
+trait BoundOnGat where Self::Assoc<u8>: Sub {
+    type Assoc<T>;
+}
+impl BoundOnGat for u8 {
+    type Assoc<T> = ();
+    //~^ ERROR the trait bound `(): Sub` is not satisfied
+}
+
+fn trivial_bound() where (): Sub {}
+//~^ ERROR the trait bound `(): Sub` is not satisfied
+
+// The following is an edge case where the unsatisfied projection predicate
+// `<<u8 as MultiAssoc>::Assoc1<()> as SuperGeneric<u16>>::Assoc == <u8 as MultiAssoc>::Assoc2`
+// contains both associated types of `MultiAssoc`. To suppress the error about the unsatisfied
+// super projection, the error's span must be equal to the span of the unsatisfied trait error.
+trait SuperGeneric<T> {
+    type Assoc;
+}
+trait SubGeneric<T>: SuperGeneric<T, Assoc = T> {}
+trait MultiAssoc
+where
+    Self::Assoc1<()>: SubGeneric<Self::Assoc2>
+{
+    type Assoc1<T>;
+    type Assoc2;
+}
+impl SuperGeneric<u16> for () {
+    type Assoc = u8;
+}
+impl MultiAssoc for u8 {
+    type Assoc1<T> = ();
+    //~^ ERROR the trait bound `(): SubGeneric<u16>` is not satisfied
+    type Assoc2 = u16;
+}
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/super-assoc-mismatch.stderr b/tests/ui/trait-bounds/super-assoc-mismatch.stderr
new file mode 100644
index 00000000000..47535776348
--- /dev/null
+++ b/tests/ui/trait-bounds/super-assoc-mismatch.stderr
@@ -0,0 +1,105 @@
+error[E0277]: the trait bound `(): Sub` is not satisfied
+  --> $DIR/super-assoc-mismatch.rs:10:22
+   |
+LL | impl BoundOnSelf for () {}
+   |                      ^^ the trait `Sub` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/super-assoc-mismatch.rs:7:1
+   |
+LL | trait Sub: Super<Assoc = u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `BoundOnSelf`
+  --> $DIR/super-assoc-mismatch.rs:9:20
+   |
+LL | trait BoundOnSelf: Sub {}
+   |                    ^^^ required by this bound in `BoundOnSelf`
+
+error[E0277]: the trait bound `(): Sub` is not satisfied
+  --> $DIR/super-assoc-mismatch.rs:14:27
+   |
+LL | impl BoundOnParam<()> for () {}
+   |                           ^^ the trait `Sub` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/super-assoc-mismatch.rs:7:1
+   |
+LL | trait Sub: Super<Assoc = u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `BoundOnParam`
+  --> $DIR/super-assoc-mismatch.rs:13:23
+   |
+LL | trait BoundOnParam<T: Sub> {}
+   |                       ^^^ required by this bound in `BoundOnParam`
+
+error[E0277]: the trait bound `(): Sub` is not satisfied
+  --> $DIR/super-assoc-mismatch.rs:21:18
+   |
+LL |     type Assoc = ();
+   |                  ^^ the trait `Sub` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/super-assoc-mismatch.rs:7:1
+   |
+LL | trait Sub: Super<Assoc = u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `BoundOnAssoc::Assoc`
+  --> $DIR/super-assoc-mismatch.rs:18:17
+   |
+LL |     type Assoc: Sub;
+   |                 ^^^ required by this bound in `BoundOnAssoc::Assoc`
+
+error[E0277]: the trait bound `(): Sub` is not satisfied
+  --> $DIR/super-assoc-mismatch.rs:29:21
+   |
+LL |     type Assoc<T> = ();
+   |                     ^^ the trait `Sub` is not implemented for `()`, which is required by `<u8 as BoundOnGat>::Assoc<u8>: Sub`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/super-assoc-mismatch.rs:7:1
+   |
+LL | trait Sub: Super<Assoc = u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `BoundOnGat`
+  --> $DIR/super-assoc-mismatch.rs:25:41
+   |
+LL | trait BoundOnGat where Self::Assoc<u8>: Sub {
+   |                                         ^^^ required by this bound in `BoundOnGat`
+
+error[E0277]: the trait bound `(): Sub` is not satisfied
+  --> $DIR/super-assoc-mismatch.rs:33:26
+   |
+LL | fn trivial_bound() where (): Sub {}
+   |                          ^^^^^^^ the trait `Sub` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/super-assoc-mismatch.rs:7:1
+   |
+LL | trait Sub: Super<Assoc = u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: see issue #48214
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+
+error[E0277]: the trait bound `(): SubGeneric<u16>` is not satisfied
+  --> $DIR/super-assoc-mismatch.rs:55:22
+   |
+LL |     type Assoc1<T> = ();
+   |                      ^^ the trait `SubGeneric<u16>` is not implemented for `()`, which is required by `<u8 as MultiAssoc>::Assoc1<()>: SubGeneric<<u8 as MultiAssoc>::Assoc2>`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/super-assoc-mismatch.rs:43:1
+   |
+LL | trait SubGeneric<T>: SuperGeneric<T, Assoc = T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `MultiAssoc`
+  --> $DIR/super-assoc-mismatch.rs:46:23
+   |
+LL | trait MultiAssoc
+   |       ---------- required by a bound in this trait
+LL | where
+LL |     Self::Assoc1<()>: SubGeneric<Self::Assoc2>
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `MultiAssoc`
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/alias/only-require-assocs-from-supertraits.rs b/tests/ui/traits/alias/only-require-assocs-from-supertraits.rs
new file mode 100644
index 00000000000..35149fdfba0
--- /dev/null
+++ b/tests/ui/traits/alias/only-require-assocs-from-supertraits.rs
@@ -0,0 +1,16 @@
+//@ check-pass
+
+#![feature(trait_alias)]
+
+trait Foo<T> {}
+trait Bar { type Assoc; }
+
+trait Alias<T: Bar> = Foo<T>;
+
+// Check that an alias only requires us to specify the associated types
+// of the principal's supertraits. For example, we shouldn't require
+// specifying the type `Assoc` on trait `Bar` just because we have some
+// `T: Bar` where clause on the alias... because that makes no sense.
+fn use_alias<T: Bar>(x: &dyn Alias<T>) {}
+
+fn main() {}
diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs
index 52ecbcc9e2c..7d71fcdd158 100644
--- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs
+++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.rs
@@ -20,6 +20,7 @@ impl<T, S> Trait<T, S> for () {}
 fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
 //~^ ERROR trait takes 1 generic argument but 2 generic arguments were supplied
 //~| ERROR trait takes 1 generic argument but 2 generic arguments were supplied
+//~| ERROR type annotations needed
     3
 }
 
diff --git a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
index e7ceb7372bf..5062d17033e 100644
--- a/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
+++ b/tests/ui/traits/associated_type_bound/116464-invalid-assoc-type-suggestion-in-trait-impl.stderr
@@ -43,7 +43,7 @@ LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), Assoc = i32> {
    |                                                        +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:18
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:27:18
    |
 LL | struct Struct<T: Trait<u32, String>> {
    |                  ^^^^^ expected 1 generic argument
@@ -59,7 +59,7 @@ LL | struct Struct<T: Trait<u32, Assoc = String>> {
    |                             +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:31:23
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:32:23
    |
 LL | trait AnotherTrait<T: Trait<T, i32>> {}
    |                       ^^^^^ expected 1 generic argument
@@ -75,7 +75,7 @@ LL | trait AnotherTrait<T: Trait<T, Assoc = i32>> {}
    |                                +++++++
 
 error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:34:9
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:35:9
    |
 LL | impl<T: Trait<u32, String>> Struct<T> {}
    |         ^^^^^ expected 1 generic argument
@@ -91,7 +91,7 @@ LL | impl<T: Trait<u32, Assoc = String>> Struct<T> {}
    |                    +++++++
 
 error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:40:58
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:41:58
    |
 LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {}
    |                                                          ^^^^^^    - help: remove this generic argument
@@ -99,7 +99,7 @@ LL | impl<T: Trait<u32, Assoc=String>, U> YetAnotherTrait for Struct<T, U> {}
    |                                                          expected 1 generic argument
    |
 note: struct defined here, with 1 generic parameter: `T`
-  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:26:8
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:27:8
    |
 LL | struct Struct<T: Trait<u32, String>> {
    |        ^^^^^^ -
@@ -116,7 +116,13 @@ error[E0207]: the type parameter `S` is not constrained by the impl trait, self
 LL | impl<T, S> Trait<T, S> for () {}
    |         ^ unconstrained type parameter
 
-error: aborting due to 9 previous errors
+error[E0282]: type annotations needed
+  --> $DIR/116464-invalid-assoc-type-suggestion-in-trait-impl.rs:20:41
+   |
+LL | fn func<T: Trait<u32, String>>(t: T) -> impl Trait<(), i32> {
+   |                                         ^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to 10 previous errors
 
-Some errors have detailed explanations: E0107, E0207.
+Some errors have detailed explanations: E0107, E0207, E0282.
 For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/traits/bound/in-arc.rs b/tests/ui/traits/bound/in-arc.rs
index 40a6115e838..2616ad84ff8 100644
--- a/tests/ui/traits/bound/in-arc.rs
+++ b/tests/ui/traits/bound/in-arc.rs
@@ -3,7 +3,7 @@
 // Tests that a heterogeneous list of existential `dyn` types can be put inside an Arc
 // and shared between threads as long as all types fulfill Send.
 
-//@ ignore-emscripten no threads support
+//@ needs-threads
 
 use std::sync::Arc;
 use std::sync::mpsc::channel;
diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs
index 74c7afd6b9e..89b2da4452a 100644
--- a/tests/ui/traits/issue-105231.rs
+++ b/tests/ui/traits/issue-105231.rs
@@ -1,7 +1,9 @@
 //~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
 struct A<T>(B<T>);
 //~^ ERROR recursive types `A` and `B` have infinite size
+//~| ERROR `T` is never used
 struct B<T>(A<A<T>>);
+//~^ ERROR `T` is never used
 trait Foo {}
 impl<T> Foo for T where T: Send {}
 impl Foo for B<u8> {}
diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr
index fe20c47c57a..6467a438375 100644
--- a/tests/ui/traits/issue-105231.stderr
+++ b/tests/ui/traits/issue-105231.stderr
@@ -3,7 +3,7 @@ error[E0072]: recursive types `A` and `B` have infinite size
    |
 LL | struct A<T>(B<T>);
    | ^^^^^^^^^^^ ---- recursive without indirection
-LL |
+...
 LL | struct B<T>(A<A<T>>);
    | ^^^^^^^^^^^ ------- recursive without indirection
    |
@@ -11,19 +11,38 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
    |
 LL ~ struct A<T>(Box<B<T>>);
 LL |
+LL |
 LL ~ struct B<T>(Box<A<A<T>>>);
    |
 
+error[E0392]: type parameter `T` is never used
+  --> $DIR/issue-105231.rs:2:10
+   |
+LL | struct A<T>(B<T>);
+   |          ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
+error[E0392]: type parameter `T` is never used
+  --> $DIR/issue-105231.rs:5:10
+   |
+LL | struct B<T>(A<A<T>>);
+   |          ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
+
 error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`)
 note: required because it appears within the type `B<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<u8>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
-  --> $DIR/issue-105231.rs:4:8
+  --> $DIR/issue-105231.rs:5:8
    |
 LL | struct B<T>(A<A<T>>);
    |        ^
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0072, E0275.
+Some errors have detailed explanations: E0072, E0275, E0392.
 For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr
index 5bc79d9cee8..330b23b5755 100644
--- a/tests/ui/traits/issue-50480.stderr
+++ b/tests/ui/traits/issue-50480.stderr
@@ -60,6 +60,14 @@ error[E0412]: cannot find type `NotDefined` in this scope
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |                     ^^^^^^^^^^ not found in this scope
 
+error[E0277]: `i32` is not an iterator
+  --> $DIR/issue-50480.rs:3:27
+   |
+LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `i32`
+
 error[E0204]: the trait `Copy` cannot be implemented for this type
   --> $DIR/issue-50480.rs:1:17
    |
@@ -87,14 +95,6 @@ LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: `i32` is not an iterator
-  --> $DIR/issue-50480.rs:3:27
-   |
-LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `i32`
-
-error[E0277]: `i32` is not an iterator
   --> $DIR/issue-50480.rs:14:33
    |
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
index a04fa1ab8a1..39d453e8035 100644
--- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
@@ -1,15 +1,3 @@
-error[E0119]: conflicting implementations of trait `Trait`
-  --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1
-   |
-LL | impl<T: Copy> Trait for T {}
-   | ------------------------- first implementation here
-LL | struct LocalTy;
-LL | impl Trait for <LocalTy as Overflow>::Assoc {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-   |
-   = note: overflow evaluating the requirement `_ == <LocalTy as Overflow>::Assoc`
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`)
-
 error[E0275]: overflow evaluating the requirement `<T as Overflow>::Assoc: Sized`
   --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18
    |
@@ -27,6 +15,18 @@ help: consider relaxing the implicit `Sized` restriction
 LL |     type Assoc: ?Sized;
    |               ++++++++
 
+error[E0119]: conflicting implementations of trait `Trait`
+  --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1
+   |
+LL | impl<T: Copy> Trait for T {}
+   | ------------------------- first implementation here
+LL | struct LocalTy;
+LL | impl Trait for <LocalTy as Overflow>::Assoc {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+   |
+   = note: overflow evaluating the requirement `_ == <LocalTy as Overflow>::Assoc`
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`)
+
 error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0119, E0275.
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index 931c46c6887..45ff9f763cd 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -13,6 +13,12 @@ LL | #![feature(lazy_type_alias)]
    = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
+error: the type `<*const T as ToUnit<'a>>::Unit` is not well-formed
+  --> $DIR/issue-118950-root-region.rs:14:21
+   |
+LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
@@ -26,12 +32,6 @@ LL |
 LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
 
-error: the type `<*const T as ToUnit<'a>>::Unit` is not well-formed
-  --> $DIR/issue-118950-root-region.rs:14:21
-   |
-LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
 error: aborting due to 3 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0119, E0412.
diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs
index 7c7c68ad60a..f62dccff58d 100644
--- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs
+++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.rs
@@ -20,6 +20,7 @@ impl<'a, I> UnwrapItemsExt for I {
 
     fn unwrap_items(self) -> Self::Iter {
         MyStruct {}
+        //~^ ERROR expected generic lifetime parameter
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr
index 089c3e4fd8a..e6b94c525ff 100644
--- a/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr
+++ b/tests/ui/type-alias-impl-trait/assoc-type-lifetime-unconstrained.stderr
@@ -4,6 +4,16 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait,
 LL | impl<'a, I> UnwrapItemsExt for I {
    |      ^^ unconstrained lifetime parameter
 
-error: aborting due to 1 previous error
+error[E0792]: expected generic lifetime parameter, found `'_`
+  --> $DIR/assoc-type-lifetime-unconstrained.rs:22:9
+   |
+LL | impl<'a, I> UnwrapItemsExt for I {
+   |      -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |         MyStruct {}
+   |         ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0792.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs
index 1824ff5e2fb..fcac83500ec 100644
--- a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs
+++ b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs
@@ -12,6 +12,8 @@ impl<T> X for () {
     //~^ ERROR the type parameter `T` is not constrained
     type I = impl Sized;
     fn f() -> Self::I {}
+    //~^ ERROR type annotations needed
+    //~| ERROR type annotations needed
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr
index 137a4db81b5..bb0e11d314c 100644
--- a/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr
+++ b/tests/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr
@@ -4,6 +4,19 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
 LL | impl<T> X for () {
    |      ^ unconstrained type parameter
 
-error: aborting due to 1 previous error
+error[E0282]: type annotations needed
+  --> $DIR/impl-with-unconstrained-param.rs:14:23
+   |
+LL |     fn f() -> Self::I {}
+   |                       ^^ cannot infer type for type parameter `T`
+
+error[E0282]: type annotations needed
+  --> $DIR/impl-with-unconstrained-param.rs:14:15
+   |
+LL |     fn f() -> Self::I {}
+   |               ^^^^^^^ cannot infer type for type parameter `T`
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0282.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/type-alias-impl-trait/issue-74244.rs b/tests/ui/type-alias-impl-trait/issue-74244.rs
index bb4104b3d25..ce8a38a3361 100644
--- a/tests/ui/type-alias-impl-trait/issue-74244.rs
+++ b/tests/ui/type-alias-impl-trait/issue-74244.rs
@@ -14,6 +14,7 @@ impl<T> Allocator for DefaultAllocator {
 type A = impl Fn(<DefaultAllocator as Allocator>::Buffer);
 
 fn foo() -> A {
+    //~^ ERROR: type annotations needed
     |_| ()
 }
 
diff --git a/tests/ui/type-alias-impl-trait/issue-74244.stderr b/tests/ui/type-alias-impl-trait/issue-74244.stderr
index f5ca56baccc..d2b50ffd86b 100644
--- a/tests/ui/type-alias-impl-trait/issue-74244.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-74244.stderr
@@ -4,6 +4,13 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
 LL | impl<T> Allocator for DefaultAllocator {
    |      ^ unconstrained type parameter
 
-error: aborting due to 1 previous error
+error[E0282]: type annotations needed
+  --> $DIR/issue-74244.rs:16:13
+   |
+LL | fn foo() -> A {
+   |             ^ cannot infer type for type parameter `T`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0282.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/type-alias-impl-trait/issue-74761-2.rs b/tests/ui/type-alias-impl-trait/issue-74761-2.rs
index f582592e9bc..e556025adee 100644
--- a/tests/ui/type-alias-impl-trait/issue-74761-2.rs
+++ b/tests/ui/type-alias-impl-trait/issue-74761-2.rs
@@ -10,6 +10,7 @@ impl<'a, 'b> A for () {
     type B = impl core::fmt::Debug;
 
     fn f(&self) -> Self::B {}
+    //~^ ERROR expected generic lifetime parameter
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr
index f15d0a069ca..26babc29000 100644
--- a/tests/ui/type-alias-impl-trait/issue-74761-2.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-74761-2.stderr
@@ -10,6 +10,16 @@ error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait,
 LL | impl<'a, 'b> A for () {
    |          ^^ unconstrained lifetime parameter
 
-error: aborting due to 2 previous errors
+error[E0792]: expected generic lifetime parameter, found `'_`
+  --> $DIR/issue-74761-2.rs:12:28
+   |
+LL | impl<'a, 'b> A for () {
+   |      -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |     fn f(&self) -> Self::B {}
+   |                            ^^
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0792.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/type-alias-impl-trait/issue-74761.rs b/tests/ui/type-alias-impl-trait/issue-74761.rs
index f582592e9bc..e556025adee 100644
--- a/tests/ui/type-alias-impl-trait/issue-74761.rs
+++ b/tests/ui/type-alias-impl-trait/issue-74761.rs
@@ -10,6 +10,7 @@ impl<'a, 'b> A for () {
     type B = impl core::fmt::Debug;
 
     fn f(&self) -> Self::B {}
+    //~^ ERROR expected generic lifetime parameter
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-74761.stderr b/tests/ui/type-alias-impl-trait/issue-74761.stderr
index 1d016fe070f..a4826c29346 100644
--- a/tests/ui/type-alias-impl-trait/issue-74761.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-74761.stderr
@@ -10,6 +10,16 @@ error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait,
 LL | impl<'a, 'b> A for () {
    |          ^^ unconstrained lifetime parameter
 
-error: aborting due to 2 previous errors
+error[E0792]: expected generic lifetime parameter, found `'_`
+  --> $DIR/issue-74761.rs:12:28
+   |
+LL | impl<'a, 'b> A for () {
+   |      -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |     fn f(&self) -> Self::B {}
+   |                            ^^
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0792.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs
index 296a3f3e300..b232097fdb3 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.rs
@@ -12,6 +12,7 @@ impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) {
     type Associated = (i32, impl Iterator<Item = i32>);
     fn into(self) -> Self::Associated {
         (0_i32, [0_i32].iter().copied())
+        //~^ ERROR: expected generic lifetime parameter, found `'_`
     }
 }
 
diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr
index cff2695304a..5f9c56f1ca9 100644
--- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr
+++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-unconstrained-lifetime.stderr
@@ -4,6 +4,16 @@ error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait,
 LL | impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) {
    |      ^^ unconstrained lifetime parameter
 
-error: aborting due to 1 previous error
+error[E0792]: expected generic lifetime parameter, found `'_`
+  --> $DIR/type-alias-impl-trait-unconstrained-lifetime.rs:14:9
+   |
+LL | impl<'a, I: Iterator<Item = i32>> Trait for (i32, I) {
+   |      -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |         (0_i32, [0_i32].iter().copied())
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0792.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/type-alias-impl-trait/variance.rs b/tests/ui/type-alias-impl-trait/variance.rs
index e92cf2513e7..eae5e5fdde2 100644
--- a/tests/ui/type-alias-impl-trait/variance.rs
+++ b/tests/ui/type-alias-impl-trait/variance.rs
@@ -6,16 +6,21 @@ trait Captures<'a> {}
 impl<T> Captures<'_> for T {}
 
 type NotCapturedEarly<'a> = impl Sized; //~ [o]
+//~^ ERROR: unconstrained opaque type
 
 type CapturedEarly<'a> = impl Sized + Captures<'a>; //~ [o]
+//~^ ERROR: unconstrained opaque type
 
 // TAIT does *not* capture `'b`
 type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>; //~ [o]
+//~^ ERROR: unconstrained opaque type
 
 // TAIT does *not* capture `'b`
 type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>; //~ [o]
+//~^ ERROR: unconstrained opaque type
 
 type Bar<'a, 'b: 'b, T> = impl Sized; //~ ERROR [o, o, o]
+//~^ ERROR: unconstrained opaque type
 
 trait Foo<'i> {
     type ImplicitCapture<'a>;
@@ -27,18 +32,24 @@ trait Foo<'i> {
 
 impl<'i> Foo<'i> for &'i () {
     type ImplicitCapture<'a> = impl Sized; //~ [o, o]
+    //~^ ERROR: unconstrained opaque type
 
     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
+    //~^ ERROR: unconstrained opaque type
 
     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
+    //~^ ERROR: unconstrained opaque type
 }
 
 impl<'i> Foo<'i> for () {
     type ImplicitCapture<'a> = impl Sized; //~ [o, o]
+    //~^ ERROR: unconstrained opaque type
 
     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>; //~ [o, o]
+    //~^ ERROR: unconstrained opaque type
 
     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>; //~ [o, o]
+    //~^ ERROR: unconstrained opaque type
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/variance.stderr b/tests/ui/type-alias-impl-trait/variance.stderr
index 1794447c89a..914541fcf66 100644
--- a/tests/ui/type-alias-impl-trait/variance.stderr
+++ b/tests/ui/type-alias-impl-trait/variance.stderr
@@ -1,3 +1,91 @@
+error: unconstrained opaque type
+  --> $DIR/variance.rs:8:29
+   |
+LL | type NotCapturedEarly<'a> = impl Sized;
+   |                             ^^^^^^^^^^
+   |
+   = note: `NotCapturedEarly` must be used in combination with a concrete type within the same module
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:11:26
+   |
+LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `CapturedEarly` must be used in combination with a concrete type within the same module
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:15:56
+   |
+LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
+   |                                                        ^^^^^^^^^^
+   |
+   = note: `NotCapturedLate` must be used in combination with a concrete type within the same module
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:19:49
+   |
+LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `Captured` must be used in combination with a concrete type within the same module
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:22:27
+   |
+LL | type Bar<'a, 'b: 'b, T> = impl Sized;
+   |                           ^^^^^^^^^^
+   |
+   = note: `Bar` must be used in combination with a concrete type within the same module
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:34:32
+   |
+LL |     type ImplicitCapture<'a> = impl Sized;
+   |                                ^^^^^^^^^^
+   |
+   = note: `ImplicitCapture` must be used in combination with a concrete type within the same impl
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:37:42
+   |
+LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `ExplicitCaptureFromHeader` must be used in combination with a concrete type within the same impl
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:40:39
+   |
+LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:45:32
+   |
+LL |     type ImplicitCapture<'a> = impl Sized;
+   |                                ^^^^^^^^^^
+   |
+   = note: `ImplicitCapture` must be used in combination with a concrete type within the same impl
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:48:42
+   |
+LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `ExplicitCaptureFromHeader` must be used in combination with a concrete type within the same impl
+
+error: unconstrained opaque type
+  --> $DIR/variance.rs:51:39
+   |
+LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `ExplicitCaptureFromGat` must be used in combination with a concrete type within the same impl
+
 error: [o]
   --> $DIR/variance.rs:8:29
    |
@@ -5,64 +93,64 @@ LL | type NotCapturedEarly<'a> = impl Sized;
    |                             ^^^^^^^^^^
 
 error: [o]
-  --> $DIR/variance.rs:10:26
+  --> $DIR/variance.rs:11:26
    |
 LL | type CapturedEarly<'a> = impl Sized + Captures<'a>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [o]
-  --> $DIR/variance.rs:13:56
+  --> $DIR/variance.rs:15:56
    |
 LL | type NotCapturedLate<'a> = dyn for<'b> Iterator<Item = impl Sized>;
    |                                                        ^^^^^^^^^^
 
 error: [o]
-  --> $DIR/variance.rs:16:49
+  --> $DIR/variance.rs:19:49
    |
 LL | type Captured<'a> = dyn for<'b> Iterator<Item = impl Sized + Captures<'a>>;
    |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [o, o, o]
-  --> $DIR/variance.rs:18:27
+  --> $DIR/variance.rs:22:27
    |
 LL | type Bar<'a, 'b: 'b, T> = impl Sized;
    |                           ^^^^^^^^^^
 
 error: [o, o]
-  --> $DIR/variance.rs:29:32
+  --> $DIR/variance.rs:34:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
 error: [o, o]
-  --> $DIR/variance.rs:31:42
+  --> $DIR/variance.rs:37:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [o, o]
-  --> $DIR/variance.rs:33:39
+  --> $DIR/variance.rs:40:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [o, o]
-  --> $DIR/variance.rs:37:32
+  --> $DIR/variance.rs:45:32
    |
 LL |     type ImplicitCapture<'a> = impl Sized;
    |                                ^^^^^^^^^^
 
 error: [o, o]
-  --> $DIR/variance.rs:39:42
+  --> $DIR/variance.rs:48:42
    |
 LL |     type ExplicitCaptureFromHeader<'a> = impl Sized + Captures<'i>;
    |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [o, o]
-  --> $DIR/variance.rs:41:39
+  --> $DIR/variance.rs:51:39
    |
 LL |     type ExplicitCaptureFromGat<'a> = impl Sized + Captures<'a>;
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 11 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/tests/ui/typeck/issue-13853-5.rs b/tests/ui/typeck/issue-13853-5.rs
index 2afdf95aacf..fc97c6c67d6 100644
--- a/tests/ui/typeck/issue-13853-5.rs
+++ b/tests/ui/typeck/issue-13853-5.rs
@@ -7,6 +7,7 @@ trait Deserializable {
 impl<'a, T: Deserializable> Deserializable for &'a str {
     //~^ ERROR type parameter `T` is not constrained
     fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str {
+        //~^ ERROR mismatched types
     }
 }
 
diff --git a/tests/ui/typeck/issue-13853-5.stderr b/tests/ui/typeck/issue-13853-5.stderr
index 1eead956328..388d5ec746c 100644
--- a/tests/ui/typeck/issue-13853-5.stderr
+++ b/tests/ui/typeck/issue-13853-5.stderr
@@ -4,6 +4,22 @@ error[E0207]: the type parameter `T` is not constrained by the impl trait, self
 LL | impl<'a, T: Deserializable> Deserializable for &'a str {
    |          ^ unconstrained type parameter
 
-error: aborting due to 1 previous error
+error[E0308]: mismatched types
+  --> $DIR/issue-13853-5.rs:9:70
+   |
+LL |     fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str {
+   |        -----------------                                             ^^^^^^^ expected `&str`, found `()`
+   |        |
+   |        implicitly returns `()` as its body has no tail or `return` expression
+   |
+help: consider returning the local binding `_y`
+   |
+LL ~     fn deserialize_token<D: Deserializer<'a>>(_x: D, _y: &'a str) -> &'a str {
+LL +         _y
+LL ~
+   |
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0207`.
+Some errors have detailed explanations: E0207, E0308.
+For more information about an error, try `rustc --explain E0207`.
diff --git a/tests/ui/variance/variance-associated-consts.rs b/tests/ui/variance/variance-associated-consts.rs
index da55bc96244..6a44a94df3f 100644
--- a/tests/ui/variance/variance-associated-consts.rs
+++ b/tests/ui/variance/variance-associated-consts.rs
@@ -12,6 +12,7 @@ trait Trait {
 #[rustc_variance]
 struct Foo<T: Trait> { //~ ERROR [o]
     field: [u8; <T as Trait>::Const]
+    //~^ ERROR: unconstrained generic constant
 }
 
 fn main() { }
diff --git a/tests/ui/variance/variance-associated-consts.stderr b/tests/ui/variance/variance-associated-consts.stderr
index e25f0879add..f41574ca3a3 100644
--- a/tests/ui/variance/variance-associated-consts.stderr
+++ b/tests/ui/variance/variance-associated-consts.stderr
@@ -1,8 +1,16 @@
+error: unconstrained generic constant
+  --> $DIR/variance-associated-consts.rs:14:12
+   |
+LL |     field: [u8; <T as Trait>::Const]
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: try adding a `where` bound using this expression: `where [(); <T as Trait>::Const]:`
+
 error: [o]
   --> $DIR/variance-associated-consts.rs:13:1
    |
 LL | struct Foo<T: Trait> {
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/variance/variance-regions-direct.rs b/tests/ui/variance/variance-regions-direct.rs
index 39ea77a8aa2..f1763c403f1 100644
--- a/tests/ui/variance/variance-regions-direct.rs
+++ b/tests/ui/variance/variance-regions-direct.rs
@@ -50,6 +50,7 @@ struct Test6<'a, 'b:'a> { //~ ERROR [+, o]
 
 #[rustc_variance]
 struct Test7<'a> { //~ ERROR [*]
+    //~^ ERROR: `'a` is never used
     x: isize
 }
 
diff --git a/tests/ui/variance/variance-regions-direct.stderr b/tests/ui/variance/variance-regions-direct.stderr
index c55730296f1..edfc888f656 100644
--- a/tests/ui/variance/variance-regions-direct.stderr
+++ b/tests/ui/variance/variance-regions-direct.stderr
@@ -1,3 +1,11 @@
+error[E0392]: lifetime parameter `'a` is never used
+  --> $DIR/variance-regions-direct.rs:52:14
+   |
+LL | struct Test7<'a> {
+   |              ^^ unused lifetime parameter
+   |
+   = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
+
 error: [+, +, +]
   --> $DIR/variance-regions-direct.rs:9:1
    |
@@ -35,10 +43,11 @@ LL | struct Test7<'a> {
    | ^^^^^^^^^^^^^^^^
 
 error: [-, +, o]
-  --> $DIR/variance-regions-direct.rs:59:1
+  --> $DIR/variance-regions-direct.rs:60:1
    |
 LL | enum Test8<'a, 'b, 'c:'b> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
+For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/variance/variance-regions-indirect.rs b/tests/ui/variance/variance-regions-indirect.rs
index 0d00535fef1..31e25641d8c 100644
--- a/tests/ui/variance/variance-regions-indirect.rs
+++ b/tests/ui/variance/variance-regions-indirect.rs
@@ -6,6 +6,7 @@
 
 #[rustc_variance]
 enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
+    //~^ ERROR: `'d` is never used
     Test8A(extern "Rust" fn(&'a isize)),
     Test8B(&'b [isize]),
     Test8C(&'b mut &'c str),
@@ -13,16 +14,19 @@ enum Base<'a, 'b, 'c:'b, 'd> { //~ ERROR [-, +, o, *]
 
 #[rustc_variance]
 struct Derived1<'w, 'x:'y, 'y, 'z> { //~ ERROR [*, o, +, -]
+    //~^ ERROR: `'w` is never used
     f: Base<'z, 'y, 'x, 'w>
 }
 
 #[rustc_variance] // Combine - and + to yield o
 struct Derived2<'a, 'b:'a, 'c> { //~ ERROR [o, o, *]
+    //~^ ERROR: `'c` is never used
     f: Base<'a, 'a, 'b, 'c>
 }
 
 #[rustc_variance] // Combine + and o to yield o (just pay attention to 'a here)
 struct Derived3<'a:'b, 'b, 'c> { //~ ERROR [o, +, *]
+    //~^ ERROR: `'c` is never used
     f: Base<'a, 'b, 'a, 'c>
 }
 
diff --git a/tests/ui/variance/variance-regions-indirect.stderr b/tests/ui/variance/variance-regions-indirect.stderr
index edf2626d598..901ec0c6a76 100644
--- a/tests/ui/variance/variance-regions-indirect.stderr
+++ b/tests/ui/variance/variance-regions-indirect.stderr
@@ -1,3 +1,35 @@
+error[E0392]: lifetime parameter `'d` is never used
+  --> $DIR/variance-regions-indirect.rs:8:26
+   |
+LL | enum Base<'a, 'b, 'c:'b, 'd> {
+   |                          ^^ unused lifetime parameter
+   |
+   = help: consider removing `'d`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: lifetime parameter `'w` is never used
+  --> $DIR/variance-regions-indirect.rs:16:17
+   |
+LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
+   |                 ^^ unused lifetime parameter
+   |
+   = help: consider removing `'w`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: lifetime parameter `'c` is never used
+  --> $DIR/variance-regions-indirect.rs:22:28
+   |
+LL | struct Derived2<'a, 'b:'a, 'c> {
+   |                            ^^ unused lifetime parameter
+   |
+   = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`
+
+error[E0392]: lifetime parameter `'c` is never used
+  --> $DIR/variance-regions-indirect.rs:28:28
+   |
+LL | struct Derived3<'a:'b, 'b, 'c> {
+   |                            ^^ unused lifetime parameter
+   |
+   = help: consider removing `'c`, referring to it in a field, or using a marker such as `PhantomData`
+
 error: [-, +, o, *]
   --> $DIR/variance-regions-indirect.rs:8:1
    |
@@ -5,28 +37,29 @@ LL | enum Base<'a, 'b, 'c:'b, 'd> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [*, o, +, -]
-  --> $DIR/variance-regions-indirect.rs:15:1
+  --> $DIR/variance-regions-indirect.rs:16:1
    |
 LL | struct Derived1<'w, 'x:'y, 'y, 'z> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [o, o, *]
-  --> $DIR/variance-regions-indirect.rs:20:1
+  --> $DIR/variance-regions-indirect.rs:22:1
    |
 LL | struct Derived2<'a, 'b:'a, 'c> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [o, +, *]
-  --> $DIR/variance-regions-indirect.rs:25:1
+  --> $DIR/variance-regions-indirect.rs:28:1
    |
 LL | struct Derived3<'a:'b, 'b, 'c> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [-, +, o]
-  --> $DIR/variance-regions-indirect.rs:30:1
+  --> $DIR/variance-regions-indirect.rs:34:1
    |
 LL | struct Derived4<'a, 'b, 'c:'b> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 9 previous errors
 
+For more information about this error, try `rustc --explain E0392`.
diff --git a/tests/ui/variance/variance-trait-bounds.rs b/tests/ui/variance/variance-trait-bounds.rs
index ad5334602a2..25a01b160dd 100644
--- a/tests/ui/variance/variance-trait-bounds.rs
+++ b/tests/ui/variance/variance-trait-bounds.rs
@@ -19,16 +19,19 @@ struct TestStruct<U,T:Setter<U>> { //~ ERROR [+, +]
 
 #[rustc_variance]
 enum TestEnum<U,T:Setter<U>> { //~ ERROR [*, +]
+    //~^ ERROR: `U` is never used
     Foo(T)
 }
 
 #[rustc_variance]
 struct TestContraStruct<U,T:Setter<U>> { //~ ERROR [*, +]
+    //~^ ERROR: `U` is never used
     t: T
 }
 
 #[rustc_variance]
 struct TestBox<U,T:Getter<U>+Setter<U>> { //~ ERROR [*, +]
+    //~^ ERROR: `U` is never used
     t: T
 }
 
diff --git a/tests/ui/variance/variance-trait-bounds.stderr b/tests/ui/variance/variance-trait-bounds.stderr
index 5a73e541c3a..95ed18c1ad2 100644
--- a/tests/ui/variance/variance-trait-bounds.stderr
+++ b/tests/ui/variance/variance-trait-bounds.stderr
@@ -1,3 +1,30 @@
+error[E0392]: type parameter `U` is never used
+  --> $DIR/variance-trait-bounds.rs:21:15
+   |
+LL | enum TestEnum<U,T:Setter<U>> {
+   |               ^ unused type parameter
+   |
+   = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead
+
+error[E0392]: type parameter `U` is never used
+  --> $DIR/variance-trait-bounds.rs:27:25
+   |
+LL | struct TestContraStruct<U,T:Setter<U>> {
+   |                         ^ unused type parameter
+   |
+   = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead
+
+error[E0392]: type parameter `U` is never used
+  --> $DIR/variance-trait-bounds.rs:33:16
+   |
+LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
+   |                ^ unused type parameter
+   |
+   = help: consider removing `U`, referring to it in a field, or using a marker such as `PhantomData`
+   = help: if you intended `U` to be a const parameter, use `const U: /* Type */` instead
+
 error: [+, +]
   --> $DIR/variance-trait-bounds.rs:16:1
    |
@@ -11,16 +38,17 @@ LL | enum TestEnum<U,T:Setter<U>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [*, +]
-  --> $DIR/variance-trait-bounds.rs:26:1
+  --> $DIR/variance-trait-bounds.rs:27:1
    |
 LL | struct TestContraStruct<U,T:Setter<U>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: [*, +]
-  --> $DIR/variance-trait-bounds.rs:31:1
+  --> $DIR/variance-trait-bounds.rs:33:1
    |
 LL | struct TestBox<U,T:Getter<U>+Setter<U>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 7 previous errors
 
+For more information about this error, try `rustc --explain E0392`.