about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-08 16:49:13 +0000
committerbors <bors@rust-lang.org>2024-11-08 16:49:13 +0000
commit59cec72a57af178767a7b8e7f624b06cc50f1087 (patch)
treecb3a4b42830fb86ca849abdb473328e4033fe8db
parent209799f3b910c64c8bd5001c0a8a55e03e7c2614 (diff)
parent0aafd6552b58a924d1adf6845683fd20d87289f2 (diff)
downloadrust-59cec72a57af178767a7b8e7f624b06cc50f1087.tar.gz
rust-59cec72a57af178767a7b8e7f624b06cc50f1087.zip
Auto merge of #132746 - flip1995:clippy-subtree-update, r=Manishearth
Clippy subtree update

r? `@Manishearth`
-rw-r--r--Cargo.lock1
-rw-r--r--src/tools/clippy/.github/workflows/clippy_dev.yml50
-rw-r--r--src/tools/clippy/.github/workflows/clippy_mq.yml (renamed from src/tools/clippy/.github/workflows/clippy_bors.yml)51
-rw-r--r--src/tools/clippy/.github/workflows/clippy_pr.yml (renamed from src/tools/clippy/.github/workflows/clippy.yml)40
-rw-r--r--src/tools/clippy/.github/workflows/deploy.yml2
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml46
-rw-r--r--src/tools/clippy/CHANGELOG.md7
-rw-r--r--src/tools/clippy/CONTRIBUTING.md16
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/README.md3
-rw-r--r--src/tools/clippy/book/src/README.md3
-rw-r--r--src/tools/clippy/book/src/development/README.md1
-rw-r--r--src/tools/clippy/book/src/development/common_tools_writing_lints.md4
-rw-r--r--src/tools/clippy/book/src/development/method_checking.md15
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md33
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs46
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs13
-rw-r--r--src/tools/clippy/clippy_config/src/types.rs301
-rw-r--r--src/tools/clippy/clippy_dev/src/serve.rs8
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs531
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/copies.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/copy_iterator.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ctfe.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/declare_clippy_lint.rs49
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs40
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_macros.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_drop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/ref_option.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/infinite_iter.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_include_file.rs63
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs59
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs60
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_hash_one.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_empty.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_all_any_identity.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs134
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs134
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/minmax.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_continue.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_late_init.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/float_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/ref_option_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/semicolon_block.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/serde_api.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/single_component_path_imports.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/attr_collector.rs40
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs69
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/mod.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs28
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs62
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs15
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs30
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs19
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs83
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/compile-test.rs3
-rw-r--r--src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs5
-rw-r--r--src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.fixed24
-rw-r--r--src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.rs24
-rw-r--r--src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.stderr23
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr10
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default/clippy.toml0
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml12
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_enum/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_impl/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_trait/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_1.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_2.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_3.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs186
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs174
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr226
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs185
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs174
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr100
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.only_enum.stderr16
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs43
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr40
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs67
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr40
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs48
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/var_1/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr62
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/private-doc-errors/doc_lints.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr9
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes.fixed7
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes.rs7
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes.stderr6
-rw-r--r--src/tools/clippy/tests/ui/author.rs (renamed from src/tools/clippy/tests/ui-internal/author.rs)2
-rw-r--r--src/tools/clippy/tests/ui/author.stdout (renamed from src/tools/clippy/tests/ui-internal/author.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/blocks.rs (renamed from src/tools/clippy/tests/ui-internal/author/blocks.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/blocks.stdout (renamed from src/tools/clippy/tests/ui-internal/author/blocks.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/call.rs (renamed from src/tools/clippy/tests/ui-internal/author/call.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/call.stdout (renamed from src/tools/clippy/tests/ui-internal/author/call.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/if.rs (renamed from src/tools/clippy/tests/ui-internal/author/if.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/if.stdout (renamed from src/tools/clippy/tests/ui-internal/author/if.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/issue_3849.rs (renamed from src/tools/clippy/tests/ui-internal/author/issue_3849.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/issue_3849.stdout (renamed from src/tools/clippy/tests/ui-internal/author/issue_3849.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/loop.rs (renamed from src/tools/clippy/tests/ui-internal/author/loop.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/loop.stdout (renamed from src/tools/clippy/tests/ui-internal/author/loop.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/macro_in_closure.rs (renamed from src/tools/clippy/tests/ui-internal/author/macro_in_closure.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/macro_in_closure.stdout (renamed from src/tools/clippy/tests/ui-internal/author/macro_in_closure.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/macro_in_loop.rs (renamed from src/tools/clippy/tests/ui-internal/author/macro_in_loop.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/macro_in_loop.stdout (renamed from src/tools/clippy/tests/ui-internal/author/macro_in_loop.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/matches.rs (renamed from src/tools/clippy/tests/ui-internal/author/matches.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/matches.stdout (renamed from src/tools/clippy/tests/ui-internal/author/matches.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/repeat.rs (renamed from src/tools/clippy/tests/ui-internal/author/repeat.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/repeat.stdout (renamed from src/tools/clippy/tests/ui-internal/author/repeat.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/author/struct.rs (renamed from src/tools/clippy/tests/ui-internal/author/struct.rs)0
-rw-r--r--src/tools/clippy/tests/ui/author/struct.stdout (renamed from src/tools/clippy/tests/ui-internal/author/struct.stdout)0
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs50
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref.fixed6
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref.rs6
-rw-r--r--src/tools/clippy/tests/ui/const_is_empty.rs14
-rw-r--r--src/tools/clippy/tests/ui/const_is_empty.stderr8
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed3
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs3
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.stderr44
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.rs20
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.stderr42
-rw-r--r--src/tools/clippy/tests/ui/iter_without_into_iter.stderr16
-rw-r--r--src/tools/clippy/tests/ui/large_const_arrays.fixed2
-rw-r--r--src/tools/clippy/tests/ui/large_const_arrays.rs2
-rw-r--r--src/tools/clippy/tests/ui/large_const_arrays.stderr22
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.fixed11
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.rs11
-rw-r--r--src/tools/clippy/tests/ui/map_all_any_identity.fixed21
-rw-r--r--src/tools/clippy/tests/ui/map_all_any_identity.rs21
-rw-r--r--src/tools/clippy/tests/ui/map_all_any_identity.stderr26
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed73
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs73
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr223
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed1
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs1
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr52
-rw-r--r--src/tools/clippy/tests/ui/missing_doc.rs8
-rw-r--r--src/tools/clippy/tests/ui/missing_doc.stderr11
-rw-r--r--src/tools/clippy/tests/ui/needless_as_bytes.fixed50
-rw-r--r--src/tools/clippy/tests/ui/needless_as_bytes.rs50
-rw-r--r--src/tools/clippy/tests/ui/needless_as_bytes.stderr29
-rw-r--r--src/tools/clippy/tests/ui/needless_continue.rs17
-rw-r--r--src/tools/clippy/tests/ui/needless_continue.stderr10
-rw-r--r--src/tools/clippy/tests/ui/no_lints.rs3
-rw-r--r--src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs29
-rw-r--r--src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr27
-rw-r--r--src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.rs57
-rw-r--r--src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.stderr83
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.stderr8
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed30
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.rs24
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr86
-rw-r--r--src/tools/clippy/tests/ui/rename.rs2
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr14
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed1
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs1
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr6
-rw-r--r--src/tools/clippy/tests/ui/semicolon_outside_block.fixed8
-rw-r--r--src/tools/clippy/tests/ui/semicolon_outside_block.rs8
-rw-r--r--src/tools/clippy/tests/ui/semicolon_outside_block.stderr30
-rw-r--r--src/tools/clippy/tests/ui/suspicious_map.rs1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_map.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_filter_map.rs13
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_filter_map.stderr53
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_find_map.rs9
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_find_map.stderr30
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.rs14
-rw-r--r--src/tools/clippy/triagebot.toml2
-rw-r--r--src/tools/clippy/util/gh-pages/index_template.html43
-rw-r--r--src/tools/clippy/util/gh-pages/script.js22
-rw-r--r--src/tools/clippy/util/gh-pages/style.css39
-rw-r--r--src/tools/clippy/util/gh-pages/theme.js4
249 files changed, 5023 insertions, 900 deletions
diff --git a/Cargo.lock b/Cargo.lock
index b0ffa716ccf..9cca91c25df 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2861,7 +2861,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
 dependencies = [
  "bitflags 2.6.0",
- "getopts",
  "memchr",
  "pulldown-cmark-escape 0.11.0",
  "unicase",
diff --git a/src/tools/clippy/.github/workflows/clippy_dev.yml b/src/tools/clippy/.github/workflows/clippy_dev.yml
index cf0a8bde202..bcb3193ad67 100644
--- a/src/tools/clippy/.github/workflows/clippy_dev.yml
+++ b/src/tools/clippy/.github/workflows/clippy_dev.yml
@@ -1,17 +1,8 @@
 name: Clippy Dev Test
 
 on:
-  push:
-    branches:
-      - auto
-      - try
+  merge_group:
   pull_request:
-    # Only run on paths, that get checked by the clippy_dev tool
-    paths:
-    - 'CHANGELOG.md'
-    - 'README.md'
-    - '**.stderr'
-    - '**.rs'
 
 env:
   RUST_BACKTRACE: 1
@@ -47,28 +38,21 @@ jobs:
         cargo check
         git reset --hard HEAD
 
-  # These jobs doesn't actually test anything, but they're only used to tell
-  # bors the build completed, as there is no practical way to detect when a
-  # workflow is successful listening to webhooks only.
-  #
-  # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
-
-  end-success:
-    name: bors dev test finished
-    if: github.event.pusher.name == 'bors' && success()
-    runs-on: ubuntu-latest
-    needs: [clippy_dev]
-
-    steps:
-      - name: Mark the job as successful
-        run: exit 0
-
-  end-failure:
-    name: bors dev test finished
-    if: github.event.pusher.name == 'bors' && (failure() || cancelled())
+  conclusion_dev:
+    needs: [ clippy_dev ]
+    # We need to ensure this job does *not* get skipped if its dependencies fail,
+    # because a skipped job is considered a success by GitHub. So we have to
+    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
+    # when the workflow is canceled manually.
+    #
+    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
+    if: ${{ !cancelled() }}
     runs-on: ubuntu-latest
-    needs: [clippy_dev]
-
     steps:
-      - name: Mark the job as a failure
-        run: exit 1
+      # Manually check the status of all dependencies. `if: failure()` does not work.
+      - name: Conclusion
+        run: |
+          # Print the dependent jobs to see them in the CI log
+          jq -C <<< '${{ toJson(needs) }}'
+          # Check if all jobs that we depend on (in the needs array) were successful.
+          jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_mq.yml
index 026771e6fcf..49622048050 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_mq.yml
@@ -1,10 +1,7 @@
-name: Clippy Test (bors)
+name: Clippy Test (merge queue)
 
 on:
-  push:
-    branches:
-      - auto
-      - try
+  merge_group:
 
 env:
   RUST_BACKTRACE: 1
@@ -13,11 +10,6 @@ env:
   CARGO_INCREMENTAL: 0
   RUSTFLAGS: -D warnings
 
-concurrency:
-  # For a given workflow, if we push to the same branch, cancel all previous builds on that branch.
-  group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}"
-  cancel-in-progress: true
-
 defaults:
   run:
     shell: bash
@@ -218,28 +210,21 @@ jobs:
       env:
         INTEGRATION: ${{ matrix.integration }}
 
-  # These jobs doesn't actually test anything, but they're only used to tell
-  # bors the build completed, as there is no practical way to detect when a
-  # workflow is successful listening to webhooks only.
-  #
-  # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
-
-  end-success:
-    name: bors test finished
-    if: github.event.pusher.name == 'bors' && success()
+  conclusion:
+    needs: [ changelog, base, metadata_collection, integration_build, integration ]
+    # We need to ensure this job does *not* get skipped if its dependencies fail,
+    # because a skipped job is considered a success by GitHub. So we have to
+    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
+    # when the workflow is canceled manually.
+    #
+    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
+    if: ${{ !cancelled() }}
     runs-on: ubuntu-latest
-    needs: [changelog, base, metadata_collection, integration_build, integration]
-
-    steps:
-      - name: Mark the job as successful
-        run: exit 0
-
-  end-failure:
-    name: bors test finished
-    if: github.event.pusher.name == 'bors' && (failure() || cancelled())
-    runs-on: ubuntu-latest
-    needs: [changelog, base, metadata_collection, integration_build, integration]
-
     steps:
-      - name: Mark the job as a failure
-        run: exit 1
+      # Manually check the status of all dependencies. `if: failure()` does not work.
+      - name: Conclusion
+        run: |
+          # Print the dependent jobs to see them in the CI log
+          jq -C <<< '${{ toJson(needs) }}'
+          # Check if all jobs that we depend on (in the needs array) were successful.
+          jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
diff --git a/src/tools/clippy/.github/workflows/clippy.yml b/src/tools/clippy/.github/workflows/clippy_pr.yml
index 0a0538490cc..2e5b5bd41df 100644
--- a/src/tools/clippy/.github/workflows/clippy.yml
+++ b/src/tools/clippy/.github/workflows/clippy_pr.yml
@@ -1,24 +1,7 @@
 name: Clippy Test
 
 on:
-  push:
-    # Ignore bors branches, since they are covered by `clippy_bors.yml`
-    branches-ignore:
-      - auto
-      - try
-    # Don't run Clippy tests, when only text files were modified
-    paths-ignore:
-    - 'COPYRIGHT'
-    - 'LICENSE-*'
-    - '**.md'
-    - '**.txt'
   pull_request:
-    # Don't run Clippy tests, when only text files were modified
-    paths-ignore:
-    - 'COPYRIGHT'
-    - 'LICENSE-*'
-    - '**.md'
-    - '**.txt'
 
 env:
   RUST_BACKTRACE: 1
@@ -35,7 +18,7 @@ concurrency:
 
 jobs:
   base:
-    # NOTE: If you modify this job, make sure you copy the changes to clippy_bors.yml
+    # NOTE: If you modify this job, make sure you copy the changes to clippy_mq.yml
     runs-on: ubuntu-latest
 
     steps:
@@ -73,3 +56,24 @@ jobs:
       run: .github/driver.sh
       env:
         OS: ${{ runner.os }}
+
+  # We need to have the "conclusion" job also on PR CI, to make it possible
+  # to add PRs to a merge queue.
+  conclusion:
+    needs: [ base ]
+    # We need to ensure this job does *not* get skipped if its dependencies fail,
+    # because a skipped job is considered a success by GitHub. So we have to
+    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
+    # when the workflow is canceled manually.
+    #
+    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
+    if: ${{ !cancelled() }}
+    runs-on: ubuntu-latest
+    steps:
+      # Manually check the status of all dependencies. `if: failure()` does not work.
+      - name: Conclusion
+        run: |
+          # Print the dependent jobs to see them in the CI log
+          jq -C <<< '${{ toJson(needs) }}'
+          # Check if all jobs that we depend on (in the needs array) were successful.
+          jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
diff --git a/src/tools/clippy/.github/workflows/deploy.yml b/src/tools/clippy/.github/workflows/deploy.yml
index 94f494b65c4..32dc251c836 100644
--- a/src/tools/clippy/.github/workflows/deploy.yml
+++ b/src/tools/clippy/.github/workflows/deploy.yml
@@ -52,7 +52,7 @@ jobs:
       run: cargo generate-lockfile
 
     - name: Cache
-      uses: Swatinem/rust-cache@v2.7.0
+      uses: Swatinem/rust-cache@v2
       with:
         save-if: ${{ github.ref == 'refs/heads/master' }}
 
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index a1b011dc32d..0d402fe7064 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -1,13 +1,8 @@
 name: Remark
 
 on:
-  push:
-    branches:
-      - auto
-      - try
+  merge_group:
   pull_request:
-    paths:
-    - '**.md'
 
 jobs:
   remark:
@@ -45,28 +40,21 @@ jobs:
     - name: Build mdbook
       run: mdbook build book
 
-  # These jobs doesn't actually test anything, but they're only used to tell
-  # bors the build completed, as there is no practical way to detect when a
-  # workflow is successful listening to webhooks only.
-  #
-  # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
-
-  end-success:
-    name: bors remark test finished
-    if: github.event.pusher.name == 'bors' && success()
-    runs-on: ubuntu-latest
-    needs: [remark]
-
-    steps:
-      - name: Mark the job as successful
-        run: exit 0
-
-  end-failure:
-    name: bors remark test finished
-    if: github.event.pusher.name == 'bors' && (failure() || cancelled())
+  conclusion_remark:
+    needs: [ remark ]
+    # We need to ensure this job does *not* get skipped if its dependencies fail,
+    # because a skipped job is considered a success by GitHub. So we have to
+    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
+    # when the workflow is canceled manually.
+    #
+    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
+    if: ${{ !cancelled() }}
     runs-on: ubuntu-latest
-    needs: [remark]
-
     steps:
-      - name: Mark the job as a failure
-        run: exit 1
+      # Manually check the status of all dependencies. `if: failure()` does not work.
+      - name: Conclusion
+        run: |
+          # Print the dependent jobs to see them in the CI log
+          jq -C <<< '${{ toJson(needs) }}'
+          # Check if all jobs that we depend on (in the needs array) were successful.
+          jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 4bdbc91db93..161fa630ed4 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5331,6 +5331,7 @@ Released 2018-09-13
 [`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range
 [`almost_swapped`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
 [`approx_constant`]: https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant
+[`arbitrary_source_item_ordering`]: https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering
 [`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/master/index.html#arc_with_non_send_sync
 [`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects
 [`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
@@ -5689,6 +5690,7 @@ Released 2018-09-13
 [`manual_unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or_default
 [`manual_while_let_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_while_let_some
 [`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names
+[`map_all_any_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_all_any_identity
 [`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone
 [`map_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_collect_result_unit
 [`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
@@ -5696,6 +5698,7 @@ Released 2018-09-13
 [`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten
 [`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity
 [`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or
+[`map_with_unused_argument_over_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges
 [`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref
 [`match_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_bool
 [`match_like_matches_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro
@@ -5761,6 +5764,7 @@ Released 2018-09-13
 [`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer
 [`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/master/index.html#naive_bytecount
 [`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type
+[`needless_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_as_bytes
 [`needless_bitwise_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bitwise_bool
 [`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool
 [`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign
@@ -6205,12 +6209,14 @@ Released 2018-09-13
 [`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
+[`module-item-order-groupings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#module-item-order-groupings
 [`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
 [`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
+[`source-item-ordering`]: https://doc.rust-lang.org/clippy/lint_configuration.html#source-item-ordering
 [`stack-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#stack-size-threshold
 [`standard-macro-braces`]: https://doc.rust-lang.org/clippy/lint_configuration.html#standard-macro-braces
 [`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold
@@ -6218,6 +6224,7 @@ Released 2018-09-13
 [`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
+[`trait-assoc-item-kinds-order`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trait-assoc-item-kinds-order
 [`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
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index b1a59238c82..1f6c918fc6c 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -21,7 +21,6 @@ All contributors are expected to follow the [Rust Code of Conduct].
     - [Rust Analyzer](#rust-analyzer)
   - [How Clippy works](#how-clippy-works)
   - [Issue and PR triage](#issue-and-pr-triage)
-  - [Bors and Homu](#bors-and-homu)
   - [Contributions](#contributions)
   - [License](#license)
 
@@ -213,16 +212,6 @@ We have prioritization labels and a sync-blocker label, which are described belo
 Or rather: before the sync this should be addressed,
 e.g. by removing a lint again, so it doesn't hit beta/stable.
 
-## Bors and Homu
-
-We use a bot powered by [Homu][homu] to help automate testing and landing of pull
-requests in Clippy. The bot's username is @bors.
-
-You can find the Clippy bors queue [here][homu_queue].
-
-If you have @bors permissions, you can find an overview of the available
-commands [here][homu_instructions].
-
 [triage]: https://forge.rust-lang.org/release/triage-procedure.html
 [l-crash]: https://github.com/rust-lang/rust-clippy/labels/L-crash
 [l-bug]: https://github.com/rust-lang/rust-clippy/labels/L-bug
@@ -230,9 +219,6 @@ commands [here][homu_instructions].
 [p-medium]: https://github.com/rust-lang/rust-clippy/labels/P-medium
 [p-high]: https://github.com/rust-lang/rust-clippy/labels/P-high
 [l-sync-blocker]: https://github.com/rust-lang/rust-clippy/labels/L-sync-blocker
-[homu]: https://github.com/rust-lang/homu
-[homu_instructions]: https://bors.rust-lang.org/
-[homu_queue]: https://bors.rust-lang.org/queue/clippy
 
 ## Contributions
 
@@ -244,7 +230,7 @@ All PRs should include a `changelog` entry with a short comment explaining the c
 "what do you believe is important from an outsider's perspective?" Often, PRs are only related to a single property of a
 lint, and then it's good to mention that one. Otherwise, it's better to include too much detail than too little.
 
-Clippy's [changelog] is created from these comments. Every release, someone gets all commits from bors with a
+Clippy's [changelog] is created from these comments. Every release, someone gets all merge commits with a
 `changelog: XYZ` entry and combines them into the changelog. This is a manual process.
 
 Examples:
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 1f7784fc489..50a2afbfc07 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -39,7 +39,7 @@ toml = "0.7.3"
 walkdir = "2.3"
 filetime = "0.2.9"
 itertools = "0.12"
-pulldown-cmark = "0.11"
+pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] }
 rinja = { version = "0.3", default-features = false, features = ["config"] }
 
 # UI test dependencies
diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md
index ec76a6dfb08..cb3a22d4288 100644
--- a/src/tools/clippy/README.md
+++ b/src/tools/clippy/README.md
@@ -1,11 +1,10 @@
 # Clippy
 
-[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test%20(bors)/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test+(bors)%22+event%3Apush+branch%3Aauto)
 [![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](#license)
 
 A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
 
-[There are over 700 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
+[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
 
 Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).
 You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.
diff --git a/src/tools/clippy/book/src/README.md b/src/tools/clippy/book/src/README.md
index 7bdfb97c3ac..5d2c3972b06 100644
--- a/src/tools/clippy/book/src/README.md
+++ b/src/tools/clippy/book/src/README.md
@@ -1,12 +1,11 @@
 # Clippy
 
-[![Clippy Test](https://github.com/rust-lang/rust-clippy/workflows/Clippy%20Test%20(bors)/badge.svg?branch=auto&event=push)](https://github.com/rust-lang/rust-clippy/actions?query=workflow%3A%22Clippy+Test+(bors)%22+event%3Apush+branch%3Aauto)
 [![License: MIT OR Apache-2.0](https://img.shields.io/crates/l/clippy.svg)](https://github.com/rust-lang/rust-clippy#license)
 
 A collection of lints to catch common mistakes and improve your
 [Rust](https://github.com/rust-lang/rust) code.
 
-[There are over 700 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
+[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
 
 Lints are divided into categories, each with a default [lint
 level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how
diff --git a/src/tools/clippy/book/src/development/README.md b/src/tools/clippy/book/src/development/README.md
index 8f09f66f595..b33cdc00ead 100644
--- a/src/tools/clippy/book/src/development/README.md
+++ b/src/tools/clippy/book/src/development/README.md
@@ -53,7 +53,6 @@ book](../lints.md).
 > - IDE setup
 > - High level overview on how Clippy works
 > - Triage procedure
-> - Bors and Homu
 
 [ast]: https://rustc-dev-guide.rust-lang.org/syntax-intro.html
 [hir]: https://rustc-dev-guide.rust-lang.org/hir.html
diff --git a/src/tools/clippy/book/src/development/common_tools_writing_lints.md b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
index 09171d86a20..77910917963 100644
--- a/src/tools/clippy/book/src/development/common_tools_writing_lints.md
+++ b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
@@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for MyStructLint {
         // Check our expr is calling a method
         if let hir::ExprKind::MethodCall(path, _, _self_arg, ..) = &expr.kind
             // Check the name of this method is `some_method`
-            && path.ident.name == sym!(some_method)
+            && path.ident.name.as_str() == "some_method"
             // Optionally, check the type of the self argument.
             // - See "Checking for a specific type"
         {
@@ -167,7 +167,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
         // Check if item is a method/function
         if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
             // Check the method is named `some_method`
-            && impl_item.ident.name == sym!(some_method)
+            && impl_item.ident.name.as_str() == "some_method"
             // We can also check it has a parameter `self`
             && signature.decl.implicit_self.has_implicit_self()
             // We can go further and even check if its return type is `String`
diff --git a/src/tools/clippy/book/src/development/method_checking.md b/src/tools/clippy/book/src/development/method_checking.md
index 56d1be37519..9c5d4b516db 100644
--- a/src/tools/clippy/book/src/development/method_checking.md
+++ b/src/tools/clippy/book/src/development/method_checking.md
@@ -3,8 +3,8 @@
 In some scenarios we might want to check for methods when developing
 a lint. There are two kinds of questions that we might be curious about:
 
-- Invocation: Does an expression call a specific method?
-- Definition: Does an `impl` define a method?
+-   Invocation: Does an expression call a specific method?
+-   Definition: Does an `impl` define a method?
 
 ## Checking if an `expr` is calling a specific method
 
@@ -23,7 +23,7 @@ impl<'tcx> LateLintPass<'tcx> for OurFancyMethodLint {
         // Check our expr is calling a method with pattern matching
         if let hir::ExprKind::MethodCall(path, _, [self_arg, ..]) = &expr.kind
             // Check if the name of this method is `our_fancy_method`
-            && path.ident.name == sym!(our_fancy_method)
+            && path.ident.name.as_str() == "our_fancy_method"
             // We can check the type of the self argument whenever necessary.
             // (It's necessary if we want to check that method is specifically belonging to a specific trait,
             // for example, a `map` method could belong to user-defined trait instead of to `Iterator`)
@@ -41,10 +41,6 @@ information on the pattern matching. As mentioned in [Define
 Lints](defining_lints.md#lint-types), the `methods` lint type is full of pattern
 matching with `MethodCall` in case the reader wishes to explore more.
 
-Additionally, we use the [`clippy_utils::sym!`][sym] macro to conveniently
-convert an input `our_fancy_method` into a `Symbol` and compare that symbol to
-the [`Ident`]'s name in the [`PathSegment`] in the [`MethodCall`].
-
 ## Checking if a `impl` block implements a method
 
 While sometimes we want to check whether a method is being called or not, other
@@ -71,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
         // Check if item is a method/function
         if let ImplItemKind::Fn(ref signature, _) = impl_item.kind
             // Check the method is named `our_fancy_method`
-            && impl_item.ident.name == sym!(our_fancy_method)
+            && impl_item.ident.name.as_str() == "our_fancy_method"
             // We can also check it has a parameter `self`
             && signature.decl.implicit_self.has_implicit_self()
             // We can go even further and even check if its return type is `String`
@@ -85,9 +81,6 @@ impl<'tcx> LateLintPass<'tcx> for MyTypeImpl {
 
 [`check_impl_item`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html#method.check_impl_item
 [`ExprKind`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html
-[`Ident`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/struct.Ident.html
 [`ImplItem`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_hir/hir/struct.ImplItem.html
 [`LateLintPass`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_lint/trait.LateLintPass.html
 [`MethodCall`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/enum.ExprKind.html#variant.MethodCall
-[`PathSegment`]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/hir/struct.PathSegment.html
-[sym]: https://doc.rust-lang.org/stable/nightly-rustc/clippy_utils/macro.sym.html
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 43b551ae216..670b5cbef82 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -456,7 +456,7 @@ default configuration of Clippy. By default, any configuration will replace the
 * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
 * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "AccessKit", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
@@ -666,6 +666,16 @@ 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)
 
 
+## `module-item-order-groupings`
+The named groupings of different source item kinds within modules.
+
+**Default Value:** `[["modules", ["extern_crate", "mod", "foreign_mod"]], ["use", ["use"]], ["macros", ["macro"]], ["global_asm", ["global_asm"]], ["UPPER_SNAKE_CASE", ["static", "const"]], ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]], ["lower_snake_case", ["fn"]]]`
+
+---
+**Affected lints:**
+* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)
+
+
 ## `msrv`
 The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
 
@@ -710,6 +720,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`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)
+* [`map_with_unused_argument_over_ranges`](https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges)
 * [`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)
@@ -783,6 +794,16 @@ The maximum number of single char bindings a scope may have
 * [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names)
 
 
+## `source-item-ordering`
+Which kind of elements should be ordered internally, possible values being `enum`, `impl`, `module`, `struct`, `trait`.
+
+**Default Value:** `["enum", "impl", "module", "struct", "trait"]`
+
+---
+**Affected lints:**
+* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)
+
+
 ## `stack-size-threshold`
 The maximum allowed stack size for functions in bytes
 
@@ -862,6 +883,16 @@ The maximum number of lines a function or method can have
 * [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
 
 
+## `trait-assoc-item-kinds-order`
+The order of associated items in traits.
+
+**Default Value:** `["const", "type", "fn"]`
+
+---
+**Affected lints:**
+* [`arbitrary_source_item_ordering`](https://rust-lang.github.io/rust-clippy/master/index.html#arbitrary_source_item_ordering)
+
+
 ## `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
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 4757c0b1339..600d5b6e2c8 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -1,6 +1,10 @@
 use crate::ClippyConfiguration;
 use crate::msrvs::Msrv;
-use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename};
+use crate::types::{
+    DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename, SourceItemOrdering,
+    SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind,
+    SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
+};
 use rustc_errors::Applicability;
 use rustc_session::Session;
 use rustc_span::edit_distance::edit_distance;
@@ -17,8 +21,9 @@ use std::{cmp, env, fmt, fs, io};
 #[rustfmt::skip]
 const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
     "KiB", "MiB", "GiB", "TiB", "PiB", "EiB",
+    "MHz", "GHz", "THz",
     "AccessKit",
-    "CoreFoundation", "CoreGraphics", "CoreText",
+    "CoAP", "CoreFoundation", "CoreGraphics", "CoreText",
     "DevOps",
     "Direct2D", "Direct3D", "DirectWrite", "DirectX",
     "ECMAScript",
@@ -46,6 +51,29 @@ const DEFAULT_ALLOWED_IDENTS_BELOW_MIN_CHARS: &[&str] = &["i", "j", "x", "y", "z
 const DEFAULT_ALLOWED_PREFIXES: &[&str] = &["to", "as", "into", "from", "try_into", "try_from"];
 const DEFAULT_ALLOWED_TRAITS_WITH_RENAMED_PARAMS: &[&str] =
     &["core::convert::From", "core::convert::TryFrom", "core::str::FromStr"];
+const DEFAULT_MODULE_ITEM_ORDERING_GROUPS: &[(&str, &[SourceItemOrderingModuleItemKind])] = {
+    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+    use SourceItemOrderingModuleItemKind::*;
+    &[
+        ("modules", &[ExternCrate, Mod, ForeignMod]),
+        ("use", &[Use]),
+        ("macros", &[Macro]),
+        ("global_asm", &[GlobalAsm]),
+        ("UPPER_SNAKE_CASE", &[Static, Const]),
+        ("PascalCase", &[TyAlias, Enum, Struct, Union, Trait, TraitAlias, Impl]),
+        ("lower_snake_case", &[Fn]),
+    ]
+};
+const DEFAULT_TRAIT_ASSOC_ITEM_KINDS_ORDER: &[SourceItemOrderingTraitAssocItemKind] = {
+    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+    use SourceItemOrderingTraitAssocItemKind::*;
+    &[Const, Type, Fn]
+};
+const DEFAULT_SOURCE_ITEM_ORDERING: &[SourceItemOrderingCategory] = {
+    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+    use SourceItemOrderingCategory::*;
+    &[Enum, Impl, Module, Struct, Trait]
+};
 
 /// Conf with parse errors
 #[derive(Default)]
@@ -102,7 +130,9 @@ pub fn sanitize_explanation(raw_docs: &str) -> String {
     // Remove tags and hidden code:
     let mut explanation = String::with_capacity(128);
     let mut in_code = false;
-    for line in raw_docs.lines().map(str::trim) {
+    for line in raw_docs.lines() {
+        let line = line.strip_prefix(' ').unwrap_or(line);
+
         if let Some(lang) = line.strip_prefix("```") {
             let tag = lang.split_once(',').map_or(lang, |(left, _)| left);
             if !in_code && matches!(tag, "" | "rust" | "ignore" | "should_panic" | "no_run" | "compile_fail") {
@@ -530,6 +560,9 @@ define_Conf! {
     /// crate. For example, `pub(crate)` items.
     #[lints(missing_docs_in_private_items)]
     missing_docs_in_crate_items: bool = false,
+    /// The named groupings of different source item kinds within modules.
+    #[lints(arbitrary_source_item_ordering)]
+    module_item_order_groupings: SourceItemOrderingModuleItemGroupings = DEFAULT_MODULE_ITEM_ORDERING_GROUPS.into(),
     /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
     #[default_text = "current version"]
     #[lints(
@@ -570,6 +603,7 @@ define_Conf! {
         manual_try_fold,
         map_clone,
         map_unwrap_or,
+        map_with_unused_argument_over_ranges,
         match_like_matches_macro,
         mem_replace_with_default,
         missing_const_for_fn,
@@ -608,6 +642,9 @@ define_Conf! {
     /// The maximum number of single char bindings a scope may have
     #[lints(many_single_char_names)]
     single_char_binding_names_threshold: u64 = 4,
+    /// Which kind of elements should be ordered internally, possible values being `enum`, `impl`, `module`, `struct`, `trait`.
+    #[lints(arbitrary_source_item_ordering)]
+    source_item_ordering: SourceItemOrdering = DEFAULT_SOURCE_ITEM_ORDERING.into(),
     /// The maximum allowed stack size for functions in bytes
     #[lints(large_stack_frames)]
     stack_size_threshold: u64 = 512_000,
@@ -637,6 +674,9 @@ define_Conf! {
     /// The maximum number of lines a function or method can have
     #[lints(too_many_lines)]
     too_many_lines_threshold: u64 = 100,
+    /// The order of associated items in traits.
+    #[lints(arbitrary_source_item_ordering)]
+    trait_assoc_item_kinds_order: SourceItemOrderingTraitAssocItemKinds = DEFAULT_TRAIT_ASSOC_ITEM_KINDS_ORDER.into(),
     /// The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
     /// reference. By default there is no limit
     #[default_text = "target_pointer_width * 2"]
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index 42651521f8d..1c3f32c2514 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -20,6 +20,7 @@ extern crate rustc_driver;
 extern crate rustc_errors;
 extern crate rustc_session;
 extern crate rustc_span;
+extern crate smallvec;
 
 mod conf;
 mod metadata;
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index 2f4da4cba3d..764ca8fb50a 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -3,6 +3,7 @@ use rustc_attr::parse_version;
 use rustc_session::{RustcVersion, Session};
 use rustc_span::{Symbol, sym};
 use serde::Deserialize;
+use smallvec::{SmallVec, smallvec};
 use std::fmt;
 
 macro_rules! msrv_aliases {
@@ -18,7 +19,7 @@ macro_rules! msrv_aliases {
 // names may refer to stabilized feature flags or library items
 msrv_aliases! {
     1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY }
-    1,82,0 { IS_NONE_OR }
+    1,82,0 { IS_NONE_OR, REPEAT_N }
     1,81,0 { LINT_REASONS_STABILIZATION }
     1,80,0 { BOX_INTO_ITER}
     1,77,0 { C_STR_LITERALS }
@@ -54,7 +55,7 @@ msrv_aliases! {
     1,33,0 { UNDERSCORE_IMPORTS }
     1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES }
     1,29,0 { ITER_FLATTEN }
-    1,28,0 { FROM_BOOL }
+    1,28,0 { FROM_BOOL, REPEAT_WITH }
     1,27,0 { ITERATOR_TRY_FOLD }
     1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN }
     1,24,0 { IS_ASCII_DIGIT }
@@ -67,7 +68,7 @@ msrv_aliases! {
 /// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]`
 #[derive(Debug, Clone)]
 pub struct Msrv {
-    stack: Vec<RustcVersion>,
+    stack: SmallVec<[RustcVersion; 2]>,
 }
 
 impl fmt::Display for Msrv {
@@ -87,14 +88,14 @@ impl<'de> Deserialize<'de> for Msrv {
     {
         let v = String::deserialize(deserializer)?;
         parse_version(Symbol::intern(&v))
-            .map(|v| Msrv { stack: vec![v] })
+            .map(|v| Msrv { stack: smallvec![v] })
             .ok_or_else(|| serde::de::Error::custom("not a valid Rust version"))
     }
 }
 
 impl Msrv {
     pub fn empty() -> Msrv {
-        Msrv { stack: Vec::new() }
+        Msrv { stack: SmallVec::new() }
     }
 
     pub fn read_cargo(&mut self, sess: &Session) {
@@ -103,7 +104,7 @@ impl Msrv {
             .and_then(|v| parse_version(Symbol::intern(&v)));
 
         match (self.current(), cargo_msrv) {
-            (None, Some(cargo_msrv)) => self.stack = vec![cargo_msrv],
+            (None, Some(cargo_msrv)) => self.stack = smallvec![cargo_msrv],
             (Some(clippy_msrv), Some(cargo_msrv)) => {
                 if clippy_msrv != cargo_msrv {
                     sess.dcx().warn(format!(
diff --git a/src/tools/clippy/clippy_config/src/types.rs b/src/tools/clippy/clippy_config/src/types.rs
index bab63911182..fe576424148 100644
--- a/src/tools/clippy/clippy_config/src/types.rs
+++ b/src/tools/clippy/clippy_config/src/types.rs
@@ -1,5 +1,6 @@
 use serde::de::{self, Deserializer, Visitor};
 use serde::{Deserialize, Serialize, ser};
+use std::collections::HashMap;
 use std::fmt;
 
 #[derive(Debug, Deserialize)]
@@ -102,6 +103,306 @@ impl<'de> Deserialize<'de> for MacroMatcher {
     }
 }
 
+/// Represents the item categories that can be ordered by the source ordering lint.
+#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum SourceItemOrderingCategory {
+    Enum,
+    Impl,
+    Module,
+    Struct,
+    Trait,
+}
+
+/// Represents which item categories are enabled for ordering.
+///
+/// The [`Deserialize`] implementation checks that there are no duplicates in
+/// the user configuration.
+pub struct SourceItemOrdering(Vec<SourceItemOrderingCategory>);
+
+impl SourceItemOrdering {
+    pub fn contains(&self, category: &SourceItemOrderingCategory) -> bool {
+        self.0.contains(category)
+    }
+}
+
+impl<T> From<T> for SourceItemOrdering
+where
+    T: Into<Vec<SourceItemOrderingCategory>>,
+{
+    fn from(value: T) -> Self {
+        Self(value.into())
+    }
+}
+
+impl core::fmt::Debug for SourceItemOrdering {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl<'de> Deserialize<'de> for SourceItemOrdering {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let items = Vec::<SourceItemOrderingCategory>::deserialize(deserializer)?;
+        let mut items_set = std::collections::HashSet::new();
+
+        for item in &items {
+            if items_set.contains(item) {
+                return Err(de::Error::custom(format!(
+                    "The category \"{item:?}\" was enabled more than once in the source ordering configuration."
+                )));
+            }
+            items_set.insert(item);
+        }
+
+        Ok(Self(items))
+    }
+}
+
+impl Serialize for SourceItemOrdering {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: ser::Serializer,
+    {
+        self.0.serialize(serializer)
+    }
+}
+
+/// Represents the items that can occur within a module.
+#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum SourceItemOrderingModuleItemKind {
+    ExternCrate,
+    Mod,
+    ForeignMod,
+    Use,
+    Macro,
+    GlobalAsm,
+    Static,
+    Const,
+    TyAlias,
+    Enum,
+    Struct,
+    Union,
+    Trait,
+    TraitAlias,
+    Impl,
+    Fn,
+}
+
+impl SourceItemOrderingModuleItemKind {
+    pub fn all_variants() -> Vec<Self> {
+        #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+        use SourceItemOrderingModuleItemKind::*;
+        vec![
+            ExternCrate,
+            Mod,
+            ForeignMod,
+            Use,
+            Macro,
+            GlobalAsm,
+            Static,
+            Const,
+            TyAlias,
+            Enum,
+            Struct,
+            Union,
+            Trait,
+            TraitAlias,
+            Impl,
+            Fn,
+        ]
+    }
+}
+
+/// Represents the configured ordering of items within a module.
+///
+/// The [`Deserialize`] implementation checks that no item kinds have been
+/// omitted and that there are no duplicates in the user configuration.
+#[derive(Clone)]
+pub struct SourceItemOrderingModuleItemGroupings {
+    groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)>,
+    lut: HashMap<SourceItemOrderingModuleItemKind, usize>,
+}
+
+impl SourceItemOrderingModuleItemGroupings {
+    fn build_lut(
+        groups: &[(String, Vec<SourceItemOrderingModuleItemKind>)],
+    ) -> HashMap<SourceItemOrderingModuleItemKind, usize> {
+        let mut lut = HashMap::new();
+        for (group_index, (_, items)) in groups.iter().enumerate() {
+            for item in items {
+                lut.insert(item.clone(), group_index);
+            }
+        }
+        lut
+    }
+
+    pub fn module_level_order_of(&self, item: &SourceItemOrderingModuleItemKind) -> Option<usize> {
+        self.lut.get(item).copied()
+    }
+}
+
+impl From<&[(&str, &[SourceItemOrderingModuleItemKind])]> for SourceItemOrderingModuleItemGroupings {
+    fn from(value: &[(&str, &[SourceItemOrderingModuleItemKind])]) -> Self {
+        let groups: Vec<(String, Vec<SourceItemOrderingModuleItemKind>)> =
+            value.iter().map(|item| (item.0.to_string(), item.1.to_vec())).collect();
+        let lut = Self::build_lut(&groups);
+        Self { groups, lut }
+    }
+}
+
+impl core::fmt::Debug for SourceItemOrderingModuleItemGroupings {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.groups.fmt(f)
+    }
+}
+
+impl<'de> Deserialize<'de> for SourceItemOrderingModuleItemGroupings {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let groups = Vec::<(String, Vec<SourceItemOrderingModuleItemKind>)>::deserialize(deserializer)?;
+        let items_total: usize = groups.iter().map(|(_, v)| v.len()).sum();
+        let lut = Self::build_lut(&groups);
+
+        let mut expected_items = SourceItemOrderingModuleItemKind::all_variants();
+        for item in lut.keys() {
+            expected_items.retain(|i| i != item);
+        }
+
+        let all_items = SourceItemOrderingModuleItemKind::all_variants();
+        if expected_items.is_empty() && items_total == all_items.len() {
+            let Some(use_group_index) = lut.get(&SourceItemOrderingModuleItemKind::Use) else {
+                return Err(de::Error::custom("Error in internal LUT."));
+            };
+            let Some((_, use_group_items)) = groups.get(*use_group_index) else {
+                return Err(de::Error::custom("Error in internal LUT."));
+            };
+            if use_group_items.len() > 1 {
+                return Err(de::Error::custom(
+                    "The group containing the \"use\" item kind may not contain any other item kinds. \
+                    The \"use\" items will (generally) be sorted by rustfmt already. \
+                    Therefore it makes no sense to implement linting rules that may conflict with rustfmt.",
+                ));
+            }
+
+            Ok(Self { groups, lut })
+        } else if items_total != all_items.len() {
+            Err(de::Error::custom(format!(
+                "Some module item kinds were configured more than once, or were missing, in the source ordering configuration. \
+                The module item kinds are: {all_items:?}"
+            )))
+        } else {
+            Err(de::Error::custom(format!(
+                "Not all module item kinds were part of the configured source ordering rule. \
+                All item kinds must be provided in the config, otherwise the required source ordering would remain ambiguous. \
+                The module item kinds are: {all_items:?}"
+            )))
+        }
+    }
+}
+
+impl Serialize for SourceItemOrderingModuleItemGroupings {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: ser::Serializer,
+    {
+        self.groups.serialize(serializer)
+    }
+}
+
+/// Represents all kinds of trait associated items.
+#[derive(Clone, Debug, Deserialize, PartialEq, PartialOrd, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum SourceItemOrderingTraitAssocItemKind {
+    Const,
+    Fn,
+    Type,
+}
+
+impl SourceItemOrderingTraitAssocItemKind {
+    pub fn all_variants() -> Vec<Self> {
+        #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+        use SourceItemOrderingTraitAssocItemKind::*;
+        vec![Const, Fn, Type]
+    }
+}
+
+/// Represents the order in which associated trait items should be ordered.
+///
+/// The reason to wrap a `Vec` in a newtype is to be able to implement
+/// [`Deserialize`]. Implementing `Deserialize` allows for implementing checks
+/// on configuration completeness at the time of loading the clippy config,
+/// letting the user know if there's any issues with the config (e.g. not
+/// listing all item kinds that should be sorted).
+#[derive(Clone)]
+pub struct SourceItemOrderingTraitAssocItemKinds(Vec<SourceItemOrderingTraitAssocItemKind>);
+
+impl SourceItemOrderingTraitAssocItemKinds {
+    pub fn index_of(&self, item: &SourceItemOrderingTraitAssocItemKind) -> Option<usize> {
+        self.0.iter().position(|i| i == item)
+    }
+}
+
+impl<T> From<T> for SourceItemOrderingTraitAssocItemKinds
+where
+    T: Into<Vec<SourceItemOrderingTraitAssocItemKind>>,
+{
+    fn from(value: T) -> Self {
+        Self(value.into())
+    }
+}
+
+impl core::fmt::Debug for SourceItemOrderingTraitAssocItemKinds {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl<'de> Deserialize<'de> for SourceItemOrderingTraitAssocItemKinds {
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: Deserializer<'de>,
+    {
+        let items = Vec::<SourceItemOrderingTraitAssocItemKind>::deserialize(deserializer)?;
+
+        let mut expected_items = SourceItemOrderingTraitAssocItemKind::all_variants();
+        for item in &items {
+            expected_items.retain(|i| i != item);
+        }
+
+        let all_items = SourceItemOrderingTraitAssocItemKind::all_variants();
+        if expected_items.is_empty() && items.len() == all_items.len() {
+            Ok(Self(items))
+        } else if items.len() != all_items.len() {
+            Err(de::Error::custom(format!(
+                "Some trait associated item kinds were configured more than once, or were missing, in the source ordering configuration. \
+                The trait associated item kinds are: {all_items:?}",
+            )))
+        } else {
+            Err(de::Error::custom(format!(
+                "Not all trait associated item kinds were part of the configured source ordering rule. \
+                All item kinds must be provided in the config, otherwise the required source ordering would remain ambiguous. \
+                The trait associated item kinds are: {all_items:?}"
+            )))
+        }
+    }
+}
+
+impl Serialize for SourceItemOrderingTraitAssocItemKinds {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: ser::Serializer,
+    {
+        self.0.serialize(serializer)
+    }
+}
+
 // these impls are never actually called but are used by the various config options that default to
 // empty lists
 macro_rules! unimplemented_serialize {
diff --git a/src/tools/clippy/clippy_dev/src/serve.rs b/src/tools/clippy/clippy_dev/src/serve.rs
index d367fefec61..a2d1236629f 100644
--- a/src/tools/clippy/clippy_dev/src/serve.rs
+++ b/src/tools/clippy/clippy_dev/src/serve.rs
@@ -20,8 +20,14 @@ pub fn run(port: u16, lint: Option<String>) -> ! {
 
     loop {
         let index_time = mtime("util/gh-pages/index.html");
+        let times = [
+            "clippy_lints/src",
+            "util/gh-pages/index_template.html",
+            "tests/compile-test.rs",
+        ]
+        .map(mtime);
 
-        if index_time < mtime("clippy_lints/src") || index_time < mtime("util/gh-pages/index_template.html") {
+        if times.iter().any(|&time| index_time < time) {
             Command::new(env::var("CARGO").unwrap_or("cargo".into()))
                 .arg("collect-metadata")
                 .spawn()
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index d6ed36d52f4..795456ad3c5 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -762,13 +762,19 @@ fn parse_contents(contents: &str, module: &str, lints: &mut Vec<Lint>) {
             Literal{..}(desc)
         );
 
-        if let Some(LintDeclSearchResult {
-            token_kind: TokenKind::CloseBrace,
-            range,
-            ..
-        }) = iter.next()
-        {
-            lints.push(Lint::new(name, group, desc, module, start..range.end));
+        if let Some(end) = iter.find_map(|t| {
+            if let LintDeclSearchResult {
+                token_kind: TokenKind::CloseBrace,
+                range,
+                ..
+            } = t
+            {
+                Some(range.end)
+            } else {
+                None
+            }
+        }) {
+            lints.push(Lint::new(name, group, desc, module, start..end));
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
new file mode 100644
index 00000000000..8719f61a890
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -0,0 +1,531 @@
+use clippy_config::Conf;
+use clippy_config::types::{
+    SourceItemOrderingCategory, SourceItemOrderingModuleItemGroupings, SourceItemOrderingModuleItemKind,
+    SourceItemOrderingTraitAssocItemKind, SourceItemOrderingTraitAssocItemKinds,
+};
+use clippy_utils::diagnostics::span_lint_and_note;
+use rustc_hir::{
+    AssocItemKind, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind, UseKind,
+    Variant, VariantData,
+};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::impl_lint_pass;
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Confirms that items are sorted in source files as per configuration.
+    ///
+    /// ### Why restrict this?
+    ///
+    /// Keeping a consistent ordering throughout the codebase helps with working
+    /// as a team, and possibly improves maintainability of the codebase. The
+    /// idea is that by defining a consistent and enforceable rule for how
+    /// source files are structured, less time will be wasted during reviews on
+    /// a topic that is (under most circumstances) not relevant to the logic
+    /// implemented in the code. Sometimes this will be referred to as
+    /// "bikeshedding".
+    ///
+    /// ### Default Ordering and Configuration
+    ///
+    /// As there is no generally applicable rule, and each project may have
+    /// different requirements, the lint can be configured with high
+    /// granularity. The configuration is split into two stages:
+    ///
+    /// 1. Which item kinds that should have an internal order enforced.
+    /// 2. Individual ordering rules per item kind.
+    ///
+    /// The item kinds that can be linted are:
+    /// - Module (with customized groupings, alphabetical within)
+    /// - Trait (with customized order of associated items, alphabetical within)
+    /// - Enum, Impl, Struct (purely alphabetical)
+    ///
+    /// #### Module Item Order
+    ///
+    /// Due to the large variation of items within modules, the ordering can be
+    /// configured on a very granular level. Item kinds can be grouped together
+    /// arbitrarily, items within groups will be ordered alphabetically. The
+    /// following table shows the default groupings:
+    ///
+    /// | Group              | Item Kinds           |
+    /// |--------------------|----------------------|
+    /// | `modules`          | "mod", "foreign_mod" |
+    /// | `use`              | "use"                |
+    /// | `macros`           | "macro"              |
+    /// | `global_asm`       | "global_asm"         |
+    /// | `UPPER_SNAKE_CASE` | "static", "const"    |
+    /// | `PascalCase`       | "ty_alias", "opaque_ty", "enum", "struct", "union", "trait", "trait_alias", "impl" |
+    /// | `lower_snake_case` | "fn"                 |
+    ///
+    /// All item kinds must be accounted for to create an enforceable linting
+    /// rule set.
+    ///
+    /// ### Known Problems
+    ///
+    /// #### Performance Impact
+    ///
+    /// Keep in mind, that ordering source code alphabetically can lead to
+    /// reduced performance in cases where the most commonly used enum variant
+    /// isn't the first entry anymore, and similar optimizations that can reduce
+    /// branch misses, cache locality and such. Either don't use this lint if
+    /// that's relevant, or disable the lint in modules or items specifically
+    /// where it matters. Other solutions can be to use profile guided
+    /// optimization (PGO), post-link optimization (e.g. using BOLT for LLVM),
+    /// or other advanced optimization methods. A good starting point to dig
+    /// into optimization is [cargo-pgo][cargo-pgo].
+    ///
+    /// #### Lints on a Contains basis
+    ///
+    /// The lint can be disabled only on a "contains" basis, but not per element
+    /// within a "container", e.g. the lint works per-module, per-struct,
+    /// per-enum, etc. but not for "don't order this particular enum variant".
+    ///
+    /// #### Module documentation
+    ///
+    /// Module level rustdoc comments are not part of the resulting syntax tree
+    /// and as such cannot be linted from within `check_mod`. Instead, the
+    /// `rustdoc::missing_documentation` lint may be used.
+    ///
+    /// #### Module Tests
+    ///
+    /// This lint does not implement detection of module tests (or other feature
+    /// dependent elements for that matter). To lint the location of mod tests,
+    /// the lint `items_after_test_module` can be used instead.
+    ///
+    /// ### Example
+    ///
+    /// ```no_run
+    /// trait TraitUnordered {
+    ///     const A: bool;
+    ///     const C: bool;
+    ///     const B: bool;
+    ///
+    ///     type SomeType;
+    ///
+    ///     fn a();
+    ///     fn c();
+    ///     fn b();
+    /// }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// trait TraitOrdered {
+    ///     const A: bool;
+    ///     const B: bool;
+    ///     const C: bool;
+    ///
+    ///     type SomeType;
+    ///
+    ///     fn a();
+    ///     fn b();
+    ///     fn c();
+    /// }
+    /// ```
+    ///
+    /// [cargo-pgo]: https://github.com/Kobzol/cargo-pgo/blob/main/README.md
+    ///
+    #[clippy::version = "1.82.0"]
+    pub ARBITRARY_SOURCE_ITEM_ORDERING,
+    restriction,
+    "arbitrary source item ordering"
+}
+
+impl_lint_pass!(ArbitrarySourceItemOrdering => [ARBITRARY_SOURCE_ITEM_ORDERING]);
+
+#[derive(Debug)]
+#[allow(clippy::struct_excessive_bools)] // Bools are cached feature flags.
+pub struct ArbitrarySourceItemOrdering {
+    assoc_types_order: SourceItemOrderingTraitAssocItemKinds,
+    enable_ordering_for_enum: bool,
+    enable_ordering_for_impl: bool,
+    enable_ordering_for_module: bool,
+    enable_ordering_for_struct: bool,
+    enable_ordering_for_trait: bool,
+    module_item_order_groupings: SourceItemOrderingModuleItemGroupings,
+}
+
+impl ArbitrarySourceItemOrdering {
+    pub fn new(conf: &'static Conf) -> Self {
+        #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+        use SourceItemOrderingCategory::*;
+        Self {
+            assoc_types_order: conf.trait_assoc_item_kinds_order.clone(),
+            enable_ordering_for_enum: conf.source_item_ordering.contains(&Enum),
+            enable_ordering_for_impl: conf.source_item_ordering.contains(&Impl),
+            enable_ordering_for_module: conf.source_item_ordering.contains(&Module),
+            enable_ordering_for_struct: conf.source_item_ordering.contains(&Struct),
+            enable_ordering_for_trait: conf.source_item_ordering.contains(&Trait),
+            module_item_order_groupings: conf.module_item_order_groupings.clone(),
+        }
+    }
+
+    /// Produces a linting warning for incorrectly ordered impl items.
+    fn lint_impl_item<T: LintContext>(&self, cx: &T, item: &ImplItemRef, before_item: &ImplItemRef) {
+        span_lint_and_note(
+            cx,
+            ARBITRARY_SOURCE_ITEM_ORDERING,
+            item.span,
+            format!(
+                "incorrect ordering of impl items (defined order: {:?})",
+                self.assoc_types_order
+            ),
+            Some(before_item.span),
+            format!("should be placed before `{}`", before_item.ident.as_str(),),
+        );
+    }
+
+    /// Produces a linting warning for incorrectly ordered item members.
+    fn lint_member_name<T: LintContext>(
+        cx: &T,
+        ident: &rustc_span::symbol::Ident,
+        before_ident: &rustc_span::symbol::Ident,
+    ) {
+        span_lint_and_note(
+            cx,
+            ARBITRARY_SOURCE_ITEM_ORDERING,
+            ident.span,
+            "incorrect ordering of items (must be alphabetically ordered)",
+            Some(before_ident.span),
+            format!("should be placed before `{}`", before_ident.as_str(),),
+        );
+    }
+
+    fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>) {
+        let span = if item.ident.as_str().is_empty() {
+            &item.span
+        } else {
+            &item.ident.span
+        };
+
+        let (before_span, note) = if before_item.ident.as_str().is_empty() {
+            (
+                &before_item.span,
+                "should be placed before the following item".to_owned(),
+            )
+        } else {
+            (
+                &before_item.ident.span,
+                format!("should be placed before `{}`", before_item.ident.as_str(),),
+            )
+        };
+
+        // This catches false positives where generated code gets linted.
+        if span == before_span {
+            return;
+        }
+
+        span_lint_and_note(
+            cx,
+            ARBITRARY_SOURCE_ITEM_ORDERING,
+            *span,
+            "incorrect ordering of items (must be alphabetically ordered)",
+            Some(*before_span),
+            note,
+        );
+    }
+
+    /// Produces a linting warning for incorrectly ordered trait items.
+    fn lint_trait_item<T: LintContext>(&self, cx: &T, item: &TraitItemRef, before_item: &TraitItemRef) {
+        span_lint_and_note(
+            cx,
+            ARBITRARY_SOURCE_ITEM_ORDERING,
+            item.span,
+            format!(
+                "incorrect ordering of trait items (defined order: {:?})",
+                self.assoc_types_order
+            ),
+            Some(before_item.span),
+            format!("should be placed before `{}`", before_item.ident.as_str(),),
+        );
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        match &item.kind {
+            ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => {
+                let mut cur_v: Option<&Variant<'_>> = None;
+                for variant in enum_def.variants {
+                    if in_external_macro(cx.sess(), variant.span) {
+                        continue;
+                    }
+
+                    if let Some(cur_v) = cur_v {
+                        if cur_v.ident.name.as_str() > variant.ident.name.as_str() && cur_v.span != variant.span {
+                            Self::lint_member_name(cx, &variant.ident, &cur_v.ident);
+                        }
+                    }
+                    cur_v = Some(variant);
+                }
+            },
+            ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
+                let mut cur_f: Option<&FieldDef<'_>> = None;
+                for field in *fields {
+                    if in_external_macro(cx.sess(), field.span) {
+                        continue;
+                    }
+
+                    if let Some(cur_f) = cur_f {
+                        if cur_f.ident.name.as_str() > field.ident.name.as_str() && cur_f.span != field.span {
+                            Self::lint_member_name(cx, &field.ident, &cur_f.ident);
+                        }
+                    }
+                    cur_f = Some(field);
+                }
+            },
+            ItemKind::Trait(is_auto, _safety, _generics, _generic_bounds, item_ref)
+                if self.enable_ordering_for_trait && *is_auto == IsAuto::No =>
+            {
+                let mut cur_t: Option<&TraitItemRef> = None;
+
+                for item in *item_ref {
+                    if in_external_macro(cx.sess(), item.span) {
+                        continue;
+                    }
+
+                    if let Some(cur_t) = cur_t {
+                        let cur_t_kind = convert_assoc_item_kind(cur_t.kind);
+                        let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);
+                        let item_kind = convert_assoc_item_kind(item.kind);
+                        let item_kind_index = self.assoc_types_order.index_of(&item_kind);
+
+                        if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
+                            Self::lint_member_name(cx, &item.ident, &cur_t.ident);
+                        } else if cur_t_kind_index > item_kind_index {
+                            self.lint_trait_item(cx, item, cur_t);
+                        }
+                    }
+                    cur_t = Some(item);
+                }
+            },
+            ItemKind::Impl(trait_impl) if self.enable_ordering_for_impl => {
+                let mut cur_t: Option<&ImplItemRef> = None;
+
+                for item in trait_impl.items {
+                    if in_external_macro(cx.sess(), item.span) {
+                        continue;
+                    }
+
+                    if let Some(cur_t) = cur_t {
+                        let cur_t_kind = convert_assoc_item_kind(cur_t.kind);
+                        let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);
+                        let item_kind = convert_assoc_item_kind(item.kind);
+                        let item_kind_index = self.assoc_types_order.index_of(&item_kind);
+
+                        if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
+                            Self::lint_member_name(cx, &item.ident, &cur_t.ident);
+                        } else if cur_t_kind_index > item_kind_index {
+                            self.lint_impl_item(cx, item, cur_t);
+                        }
+                    }
+                    cur_t = Some(item);
+                }
+            },
+            _ => {}, // Catch-all for `ItemKinds` that don't have fields.
+        }
+    }
+
+    fn check_mod(&mut self, cx: &LateContext<'tcx>, module: &'tcx Mod<'tcx>, _: HirId) {
+        struct CurItem<'a> {
+            item: &'a Item<'a>,
+            order: usize,
+            name: String,
+        }
+        let mut cur_t: Option<CurItem<'_>> = None;
+
+        if !self.enable_ordering_for_module {
+            return;
+        }
+
+        let items = module.item_ids.iter().map(|&id| cx.tcx.hir().item(id));
+
+        // Iterates over the items within a module.
+        //
+        // As of 2023-05-09, the Rust compiler will hold the entries in the same
+        // order as they appear in the source code, which is convenient for us,
+        // as no sorting by source map/line of code has to be applied.
+        //
+        for item in items {
+            if in_external_macro(cx.sess(), item.span) {
+                continue;
+            }
+
+            // The following exceptions (skipping with `continue;`) may not be
+            // complete, edge cases have not been explored further than what
+            // appears in the existing code base.
+            if item.ident.name == rustc_span::symbol::kw::Empty {
+                if let ItemKind::Impl(_) = item.kind {
+                    // Sorting trait impls for unnamed types makes no sense.
+                    if get_item_name(item).is_empty() {
+                        continue;
+                    }
+                } else if let ItemKind::ForeignMod { .. } = item.kind {
+                    continue;
+                } else if let ItemKind::GlobalAsm(_) = item.kind {
+                    continue;
+                } else if let ItemKind::Use(path, use_kind) = item.kind {
+                    if path.segments.is_empty() {
+                        // Use statements that contain braces get caught here.
+                        // They will still be linted internally.
+                        continue;
+                    } else if path.segments.len() >= 2
+                        && (path.segments[0].ident.name == rustc_span::sym::std
+                            || path.segments[0].ident.name == rustc_span::sym::core)
+                        && path.segments[1].ident.name == rustc_span::sym::prelude
+                    {
+                        // Filters the autogenerated prelude use statement.
+                        // e.g. `use std::prelude::rustc_2021`
+                    } else if use_kind == UseKind::Glob {
+                        // Filters glob kinds of uses.
+                        // e.g. `use std::sync::*`
+                    } else {
+                        // This can be used for debugging.
+                        // println!("Unknown autogenerated use statement: {:?}", item);
+                    }
+                    continue;
+                }
+            }
+
+            if item.ident.name.as_str().starts_with('_') {
+                // Filters out unnamed macro-like impls for various derives,
+                // e.g. serde::Serialize or num_derive::FromPrimitive.
+                continue;
+            }
+
+            if item.ident.name == rustc_span::sym::std && item.span.is_dummy() {
+                if let ItemKind::ExternCrate(None) = item.kind {
+                    // Filters the auto-included Rust standard library.
+                    continue;
+                }
+                println!("Unknown item: {item:?}");
+            }
+
+            let item_kind = convert_module_item_kind(&item.kind);
+            let module_level_order = self
+                .module_item_order_groupings
+                .module_level_order_of(&item_kind)
+                .unwrap_or_default();
+
+            if let Some(cur_t) = cur_t.as_ref() {
+                use std::cmp::Ordering; // Better legibility.
+                match module_level_order.cmp(&cur_t.order) {
+                    Ordering::Less => {
+                        Self::lint_member_item(cx, item, cur_t.item);
+                    },
+                    Ordering::Equal if item_kind == SourceItemOrderingModuleItemKind::Use => {
+                        // Skip ordering use statements, as these should be ordered by rustfmt.
+                    },
+                    Ordering::Equal if cur_t.name > get_item_name(item) => {
+                        Self::lint_member_item(cx, item, cur_t.item);
+                    },
+                    Ordering::Equal | Ordering::Greater => {
+                        // Nothing to do in this case, they're already in the right order.
+                    },
+                }
+            }
+
+            // Makes a note of the current item for comparison with the next.
+            cur_t = Some(CurItem {
+                order: module_level_order,
+                item,
+                name: get_item_name(item),
+            });
+        }
+    }
+}
+
+/// Converts a [`rustc_hir::AssocItemKind`] to a
+/// [`SourceItemOrderingTraitAssocItemKind`].
+///
+/// This is implemented here because `rustc_hir` is not a dependency of
+/// `clippy_config`.
+fn convert_assoc_item_kind(value: AssocItemKind) -> SourceItemOrderingTraitAssocItemKind {
+    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+    use SourceItemOrderingTraitAssocItemKind::*;
+    match value {
+        AssocItemKind::Const { .. } => Const,
+        AssocItemKind::Type { .. } => Type,
+        AssocItemKind::Fn { .. } => Fn,
+    }
+}
+
+/// Converts a [`rustc_hir::ItemKind`] to a
+/// [`SourceItemOrderingModuleItemKind`].
+///
+/// This is implemented here because `rustc_hir` is not a dependency of
+/// `clippy_config`.
+fn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleItemKind {
+    #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
+    use SourceItemOrderingModuleItemKind::*;
+    match value {
+        ItemKind::ExternCrate(..) => ExternCrate,
+        ItemKind::Use(..) => Use,
+        ItemKind::Static(..) => Static,
+        ItemKind::Const(..) => Const,
+        ItemKind::Fn(..) => Fn,
+        ItemKind::Macro(..) => Macro,
+        ItemKind::Mod(..) => Mod,
+        ItemKind::ForeignMod { .. } => ForeignMod,
+        ItemKind::GlobalAsm(..) => GlobalAsm,
+        ItemKind::TyAlias(..) => TyAlias,
+        ItemKind::Enum(..) => Enum,
+        ItemKind::Struct(..) => Struct,
+        ItemKind::Union(..) => Union,
+        ItemKind::Trait(..) => Trait,
+        ItemKind::TraitAlias(..) => TraitAlias,
+        ItemKind::Impl(..) => Impl,
+    }
+}
+
+/// Gets the item name for sorting purposes, which in the general case is
+/// `item.ident.name`.
+///
+/// For trait impls, the name used for sorting will be the written path of
+/// `item.self_ty` plus the written path of `item.of_trait`, joined with
+/// exclamation marks. Exclamation marks are used because they are the first
+/// printable ASCII character.
+///
+/// Trait impls generated using a derive-macro will have their path rewritten,
+/// such that for example `Default` is `$crate::default::Default`, and
+/// `std::clone::Clone` is `$crate::clone::Clone`. This behaviour is described
+/// further in the [Rust Reference, Paths Chapter][rust_ref].
+///
+/// [rust_ref]: https://doc.rust-lang.org/reference/paths.html#crate-1
+fn get_item_name(item: &Item<'_>) -> String {
+    match item.kind {
+        ItemKind::Impl(im) => {
+            if let TyKind::Path(path) = im.self_ty.kind {
+                match path {
+                    QPath::Resolved(_, path) => {
+                        let segs = path.segments.iter();
+                        let mut segs: Vec<String> = segs.map(|s| s.ident.name.as_str().to_owned()).collect();
+
+                        if let Some(of_trait) = im.of_trait {
+                            let mut trait_segs: Vec<String> = of_trait
+                                .path
+                                .segments
+                                .iter()
+                                .map(|s| s.ident.name.as_str().to_owned())
+                                .collect();
+                            segs.append(&mut trait_segs);
+                        }
+
+                        segs.push(String::new());
+                        segs.join("!!")
+                    },
+                    QPath::TypeRelative(_, _path_seg) => {
+                        // This case doesn't exist in the clippy tests codebase.
+                        String::new()
+                    },
+                    QPath::LangItem(_, _) => String::new(),
+                }
+            } else {
+                // Impls for anything that isn't a named type can be skipped.
+                String::new()
+            }
+        },
+        _ => item.ident.name.as_str().to_owned(),
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
index 684756ce87f..c29c9f08cf7 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -14,7 +14,7 @@ mod utils;
 
 use clippy_config::Conf;
 use clippy_config::msrvs::{self, Msrv};
-use rustc_ast::{Attribute, MetaItemInner, MetaItemKind, self as ast};
+use rustc_ast::{self as ast, Attribute, MetaItemInner, MetaItemKind};
 use rustc_hir::{ImplItem, Item, TraitItem};
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
index 92b9f9cba52..dc5a6857089 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -1,10 +1,9 @@
-use super::utils::{extract_clippy_lint, is_lint_level, is_word};
 use super::USELESS_ATTRIBUTE;
+use super::utils::{extract_clippy_lint, is_lint_level, is_word};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{SpanRangeExt, first_line_of_span};
-use rustc_ast::MetaItemInner;
+use rustc_ast::{Attribute, Item, ItemKind, MetaItemInner};
 use rustc_errors::Applicability;
-use rustc_ast::{Item, ItemKind, Attribute};
 use rustc_lint::{EarlyContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
index 9952d0af99e..6948cf560a5 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -15,7 +15,7 @@ declare_clippy_lint! {
     /// `MutexGuard`.
     ///
     /// ### Why is this bad?
-    /// The Mutex types found in [`std::sync`][https://doc.rust-lang.org/stable/std/sync/] and
+    /// The Mutex types found in [`std::sync`](https://doc.rust-lang.org/stable/std/sync/) and
     /// [`parking_lot`](https://docs.rs/parking_lot/latest/parking_lot/) are
     /// not designed to operate in an async context across await points.
     ///
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 26888f7e3a0..26a20bc99a0 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -203,6 +203,21 @@ fn check_simplify_not(cx: &LateContext<'_>, msrv: &Msrv, expr: &Expr<'_>) {
         && let Some(suggestion) = simplify_not(cx, msrv, inner)
         && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
     {
+        use clippy_utils::sugg::{Sugg, has_enclosing_paren};
+        let maybe_par = if let Some(sug) = Sugg::hir_opt(cx, inner) {
+            match sug {
+                Sugg::BinOp(..) => true,
+                Sugg::MaybeParen(sug) if !has_enclosing_paren(&sug) => true,
+                _ => false,
+            }
+        } else {
+            false
+        };
+        let suggestion = if maybe_par {
+            format!("({suggestion})")
+        } else {
+            suggestion
+        };
         span_lint_and_sugg(
             cx,
             NONMINIMAL_BOOL,
diff --git a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
index cba8224b84c..f2551a05b1a 100644
--- a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{get_parent_expr, is_from_proc_macro, is_lint_allowed};
 use rustc_errors::Applicability;
-use rustc_hir::{ExprKind, UnOp};
+use rustc_hir::{BorrowKind, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty;
@@ -49,7 +49,7 @@ declare_lint_pass!(BorrowDerefRef => [BORROW_DEREF_REF]);
 
 impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {
-        if let ExprKind::AddrOf(_, Mutability::Not, addrof_target) = e.kind
+        if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, addrof_target) = e.kind
             && let ExprKind::Unary(UnOp::Deref, deref_target) = addrof_target.kind
             && !matches!(deref_target.kind, ExprKind::Unary(UnOp::Deref, ..))
             && !e.span.from_expansion()
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index b11b967f8bc..205357afd84 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
         );
         lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
     } else if let ExprKind::MethodCall(method_path, self_arg, [], _) = &expr.kind {
-        if method_path.ident.name == sym!(cast)
+        if method_path.ident.name.as_str() == "cast"
             && let Some(generic_args) = method_path.args
             && let [GenericArg::Type(cast_to)] = generic_args.args
             // There probably is no obvious reason to do this, just to be consistent with `as` cases.
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 811d33c8bde..abd80abffe6 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -268,8 +268,7 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx
                 if !snippet
                     .split("->")
                     .skip(1)
-                    .map(|s| snippet_eq_ty(s, cast_from) || s.split("where").any(|ty| snippet_eq_ty(ty, cast_from)))
-                    .any(|a| a)
+                    .any(|s| snippet_eq_ty(s, cast_from) || s.split("where").any(|ty| snippet_eq_ty(ty, cast_from)))
                 {
                     return ControlFlow::Break(());
                 }
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index 2e7f91a842e..f76e399517c 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -232,7 +232,7 @@ fn get_types_from_cast<'a>(
     // or `to_type::MAX as from_type`
     let call_from_cast: Option<(&Expr<'_>, &str)> = if let ExprKind::Cast(limit, from_type) = &expr.kind
         // to_type::max_value(), from_type
-        && let TyKind::Path(ref from_type_path) = &from_type.kind
+        && let TyKind::Path(from_type_path) = &from_type.kind
         && let Some(from_sym) = int_ty_to_sym(from_type_path)
     {
         Some((limit, from_sym))
@@ -245,7 +245,7 @@ fn get_types_from_cast<'a>(
         if let ExprKind::Call(from_func, [limit]) = &expr.kind
             // `from_type::from, to_type::max_value()`
             // `from_type::from`
-            && let ExprKind::Path(ref path) = &from_func.kind
+            && let ExprKind::Path(path) = &from_func.kind
             && let Some(from_sym) = get_implementing_type(path, INTS, "from")
         {
             Some((limit, from_sym))
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 477435236a5..383fae7992b 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -30,7 +30,7 @@ declare_clippy_lint! {
     #[clippy::version = "1.35.0"]
     pub COGNITIVE_COMPLEXITY,
     nursery,
-    "functions that should be split up into multiple functions"
+    "functions that should be split up into multiple functions",
     @eval_always = true
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs
index d90a22bb62a..c4afdc757d8 100644
--- a/src/tools/clippy/clippy_lints/src/copies.rs
+++ b/src/tools/clippy/clippy_lints/src/copies.rs
@@ -540,24 +540,22 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo
             .iter()
             .filter(|&&(_, name)| !name.as_str().starts_with('_'))
             .any(|&(_, name)| {
-                let mut walker = ContainsName {
-                    name,
-                    result: false,
-                    cx,
-                };
+                let mut walker = ContainsName { name, cx };
 
                 // Scan block
-                block
+                let mut res = block
                     .stmts
                     .iter()
                     .filter(|stmt| !ignore_span.overlaps(stmt.span))
-                    .for_each(|stmt| intravisit::walk_stmt(&mut walker, stmt));
+                    .try_for_each(|stmt| intravisit::walk_stmt(&mut walker, stmt));
 
                 if let Some(expr) = block.expr {
-                    intravisit::walk_expr(&mut walker, expr);
+                    if res.is_continue() {
+                        res = intravisit::walk_expr(&mut walker, expr);
+                    }
                 }
 
-                walker.result
+                res.is_break()
             })
     })
 }
diff --git a/src/tools/clippy/clippy_lints/src/copy_iterator.rs b/src/tools/clippy/clippy_lints/src/copy_iterator.rs
index 50fd76a3a47..4ecf3e41611 100644
--- a/src/tools/clippy/clippy_lints/src/copy_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/copy_iterator.rs
@@ -37,7 +37,7 @@ declare_lint_pass!(CopyIterator => [COPY_ITERATOR]);
 impl<'tcx> LateLintPass<'tcx> for CopyIterator {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if let ItemKind::Impl(Impl {
-            of_trait: Some(ref trait_ref),
+            of_trait: Some(trait_ref),
             ..
         }) = item.kind
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
diff --git a/src/tools/clippy/clippy_lints/src/ctfe.rs b/src/tools/clippy/clippy_lints/src/ctfe.rs
index 181514e8372..589b99518a0 100644
--- a/src/tools/clippy/clippy_lints/src/ctfe.rs
+++ b/src/tools/clippy/clippy_lints/src/ctfe.rs
@@ -5,7 +5,6 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
-
 declare_lint_pass! {
     /// Ensures that Constant-time Function Evaluation is being done (specifically, MIR lint passes).
     /// As Clippy deactivates codegen, this lint ensures that CTFE (used in hard errors) is still ran.
diff --git a/src/tools/clippy/clippy_lints/src/declare_clippy_lint.rs b/src/tools/clippy/clippy_lints/src/declare_clippy_lint.rs
index a785a9d377c..4d908af4084 100644
--- a/src/tools/clippy/clippy_lints/src/declare_clippy_lint.rs
+++ b/src/tools/clippy/clippy_lints/src/declare_clippy_lint.rs
@@ -4,7 +4,7 @@ macro_rules! declare_clippy_lint {
     (@
         $(#[doc = $lit:literal])*
         pub $lint_name:ident,
-        $category:ident,
+        $level:ident,
         $lintcategory:expr,
         $desc:literal,
         $version_expr:expr,
@@ -15,7 +15,7 @@ macro_rules! declare_clippy_lint {
             $(#[doc = $lit])*
             #[clippy::version = $version_lit]
             pub clippy::$lint_name,
-            $category,
+            $level,
             $desc,
             report_in_external_macro:true
             $(, @eval_always = $eval_always)?
@@ -35,12 +35,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         restriction,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Allow, crate::LintCategory::Restriction, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
     (
@@ -49,12 +50,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         style,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Warn, crate::LintCategory::Style, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
     (
@@ -63,12 +65,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         correctness,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Deny, crate::LintCategory::Correctness, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
 
         }
     };
@@ -78,12 +81,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         perf,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Warn, crate::LintCategory::Perf, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
     (
@@ -92,12 +96,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         complexity,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Warn, crate::LintCategory::Complexity, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
     (
@@ -106,12 +111,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         suspicious,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Warn, crate::LintCategory::Suspicious, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
     (
@@ -120,12 +126,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         nursery,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Allow, crate::LintCategory::Nursery, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
     (
@@ -134,12 +141,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         pedantic,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Allow, crate::LintCategory::Pedantic, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
     (
@@ -148,12 +156,13 @@ macro_rules! declare_clippy_lint {
         pub $lint_name:ident,
         cargo,
         $desc:literal
-        $(@eval_always = $eval_always: literal)?
+        $(, @eval_always = $eval_always: literal)?
     ) => {
         declare_clippy_lint! {@
             $(#[doc = $lit])*
             pub $lint_name, Allow, crate::LintCategory::Cargo, $desc,
-            Some($version), $version $(, $eval_always)?
+            Some($version), $version
+            $(, $eval_always)?
         }
     };
 
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 3c4e75df8ab..edb52851e0c 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -28,12 +28,15 @@ pub static LINTS: &[&crate::LintInfo] = &[
     #[cfg(feature = "internal")]
     crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO,
     #[cfg(feature = "internal")]
+    crate::utils::internal_lints::slow_symbol_comparisons::SLOW_SYMBOL_COMPARISONS_INFO,
+    #[cfg(feature = "internal")]
     crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO,
     #[cfg(feature = "internal")]
     crate::utils::internal_lints::unsorted_clippy_utils_paths::UNSORTED_CLIPPY_UTILS_PATHS_INFO,
     crate::absolute_paths::ABSOLUTE_PATHS_INFO,
     crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO,
     crate::approx_const::APPROX_CONSTANT_INFO,
+    crate::arbitrary_source_item_ordering::ARBITRARY_SOURCE_ITEM_ORDERING_INFO,
     crate::arc_with_non_send_sync::ARC_WITH_NON_SEND_SYNC_INFO,
     crate::as_conversions::AS_CONVERSIONS_INFO,
     crate::asm_syntax::INLINE_ASM_X86_ATT_SYNTAX_INFO,
@@ -414,14 +417,17 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::methods::MANUAL_SPLIT_ONCE_INFO,
     crate::methods::MANUAL_STR_REPEAT_INFO,
     crate::methods::MANUAL_TRY_FOLD_INFO,
+    crate::methods::MAP_ALL_ANY_IDENTITY_INFO,
     crate::methods::MAP_CLONE_INFO,
     crate::methods::MAP_COLLECT_RESULT_UNIT_INFO,
     crate::methods::MAP_ERR_IGNORE_INFO,
     crate::methods::MAP_FLATTEN_INFO,
     crate::methods::MAP_IDENTITY_INFO,
     crate::methods::MAP_UNWRAP_OR_INFO,
+    crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES_INFO,
     crate::methods::MUT_MUTEX_LOCK_INFO,
     crate::methods::NAIVE_BYTECOUNT_INFO,
+    crate::methods::NEEDLESS_AS_BYTES_INFO,
     crate::methods::NEEDLESS_CHARACTER_ITERATION_INFO,
     crate::methods::NEEDLESS_COLLECT_INFO,
     crate::methods::NEEDLESS_OPTION_AS_DEREF_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 2920bbb4c81..2b6bfafe695 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -187,7 +187,7 @@ fn check_enum<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>, func_expr: &Ex
 impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if let ItemKind::Impl(Impl {
-            of_trait: Some(ref trait_ref),
+            of_trait: Some(trait_ref),
             items: [child],
             self_ty,
             ..
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index e8e21edd494..e569c4dc786 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -1,3 +1,5 @@
+use std::ops::ControlFlow;
+
 use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy};
 use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, paths};
@@ -202,7 +204,7 @@ declare_lint_pass!(Derive => [
 impl<'tcx> LateLintPass<'tcx> for Derive {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if let ItemKind::Impl(Impl {
-            of_trait: Some(ref trait_ref),
+            of_trait: Some(trait_ref),
             ..
         }) = item.kind
         {
@@ -371,9 +373,8 @@ fn check_unsafe_derive_deserialize<'tcx>(
     ty: Ty<'tcx>,
 ) {
     fn has_unsafe<'tcx>(cx: &LateContext<'tcx>, item: &'tcx Item<'_>) -> bool {
-        let mut visitor = UnsafeVisitor { cx, has_unsafe: false };
-        walk_item(&mut visitor, item);
-        visitor.has_unsafe
+        let mut visitor = UnsafeVisitor { cx };
+        walk_item(&mut visitor, item).is_break()
     }
 
     if let Some(trait_def_id) = trait_ref.trait_def_id()
@@ -406,38 +407,37 @@ fn check_unsafe_derive_deserialize<'tcx>(
 
 struct UnsafeVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
-    has_unsafe: bool,
 }
 
 impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
+    type Result = ControlFlow<()>;
     type NestedFilter = nested_filter::All;
 
-    fn visit_fn(&mut self, kind: FnKind<'tcx>, decl: &'tcx FnDecl<'_>, body_id: BodyId, _: Span, id: LocalDefId) {
-        if self.has_unsafe {
-            return;
-        }
-
+    fn visit_fn(
+        &mut self,
+        kind: FnKind<'tcx>,
+        decl: &'tcx FnDecl<'_>,
+        body_id: BodyId,
+        _: Span,
+        id: LocalDefId,
+    ) -> Self::Result {
         if let Some(header) = kind.header()
             && header.safety == Safety::Unsafe
         {
-            self.has_unsafe = true;
+            ControlFlow::Break(())
+        } else {
+            walk_fn(self, kind, decl, body_id, id)
         }
-
-        walk_fn(self, kind, decl, body_id, id);
     }
 
-    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
-        if self.has_unsafe {
-            return;
-        }
-
+    fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> Self::Result {
         if let ExprKind::Block(block, _) = expr.kind {
             if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) {
-                self.has_unsafe = true;
+                return ControlFlow::Break(());
             }
         }
 
-        walk_expr(self, expr);
+        walk_expr(self, expr)
     }
 
     fn nested_visit_map(&mut self) -> Self::Map {
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index b51d343132b..bdd49bf8aa7 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -2,7 +2,6 @@ use clippy_config::Conf;
 use clippy_utils::create_disallowed_map;
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::macros::macro_backtrace;
-use rustc_ast::Attribute;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Diag;
 use rustc_hir::def_id::DefIdMap;
@@ -14,6 +13,8 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
 use rustc_span::{ExpnId, MacroKind, Span};
 
+use crate::utils::attr_collector::AttrStorage;
+
 declare_clippy_lint! {
     /// ### What it does
     /// Denies the configured macros in clippy.toml
@@ -64,14 +65,19 @@ pub struct DisallowedMacros {
     // Track the most recently seen node that can have a `derive` attribute.
     // Needed to use the correct lint level.
     derive_src: Option<OwnerId>,
+
+    // When a macro is disallowed in an early pass, it's stored
+    // and emitted during the late pass. This happens for attributes.
+    earlies: AttrStorage,
 }
 
 impl DisallowedMacros {
-    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
+    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf, earlies: AttrStorage) -> Self {
         Self {
             disallowed: create_disallowed_map(tcx, &conf.disallowed_macros),
             seen: FxHashSet::default(),
             derive_src: None,
+            earlies,
         }
     }
 
@@ -114,6 +120,15 @@ impl DisallowedMacros {
 impl_lint_pass!(DisallowedMacros => [DISALLOWED_MACROS]);
 
 impl LateLintPass<'_> for DisallowedMacros {
+    fn check_crate(&mut self, cx: &LateContext<'_>) {
+        // once we check a crate in the late pass we can emit the early pass lints
+        if let Some(attr_spans) = self.earlies.clone().0.get() {
+            for span in attr_spans {
+                self.check(cx, *span, None);
+            }
+        }
+    }
+
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
         self.check(cx, expr.span, None);
         // `$t + $t` can have the context of $t, check also the span of the binary operator
@@ -164,8 +179,4 @@ impl LateLintPass<'_> for DisallowedMacros {
     fn check_path(&mut self, cx: &LateContext<'_>, path: &Path<'_>, _: HirId) {
         self.check(cx, path.span, None);
     }
-
-    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &Attribute) {
-        self.check(cx, attr.span, self.derive_src);
-    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
index f79264e6b04..53c24a3faf1 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
@@ -80,7 +80,7 @@ impl EarlyLintPass for DisallowedScriptIdents {
         let mut symbols: Vec<_> = symbols.iter().collect();
         symbols.sort_unstable_by_key(|k| k.1);
 
-        for (symbol, &span) in &symbols {
+        for &(symbol, &span) in &symbols {
             // Note: `symbol.as_str()` is an expensive operation, thus should not be called
             // more than once for a single symbol.
             let symbol_str = symbol.as_str();
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 89c6a4e08dc..df7c37a192a 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -427,11 +427,11 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks if the first line in the documentation of items listed in module page is too long.
+    /// Checks if the first paragraph in the documentation of items listed in the module page is too long.
     ///
     /// ### Why is this bad?
-    /// Documentation will show the first paragraph of the doscstring in the summary page of a
-    /// module, so having a nice, short summary in the first paragraph is part of writing good docs.
+    /// Documentation will show the first paragraph of the docstring in the summary page of a
+    /// module. Having a nice, short summary in the first paragraph is part of writing good docs.
     ///
     /// ### Example
     /// ```no_run
@@ -453,7 +453,7 @@ declare_clippy_lint! {
     #[clippy::version = "1.82.0"]
     pub TOO_LONG_FIRST_DOC_PARAGRAPH,
     nursery,
-    "ensure that the first line of a documentation paragraph isn't too long"
+    "ensure the first documentation paragraph is short"
 }
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs
index b66dd2108fc..10a84b1b2ff 100644
--- a/src/tools/clippy/clippy_lints/src/empty_drop.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs
@@ -36,7 +36,7 @@ declare_lint_pass!(EmptyDrop => [EMPTY_DROP]);
 impl LateLintPass<'_> for EmptyDrop {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         if let ItemKind::Impl(Impl {
-            of_trait: Some(ref trait_ref),
+            of_trait: Some(trait_ref),
             items: [child],
             ..
         }) = item.kind
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 6ca599ed361..de10b7bf533 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -9,8 +9,7 @@ use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, Saf
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{
-    self, Binder, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, Ty, TypeVisitableExt,
-    TypeckResults,
+    self, Binder, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, Ty, TypeVisitableExt, TypeckResults,
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
@@ -204,11 +203,16 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
                             // 'cuz currently nothing changes after deleting this check.
                             local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
                         }) {
-                            match cx.tcx.infer_ctxt().build(cx.typing_mode()).err_ctxt().type_implements_fn_trait(
-                                cx.param_env,
-                                Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
-                                ty::PredicatePolarity::Positive,
-                            ) {
+                            match cx
+                                .tcx
+                                .infer_ctxt()
+                                .build(cx.typing_mode())
+                                .err_ctxt()
+                                .type_implements_fn_trait(
+                                    cx.param_env,
+                                    Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
+                                    ty::PredicatePolarity::Positive,
+                                ) {
                                 // Mutable closure is used after current expr; we cannot consume it.
                                 Ok((ClosureKind::FnMut, _)) => snippet = format!("&mut {snippet}"),
                                 Ok((ClosureKind::Fn, _)) if !callee_ty_raw.is_ref() => {
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 4e4434ec7d1..0550c22761a 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
             // match call to write_fmt
             && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind)
             && let ExprKind::Call(write_recv_path, []) = write_recv.kind
-            && write_fun.ident.name == sym!(write_fmt)
+            && write_fun.ident.name.as_str() == "write_fmt"
             && let Some(def_id) = path_def_id(cx, write_recv_path)
         {
             // match calls to std::io::stdout() / std::io::stderr ()
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index d5a2e06863d..14da0b515a5 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -1,3 +1,5 @@
+use std::ops::ControlFlow;
+
 use clippy_config::Conf;
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
@@ -115,25 +117,26 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
 }
 
 /// Finds the occurrences of `Self` and `self`
+///
+/// Returns `ControlFlow::break` if any of the `self`/`Self` usages were from an expansion, or the
+/// body contained a binding already named `val`.
 struct SelfFinder<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     /// Occurrences of `Self`
     upper: Vec<Span>,
     /// Occurrences of `self`
     lower: Vec<Span>,
-    /// If any of the `self`/`Self` usages were from an expansion, or the body contained a binding
-    /// already named `val`
-    invalid: bool,
 }
 
 impl<'tcx> Visitor<'tcx> for SelfFinder<'_, 'tcx> {
+    type Result = ControlFlow<()>;
     type NestedFilter = OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
         self.cx.tcx.hir()
     }
 
-    fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
+    fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> Self::Result {
         for segment in path.segments {
             match segment.ident.name {
                 kw::SelfLower => self.lower.push(segment.ident.span),
@@ -141,17 +144,19 @@ impl<'tcx> Visitor<'tcx> for SelfFinder<'_, 'tcx> {
                 _ => continue,
             }
 
-            self.invalid |= segment.ident.span.from_expansion();
+            if segment.ident.span.from_expansion() {
+                return ControlFlow::Break(());
+            }
         }
 
-        if !self.invalid {
-            walk_path(self, path);
-        }
+        walk_path(self, path)
     }
 
-    fn visit_name(&mut self, name: Symbol) {
+    fn visit_name(&mut self, name: Symbol) -> Self::Result {
         if name == sym::val {
-            self.invalid = true;
+            ControlFlow::Break(())
+        } else {
+            ControlFlow::Continue(())
         }
     }
 }
@@ -209,11 +214,9 @@ fn convert_to_from(
         cx,
         upper: Vec::new(),
         lower: Vec::new(),
-        invalid: false,
     };
-    finder.visit_expr(body.value);
 
-    if finder.invalid {
+    if finder.visit_expr(body.value).is_break() {
         return None;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
index d62d008d480..c8828c93615 100644
--- a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
@@ -41,7 +41,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
         if let ExprKind::Call(box_from_raw, [arg]) = expr.kind
             && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind
-            && seg.ident.name == sym!(from_raw)
+            && seg.ident.name.as_str() == "from_raw"
             && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
             && let arg_kind = cx.typeck_results().expr_ty(arg).kind()
             && let ty::RawPtr(ty, _) = arg_kind
diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs
index 91d73c2a9c9..be3d0f7ad63 100644
--- a/src/tools/clippy/clippy_lints/src/functions/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs
@@ -441,7 +441,7 @@ declare_clippy_lint! {
     /// fn bar(&self) -> Option<&String> { None }
     /// # }
     /// ```
-    #[clippy::version = "1.82.0"]
+    #[clippy::version = "1.83.0"]
     pub REF_OPTION,
     pedantic,
     "function signature uses `&Option<T>` instead of `Option<&T>`"
diff --git a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs
index 373ecd74cb3..aba0fbcb9fe 100644
--- a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs
@@ -15,9 +15,9 @@ use rustc_span::{Span, sym};
 fn check_ty<'a>(cx: &LateContext<'a>, param: &rustc_hir::Ty<'a>, param_ty: Ty<'a>, fixes: &mut Vec<(Span, String)>) {
     if let ty::Ref(_, opt_ty, Mutability::Not) = param_ty.kind()
         && is_type_diagnostic_item(cx, *opt_ty, sym::Option)
-        && let ty::Adt(_, opt_gen) = opt_ty.kind()
-        && let [gen] = opt_gen.as_slice()
-        && let GenericArgKind::Type(gen_ty) = gen.unpack()
+        && let ty::Adt(_, opt_gen_args) = opt_ty.kind()
+        && let [gen_arg] = opt_gen_args.as_slice()
+        && let GenericArgKind::Type(gen_ty) = gen_arg.unpack()
         && !gen_ty.is_ref()
         // Need to gen the original spans, so first parsing mid, and hir parsing afterward
         && let hir::TyKind::Ref(lifetime, hir::MutTy { ty, .. }) = param.kind
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index 4c5375730b8..c370f206c8f 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -340,7 +340,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
             if self.cx.tcx.is_diagnostic_item(sym::HashMap, ty_did) {
                 if method.ident.name == sym::new {
                     self.suggestions.insert(e.span, "HashMap::default()".to_string());
-                } else if method.ident.name == sym!(with_capacity) {
+                } else if method.ident.name.as_str() == "with_capacity" {
                     self.suggestions.insert(
                         e.span,
                         format!(
@@ -352,7 +352,7 @@ impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
             } else if self.cx.tcx.is_diagnostic_item(sym::HashSet, ty_did) {
                 if method.ident.name == sym::new {
                     self.suggestions.insert(e.span, "HashSet::default()".to_string());
-                } else if method.ident.name == sym!(with_capacity) {
+                } else if method.ident.name.as_str() == "with_capacity" {
                     self.suggestions.insert(
                         e.span,
                         format!(
diff --git a/src/tools/clippy/clippy_lints/src/infinite_iter.rs b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
index 71c317552ee..48874d6064b 100644
--- a/src/tools/clippy/clippy_lints/src/infinite_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/infinite_iter.rs
@@ -157,7 +157,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                     .and(cap);
                 }
             }
-            if method.ident.name == sym!(flat_map) && args.len() == 1 {
+            if method.ident.name.as_str() == "flat_map" && args.len() == 1 {
                 if let ExprKind::Closure(&Closure { body, .. }) = args[0].kind {
                     let body = cx.tcx.hir().body(body);
                     return is_infinite(cx, body.value);
@@ -224,7 +224,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                     return MaybeInfinite.and(is_infinite(cx, receiver));
                 }
             }
-            if method.ident.name == sym!(last) && args.is_empty() {
+            if method.ident.name.as_str() == "last" && args.is_empty() {
                 let not_double_ended = cx
                     .tcx
                     .get_diagnostic_item(sym::DoubleEndedIterator)
@@ -234,7 +234,7 @@ fn complete_infinite_iter(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness {
                 if not_double_ended {
                     return is_infinite(cx, receiver);
                 }
-            } else if method.ident.name == sym!(collect) {
+            } else if method.ident.name.as_str() == "collect" {
                 let ty = cx.typeck_results().expr_ty(expr);
                 if matches!(
                     get_type_diagnostic_name(cx, ty),
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
index 1e6404190d3..314d0dfa26c 100644
--- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -142,7 +142,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
                 ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some()
             })
             && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| {
-                if item.ident.name == sym!(IntoIter) {
+                if item.ident.name.as_str() == "IntoIter" {
                     Some(cx.tcx.hir().impl_item(item.id).expect_type().span)
                 } else {
                     None
@@ -247,8 +247,8 @@ impl {self_ty_without_ref} {{
                     let sugg = format!(
                         "
 impl IntoIterator for {self_ty_snippet} {{
-    type IntoIter = {ret_ty};
     type Item = {iter_ty};
+    type IntoIter = {ret_ty};
     fn into_iter(self) -> Self::IntoIter {{
         self.iter()
     }}
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index 5d2b521b250..aa8b4d88d2f 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -4,7 +4,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::{self, ConstKind};
+use rustc_middle::ty::{self, ParamEnv};
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, Span};
 
@@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
             && !item.span.from_expansion()
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Array(element_type, cst) = ty.kind()
-            && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
+            && let Ok((_, ty::ValTree::Leaf(element_count))) = cst.eval_valtree(cx.tcx, ParamEnv::empty(), item.span)
             && let element_count = element_count.to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)
diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs
index f2f841dcec3..ab3d19f89c3 100644
--- a/src/tools/clippy/clippy_lints/src/large_include_file.rs
+++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs
@@ -1,11 +1,12 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::root_macro_call_first_node;
-use rustc_ast::LitKind;
+use clippy_utils::source::snippet_opt;
+use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, LitKind};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -51,6 +52,24 @@ impl LargeIncludeFile {
 
 impl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]);
 
+impl LargeIncludeFile {
+    fn emit_lint(&self, cx: &LateContext<'_>, span: Span) {
+        #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
+        span_lint_and_then(
+            cx,
+            LARGE_INCLUDE_FILE,
+            span,
+            "attempted to include a large file",
+            |diag| {
+                diag.note(format!(
+                    "the configuration allows a maximum size of {} bytes",
+                    self.max_file_size
+                ));
+            },
+        );
+    }
+}
+
 impl LateLintPass<'_> for LargeIncludeFile {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
         if let ExprKind::Lit(lit) = &expr.kind
@@ -66,19 +85,33 @@ impl LateLintPass<'_> for LargeIncludeFile {
             && (cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id)
                 || cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id))
         {
-            #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
-            span_lint_and_then(
-                cx,
-                LARGE_INCLUDE_FILE,
-                expr.span.source_callsite(),
-                "attempted to include a large file",
-                |diag| {
-                    diag.note(format!(
-                        "the configuration allows a maximum size of {} bytes",
-                        self.max_file_size
-                    ));
-                },
-            );
+            self.emit_lint(cx, expr.span.source_callsite());
+        }
+    }
+
+    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &Attribute) {
+        if !attr.span.from_expansion()
+            // Currently, rustc limits the usage of macro at the top-level of attributes,
+            // so we don't need to recurse into each level.
+            && let AttrKind::Normal(ref normal) = attr.kind
+            && let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
+            && !attr.span.contains(meta.span)
+            // Since the `include_str` is already expanded at this point, we can only take the
+            // whole attribute snippet and then modify for our suggestion.
+            && let Some(snippet) = snippet_opt(cx, attr.span)
+            // We cannot remove this because a `#[doc = include_str!("...")]` attribute can
+            // occupy several lines.
+            && let Some(start) = snippet.find('[')
+            && let Some(end) = snippet.rfind(']')
+            && let snippet = &snippet[start + 1..end]
+            // We check that the expansion actually comes from `include_str!` and not just from
+            // another macro.
+            && let Some(sub_snippet) = snippet.trim().strip_prefix("doc")
+            && let Some(sub_snippet) = sub_snippet.trim().strip_prefix("=")
+            && let sub_snippet = sub_snippet.trim()
+            && (sub_snippet.starts_with("include_str!") || sub_snippet.starts_with("include_bytes!"))
+        {
+            self.emit_lint(cx, attr.span);
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 47c65ee6d0b..b7887ef76a5 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -629,7 +629,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
                 .filter_by_name_unhygienic(is_empty)
                 .any(|item| is_is_empty(cx, item))
         }),
-        ty::Alias(ty::Projection, ref proj) => has_is_empty_impl(cx, proj.def_id),
+        ty::Alias(ty::Projection, proj) => has_is_empty_impl(cx, proj.def_id),
         ty::Adt(id, _) => has_is_empty_impl(cx, id.did()),
         ty::Array(..) | ty::Slice(..) | ty::Str => true,
         _ => false,
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 3fd07ced0e4..c9064df25ac 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -73,6 +73,7 @@ pub mod deprecated_lints;
 mod absolute_paths;
 mod almost_complete_range;
 mod approx_const;
+mod arbitrary_source_item_ordering;
 mod arc_with_non_send_sync;
 mod as_conversions;
 mod asm_syntax;
@@ -400,6 +401,7 @@ use clippy_config::{Conf, get_configuration_metadata, sanitize_explanation};
 use clippy_utils::macros::FormatArgsStorage;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_lint::{Lint, LintId};
+use utils::attr_collector::{AttrCollector, AttrStorage};
 
 /// Register all pre expansion lints
 ///
@@ -464,6 +466,7 @@ pub(crate) enum LintCategory {
     #[cfg(feature = "internal")]
     Internal,
 }
+
 #[allow(clippy::enum_glob_use)]
 use LintCategory::*;
 
@@ -585,6 +588,10 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         ))
     });
 
+    let attr_storage = AttrStorage::default();
+    let attrs = attr_storage.clone();
+    store.register_early_pass(move || Box::new(AttrCollector::new(attrs.clone())));
+
     // all the internal lints
     #[cfg(feature = "internal")]
     {
@@ -606,6 +613,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         store.register_late_pass(|_| {
             Box::new(utils::internal_lints::almost_standard_lint_formulation::AlmostStandardFormulation::new())
         });
+        store.register_late_pass(|_| Box::new(utils::internal_lints::slow_symbol_comparisons::SlowSymbolComparisons));
     }
 
     store.register_late_pass(|_| Box::new(ctfe::ClippyCtfe));
@@ -795,7 +803,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(unwrap_in_result::UnwrapInResult));
     store.register_late_pass(|_| Box::new(semicolon_if_nothing_returned::SemicolonIfNothingReturned));
     store.register_late_pass(|_| Box::new(async_yields_async::AsyncYieldsAsync));
-    store.register_late_pass(move |tcx| Box::new(disallowed_macros::DisallowedMacros::new(tcx, conf)));
+    let attrs = attr_storage.clone();
+    store.register_late_pass(move |tcx| Box::new(disallowed_macros::DisallowedMacros::new(tcx, conf, attrs.clone())));
     store.register_late_pass(move |tcx| Box::new(disallowed_methods::DisallowedMethods::new(tcx, conf)));
     store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86AttSyntax));
     store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax));
@@ -953,5 +962,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| Box::new(unused_trait_names::UnusedTraitNames::new(conf)));
     store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp));
     store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound));
+    store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf)));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
index 119e410b91c..ee561ea85ed 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -29,11 +29,7 @@ pub(super) fn check(
             if !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) {
                 return;
             }
-        } else if count
-            .try_to_target_usize(cx.tcx)
-            .map_or(true, |x| x > 32)
-            && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN)
-        {
+        } else if count.try_to_target_usize(cx.tcx).map_or(true, |x| x > 32) && !msrv.meets(msrvs::ARRAY_IMPL_ANY_LEN) {
             return;
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
index e25c03db534..9f543b79bac 100644
--- a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
@@ -1,12 +1,13 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{fn_def_id, is_from_proc_macro, is_lint_allowed};
 use hir::intravisit::{Visitor, walk_expr};
-use hir::{Expr, ExprKind, FnRetTy, FnSig, Node};
+use hir::{Expr, ExprKind, FnRetTy, FnSig, Node, TyKind};
 use rustc_ast::Label;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
+use rustc_span::sym;
 
 use super::INFINITE_LOOP;
 
@@ -25,13 +26,7 @@ pub(super) fn check<'tcx>(
         return;
     };
     // Or, its parent function is already returning `Never`
-    if matches!(
-        parent_fn_ret,
-        FnRetTy::Return(hir::Ty {
-            kind: hir::TyKind::Never,
-            ..
-        })
-    ) {
+    if is_never_return(parent_fn_ret) {
         return;
     }
 
@@ -69,6 +64,16 @@ pub(super) fn check<'tcx>(
 fn get_parent_fn_ret_ty<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<FnRetTy<'tcx>> {
     for (_, parent_node) in cx.tcx.hir().parent_iter(expr.hir_id) {
         match parent_node {
+            // Skip `Coroutine` closures, these are the body of `async fn`, not async closures.
+            // This is because we still need to backtrack one parent node to get the `OpaqueDef` ty.
+            Node::Expr(Expr {
+                kind:
+                    ExprKind::Closure(hir::Closure {
+                        kind: hir::ClosureKind::Coroutine(_),
+                        ..
+                    }),
+                ..
+            }) => (),
             Node::Item(hir::Item {
                 kind: hir::ItemKind::Fn(FnSig { decl, .. }, _, _),
                 ..
@@ -143,3 +148,41 @@ impl<'hir> Visitor<'hir> for LoopVisitor<'hir, '_> {
         }
     }
 }
+
+/// Return `true` if the given [`FnRetTy`] is never (!).
+///
+/// Note: This function also take care of return type of async fn,
+/// as the actual type is behind an [`OpaqueDef`](TyKind::OpaqueDef).
+fn is_never_return(ret_ty: FnRetTy<'_>) -> bool {
+    let FnRetTy::Return(hir_ty) = ret_ty else { return false };
+
+    match hir_ty.kind {
+        TyKind::Never => true,
+        TyKind::OpaqueDef(hir::OpaqueTy {
+            origin: hir::OpaqueTyOrigin::AsyncFn { .. },
+            bounds,
+            ..
+        }) => {
+            if let Some(trait_ref) = bounds.iter().find_map(|b| b.trait_ref())
+                && let Some(segment) = trait_ref
+                    .path
+                    .segments
+                    .iter()
+                    .find(|seg| seg.ident.name == sym::future_trait)
+                && let Some(args) = segment.args
+                && let Some(cst_kind) = args
+                    .constraints
+                    .iter()
+                    .find_map(|cst| (cst.ident.name == sym::Output).then_some(cst.kind))
+                && let hir::AssocItemConstraintKind::Equality {
+                    term: hir::Term::Ty(ty),
+                } = cst_kind
+            {
+                matches!(ty.kind, TyKind::Never)
+            } else {
+                false
+            }
+        },
+        _ => false,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs b/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs
index 1a1cde3c5bd..7da4fa76e2c 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs
@@ -19,10 +19,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'
         cx,
         ids: HirIdSet::default(),
         def_ids: DefIdMap::default(),
-        skip: false,
     };
-    var_visitor.visit_expr(cond);
-    if var_visitor.skip {
+    if var_visitor.visit_expr(cond).is_break() {
         return;
     }
     let used_in_condition = &var_visitor.ids;
@@ -81,7 +79,6 @@ struct VarCollectorVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     ids: HirIdSet,
     def_ids: DefIdMap<bool>,
-    skip: bool,
 }
 
 impl<'tcx> VarCollectorVisitor<'_, 'tcx> {
@@ -104,11 +101,15 @@ impl<'tcx> VarCollectorVisitor<'_, 'tcx> {
 }
 
 impl<'tcx> Visitor<'tcx> for VarCollectorVisitor<'_, 'tcx> {
-    fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
+    type Result = ControlFlow<()>;
+    fn visit_expr(&mut self, ex: &'tcx Expr<'_>) -> Self::Result {
         match ex.kind {
-            ExprKind::Path(_) => self.insert_def_id(ex),
+            ExprKind::Path(_) => {
+                self.insert_def_id(ex);
+                ControlFlow::Continue(())
+            },
             // If there is any function/method call… we just stop analysis
-            ExprKind::Call(..) | ExprKind::MethodCall(..) => self.skip = true,
+            ExprKind::Call(..) | ExprKind::MethodCall(..) => ControlFlow::Break(()),
 
             _ => walk_expr(self, ex),
         }
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
index 74467522619..b7e37c1a876 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -1,3 +1,5 @@
+use std::ops::ControlFlow;
+
 use super::WHILE_LET_ON_ITERATOR;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
@@ -204,35 +206,32 @@ fn uses_iter<'tcx>(cx: &LateContext<'tcx>, iter_expr: &IterExpr, container: &'tc
     struct V<'a, 'b, 'tcx> {
         cx: &'a LateContext<'tcx>,
         iter_expr: &'b IterExpr,
-        uses_iter: bool,
     }
     impl<'tcx> Visitor<'tcx> for V<'_, '_, 'tcx> {
-        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
-            if self.uses_iter {
-                // return
-            } else if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
-                self.uses_iter = true;
+        type Result = ControlFlow<()>;
+        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {
+            if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
+                ControlFlow::Break(())
             } else if let (e, true) = skip_fields_and_path(e) {
                 if let Some(e) = e {
-                    self.visit_expr(e);
+                    self.visit_expr(e)
+                } else {
+                    ControlFlow::Continue(())
                 }
             } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
                 if is_res_used(self.cx, self.iter_expr.path, id) {
-                    self.uses_iter = true;
+                    ControlFlow::Break(())
+                } else {
+                    ControlFlow::Continue(())
                 }
             } else {
-                walk_expr(self, e);
+                walk_expr(self, e)
             }
         }
     }
 
-    let mut v = V {
-        cx,
-        iter_expr,
-        uses_iter: false,
-    };
-    v.visit_expr(container);
-    v.uses_iter
+    let mut v = V { cx, iter_expr };
+    v.visit_expr(container).is_break()
 }
 
 #[expect(clippy::too_many_lines)]
@@ -242,34 +241,38 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
         iter_expr: &'b IterExpr,
         loop_id: HirId,
         after_loop: bool,
-        used_iter: bool,
     }
     impl<'tcx> Visitor<'tcx> for AfterLoopVisitor<'_, '_, 'tcx> {
         type NestedFilter = OnlyBodies;
+        type Result = ControlFlow<()>;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
         }
 
-        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
-            if self.used_iter {
-                return;
-            }
+        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {
             if self.after_loop {
                 if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
-                    self.used_iter = true;
+                    ControlFlow::Break(())
                 } else if let (e, true) = skip_fields_and_path(e) {
                     if let Some(e) = e {
-                        self.visit_expr(e);
+                        self.visit_expr(e)
+                    } else {
+                        ControlFlow::Continue(())
                     }
                 } else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
-                    self.used_iter = is_res_used(self.cx, self.iter_expr.path, id);
+                    if is_res_used(self.cx, self.iter_expr.path, id) {
+                        ControlFlow::Break(())
+                    } else {
+                        ControlFlow::Continue(())
+                    }
                 } else {
-                    walk_expr(self, e);
+                    walk_expr(self, e)
                 }
             } else if self.loop_id == e.hir_id {
                 self.after_loop = true;
+                ControlFlow::Continue(())
             } else {
-                walk_expr(self, e);
+                walk_expr(self, e)
             }
         }
     }
@@ -347,9 +350,8 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
             iter_expr,
             loop_id: loop_expr.hir_id,
             after_loop: false,
-            used_iter: false,
         };
-        v.visit_expr(cx.tcx.hir().body(cx.enclosing_body.unwrap()).value);
-        v.used_iter
+        v.visit_expr(cx.tcx.hir().body(cx.enclosing_body.unwrap()).value)
+            .is_break()
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index c904137da1a..3c77db84a40 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -106,13 +106,12 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
 
 fn future_trait_ref<'tcx>(cx: &LateContext<'tcx>, opaque: &'tcx OpaqueTy<'tcx>) -> Option<&'tcx TraitRef<'tcx>> {
     if let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
-            if let GenericBound::Trait(poly) = bound {
-                Some(&poly.trait_ref)
-            } else {
-                None
-            }
-        })
-        && trait_ref.trait_def_id() == cx.tcx.lang_items().future_trait()
+        if let GenericBound::Trait(poly) = bound {
+            Some(&poly.trait_ref)
+        } else {
+            None
+        }
+    }) && trait_ref.trait_def_id() == cx.tcx.lang_items().future_trait()
     {
         return Some(trait_ref);
     }
@@ -156,16 +155,18 @@ fn captures_all_lifetimes(cx: &LateContext<'_>, fn_def_id: LocalDefId, opaque_de
         .tcx
         .opaque_captured_lifetimes(opaque_def_id)
         .iter()
-        .filter(|&(lifetime, _)| match *lifetime {
-            ResolvedArg::EarlyBound(_) | ResolvedArg::LateBound(ty::INNERMOST, _, _) => true,
-            _ => false,
+        .filter(|&(lifetime, _)| {
+            matches!(
+                *lifetime,
+                ResolvedArg::EarlyBound(_) | ResolvedArg::LateBound(ty::INNERMOST, _, _)
+            )
         })
         .count();
     num_captured_lifetimes == num_early_lifetimes + num_late_lifetimes
 }
 
 fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> {
-    if let Some(Expr {
+    if let Some(&Expr {
         kind: ExprKind::Closure(&Closure { kind, body, .. }),
         ..
     }) = block.expr
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index 1bd8813e348..fd71167f814 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -7,8 +7,7 @@ use rustc_ast::ast::LitKind;
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
@@ -53,7 +52,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if let ExprKind::Binary(bin_op, left_expr, right_expr) = expr.kind
             && let BinOpKind::Mul = &bin_op.node
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.from_expansion()
             && self.msrv.meets(msrvs::MANUAL_BITS)
             && let ctxt = expr.span.ctxt()
             && left_expr.span.ctxt() == ctxt
diff --git a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
index c62bd65bea6..7a9c9963742 100644
--- a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
@@ -68,7 +68,7 @@ impl LateLintPass<'_> for ManualHashOne {
             && let Some(init) = local.init
             && !init.span.from_expansion()
             && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind
-            && seg.ident.name == sym!(build_hasher)
+            && seg.ident.name.as_str() == "build_hasher"
 
             && let Node::Stmt(local_stmt) = cx.tcx.parent_hir_node(local.hir_id)
             && let Node::Block(block) = cx.tcx.parent_hir_node(local_stmt.hir_id)
@@ -96,7 +96,7 @@ impl LateLintPass<'_> for ManualHashOne {
             && let Node::Expr(finish_expr) = cx.tcx.parent_hir_node(path_expr.hir_id)
             && !finish_expr.span.from_expansion()
             && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind
-            && seg.ident.name == sym!(finish)
+            && seg.ident.name.as_str() == "finish"
 
             && self.msrv.meets(msrvs::BUILD_HASHER_HASH_ONE)
         {
diff --git a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
index 24207705743..dec8c5d85de 100644
--- a/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs
@@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
                 check_is_ascii(cx, macro_call.span, recv, &range, None);
             }
         } else if let ExprKind::MethodCall(path, receiver, [arg], ..) = expr.kind
-            && path.ident.name == sym!(contains)
+            && path.ident.name.as_str() == "contains"
             && let Some(higher::Range {
                 start: Some(start),
                 end: Some(end),
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
index 64cb7a06ce9..6d62b530ae7 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
@@ -148,7 +148,7 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option<bool> {
         }) => Some(*b),
         ExprKind::Block(
             rustc_hir::Block {
-                stmts: &[],
+                stmts: [],
                 expr: Some(exp),
                 ..
             },
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
index 463aa602bc8..1267fc9d0a5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
@@ -1,3 +1,5 @@
+use std::ops::ControlFlow;
+
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::is_type_lang_item;
 use rustc_ast::ast::LitKind;
@@ -23,11 +25,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>, arm
     if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty(scrutinee).kind()
         && let ty::Str = ty.kind()
     {
-        let mut visitor = MatchExprVisitor { cx, case_method: None };
-
-        visitor.visit_expr(scrutinee);
-
-        if let Some(case_method) = visitor.case_method {
+        let mut visitor = MatchExprVisitor { cx };
+        if let ControlFlow::Break(case_method) = visitor.visit_expr(scrutinee) {
             if let Some((bad_case_span, bad_case_sym)) = verify_case(&case_method, arms) {
                 lint(cx, &case_method, bad_case_span, bad_case_sym.as_str());
             }
@@ -37,30 +36,33 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>, arm
 
 struct MatchExprVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
-    case_method: Option<CaseMethod>,
 }
 
 impl<'tcx> Visitor<'tcx> for MatchExprVisitor<'_, 'tcx> {
-    fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
-        match ex.kind {
-            ExprKind::MethodCall(segment, receiver, [], _) if self.case_altered(segment.ident.as_str(), receiver) => {},
-            _ => walk_expr(self, ex),
+    type Result = ControlFlow<CaseMethod>;
+    fn visit_expr(&mut self, ex: &'tcx Expr<'_>) -> Self::Result {
+        if let ExprKind::MethodCall(segment, receiver, [], _) = ex.kind {
+            let result = self.case_altered(segment.ident.as_str(), receiver);
+            if result.is_break() {
+                return result;
+            }
         }
+
+        walk_expr(self, ex)
     }
 }
 
 impl MatchExprVisitor<'_, '_> {
-    fn case_altered(&mut self, segment_ident: &str, receiver: &Expr<'_>) -> bool {
+    fn case_altered(&mut self, segment_ident: &str, receiver: &Expr<'_>) -> ControlFlow<CaseMethod> {
         if let Some(case_method) = get_case_method(segment_ident) {
             let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
 
             if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str {
-                self.case_method = Some(case_method);
-                return true;
+                return ControlFlow::Break(case_method);
             }
         }
 
-        false
+        ControlFlow::Continue(())
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index 42d9efe4ff6..9e54475033c 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -10,7 +10,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, MatchSource, Node, PatKind, UnOp};
 use rustc_lint::LateContext;
 use rustc_span::symbol::Ident;
-use rustc_span::{Span, Symbol, sym};
+use rustc_span::{Span, sym};
 use std::borrow::Cow;
 use std::ops::ControlFlow;
 
@@ -95,7 +95,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv:
         } else if let ExprKind::MethodCall(path, recv, args, ..) = guard.kind
             && let Some(binding) = get_pat_binding(cx, recv, outer_arm)
         {
-            check_method_calls(cx, outer_arm, path.ident.name, recv, args, guard, &binding);
+            check_method_calls(cx, outer_arm, path.ident.name.as_str(), recv, args, guard, &binding);
         }
     }
 }
@@ -103,7 +103,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv:
 fn check_method_calls<'tcx>(
     cx: &LateContext<'tcx>,
     arm: &Arm<'tcx>,
-    method: Symbol,
+    method: &str,
     recv: &Expr<'_>,
     args: &[Expr<'_>],
     if_expr: &Expr<'_>,
@@ -112,7 +112,7 @@ fn check_method_calls<'tcx>(
     let ty = cx.typeck_results().expr_ty(recv).peel_refs();
     let slice_like = ty.is_slice() || ty.is_array();
 
-    let sugg = if method == sym!(is_empty) {
+    let sugg = if method == "is_empty" {
         // `s if s.is_empty()` becomes ""
         // `arr if arr.is_empty()` becomes []
 
@@ -137,9 +137,9 @@ fn check_method_calls<'tcx>(
 
         if needles.is_empty() {
             sugg.insert_str(1, "..");
-        } else if method == sym!(starts_with) {
+        } else if method == "starts_with" {
             sugg.insert_str(sugg.len() - 1, ", ..");
-        } else if method == sym!(ends_with) {
+        } else if method == "ends_with" {
             sugg.insert_str(1, ".., ");
         } else {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
index 9ca75fb2615..ca45ed6ea59 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -319,10 +319,9 @@ fn found_good_method<'tcx>(
     node: (&PatKind<'_>, &PatKind<'_>),
 ) -> Option<(&'static str, Option<&'tcx Expr<'tcx>>)> {
     match node {
-        (
-            PatKind::TupleStruct(ref path_left, patterns_left, _),
-            PatKind::TupleStruct(ref path_right, patterns_right, _),
-        ) if patterns_left.len() == 1 && patterns_right.len() == 1 => {
+        (PatKind::TupleStruct(path_left, patterns_left, _), PatKind::TupleStruct(path_right, patterns_right, _))
+            if patterns_left.len() == 1 && patterns_right.len() == 1 =>
+        {
             if let (PatKind::Wild, PatKind::Wild) = (&patterns_left[0].kind, &patterns_right[0].kind) {
                 find_good_method_for_match(
                     cx,
@@ -350,8 +349,8 @@ fn found_good_method<'tcx>(
                 None
             }
         },
-        (PatKind::TupleStruct(ref path_left, patterns, _), PatKind::Path(ref path_right))
-        | (PatKind::Path(ref path_left), PatKind::TupleStruct(ref path_right, patterns, _))
+        (PatKind::TupleStruct(path_left, patterns, _), PatKind::Path(path_right))
+        | (PatKind::Path(path_left), PatKind::TupleStruct(path_right, patterns, _))
             if patterns.len() == 1 =>
         {
             if let PatKind::Wild = patterns[0].kind {
@@ -381,14 +380,14 @@ fn found_good_method<'tcx>(
                 None
             }
         },
-        (PatKind::TupleStruct(ref path_left, patterns, _), PatKind::Wild) if patterns.len() == 1 => {
+        (PatKind::TupleStruct(path_left, patterns, _), PatKind::Wild) if patterns.len() == 1 => {
             if let PatKind::Wild = patterns[0].kind {
                 get_good_method(cx, arms, path_left)
             } else {
                 None
             }
         },
-        (PatKind::Path(ref path_left), PatKind::Wild) => get_good_method(cx, arms, path_left),
+        (PatKind::Path(path_left), PatKind::Wild) => get_good_method(cx, arms, path_left),
         _ => None,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 047d070a131..2aea25b5f12 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -247,7 +247,10 @@ impl<'a> PatState<'a> {
         let states = match self {
             Self::Wild => return None,
             Self::Other => {
-                *self = Self::StdEnum(cx.arena.alloc_from_iter((0..adt.variants().len()).map(|_| Self::Other)));
+                *self = Self::StdEnum(
+                    cx.arena
+                        .alloc_from_iter(std::iter::repeat_with(|| Self::Other).take(adt.variants().len())),
+                );
                 let Self::StdEnum(x) = self else {
                     unreachable!();
                 };
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
index 06482a743dd..c1653b65e98 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -21,8 +21,8 @@ fn is_method(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol) -> bool
         ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name,
         ExprKind::Path(QPath::Resolved(_, segments)) => segments.segments.last().unwrap().ident.name == method_name,
         ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name,
-        ExprKind::Closure(&Closure { body, .. }) => {
-            let body = cx.tcx.hir().body(body);
+        ExprKind::Closure(Closure { body, .. }) => {
+            let body = cx.tcx.hir().body(*body);
             let closure_expr = peel_blocks(body.value);
             match closure_expr.kind {
                 ExprKind::MethodCall(PathSegment { ident, .. }, receiver, ..) => {
@@ -234,12 +234,12 @@ impl<'tcx> OffendingFilterExpr<'tcx> {
             // the latter only calls `effect` once
             let side_effect_expr_span = receiver.can_have_side_effects().then_some(receiver.span);
 
-            if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name == sym!(is_some) {
+            if cx.tcx.is_diagnostic_item(sym::Option, recv_ty.did()) && path.ident.name.as_str() == "is_some" {
                 Some(Self::IsSome {
                     receiver,
                     side_effect_expr_span,
                 })
-            } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name == sym!(is_ok) {
+            } else if cx.tcx.is_diagnostic_item(sym::Result, recv_ty.did()) && path.ident.name.as_str() == "is_ok" {
                 Some(Self::IsOk {
                     receiver,
                     side_effect_expr_span,
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
index cc82f6cfd63..a0c21faaa4c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
@@ -1,6 +1,7 @@
 use clippy_utils::consts::ConstEvalCtxt;
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::{find_binding_init, path_to_local};
+use clippy_utils::macros::{is_assert_macro, root_macro_call};
+use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context, path_to_local};
 use rustc_hir::{Expr, HirId};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -14,6 +15,16 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_
     if in_external_macro(cx.sess(), expr.span) || !receiver.span.eq_ctxt(expr.span) {
         return;
     }
+    if let Some(parent) = get_parent_expr(cx, expr) {
+        if let Some(parent) = get_parent_expr(cx, parent) {
+            if is_inside_always_const_context(cx.tcx, expr.hir_id)
+                && let Some(macro_call) = root_macro_call(parent.span)
+                && is_assert_macro(cx, macro_call.def_id)
+            {
+                return;
+            }
+        }
+    }
     let init_expr = expr_or_init(cx, receiver);
     if !receiver.span.eq_ctxt(init_expr.span) {
         return;
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
index 9d462bd1845..9a62b719a8f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_out_of_bounds.rs
@@ -29,10 +29,7 @@ fn get_iterator_length<'tcx>(cx: &LateContext<'tcx>, iter: &'tcx Expr<'tcx>) ->
     if cx.tcx.is_diagnostic_item(sym::ArrayIntoIter, did) {
         // For array::IntoIter<T, const N: usize>, the length is the second generic
         // parameter.
-        substs
-            .const_at(1)
-            .try_to_target_usize(cx.tcx)
-            .map(u128::from)
+        substs.const_at(1).try_to_target_usize(cx.tcx).map(u128::from)
     } else if cx.tcx.is_diagnostic_item(sym::SliceIter, did)
         && let ExprKind::MethodCall(_, recv, ..) = iter.kind
     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_all_any_identity.rs b/src/tools/clippy/clippy_lints/src/methods/map_all_any_identity.rs
new file mode 100644
index 00000000000..ac11baa2d54
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/map_all_any_identity.rs
@@ -0,0 +1,43 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::SpanRangeExt;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_span::{Span, sym};
+
+use super::MAP_ALL_ANY_IDENTITY;
+
+#[allow(clippy::too_many_arguments)]
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    recv: &Expr<'_>,
+    map_call_span: Span,
+    map_arg: &Expr<'_>,
+    any_call_span: Span,
+    any_arg: &Expr<'_>,
+    method: &str,
+) {
+    if is_trait_method(cx, expr, sym::Iterator)
+        && is_trait_method(cx, recv, sym::Iterator)
+        && is_expr_identity_function(cx, any_arg)
+        && let map_any_call_span = map_call_span.with_hi(any_call_span.hi())
+        && let Some(map_arg) = map_arg.span.get_source_text(cx)
+    {
+        span_lint_and_then(
+            cx,
+            MAP_ALL_ANY_IDENTITY,
+            map_any_call_span,
+            format!("usage of `.map(...).{method}(identity)`"),
+            |diag| {
+                diag.span_suggestion_verbose(
+                    map_any_call_span,
+                    format!("use `.{method}(...)` instead"),
+                    format!("{method}({map_arg})"),
+                    Applicability::MachineApplicable,
+                );
+            },
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
new file mode 100644
index 00000000000..fc656fd78ba
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
@@ -0,0 +1,134 @@
+use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES;
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{eager_or_lazy, higher, usage};
+use rustc_ast::LitKind;
+use rustc_ast::ast::RangeLimits;
+use rustc_data_structures::packed::Pu128;
+use rustc_errors::Applicability;
+use rustc_hir::{Body, Closure, Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+
+fn extract_count_with_applicability(
+    cx: &LateContext<'_>,
+    range: higher::Range<'_>,
+    applicability: &mut Applicability,
+) -> Option<String> {
+    let start = range.start?;
+    let end = range.end?;
+    // TODO: This doens't handle if either the start or end are negative literals, or if the start is
+    // not a literal. In the first case, we need to be careful about how we handle computing the
+    // count to avoid overflows. In the second, we may need to add parenthesis to make the
+    // suggestion correct.
+    if let ExprKind::Lit(lit) = start.kind
+        && let LitKind::Int(Pu128(lower_bound), _) = lit.node
+    {
+        if let ExprKind::Lit(lit) = end.kind
+            && let LitKind::Int(Pu128(upper_bound), _) = lit.node
+        {
+            // Here we can explicitly calculate the number of iterations
+            let count = if upper_bound >= lower_bound {
+                match range.limits {
+                    RangeLimits::HalfOpen => upper_bound - lower_bound,
+                    RangeLimits::Closed => (upper_bound - lower_bound).checked_add(1)?,
+                }
+            } else {
+                0
+            };
+            return Some(format!("{count}"));
+        }
+        let end_snippet = Sugg::hir_with_applicability(cx, end, "...", applicability)
+            .maybe_par()
+            .into_string();
+        if lower_bound == 0 {
+            if range.limits == RangeLimits::Closed {
+                return Some(format!("{end_snippet} + 1"));
+            }
+            return Some(end_snippet);
+        }
+        if range.limits == RangeLimits::Closed {
+            return Some(format!("{end_snippet} - {}", lower_bound - 1));
+        }
+        return Some(format!("{end_snippet} - {lower_bound}"));
+    }
+    None
+}
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    ex: &Expr<'_>,
+    receiver: &Expr<'_>,
+    arg: &Expr<'_>,
+    msrv: &Msrv,
+    method_call_span: Span,
+) {
+    let mut applicability = Applicability::MaybeIncorrect;
+    if let Some(range) = higher::Range::hir(receiver)
+        && let ExprKind::Closure(Closure { body, .. }) = arg.kind
+        && let body_hir = cx.tcx.hir().body(*body)
+        && let Body {
+            params: [param],
+            value: body_expr,
+        } = body_hir
+        && !usage::BindingUsageFinder::are_params_used(cx, body_hir)
+        && let Some(count) = extract_count_with_applicability(cx, range, &mut applicability)
+    {
+        let method_to_use_name;
+        let new_span;
+        let use_take;
+
+        if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {
+            if msrv.meets(msrvs::REPEAT_N) {
+                method_to_use_name = "repeat_n";
+                let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability);
+                new_span = (arg.span, format!("{body_snippet}, {count}"));
+                use_take = false;
+            } else {
+                method_to_use_name = "repeat";
+                let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability);
+                new_span = (arg.span, body_snippet.to_string());
+                use_take = true;
+            }
+        } else if msrv.meets(msrvs::REPEAT_WITH) {
+            method_to_use_name = "repeat_with";
+            new_span = (param.span, String::new());
+            use_take = true;
+        } else {
+            return;
+        }
+
+        // We need to provide nonempty parts to diag.multipart_suggestion so we
+        // collate all our parts here and then remove those that are empty.
+        let mut parts = vec![
+            (
+                receiver.span.to(method_call_span),
+                format!("std::iter::{method_to_use_name}"),
+            ),
+            new_span,
+        ];
+        if use_take {
+            parts.push((ex.span.shrink_to_hi(), format!(".take({count})")));
+        }
+
+        span_lint_and_then(
+            cx,
+            MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
+            ex.span,
+            "map of a closure that does not depend on its parameter over a range",
+            |diag| {
+                diag.multipart_suggestion(
+                    if use_take {
+                        format!("remove the explicit range and use `{method_to_use_name}` and `take`")
+                    } else {
+                        format!("remove the explicit range and use `{method_to_use_name}`")
+                    },
+                    parts,
+                    applicability,
+                );
+            },
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 2a391870d70..b1809796355 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -60,13 +60,16 @@ mod manual_ok_or;
 mod manual_saturating_arithmetic;
 mod manual_str_repeat;
 mod manual_try_fold;
+mod map_all_any_identity;
 mod map_clone;
 mod map_collect_result_unit;
 mod map_err_ignore;
 mod map_flatten;
 mod map_identity;
 mod map_unwrap_or;
+mod map_with_unused_argument_over_ranges;
 mod mut_mutex_lock;
+mod needless_as_bytes;
 mod needless_character_iteration;
 mod needless_collect;
 mod needless_option_as_deref;
@@ -4166,6 +4169,90 @@ declare_clippy_lint! {
     "calling `.first().is_some()` or `.first().is_none()` instead of `.is_empty()`"
 }
 
+declare_clippy_lint! {
+   /// ### What it does
+   /// It detects useless calls to `str::as_bytes()` before calling `len()` or `is_empty()`.
+   ///
+   /// ### Why is this bad?
+   /// The `len()` and `is_empty()` methods are also directly available on strings, and they
+   /// return identical results. In particular, `len()` on a string returns the number of
+   /// bytes.
+   ///
+   /// ### Example
+   /// ```
+   /// let len = "some string".as_bytes().len();
+   /// let b = "some string".as_bytes().is_empty();
+   /// ```
+   /// Use instead:
+   /// ```
+   /// let len = "some string".len();
+   /// let b = "some string".is_empty();
+   /// ```
+   #[clippy::version = "1.84.0"]
+   pub NEEDLESS_AS_BYTES,
+   complexity,
+   "detect useless calls to `as_bytes()`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `.map(…)`, followed by `.all(identity)` or `.any(identity)`.
+    ///
+    /// ### Why is this bad?
+    /// The `.all(…)` or `.any(…)` methods can be called directly in place of `.map(…)`.
+    ///
+    /// ### Example
+    /// ```
+    /// # let mut v = [""];
+    /// let e1 = v.iter().map(|s| s.is_empty()).all(|a| a);
+    /// let e2 = v.iter().map(|s| s.is_empty()).any(std::convert::identity);
+    /// ```
+    /// Use instead:
+    /// ```
+    /// # let mut v = [""];
+    /// let e1 = v.iter().all(|s| s.is_empty());
+    /// let e2 = v.iter().any(|s| s.is_empty());
+    /// ```
+    #[clippy::version = "1.84.0"]
+    pub MAP_ALL_ANY_IDENTITY,
+    complexity,
+    "combine `.map(_)` followed by `.all(identity)`/`.any(identity)` into a single call"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Checks for `Iterator::map` over ranges without using the parameter which
+    /// could be more clearly expressed using `std::iter::repeat(...).take(...)`
+    /// or `std::iter::repeat_n`.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// It expresses the intent more clearly to `take` the correct number of times
+    /// from a generating function than to apply a closure to each number in a
+    /// range only to discard them.
+    ///
+    /// ### Example
+    ///
+    /// ```no_run
+    /// let random_numbers : Vec<_> = (0..10).map(|_| { 3 + 1 }).collect();
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let f : Vec<_> = std::iter::repeat( 3 + 1 ).take(10).collect();
+    /// ```
+    ///
+    /// ### Known Issues
+    ///
+    /// This lint may suggest replacing a `Map<Range>` with a `Take<RepeatWith>`.
+    /// The former implements some traits that the latter does not, such as
+    /// `DoubleEndedIterator`.
+    #[clippy::version = "1.84.0"]
+    pub MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
+    restriction,
+    "map of a trivial closure (not dependent on parameter) over a range"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Msrv,
@@ -4327,6 +4414,9 @@ impl_lint_pass!(Methods => [
     NEEDLESS_CHARACTER_ITERATION,
     MANUAL_INSPECT,
     UNNECESSARY_MIN_OR_MAX,
+    NEEDLESS_AS_BYTES,
+    MAP_ALL_ANY_IDENTITY,
+    MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -4534,15 +4624,21 @@ impl Methods {
                 ("all", [arg]) => {
                     unused_enumerate_index::check(cx, expr, recv, arg);
                     needless_character_iteration::check(cx, expr, recv, arg, true);
-                    if let Some(("cloned", recv2, [], _, _)) = method_call(recv) {
-                        iter_overeager_cloned::check(
-                            cx,
-                            expr,
-                            recv,
-                            recv2,
-                            iter_overeager_cloned::Op::NeedlessMove(arg),
-                            false,
-                        );
+                    match method_call(recv) {
+                        Some(("cloned", recv2, [], _, _)) => {
+                            iter_overeager_cloned::check(
+                                cx,
+                                expr,
+                                recv,
+                                recv2,
+                                iter_overeager_cloned::Op::NeedlessMove(arg),
+                                false,
+                            );
+                        },
+                        Some(("map", _, [map_arg], _, map_call_span)) => {
+                            map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "all");
+                        },
+                        _ => {},
                     }
                 },
                 ("and_then", [arg]) => {
@@ -4571,6 +4667,9 @@ impl Methods {
                         {
                             string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv);
                         },
+                        Some(("map", _, [map_arg], _, map_call_span)) => {
+                            map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "any");
+                        },
                         _ => {},
                     }
                 },
@@ -4764,8 +4863,14 @@ impl Methods {
                     unit_hash::check(cx, expr, recv, arg);
                 },
                 ("is_empty", []) => {
-                    if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) {
-                        redundant_as_str::check(cx, expr, recv, as_str_span, span);
+                    match method_call(recv) {
+                        Some(("as_bytes", prev_recv, [], _, _)) => {
+                            needless_as_bytes::check(cx, "is_empty", recv, prev_recv, expr.span);
+                        },
+                        Some(("as_str", recv, [], as_str_span, _)) => {
+                            redundant_as_str::check(cx, expr, recv, as_str_span, span);
+                        },
+                        _ => {},
                     }
                     is_empty::check(cx, expr, recv);
                 },
@@ -4795,6 +4900,11 @@ impl Methods {
                         );
                     }
                 },
+                ("len", []) => {
+                    if let Some(("as_bytes", prev_recv, [], _, _)) = method_call(recv) {
+                        needless_as_bytes::check(cx, "len", recv, prev_recv, expr.span);
+                    }
+                },
                 ("lock", []) => {
                     mut_mutex_lock::check(cx, expr, recv, span);
                 },
@@ -4802,6 +4912,7 @@ impl Methods {
                     if name == "map" {
                         unused_enumerate_index::check(cx, expr, recv, m_arg);
                         map_clone::check(cx, expr, recv, m_arg, &self.msrv);
+                        map_with_unused_argument_over_ranges::check(cx, expr, recv, m_arg, &self.msrv, span);
                         match method_call(recv) {
                             Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => {
                                 iter_kv_map::check(cx, map_name, expr, recv2, m_arg, &self.msrv);
@@ -5182,7 +5293,6 @@ impl ShouldImplTraitCase {
 }
 
 #[rustfmt::skip]
-#[expect(clippy::large_const_arrays, reason = "`Span` is not sync, so this can't be static")]
 const TRAIT_METHODS: [ShouldImplTraitCase; 30] = [
     ShouldImplTraitCase::new("std::ops::Add", "add",  2,  FN_HEADER,  SelfKind::Value,  OutType::Any, true),
     ShouldImplTraitCase::new("std::convert::AsMut", "as_mut",  1,  FN_HEADER,  SelfKind::RefMut,  OutType::Ref, true),
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs b/src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs
new file mode 100644
index 00000000000..75e9f317230
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs
@@ -0,0 +1,28 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::ty::is_type_lang_item;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, LangItem};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+
+use super::NEEDLESS_AS_BYTES;
+
+pub fn check(cx: &LateContext<'_>, method: &str, recv: &Expr<'_>, prev_recv: &Expr<'_>, span: Span) {
+    if cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice()
+        && let ty1 = cx.typeck_results().expr_ty_adjusted(prev_recv).peel_refs()
+        && (is_type_lang_item(cx, ty1, LangItem::String) || ty1.is_str())
+    {
+        let mut app = Applicability::MachineApplicable;
+        let sugg = Sugg::hir_with_context(cx, prev_recv, span.ctxt(), "..", &mut app);
+        span_lint_and_sugg(
+            cx,
+            NEEDLESS_AS_BYTES,
+            span,
+            "needless call to `as_bytes()`",
+            format!("`{method}()` can be called directly on strings"),
+            format!("{sugg}.{method}()"),
+            app,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 96a31812ca4..055107068ae 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -322,7 +322,7 @@ impl<'tcx> Visitor<'tcx> for IterFunctionVisitor<'_, 'tcx> {
         // Check function calls on our collection
         if let ExprKind::MethodCall(method_name, recv, args, _) = &expr.kind {
             if args.is_empty()
-                && method_name.ident.name == sym!(collect)
+                && method_name.ident.name.as_str() == "collect"
                 && is_trait_method(self.cx, expr, sym::Iterator)
             {
                 self.current_mutably_captured_ids = get_captured_ids(self.cx, self.cx.typeck_results().expr_ty(recv));
diff --git a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs
index 65e545ed03a..db2b9d4d92f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/read_line_without_trim.rs
@@ -44,7 +44,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<
             if let Some(parent) = get_parent_expr(cx, expr) {
                 let data = if let ExprKind::MethodCall(segment, recv, args, span) = parent.kind {
                     if args.is_empty()
-                        && segment.ident.name == sym!(parse)
+                        && segment.ident.name.as_str() == "parse"
                         && let parse_result_ty = cx.typeck_results().expr_ty(parent)
                         && is_type_diagnostic_item(cx, parse_result_ty, sym::Result)
                         && let ty::Adt(_, substs) = parse_result_ty.kind()
@@ -58,7 +58,7 @@ pub fn check(cx: &LateContext<'_>, call: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<
                             "calling `.parse()` on a string without trimming the trailing newline character",
                             "checking",
                         ))
-                    } else if segment.ident.name == sym!(ends_with)
+                    } else if segment.ident.name.as_str() == "ends_with"
                         && recv.span == expr.span
                         && let [arg] = args
                         && expr_is_string_literal_without_trailing_newline(arg)
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
index ca46da81fa0..bab439015c5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -1,13 +1,15 @@
 use super::utils::clone_or_copy_needed;
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::is_copy;
 use clippy_utils::usage::mutated_variables;
 use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
-use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
+use clippy_utils::{MaybePath, is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
 use core::ops::ControlFlow;
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_lint::LateContext;
+use rustc_middle::query::Key;
 use rustc_middle::ty;
 use rustc_span::sym;
 
@@ -36,9 +38,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
                 ControlFlow::Continue(Descend::Yes)
             }
         });
-
         let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);
         let sugg = if !found_filtering {
+            // Check if the closure is .filter_map(|x| Some(x))
+            if name == "filter_map"
+                && let hir::ExprKind::Call(expr, args) = body.value.kind
+                && is_res_lang_ctor(cx, path_res(cx, expr), OptionSome)
+                && arg_id.ty_def_id() == args[0].hir_id().ty_def_id()
+                && let hir::ExprKind::Path(_) = args[0].kind
+            {
+                span_lint_and_sugg(
+                    cx,
+                    UNNECESSARY_FILTER_MAP,
+                    expr.span,
+                    format!("{name} is unnecessary"),
+                    "try removing the filter_map",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
             if name == "filter_map" { "map" } else { "map(..).next()" }
         } else if !found_mapping && !mutates_arg && (!clone_or_copy_needed || is_copy(cx, in_ty)) {
             match cx.typeck_results().expr_ty(body.value).kind() {
@@ -52,7 +70,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
         } else {
             return;
         };
-        span_lint(
+        span_lint_and_sugg(
             cx,
             if name == "filter_map" {
                 UNNECESSARY_FILTER_MAP
@@ -60,7 +78,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
                 UNNECESSARY_FIND_MAP
             },
             expr.span,
-            format!("this `.{name}` can be written more simply using `.{sugg}`"),
+            format!("this `.{name}` can be written more simply"),
+            "try instead",
+            sugg.to_string(),
+            Applicability::MaybeIncorrect,
         );
     }
 }
@@ -78,7 +99,7 @@ fn check_expression<'tcx>(cx: &LateContext<'tcx>, arg_id: hir::HirId, expr: &'tc
             (true, true)
         },
         hir::ExprKind::MethodCall(segment, recv, [arg], _) => {
-            if segment.ident.name == sym!(then_some)
+            if segment.ident.name.as_str() == "then_some"
                 && cx.typeck_results().expr_ty(recv).is_bool()
                 && path_to_local_id(arg, arg_id)
             {
diff --git a/src/tools/clippy/clippy_lints/src/minmax.rs b/src/tools/clippy/clippy_lints/src/minmax.rs
index e95864c6db8..ed89b3b3438 100644
--- a/src/tools/clippy/clippy_lints/src/minmax.rs
+++ b/src/tools/clippy/clippy_lints/src/minmax.rs
@@ -79,9 +79,9 @@ fn min_max<'a, 'tcx>(cx: &LateContext<'tcx>, expr: &'a Expr<'a>) -> Option<(MinM
         },
         ExprKind::MethodCall(path, receiver, args @ [_], _) => {
             if cx.typeck_results().expr_ty(receiver).is_floating_point() || is_trait_method(cx, expr, sym::Ord) {
-                if path.ident.name == sym!(max) {
+                if path.ident.name.as_str() == "max" {
                     fetch_const(cx, Some(receiver), args, MinMax::Max)
-                } else if path.ident.name == sym!(min) {
+                } else if path.ident.name.as_str() == "min" {
                     fetch_const(cx, Some(receiver), args, MinMax::Min)
                 } else {
                     None
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index ce508d85d63..1300c7d1062 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -12,11 +12,13 @@ use clippy_utils::is_from_proc_macro;
 use clippy_utils::source::SpanRangeExt;
 use rustc_ast::ast::{self, MetaItem, MetaItemKind};
 use rustc_hir as hir;
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::Visibility;
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::CRATE_DEF_ID;
+use rustc_span::symbol::kw;
 use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
@@ -110,6 +112,21 @@ impl MissingDoc {
             return;
         }
 
+        if let Some(parent_def_id) = cx.tcx.opt_parent(def_id.to_def_id())
+            && let DefKind::AnonConst
+            | DefKind::AssocConst
+            | DefKind::AssocFn
+            | DefKind::Closure
+            | DefKind::Const
+            | DefKind::Fn
+            | DefKind::InlineConst
+            | DefKind::Static { .. }
+            | DefKind::SyntheticCoroutineBody = cx.tcx.def_kind(parent_def_id)
+        {
+            // Nested item has no generated documentation, so it doesn't need to be documented.
+            return;
+        }
+
         let has_doc = attrs
             .iter()
             .any(|a| a.doc_str().is_some() || Self::has_include(a.meta()))
@@ -184,8 +201,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
                     }
                 }
             },
-            hir::ItemKind::Const(..)
-            | hir::ItemKind::Enum(..)
+            hir::ItemKind::Const(..) => {
+                if it.ident.name == kw::Underscore {
+                    note_prev_span_then_ret!(self.prev_span, it.span);
+                }
+            },
+            hir::ItemKind::Enum(..)
             | hir::ItemKind::Macro(..)
             | hir::ItemKind::Mod(..)
             | hir::ItemKind::Static(..)
diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
index fc01b6753f1..f28b431ab99 100644
--- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
@@ -116,7 +116,7 @@ fn should_lint<'tcx>(
 
             if path.ident.name == sym::debug_struct && is_type_diagnostic_item(cx, recv_ty, sym::Formatter) {
                 has_debug_struct = true;
-            } else if path.ident.name == sym!(finish_non_exhaustive)
+            } else if path.ident.name.as_str() == "finish_non_exhaustive"
                 && is_type_diagnostic_item(cx, recv_ty, sym::DebugStruct)
             {
                 has_finish_non_exhaustive = true;
diff --git a/src/tools/clippy/clippy_lints/src/needless_continue.rs b/src/tools/clippy/clippy_lints/src/needless_continue.rs
index ce97370d4d9..c4836772933 100644
--- a/src/tools/clippy/clippy_lints/src/needless_continue.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_continue.rs
@@ -330,10 +330,11 @@ fn suggestion_snippet_for_continue_inside_else(cx: &EarlyContext<'_>, data: &Lin
 }
 
 fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) {
-    if let ast::ExprKind::Loop(loop_block, ..) = &expr.kind
+    if let ast::ExprKind::Loop(loop_block, loop_label, ..) = &expr.kind
         && let Some(last_stmt) = loop_block.stmts.last()
         && let ast::StmtKind::Expr(inner_expr) | ast::StmtKind::Semi(inner_expr) = &last_stmt.kind
-        && let ast::ExprKind::Continue(_) = inner_expr.kind
+        && let ast::ExprKind::Continue(continue_label) = inner_expr.kind
+        && compare_labels(loop_label.as_ref(), continue_label.as_ref())
     {
         span_lint_and_help(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
index 46cdb82130f..a67addea948 100644
--- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
@@ -347,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {
         if let LetStmt {
             init: None,
             pat:
-                &Pat {
+                Pat {
                     kind: PatKind::Binding(BindingMode::NONE, binding_id, _, None),
                     ..
                 },
@@ -357,7 +357,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {
             && let Some((_, Node::Stmt(local_stmt))) = parents.next()
             && let Some((_, Node::Block(block))) = parents.next()
         {
-            check(cx, local, local_stmt, block, binding_id);
+            check(cx, local, local_stmt, block, *binding_id);
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
index 9a1c397b5b2..852a0ce8c6d 100644
--- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::{DefId, DefIdMap};
-use rustc_hir::{GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, BoundPolarity, WherePredicate};
+use rustc_hir::{BoundPolarity, GenericBound, Generics, PolyTraitRef, TraitBoundModifiers, WherePredicate};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{ClauseKind, PredicatePolarity};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index f8c815d9729..b7dc269061c 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -183,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
             .iter()
             .zip(fn_sig.inputs())
             .zip(body.params)
-            .filter(|((&input, &ty), arg)| !should_skip(cx, input, ty, arg))
+            .filter(|&((&input, &ty), arg)| !should_skip(cx, input, ty, arg))
             .peekable();
         if it.peek().is_none() {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 2e5195d459f..74536028b5d 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -159,8 +159,12 @@ impl NoEffect {
 
                                 // Remove `impl Future<Output = T>` to get `T`
                                 if cx.tcx.ty_is_opaque_future(ret_ty)
-                                    && let Some(true_ret_ty) =
-                                        cx.tcx.infer_ctxt().build(cx.typing_mode()).err_ctxt().get_impl_future_output_ty(ret_ty)
+                                    && let Some(true_ret_ty) = cx
+                                        .tcx
+                                        .infer_ctxt()
+                                        .build(cx.typing_mode())
+                                        .err_ctxt()
+                                        .get_impl_future_output_ty(ret_ty)
                                 {
                                     ret_ty = true_ret_ty;
                                 }
diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
index 8d5a523fd8f..64587e08ddc 100644
--- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
+++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::source::{snippet, snippet_with_applicability};
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -18,13 +18,13 @@ declare_clippy_lint! {
     /// Rust ABI can break this at any point.
     ///
     /// ### Example
-    /// ```no_run
+    /// ```rust,ignore
     ///  #[no_mangle]
     ///  fn example(arg_one: u32, arg_two: usize) {}
     /// ```
     ///
     /// Use instead:
-    /// ```no_run
+    /// ```rust,ignore
     ///  #[no_mangle]
     ///  extern "C" fn example(arg_one: u32, arg_two: usize) {}
     /// ```
@@ -40,24 +40,25 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
         if let ItemKind::Fn(fn_sig, _, _) = &item.kind {
             let attrs = cx.tcx.hir().attrs(item.hir_id());
             let mut app = Applicability::MaybeIncorrect;
-            let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut app);
+            let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(item.ident.span.lo()), "..", &mut app);
             for attr in attrs {
                 if let Some(ident) = attr.ident()
                     && ident.name == rustc_span::sym::no_mangle
                     && fn_sig.header.abi == Abi::Rust
-                    && let Some((fn_attrs, _)) = snippet.split_once("fn")
+                    && let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn")
                     && !fn_attrs.contains("extern")
                 {
                     let sugg_span = fn_sig
                         .span
                         .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))
                         .shrink_to_lo();
+                    let attr_snippet = snippet(cx, attr.span, "..");
 
                     span_lint_and_then(
                         cx,
                         NO_MANGLE_WITH_RUST_ABI,
                         fn_sig.span,
-                        "`#[no_mangle]` set on a function with the default (`Rust`) ABI",
+                        format!("`{attr_snippet}` set on a function with the default (`Rust`) ABI"),
                         |diag| {
                             diag.span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", app)
                                 .span_suggestion(sugg_span, "or explicitly set the default", "extern \"Rust\" ", app);
diff --git a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
index 3f156aa5510..0caa19cd844 100644
--- a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
+++ b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
@@ -43,12 +43,12 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
         match &expr.kind {
             ExprKind::MethodCall(path, func, [param], _) => {
                 if let Some(adt) = cx.typeck_results().expr_ty(func).peel_refs().ty_adt_def()
-                    && ((path.ident.name == sym!(mode)
+                    && ((path.ident.name.as_str() == "mode"
                         && matches!(
                             cx.tcx.get_diagnostic_name(adt.did()),
                             Some(sym::FsOpenOptions | sym::DirBuilder)
                         ))
-                        || (path.ident.name == sym!(set_mode)
+                        || (path.ident.name.as_str() == "set_mode"
                             && cx.tcx.is_diagnostic_item(sym::FsPermissions, adt.did())))
                     && let ExprKind::Lit(_) = param.kind
                     && param.span.eq_ctxt(expr.span)
diff --git a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
index 8e394944c21..ab5f91c1d67 100644
--- a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
@@ -107,7 +107,7 @@ fn is_signum(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     }
 
     if let ExprKind::MethodCall(method_name, self_arg, [], _) = expr.kind
-        && sym!(signum) == method_name.ident.name
+        && method_name.ident.name.as_str() == "signum"
     // Check that the receiver of the signum() is a float (expressions[0] is the receiver of
     // the method call)
     {
diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
index 18e6aad9c9a..794bef7b321 100644
--- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
@@ -34,7 +34,7 @@ declare_lint_pass!(PartialEqNeImpl => [PARTIALEQ_NE_IMPL]);
 impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if let ItemKind::Impl(Impl {
-            of_trait: Some(ref trait_ref),
+            of_trait: Some(trait_ref),
             items: impl_items,
             ..
         }) = item.kind
diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
index 56d07aeae17..808a7e005c6 100644
--- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
@@ -96,7 +96,7 @@ fn expr_as_ptr_offset_call<'tcx>(
             if path_segment.ident.name == sym::offset {
                 return Some((arg_0, arg_1, Method::Offset));
             }
-            if path_segment.ident.name == sym!(wrapping_offset) {
+            if path_segment.ident.name.as_str() == "wrapping_offset" {
                 return Some((arg_0, arg_1, Method::WrappingOffset));
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index 9344cb41993..cb374fcf20e 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -93,7 +93,7 @@ enum IfBlockType<'hir> {
 
 fn find_let_else_ret_expression<'hir>(block: &'hir Block<'hir>) -> Option<&'hir Expr<'hir>> {
     if let Block {
-        stmts: &[],
+        stmts: [],
         expr: Some(els),
         ..
     } = block
@@ -163,8 +163,8 @@ fn is_early_return(smbl: Symbol, cx: &LateContext<'_>, if_block: &IfBlockType<'_
             is_type_diagnostic_item(cx, caller_ty, smbl)
                 && expr_return_none_or_err(smbl, cx, if_then, caller, None)
                 && match smbl {
-                    sym::Option => call_sym == sym!(is_none),
-                    sym::Result => call_sym == sym!(is_err),
+                    sym::Option => call_sym.as_str() == "is_none",
+                    sym::Result => call_sym.as_str() == "is_err",
                     _ => false,
                 }
         },
diff --git a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
index 19ce08bde10..7d59bf24d93 100644
--- a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
@@ -39,7 +39,7 @@ impl<'tcx> LateLintPass<'tcx> for RefOptionRef {
     fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
         if let TyKind::Ref(_, ref mut_ty) = ty.kind
             && mut_ty.mutbl == Mutability::Not
-            && let TyKind::Path(ref qpath) = &mut_ty.ty.kind
+            && let TyKind::Path(qpath) = &mut_ty.ty.kind
             && let last = last_path_segment(qpath)
             && let Some(def_id) = last.res.opt_def_id()
             && cx.tcx.is_diagnostic_item(sym::Option, def_id)
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 110dea8fb8e..1e0f6dff1ab 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -347,7 +347,7 @@ fn check_final_expr<'tcx>(
     let peeled_drop_expr = expr.peel_drop_temps();
     match &peeled_drop_expr.kind {
         // simple return is always "bad"
-        ExprKind::Ret(ref inner) => {
+        ExprKind::Ret(inner) => {
             // check if expr return nothing
             let ret_span = if inner.is_none() && replacement == RetReplacement::Empty {
                 extend_span_to_previous_non_ws(cx, peeled_drop_expr.span)
diff --git a/src/tools/clippy/clippy_lints/src/semicolon_block.rs b/src/tools/clippy/clippy_lints/src/semicolon_block.rs
index 09f1c112352..d85f4a8fa01 100644
--- a/src/tools/clippy/clippy_lints/src/semicolon_block.rs
+++ b/src/tools/clippy/clippy_lints/src/semicolon_block.rs
@@ -101,17 +101,21 @@ impl SemicolonBlock {
         );
     }
 
-    fn semicolon_outside_block(
-        &self,
-        cx: &LateContext<'_>,
-        block: &Block<'_>,
-        tail_stmt_expr: &Expr<'_>,
-        semi_span: Span,
-    ) {
+    fn semicolon_outside_block(&self, cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>) {
         let insert_span = block.span.with_lo(block.span.hi());
-        // account for macro calls
-        let semi_span = cx.sess().source_map().stmt_span(semi_span, block.span);
-        let remove_span = semi_span.with_lo(tail_stmt_expr.span.source_callsite().hi());
+
+        // For macro call semicolon statements (`mac!();`), the statement's span does not actually
+        // include the semicolon itself, so use `mac_call_stmt_semi_span`, which finds the semicolon
+        // based on a source snippet.
+        // (Does not use `stmt_span` as that requires `.from_expansion()` to return true,
+        // which is not the case for e.g. `line!();` and `asm!();`)
+        let Some(remove_span) = cx
+            .sess()
+            .source_map()
+            .mac_call_stmt_semi_span(tail_stmt_expr.span.source_callsite())
+        else {
+            return;
+        };
 
         if self.semicolon_outside_block_ignore_multiline && get_line(cx, remove_span) != get_line(cx, insert_span) {
             return;
@@ -150,13 +154,12 @@ impl LateLintPass<'_> for SemicolonBlock {
                 };
                 let &Stmt {
                     kind: StmtKind::Semi(expr),
-                    span,
                     ..
                 } = stmt
                 else {
                     return;
                 };
-                self.semicolon_outside_block(cx, block, expr, span);
+                self.semicolon_outside_block(cx, block, expr);
             },
             StmtKind::Semi(Expr {
                 kind: ExprKind::Block(block @ Block { expr: Some(tail), .. }, _),
diff --git a/src/tools/clippy/clippy_lints/src/serde_api.rs b/src/tools/clippy/clippy_lints/src/serde_api.rs
index fcf1c4cc5c2..6a0dfde2d9c 100644
--- a/src/tools/clippy/clippy_lints/src/serde_api.rs
+++ b/src/tools/clippy/clippy_lints/src/serde_api.rs
@@ -26,7 +26,7 @@ declare_lint_pass!(SerdeApi => [SERDE_API_MISUSE]);
 impl<'tcx> LateLintPass<'tcx> for SerdeApi {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if let ItemKind::Impl(Impl {
-            of_trait: Some(ref trait_ref),
+            of_trait: Some(trait_ref),
             items,
             ..
         }) = item.kind
diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
index 9fdee8543a8..fa082453504 100644
--- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
@@ -174,7 +174,7 @@ impl SingleComponentPathImports {
         }
 
         match &item.kind {
-            ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) => {
+            ItemKind::Mod(_, ModKind::Loaded(items, ..)) => {
                 self.check_mod(items);
             },
             ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => {
diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
index ec6e45256d1..8c8f11569c8 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -235,7 +235,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
         if self.initialization_found
             && let ExprKind::MethodCall(path, self_arg, [extend_arg], _) = expr.kind
             && path_to_local_id(self_arg, self.vec_alloc.local_id)
-            && path.ident.name == sym!(extend)
+            && path.ident.name.as_str() == "extend"
             && self.is_repeat_take(extend_arg)
         {
             self.slow_expression = Some(InitializationType::Extend(expr));
@@ -247,7 +247,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
         if self.initialization_found
             && let ExprKind::MethodCall(path, self_arg, [len_arg, fill_arg], _) = expr.kind
             && path_to_local_id(self_arg, self.vec_alloc.local_id)
-            && path.ident.name == sym!(resize)
+            && path.ident.name.as_str() == "resize"
             // Check that is filled with 0
             && is_integer_literal(fill_arg, 0)
         {
@@ -269,7 +269,7 @@ impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
     /// Returns `true` if give expression is `repeat(0).take(...)`
     fn is_repeat_take(&mut self, expr: &'tcx Expr<'tcx>) -> bool {
         if let ExprKind::MethodCall(take_path, recv, [len_arg], _) = expr.kind
-            && take_path.ident.name == sym!(take)
+            && take_path.ident.name.as_str() == "take"
             // Check that take is applied to `repeat(0)`
             && self.is_repeat_zero(recv)
         {
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index bf49bb60162..e09c0706006 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -286,7 +286,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
 
         if !in_external_macro(cx.sess(), e.span)
             && let ExprKind::MethodCall(path, receiver, ..) = &e.kind
-            && path.ident.name == sym!(as_bytes)
+            && path.ident.name.as_str() == "as_bytes"
             && let ExprKind::Lit(lit) = &receiver.kind
             && let LitKind::Str(lit_content, _) = &lit.node
         {
@@ -332,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
         }
 
         if let ExprKind::MethodCall(path, recv, [], _) = &e.kind
-            && path.ident.name == sym!(into_bytes)
+            && path.ident.name.as_str() == "into_bytes"
             && let ExprKind::MethodCall(path, recv, [], _) = &recv.kind
             && matches!(path.ident.name.as_str(), "to_owned" | "to_string")
             && let ExprKind::Lit(lit) = &recv.kind
@@ -493,7 +493,7 @@ impl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
         let tyckres = cx.typeck_results();
         if let ExprKind::MethodCall(path, split_recv, [], split_ws_span) = expr.kind
-            && path.ident.name == sym!(split_whitespace)
+            && path.ident.name.as_str() == "split_whitespace"
             && let Some(split_ws_def_id) = tyckres.type_dependent_def_id(expr.hir_id)
             && cx.tcx.is_diagnostic_item(sym::str_split_whitespace, split_ws_def_id)
             && let ExprKind::MethodCall(path, _trim_recv, [], trim_span) = split_recv.kind
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
index be32dc0aab0..0d809c17989 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
@@ -334,7 +334,7 @@ fn strip_non_ident_wrappers(expr: &Expr) -> &Expr {
     let mut output = expr;
     loop {
         output = match &output.kind {
-            ExprKind::Paren(ref inner) | ExprKind::Unary(_, ref inner) => inner,
+            ExprKind::Paren(inner) | ExprKind::Unary(_, inner) => inner,
             _ => {
                 return output;
             },
@@ -348,13 +348,13 @@ fn extract_related_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {
 
 fn if_statement_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {
     match kind {
-        ExprKind::If(ref condition, _, _) => chained_binops(&condition.kind),
-        ExprKind::Paren(ref e) => if_statement_binops(&e.kind),
-        ExprKind::Block(ref block, _) => {
+        ExprKind::If(condition, _, _) => chained_binops(&condition.kind),
+        ExprKind::Paren(e) => if_statement_binops(&e.kind),
+        ExprKind::Block(block, _) => {
             let mut output = None;
             for stmt in &block.stmts {
-                match stmt.kind {
-                    StmtKind::Expr(ref e) | StmtKind::Semi(ref e) => {
+                match &stmt.kind {
+                    StmtKind::Expr(e) | StmtKind::Semi(e) => {
                         output = append_opt_vecs(output, if_statement_binops(&e.kind));
                     },
                     _ => {},
@@ -383,7 +383,7 @@ fn append_opt_vecs<A>(target_opt: Option<Vec<A>>, source_opt: Option<Vec<A>>) ->
 fn chained_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {
     match kind {
         ExprKind::Binary(_, left_outer, right_outer) => chained_binops_helper(left_outer, right_outer),
-        ExprKind::Paren(ref e) | ExprKind::Unary(_, ref e) => chained_binops(&e.kind),
+        ExprKind::Paren(e) | ExprKind::Unary(_, e) => chained_binops(&e.kind),
         _ => None,
     }
 }
@@ -391,16 +391,14 @@ fn chained_binops(kind: &ExprKind) -> Option<Vec<BinaryOp<'_>>> {
 fn chained_binops_helper<'expr>(left_outer: &'expr Expr, right_outer: &'expr Expr) -> Option<Vec<BinaryOp<'expr>>> {
     match (&left_outer.kind, &right_outer.kind) {
         (
-            ExprKind::Paren(ref left_e) | ExprKind::Unary(_, ref left_e),
-            ExprKind::Paren(ref right_e) | ExprKind::Unary(_, ref right_e),
+            ExprKind::Paren(left_e) | ExprKind::Unary(_, left_e),
+            ExprKind::Paren(right_e) | ExprKind::Unary(_, right_e),
         ) => chained_binops_helper(left_e, right_e),
-        (ExprKind::Paren(ref left_e) | ExprKind::Unary(_, ref left_e), _) => chained_binops_helper(left_e, right_outer),
-        (_, ExprKind::Paren(ref right_e) | ExprKind::Unary(_, ref right_e)) => {
-            chained_binops_helper(left_outer, right_e)
-        },
+        (ExprKind::Paren(left_e) | ExprKind::Unary(_, left_e), _) => chained_binops_helper(left_e, right_outer),
+        (_, ExprKind::Paren(right_e) | ExprKind::Unary(_, right_e)) => chained_binops_helper(left_outer, right_e),
         (
-            ExprKind::Binary(Spanned { node: left_op, .. }, ref left_left, ref left_right),
-            ExprKind::Binary(Spanned { node: right_op, .. }, ref right_left, ref right_right),
+            ExprKind::Binary(Spanned { node: left_op, .. }, left_left, left_right),
+            ExprKind::Binary(Spanned { node: right_op, .. }, right_left, right_right),
         ) => match (
             chained_binops_helper(left_left, left_right),
             chained_binops_helper(right_left, right_right),
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index 6cba560393d..23362506cca 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -392,7 +392,7 @@ impl<'tcx> IndexBinding<'_, 'tcx> {
         for stmt in self.block.stmts {
             match stmt.kind {
                 StmtKind::Expr(expr) | StmtKind::Semi(expr) => v.visit_expr(expr),
-                StmtKind::Let(LetStmt { ref init, .. }) => {
+                StmtKind::Let(LetStmt { init, .. }) => {
                     if let Some(init) = init.as_ref() {
                         v.visit_expr(init);
                     }
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 3da4bf67558..07bf4319ff0 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -10,8 +10,8 @@ use rustc_data_structures::unhash::UnhashMap;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{
-    GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
-    TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate, BoundPolarity,
+    BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
+    TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
@@ -124,7 +124,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
         let mut self_bounds_map = FxHashMap::default();
 
         for predicate in item.generics.predicates {
-            if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate
+            if let WherePredicate::BoundPredicate(bound_predicate) = predicate
                 && bound_predicate.origin != PredicateOrigin::ImplTrait
                 && !bound_predicate.span.from_expansion()
                 && let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind
@@ -268,7 +268,7 @@ impl TraitBounds {
         let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default();
         let mut applicability = Applicability::MaybeIncorrect;
         for bound in generics.predicates {
-            if let WherePredicate::BoundPredicate(ref p) = bound
+            if let WherePredicate::BoundPredicate(p) = bound
                 && p.origin != PredicateOrigin::ImplTrait
                 && p.bounds.len() as u64 <= self.max_trait_bounds
                 && !p.span.from_expansion()
@@ -379,7 +379,7 @@ struct ComparableTraitRef<'a, 'tcx> {
 
 impl PartialEq for ComparableTraitRef<'_, '_> {
     fn eq(&self, other: &Self) -> bool {
-        SpanlessEq::new(self.cx).eq_modifiers(self.modifiers, other.modifiers)
+        SpanlessEq::eq_modifiers(self.modifiers, other.modifiers)
             && SpanlessEq::new(self.cx)
                 .paths_by_resolution()
                 .eq_path(self.trait_ref.path, other.trait_ref.path)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs
index 1dfc9f7091e..ca9daf2d2a0 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/eager_transmute.rs
@@ -43,7 +43,7 @@ fn binops_with_local(cx: &LateContext<'_>, local_expr: &Expr<'_>, expr: &Expr<'_
             binops_with_local(cx, local_expr, lhs) || binops_with_local(cx, local_expr, rhs)
         },
         ExprKind::MethodCall(path, receiver, [arg], _)
-            if path.ident.name == sym!(contains)
+            if path.ident.name.as_str() == "contains"
                 // ... `contains` called on some kind of range
                 && let Some(receiver_adt) = cx.typeck_results().expr_ty(receiver).peel_refs().ty_adt_def()
                 && let lang_items = cx.tcx.lang_items()
@@ -81,7 +81,7 @@ pub(super) fn check<'tcx>(
     if let Some(then_some_call) = peel_parent_unsafe_blocks(cx, expr)
         && let ExprKind::MethodCall(path, receiver, [arg], _) = then_some_call.kind
         && cx.typeck_results().expr_ty(receiver).is_bool()
-        && path.ident.name == sym!(then_some)
+        && path.ident.name.as_str() == "then_some"
         && is_local_with_projections(transmutable)
         && binops_with_local(cx, transmutable, receiver)
         && is_normalizable(cx, cx.param_env, from_ty)
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index 44eb0a6c593..0bba611116b 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -295,7 +295,7 @@ fn expr_has_unnecessary_safety_comment<'tcx>(
     if cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, ref node)| {
         matches!(
             node,
-            Node::Block(&Block {
+            Node::Block(Block {
                 rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
                 ..
             }),
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index bf2d75ea1a9..1a1284ce9c4 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -194,7 +194,7 @@ fn needs_inferred_result_ty(
     let (id, receiver, args) = match e.kind {
         ExprKind::Call(
             Expr {
-                kind: ExprKind::Path(ref path),
+                kind: ExprKind::Path(path),
                 hir_id,
                 ..
             },
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
index e7d26fa238e..0f4bd286145 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
@@ -149,7 +149,7 @@ fn is_empty_block(expr: &Expr<'_>) -> bool {
         expr.kind,
         ExprKind::Block(
             Block {
-                stmts: &[],
+                stmts: [],
                 expr: None,
                 ..
             },
diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
index cf406b817da..7c9455bf8ab 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
-use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths, peel_blocks};
+use clippy_utils::{is_res_lang_ctor, is_trait_method, match_def_path, match_trait_method, paths, peel_blocks};
 use hir::{ExprKind, HirId, PatKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -83,6 +83,28 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
     /// to consider the arms, and we want to avoid breaking the logic for situations where things
     /// get desugared to match.
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) {
+        let fn_def_id = block.hir_id.owner.to_def_id();
+        if let Some(impl_id) = cx.tcx.impl_of_method(fn_def_id)
+            && let Some(trait_id) = cx.tcx.trait_id_of_impl(impl_id)
+        {
+            // We don't want to lint inside io::Read or io::Write implementations, as the author has more
+            // information about their trait implementation than our lint, see https://github.com/rust-lang/rust-clippy/issues/4836
+            if cx.tcx.is_diagnostic_item(sym::IoRead, trait_id) || cx.tcx.is_diagnostic_item(sym::IoWrite, trait_id) {
+                return;
+            }
+
+            let async_paths: [&[&str]; 4] = [
+                &paths::TOKIO_IO_ASYNCREADEXT,
+                &paths::TOKIO_IO_ASYNCWRITEEXT,
+                &paths::FUTURES_IO_ASYNCREADEXT,
+                &paths::FUTURES_IO_ASYNCWRITEEXT,
+            ];
+
+            if async_paths.into_iter().any(|path| match_def_path(cx, trait_id, path)) {
+                return;
+            }
+        }
+
         for stmt in block.stmts {
             if let hir::StmtKind::Semi(exp) = stmt.kind {
                 check_expr(cx, exp);
@@ -222,7 +244,7 @@ fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
 }
 
 fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
-    while let ExprKind::Call(func, [ref arg_0]) = expr.kind
+    while let ExprKind::Call(func, [arg_0]) = expr.kind
         && matches!(
             func.kind,
             ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
@@ -244,7 +266,7 @@ fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
 /// waited on.  Otherwise return None.
 fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
     if let ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind {
-        if let ExprKind::Call(func, [ref arg_0]) = expr.kind {
+        if let ExprKind::Call(func, [arg_0]) = expr.kind {
             if matches!(
                 func.kind,
                 ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..))
diff --git a/src/tools/clippy/clippy_lints/src/utils/attr_collector.rs b/src/tools/clippy/clippy_lints/src/utils/attr_collector.rs
new file mode 100644
index 00000000000..1522553bbf5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/utils/attr_collector.rs
@@ -0,0 +1,40 @@
+use std::mem;
+use std::sync::OnceLock;
+
+use rustc_ast::{Attribute, Crate};
+use rustc_data_structures::sync::Lrc;
+use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_session::impl_lint_pass;
+use rustc_span::Span;
+
+#[derive(Clone, Default)]
+pub struct AttrStorage(pub Lrc<OnceLock<Vec<Span>>>);
+
+pub struct AttrCollector {
+    storage: AttrStorage,
+    attrs: Vec<Span>,
+}
+
+impl AttrCollector {
+    pub fn new(storage: AttrStorage) -> Self {
+        Self {
+            storage,
+            attrs: Vec::new(),
+        }
+    }
+}
+
+impl_lint_pass!(AttrCollector => []);
+
+impl EarlyLintPass for AttrCollector {
+    fn check_attribute(&mut self, _cx: &EarlyContext<'_>, attr: &Attribute) {
+        self.attrs.push(attr.span);
+    }
+
+    fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &Crate) {
+        self.storage
+            .0
+            .set(mem::take(&mut self.attrs))
+            .expect("should only be called once");
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 31f9d84f5e4..1bf24083665 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -396,7 +396,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 self.pat(field!(let_expr.pat));
                 // Does what ExprKind::Cast does, only adds a clause for the type
                 // if it's a path
-                if let Some(TyKind::Path(ref qpath)) = let_expr.value.ty.as_ref().map(|ty| &ty.kind) {
+                if let Some(TyKind::Path(qpath)) = let_expr.value.ty.as_ref().map(|ty| &ty.kind) {
                     bind!(self, qpath);
                     chain!(self, "let TyKind::Path(ref {qpath}) = {let_expr}.ty.kind");
                     self.qpath(qpath);
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
index f662c7651f6..deb983b6971 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints.rs
@@ -6,5 +6,6 @@ pub mod lint_without_lint_pass;
 pub mod msrv_attr_impl;
 pub mod outer_expn_data_pass;
 pub mod produce_ice;
+pub mod slow_symbol_comparisons;
 pub mod unnecessary_def_path;
 pub mod unsorted_clippy_utils_paths;
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs
index a3f9abe4f96..eaeb754a23f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs
@@ -79,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {
 
         if let ExprKind::Call(func, [call_cx, call_lint, call_sp, call_msg, call_f]) = expr.kind
             && is_expr_path_def_path(cx, func, &["clippy_utils", "diagnostics", "span_lint_and_then"])
-            && let ExprKind::Closure(&Closure { body, .. }) = &call_f.kind
+            && let ExprKind::Closure(&Closure { body, .. }) = call_f.kind
             && let body = cx.tcx.hir().body(body)
             && let only_expr = peel_blocks_with_stmt(body.value)
             && let ExprKind::MethodCall(ps, recv, span_call_args, _) = &only_expr.kind
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index 51235de9f29..af38e066559 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -21,7 +21,7 @@ declare_clippy_lint! {
     ///
     /// ### Why is this bad?
     /// The compiler only knows lints via a `LintPass`. Without
-    /// putting a lint to a `LintPass::get_lints()`'s return, the compiler will not
+    /// putting a lint to a `LintPass::lint_vec()`'s return, the compiler will not
     /// know the name of the lint.
     ///
     /// ### Known problems
@@ -123,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
                     .expect("lints must have a description field");
 
                 if let ExprKind::Lit(Spanned {
-                    node: LitKind::Str(ref sym, _),
+                    node: LitKind::Str(sym, _),
                     ..
                 }) = field.expr.kind
                 {
@@ -159,8 +159,8 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
                 let body = cx.tcx.hir().body_owned_by(
                     impl_item_refs
                         .iter()
-                        .find(|iiref| iiref.ident.as_str() == "get_lints")
-                        .expect("LintPass needs to implement get_lints")
+                        .find(|iiref| iiref.ident.as_str() == "lint_vec")
+                        .expect("LintPass needs to implement lint_vec")
                         .id
                         .owner_id
                         .def_id,
@@ -218,9 +218,7 @@ pub(super) fn is_lint_ref_type(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
 
 fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'_>) {
     if let Some(value) = extract_clippy_version_value(cx, item) {
-        // The `sym!` macro doesn't work as it only expects a single token.
-        // It's better to keep it this way and have a direct `Symbol::intern` call here.
-        if value == Symbol::intern("pre 1.29.0") {
+        if value.as_str() == "pre 1.29.0" {
             return;
         }
 
@@ -251,7 +249,7 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'
 pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option<Symbol> {
     let attrs = cx.tcx.hir().attrs(item.hir_id());
     attrs.iter().find_map(|attr| {
-        if let ast::AttrKind::Normal(ref attr_kind) = &attr.kind
+        if let ast::AttrKind::Normal(attr_kind) = &attr.kind
             // Identify attribute
             && let [tool_name, attr_name] = &attr_kind.item.path.segments[..]
             && tool_name.ident.name == sym::clippy
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
index 63fcbd61528..68692246153 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
@@ -42,7 +42,7 @@ impl LateLintPass<'_> for MsrvAttrImpl {
                     .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_)))
                     .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV))
             })
-            && !items.iter().any(|item| item.ident.name == sym!(check_attributes))
+            && !items.iter().any(|item| item.ident.name.as_str() == "check_attributes")
         {
             let context = if is_late_pass { "LateContext" } else { "EarlyContext" };
             let lint_pass = if is_late_pass { "LateLintPass" } else { "EarlyLintPass" };
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
new file mode 100644
index 00000000000..3742be0e103
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
@@ -0,0 +1,69 @@
+use clippy_utils::consts::{ConstEvalCtxt, Constant};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::match_type;
+use clippy_utils::{match_function_call, paths};
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::declare_lint_pass;
+use rustc_span::Span;
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Detects symbol comparision using `Symbol::intern`.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// Comparision via `Symbol::as_str()` is faster if the interned symbols are not reused.
+    ///
+    /// ### Example
+    ///
+    /// None, see suggestion.
+    pub SLOW_SYMBOL_COMPARISONS,
+    internal,
+    "detects slow comparisions of symbol"
+}
+
+declare_lint_pass!(SlowSymbolComparisons => [SLOW_SYMBOL_COMPARISONS]);
+
+fn check_slow_comparison<'tcx>(
+    cx: &LateContext<'tcx>,
+    op1: &'tcx Expr<'tcx>,
+    op2: &'tcx Expr<'tcx>,
+) -> Option<(Span, String)> {
+    if match_type(cx, cx.typeck_results().expr_ty(op1), &paths::SYMBOL)
+        && let Some([symbol_name_expr]) = match_function_call(cx, op2, &paths::SYMBOL_INTERN)
+        && let Some(Constant::Str(symbol_name)) = ConstEvalCtxt::new(cx).eval_simple(symbol_name_expr)
+    {
+        Some((op1.span, symbol_name))
+    } else {
+        None
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for SlowSymbolComparisons {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
+        if let ExprKind::Binary(op, left, right) = expr.kind
+            && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne)
+            && let Some((symbol_span, symbol_name)) =
+                check_slow_comparison(cx, left, right).or_else(|| check_slow_comparison(cx, right, left))
+        {
+            let mut applicability = Applicability::MachineApplicable;
+            span_lint_and_sugg(
+                cx,
+                SLOW_SYMBOL_COMPARISONS,
+                expr.span,
+                "comparing `Symbol` via `Symbol::intern`",
+                "use `Symbol::as_str` and check the string instead",
+                format!(
+                    "{}.as_str() {} \"{symbol_name}\"",
+                    snippet_with_applicability(cx, symbol_span, "symbol", &mut applicability),
+                    op.node.as_str()
+                ),
+                applicability,
+            );
+        };
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs
index 13e9ead9a57..4476cd1005e 100644
--- a/src/tools/clippy/clippy_lints/src/utils/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs
@@ -1,5 +1,7 @@
+pub mod attr_collector;
 pub mod author;
 pub mod dump_hir;
 pub mod format_args_collector;
+
 #[cfg(feature = "internal")]
 pub mod internal_lints;
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index c5e2c8c09a2..75169e05734 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -21,7 +21,7 @@ use rustc_hir::{
     ImplItem, ImplItemKind, IsAuto, Item, ItemKind, Lit, LoopSource, MatchSource, MutTy, Node, Path, QPath, Safety,
     TraitItem, TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Variant, VariantData, YieldSource,
 };
-use rustc_lint::{LateContext, LintContext, EarlyContext};
+use rustc_lint::{EarlyContext, LateContext, LintContext};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_span::symbol::{Ident, kw};
@@ -63,8 +63,8 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) ->
             Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit),
         } && match end_pat {
             Pat::Str(text) => end_str.ends_with(text),
-            Pat::MultiStr(texts) => texts.iter().any(|s| start_str.ends_with(s)),
-            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
+            Pat::MultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),
+            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),
             Pat::Sym(sym) => end_str.ends_with(sym.as_str()),
             Pat::Num => end_str.as_bytes().last().map_or(false, u8::is_ascii_hexdigit),
         })
@@ -333,26 +333,32 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
     match attr.kind {
         AttrKind::Normal(..) => {
             if let Some(ident) = attr.ident() {
-                // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of
-                // refactoring
                 // NOTE: This will likely have false positives, like `allow = 1`
-                (
-                    Pat::OwnedMultiStr(vec![ident.to_string(), "#".to_owned()]),
-                    Pat::Str(""),
-                )
+                let ident_string = ident.to_string();
+                if attr.style == AttrStyle::Outer {
+                    (
+                        Pat::OwnedMultiStr(vec!["#[".to_owned() + &ident_string, ident_string]),
+                        Pat::Str(""),
+                    )
+                } else {
+                    (
+                        Pat::OwnedMultiStr(vec!["#![".to_owned() + &ident_string, ident_string]),
+                        Pat::Str(""),
+                    )
+                }
             } else {
                 (Pat::Str("#"), Pat::Str("]"))
             }
         },
         AttrKind::DocComment(_kind @ CommentKind::Line, ..) => {
-            if matches!(attr.style, AttrStyle::Outer) {
+            if attr.style == AttrStyle::Outer {
                 (Pat::Str("///"), Pat::Str(""))
             } else {
                 (Pat::Str("//!"), Pat::Str(""))
             }
         },
         AttrKind::DocComment(_kind @ CommentKind::Block, ..) => {
-            if matches!(attr.style, AttrStyle::Outer) {
+            if attr.style == AttrStyle::Outer {
                 (Pat::Str("/**"), Pat::Str("*/"))
             } else {
                 (Pat::Str("/*!"), Pat::Str("*/"))
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 67c31abbdda..24a02c7ef87 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -1,3 +1,7 @@
+//! A simple const eval API, for use on arbitrary HIR expressions.
+//!
+//! This cannot use rustc's const eval, aka miri, as arbitrary HIR expressions cannot be lowered to
+//! executable MIR bodies, so we have to do this instead.
 #![allow(clippy::float_cmp)]
 
 use crate::macros::HirNode;
@@ -379,6 +383,8 @@ impl Ord for FullInt {
 /// The context required to evaluate a constant expression.
 ///
 /// This is currently limited to constant folding and reading the value of named constants.
+///
+/// See the module level documentation for some context.
 pub struct ConstEvalCtxt<'tcx> {
     tcx: TyCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index 4877fb65d37..ddb7a6635e0 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -9,6 +9,8 @@
 //! ~The `INTERNAL_METADATA_COLLECTOR` lint
 
 use rustc_errors::{Applicability, Diag, DiagMessage, MultiSpan, SubdiagMessage};
+#[cfg(debug_assertions)]
+use rustc_errors::{EmissionGuarantee, SubstitutionPart, Suggestions};
 use rustc_hir::HirId;
 use rustc_lint::{LateContext, Lint, LintContext};
 use rustc_span::Span;
@@ -28,6 +30,43 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
     }
 }
 
+/// Makes sure that a diagnostic is well formed.
+///
+/// rustc debug asserts a few properties about spans,
+/// but the clippy repo uses a distributed rustc build with debug assertions disabled,
+/// so this has historically led to problems during subtree syncs where those debug assertions
+/// only started triggered there.
+///
+/// This function makes sure we also validate them in debug clippy builds.
+#[cfg(debug_assertions)]
+fn validate_diag(diag: &Diag<'_, impl EmissionGuarantee>) {
+    let suggestions = match &diag.suggestions {
+        Suggestions::Enabled(suggs) => &**suggs,
+        Suggestions::Sealed(suggs) => &**suggs,
+        Suggestions::Disabled => return,
+    };
+
+    for substitution in suggestions.iter().flat_map(|s| &s.substitutions) {
+        assert_eq!(
+            substitution
+                .parts
+                .iter()
+                .find(|SubstitutionPart { snippet, span }| snippet.is_empty() && span.is_empty()),
+            None,
+            "span must not be empty and have no suggestion"
+        );
+
+        assert_eq!(
+            substitution
+                .parts
+                .array_windows()
+                .find(|[a, b]| a.span.overlaps(b.span)),
+            None,
+            "suggestion must not have overlapping parts"
+        );
+    }
+}
+
 /// Emit a basic lint message with a `msg` and a `span`.
 ///
 /// This is the most primitive of our lint emission methods and can
@@ -64,6 +103,9 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
     cx.span_lint(lint, sp, |diag| {
         diag.primary_message(msg);
         docs_link(diag, lint);
+
+        #[cfg(debug_assertions)]
+        validate_diag(diag);
     });
 }
 
@@ -118,6 +160,9 @@ pub fn span_lint_and_help<T: LintContext>(
             diag.help(help.into());
         }
         docs_link(diag, lint);
+
+        #[cfg(debug_assertions)]
+        validate_diag(diag);
     });
 }
 
@@ -175,6 +220,9 @@ pub fn span_lint_and_note<T: LintContext>(
             diag.note(note.into());
         }
         docs_link(diag, lint);
+
+        #[cfg(debug_assertions)]
+        validate_diag(diag);
     });
 }
 
@@ -208,6 +256,9 @@ where
         diag.primary_message(msg);
         f(diag);
         docs_link(diag, lint);
+
+        #[cfg(debug_assertions)]
+        validate_diag(diag);
     });
 }
 
@@ -240,6 +291,9 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s
     cx.tcx.node_span_lint(lint, hir_id, sp, |diag| {
         diag.primary_message(msg);
         docs_link(diag, lint);
+
+        #[cfg(debug_assertions)]
+        validate_diag(diag);
     });
 }
 
@@ -280,6 +334,9 @@ pub fn span_lint_hir_and_then(
         diag.primary_message(msg);
         f(diag);
         docs_link(diag, lint);
+
+        #[cfg(debug_assertions)]
+        validate_diag(diag);
     });
 }
 
@@ -316,7 +373,7 @@ pub fn span_lint_hir_and_then(
 ///     |
 ///     = note: `-D fold-any` implied by `-D warnings`
 /// ```
-#[expect(clippy::collapsible_span_lint_calls)]
+#[cfg_attr(not(debug_assertions), expect(clippy::collapsible_span_lint_calls))]
 pub fn span_lint_and_sugg<T: LintContext>(
     cx: &T,
     lint: &'static Lint,
@@ -328,5 +385,8 @@ pub fn span_lint_and_sugg<T: LintContext>(
 ) {
     span_lint_and_then(cx, lint, sp, msg.into(), |diag| {
         diag.span_suggestion(sp, help.into(), sugg, applicability);
+
+        #[cfg(debug_assertions)]
+        validate_diag(diag);
     });
 }
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index 3175a9a1dd3..11bbe734844 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -103,7 +103,7 @@ impl<'hir> IfLet<'hir> {
     /// Parses an `if let` expression
     pub fn hir(cx: &LateContext<'_>, expr: &Expr<'hir>) -> Option<Self> {
         if let ExprKind::If(
-            Expr {
+            &Expr {
                 kind:
                     ExprKind::Let(&hir::LetExpr {
                         pat: let_pat,
@@ -381,12 +381,12 @@ impl<'hir> WhileLet<'hir> {
     /// Parses a desugared `while let` loop
     pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {
         if let ExprKind::Loop(
-            Block {
+            &Block {
                 expr:
-                    Some(Expr {
+                    Some(&Expr {
                         kind:
                             ExprKind::If(
-                                Expr {
+                                &Expr {
                                     kind:
                                         ExprKind::Let(&hir::LetExpr {
                                             pat: let_pat,
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 8004bc68b2e..cb69f8e5a0e 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -128,7 +128,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
         self.inter_expr().eq_path_segments(left, right)
     }
 
-    pub fn eq_modifiers(&mut self, left: TraitBoundModifiers, right: TraitBoundModifiers) -> bool {
+    pub fn eq_modifiers(left: TraitBoundModifiers, right: TraitBoundModifiers) -> bool {
         std::mem::discriminant(&left.constness) == std::mem::discriminant(&right.constness)
             && std::mem::discriminant(&left.polarity) == std::mem::discriminant(&right.polarity)
     }
@@ -1201,11 +1201,11 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 self.hash_ty(ty);
                 self.hash_pat(pat);
             },
-            TyKind::Ptr(ref mut_ty) => {
+            TyKind::Ptr(mut_ty) => {
                 self.hash_ty(mut_ty.ty);
                 mut_ty.mutbl.hash(&mut self.s);
             },
-            TyKind::Ref(lifetime, ref mut_ty) => {
+            TyKind::Ref(lifetime, mut_ty) => {
                 self.hash_lifetime(lifetime);
                 self.hash_ty(mut_ty.ty);
                 mut_ty.mutbl.hash(&mut self.s);
@@ -1230,14 +1230,19 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     self.hash_ty(ty);
                 }
             },
-            TyKind::Path(ref qpath) => self.hash_qpath(qpath),
+            TyKind::Path(qpath) => self.hash_qpath(qpath),
             TyKind::TraitObject(_, lifetime, _) => {
                 self.hash_lifetime(lifetime);
             },
             TyKind::Typeof(anon_const) => {
                 self.hash_body(anon_const.body);
             },
-            TyKind::Err(_) | TyKind::Infer | TyKind::Never | TyKind::InferDelegation(..) | TyKind::OpaqueDef(_) | TyKind::AnonAdt(_) => {},
+            TyKind::Err(_)
+            | TyKind::Infer
+            | TyKind::Never
+            | TyKind::InferDelegation(..)
+            | TyKind::OpaqueDef(_)
+            | TyKind::AnonAdt(_) => {},
         }
     }
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 0f712068e65..50d334acf18 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -9,6 +9,7 @@
 #![feature(rustc_private)]
 #![feature(assert_matches)]
 #![feature(unwrap_infallible)]
+#![feature(array_windows)]
 #![recursion_limit = "512"]
 #![allow(
     clippy::missing_errors_doc,
@@ -688,11 +689,11 @@ pub fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> Vec<Res> {
 ///
 /// This function is expensive and should be used sparingly.
 pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
-    let (base, path) = match *path {
+    let (base, path) = match path {
         [primitive] => {
             return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
         },
-        [base, ref path @ ..] => (base, path),
+        [base, path @ ..] => (base, path),
         _ => return Vec::new(),
     };
 
@@ -744,7 +745,7 @@ pub fn def_path_res_with_base(tcx: TyCtxt<'_>, mut base: Vec<Res>, mut path: &[&
 }
 
 /// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].
-pub fn def_path_def_ids(tcx: TyCtxt<'_>, path: &[&str]) -> impl Iterator<Item = DefId> {
+pub fn def_path_def_ids(tcx: TyCtxt<'_>, path: &[&str]) -> impl Iterator<Item = DefId> + use<> {
     def_path_res(tcx, path).into_iter().filter_map(|res| res.opt_def_id())
 }
 
@@ -934,7 +935,7 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
             }
         },
         ExprKind::Call(repl_func, []) => is_default_equivalent_call(cx, repl_func),
-        ExprKind::Call(from_func, [ref arg]) => is_default_equivalent_from(cx, from_func, arg),
+        ExprKind::Call(from_func, [arg]) => is_default_equivalent_from(cx, from_func, arg),
         ExprKind::Path(qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, e.hir_id), OptionNone),
         ExprKind::AddrOf(rustc_hir::BorrowKind::Ref, _, expr) => matches!(expr.kind, ExprKind::Array([])),
         _ => false,
@@ -947,7 +948,7 @@ fn is_default_equivalent_from(cx: &LateContext<'_>, from_func: &Expr<'_>, arg: &
     {
         match arg.kind {
             ExprKind::Lit(hir::Lit {
-                node: LitKind::Str(ref sym, _),
+                node: LitKind::Str(sym, _),
                 ..
             }) => return sym.is_empty() && is_path_lang_item(cx, ty, LangItem::String),
             ExprKind::Array([]) => return is_path_diagnostic_item(cx, ty, sym::Vec),
@@ -1337,15 +1338,17 @@ pub fn get_item_name(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
 pub struct ContainsName<'a, 'tcx> {
     pub cx: &'a LateContext<'tcx>,
     pub name: Symbol,
-    pub result: bool,
 }
 
 impl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> {
+    type Result = ControlFlow<()>;
     type NestedFilter = nested_filter::OnlyBodies;
 
-    fn visit_name(&mut self, name: Symbol) {
+    fn visit_name(&mut self, name: Symbol) -> Self::Result {
         if self.name == name {
-            self.result = true;
+            ControlFlow::Break(())
+        } else {
+            ControlFlow::Continue(())
         }
     }
 
@@ -1356,13 +1359,8 @@ impl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> {
 
 /// Checks if an `Expr` contains a certain name.
 pub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool {
-    let mut cn = ContainsName {
-        name,
-        result: false,
-        cx,
-    };
-    cn.visit_expr(expr);
-    cn.result
+    let mut cn = ContainsName { cx, name };
+    cn.visit_expr(expr).is_break()
 }
 
 /// Returns `true` if `expr` contains a return expression
@@ -3459,7 +3457,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
 pub fn is_parent_stmt(cx: &LateContext<'_>, id: HirId) -> bool {
     matches!(
         cx.tcx.parent_hir_node(id),
-        Node::Stmt(..) | Node::Block(Block { stmts: &[], .. })
+        Node::Stmt(..) | Node::Block(Block { stmts: [], .. })
     )
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 41785e161d0..ce1a20e0066 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -19,7 +19,7 @@ use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{
     self, AdtDef, AliasTy, AssocItem, AssocKind, Binder, BoundRegion, FnSig, GenericArg, GenericArgKind,
     GenericArgsRef, GenericParamDefKind, IntTy, ParamEnv, Region, RegionKind, TraitRef, Ty, TyCtxt, TypeSuperVisitable,
-    TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr, TypingMode,
+    TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, UintTy, Upcast, VariantDef, VariantDiscr,
 };
 use rustc_span::symbol::Ident;
 use rustc_span::{DUMMY_SP, Span, Symbol, sym};
@@ -274,11 +274,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
         .map(|arg| arg.into().unwrap_or_else(|| infcx.next_ty_var(DUMMY_SP).into()))
         .collect::<Vec<_>>();
 
-    let trait_ref = TraitRef::new(
-        tcx,
-        trait_id,
-        [GenericArg::from(ty)].into_iter().chain(args),
-    );
+    let trait_ref = TraitRef::new(tcx, trait_id, [GenericArg::from(ty)].into_iter().chain(args));
 
     debug_assert_matches!(
         tcx.def_kind(trait_id),
@@ -975,9 +971,7 @@ pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {
     match (cx.layout_of(ty).map(|layout| layout.size.bytes()), ty.kind()) {
         (Ok(size), _) => size,
         (Err(_), ty::Tuple(list)) => list.iter().map(|t| approx_ty_size(cx, t)).sum(),
-        (Err(_), ty::Array(t, n)) => {
-            n.try_to_target_usize(cx.tcx).unwrap_or_default() * approx_ty_size(cx, *t)
-        },
+        (Err(_), ty::Array(t, n)) => n.try_to_target_usize(cx.tcx).unwrap_or_default() * approx_ty_size(cx, *t),
         (Err(_), ty::Adt(def, subst)) if def.is_struct() => def
             .variants()
             .iter()
@@ -1284,7 +1278,12 @@ pub fn make_normalized_projection_with_regions<'tcx>(
 
 pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
     let cause = ObligationCause::dummy();
-    match tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)).at(&cause, param_env).query_normalize(ty) {
+    match tcx
+        .infer_ctxt()
+        .build(TypingMode::from_param_env(param_env))
+        .at(&cause, param_env)
+        .query_normalize(ty)
+    {
         Ok(ty) => ty.value,
         Err(_) => ty,
     }
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index 3021f21df12..d7640ebfb00 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -302,9 +302,9 @@ fn type_is_inferable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> bo
     // Check that all type parameters appear in the functions input types.
     (0..(generics.parent_count + generics.own_params.len()) as u32).all(|index| {
         fn_sig
-                .inputs()
-                .iter()
-                .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
+            .inputs()
+            .iter()
+            .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
     })
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index 4bfc9dd9213..c8c25456f69 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -109,34 +109,28 @@ impl<'tcx> Visitor<'tcx> for ParamBindingIdCollector {
 pub struct BindingUsageFinder<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     binding_ids: Vec<HirId>,
-    usage_found: bool,
 }
 impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
     pub fn are_params_used(cx: &'a LateContext<'tcx>, body: &'tcx hir::Body<'tcx>) -> bool {
         let mut finder = BindingUsageFinder {
             cx,
             binding_ids: ParamBindingIdCollector::collect_binding_hir_ids(body),
-            usage_found: false,
         };
-        finder.visit_body(body);
-        finder.usage_found
+        finder.visit_body(body).is_break()
     }
 }
 impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> {
+    type Result = ControlFlow<()>;
     type NestedFilter = nested_filter::OnlyBodies;
 
-    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
-        if !self.usage_found {
-            intravisit::walk_expr(self, expr);
-        }
-    }
-
-    fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) {
+    fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) -> Self::Result {
         if let Res::Local(id) = path.res {
             if self.binding_ids.contains(&id) {
-                self.usage_found = true;
+                return ControlFlow::Break(());
             }
         }
+
+        ControlFlow::Continue(())
     }
 
     fn nested_visit_map(&mut self) -> Self::Map {
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 8db6502dbfb..8f5ec185bf1 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -324,17 +324,15 @@ pub fn is_local_used<'tcx>(cx: &LateContext<'tcx>, visitable: impl Visitable<'tc
 pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
     struct V<'a, 'tcx> {
         cx: &'a LateContext<'tcx>,
-        is_const: bool,
     }
+
     impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
+        type Result = ControlFlow<()>;
         type NestedFilter = intravisit::nested_filter::None;
 
-        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
-            if !self.is_const {
-                return;
-            }
+        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {
             match e.kind {
-                ExprKind::ConstBlock(_) => return,
+                ExprKind::ConstBlock(_) => return ControlFlow::Continue(()),
                 ExprKind::Call(
                     &Expr {
                         kind: ExprKind::Path(ref p),
@@ -394,37 +392,34 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
                 | ExprKind::Type(..) => (),
 
                 _ => {
-                    self.is_const = false;
-                    return;
+                    return ControlFlow::Break(());
                 },
             }
-            walk_expr(self, e);
+
+            walk_expr(self, e)
         }
     }
 
-    let mut v = V { cx, is_const: true };
-    v.visit_expr(e);
-    v.is_const
+    let mut v = V { cx };
+    v.visit_expr(e).is_continue()
 }
 
 /// Checks if the given expression performs an unsafe operation outside of an unsafe block.
 pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
     struct V<'a, 'tcx> {
         cx: &'a LateContext<'tcx>,
-        is_unsafe: bool,
     }
     impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
         type NestedFilter = nested_filter::OnlyBodies;
+        type Result = ControlFlow<()>;
+
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
         }
-        fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
-            if self.is_unsafe {
-                return;
-            }
+        fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> Self::Result {
             match e.kind {
                 ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_unsafe_ptr() => {
-                    self.is_unsafe = true;
+                    ControlFlow::Break(())
                 },
                 ExprKind::MethodCall(..)
                     if self
@@ -435,13 +430,13 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
                             self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe
                         }) =>
                 {
-                    self.is_unsafe = true;
+                    ControlFlow::Break(())
                 },
                 ExprKind::Call(func, _) => match *self.cx.typeck_results().expr_ty(func).peel_refs().kind() {
                     ty::FnDef(id, _) if self.cx.tcx.fn_sig(id).skip_binder().safety() == Safety::Unsafe => {
-                        self.is_unsafe = true;
+                        ControlFlow::Break(())
                     },
-                    ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => self.is_unsafe = true,
+                    ty::FnPtr(_, hdr) if hdr.safety == Safety::Unsafe => ControlFlow::Break(()),
                     _ => walk_expr(self, e),
                 },
                 ExprKind::Path(ref p)
@@ -451,56 +446,54 @@ pub fn is_expr_unsafe<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> bool {
                         .opt_def_id()
                         .map_or(false, |id| self.cx.tcx.is_mutable_static(id)) =>
                 {
-                    self.is_unsafe = true;
+                    ControlFlow::Break(())
                 },
                 _ => walk_expr(self, e),
             }
         }
-        fn visit_block(&mut self, b: &'tcx Block<'_>) {
-            if !matches!(b.rules, BlockCheckMode::UnsafeBlock(_)) {
-                walk_block(self, b);
+        fn visit_block(&mut self, b: &'tcx Block<'_>) -> Self::Result {
+            if matches!(b.rules, BlockCheckMode::UnsafeBlock(_)) {
+                ControlFlow::Continue(())
+            } else {
+                walk_block(self, b)
             }
         }
-        fn visit_nested_item(&mut self, id: ItemId) {
-            if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind {
-                self.is_unsafe = i.safety == Safety::Unsafe;
+        fn visit_nested_item(&mut self, id: ItemId) -> Self::Result {
+            if let ItemKind::Impl(i) = &self.cx.tcx.hir().item(id).kind
+                && i.safety == Safety::Unsafe
+            {
+                ControlFlow::Break(())
+            } else {
+                ControlFlow::Continue(())
             }
         }
     }
-    let mut v = V { cx, is_unsafe: false };
-    v.visit_expr(e);
-    v.is_unsafe
+    let mut v = V { cx };
+    v.visit_expr(e).is_break()
 }
 
 /// Checks if the given expression contains an unsafe block
 pub fn contains_unsafe_block<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
     struct V<'cx, 'tcx> {
         cx: &'cx LateContext<'tcx>,
-        found_unsafe: bool,
     }
     impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
+        type Result = ControlFlow<()>;
         type NestedFilter = nested_filter::OnlyBodies;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
         }
 
-        fn visit_block(&mut self, b: &'tcx Block<'_>) {
-            if self.found_unsafe {
-                return;
-            }
+        fn visit_block(&mut self, b: &'tcx Block<'_>) -> Self::Result {
             if b.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) {
-                self.found_unsafe = true;
-                return;
+                ControlFlow::Break(())
+            } else {
+                walk_block(self, b)
             }
-            walk_block(self, b);
         }
     }
-    let mut v = V {
-        cx,
-        found_unsafe: false,
-    };
-    v.visit_expr(e);
-    v.found_unsafe
+    let mut v = V { cx };
+    v.visit_expr(e).is_break()
 }
 
 /// Runs the given function for each sub-expression producing the final value consumed by the parent
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index e11ab40b9de..37d9cce2465 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2024-10-18"
+channel = "nightly-2024-11-07"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 5774e20e0be..b8e0413e97b 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -396,7 +396,8 @@ struct Renderer<'a> {
 
 impl Renderer<'_> {
     fn markdown(input: &str) -> Safe<String> {
-        let parser = Parser::new_ext(input, Options::all());
+        let input = clippy_config::sanitize_explanation(input);
+        let parser = Parser::new_ext(&input, Options::all());
         let mut html_output = String::new();
         html::push_html(&mut html_output, parser);
         // Oh deer, what a hack :O
diff --git a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
index 1fd03cfe36d..d59e9cbbb61 100644
--- a/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
+++ b/src/tools/clippy/tests/ui-internal/lint_without_lint_pass.rs
@@ -7,7 +7,7 @@ extern crate rustc_middle;
 #[macro_use]
 extern crate rustc_session;
 extern crate rustc_lint;
-use rustc_lint::LintPass;
+use rustc_lint::{LintPass, LintVec};
 
 declare_tool_lint! {
     pub clippy::TEST_LINT,
@@ -35,6 +35,9 @@ impl LintPass for Pass {
     fn name(&self) -> &'static str {
         "TEST_LINT"
     }
+    fn get_lints(&self) -> LintVec {
+        vec![TEST_LINT]
+    }
 }
 
 declare_lint_pass!(Pass2 => [TEST_LINT_REGISTERED]);
diff --git a/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.fixed b/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.fixed
new file mode 100644
index 00000000000..2cbd646a0fd
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.fixed
@@ -0,0 +1,24 @@
+#![feature(rustc_private)]
+#![warn(clippy::slow_symbol_comparisons)]
+
+extern crate rustc_span;
+
+use clippy_utils::sym;
+use rustc_span::Symbol;
+
+fn main() {
+    let symbol = sym!(example);
+    let other_symbol = sym!(other_example);
+
+    // Should lint
+    let slow_comparison = symbol.as_str() == "example";
+    //~^ error: comparing `Symbol` via `Symbol::intern`
+    let slow_comparison_macro = symbol.as_str() == "example";
+    //~^ error: comparing `Symbol` via `Symbol::intern`
+    let slow_comparison_backwards = symbol.as_str() == "example";
+    //~^ error: comparing `Symbol` via `Symbol::intern`
+
+    // Should not lint
+    let faster_comparison = symbol.as_str() == "other_example";
+    let preinterned_comparison = symbol == other_symbol;
+}
diff --git a/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.rs b/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.rs
new file mode 100644
index 00000000000..0cea3c3fcff
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.rs
@@ -0,0 +1,24 @@
+#![feature(rustc_private)]
+#![warn(clippy::slow_symbol_comparisons)]
+
+extern crate rustc_span;
+
+use clippy_utils::sym;
+use rustc_span::Symbol;
+
+fn main() {
+    let symbol = sym!(example);
+    let other_symbol = sym!(other_example);
+
+    // Should lint
+    let slow_comparison = symbol == Symbol::intern("example");
+    //~^ error: comparing `Symbol` via `Symbol::intern`
+    let slow_comparison_macro = symbol == sym!(example);
+    //~^ error: comparing `Symbol` via `Symbol::intern`
+    let slow_comparison_backwards = sym!(example) == symbol;
+    //~^ error: comparing `Symbol` via `Symbol::intern`
+
+    // Should not lint
+    let faster_comparison = symbol.as_str() == "other_example";
+    let preinterned_comparison = symbol == other_symbol;
+}
diff --git a/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.stderr b/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.stderr
new file mode 100644
index 00000000000..72cb20a7fed
--- /dev/null
+++ b/src/tools/clippy/tests/ui-internal/slow_symbol_comparisons.stderr
@@ -0,0 +1,23 @@
+error: comparing `Symbol` via `Symbol::intern`
+  --> tests/ui-internal/slow_symbol_comparisons.rs:14:27
+   |
+LL |     let slow_comparison = symbol == Symbol::intern("example");
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"`
+   |
+   = note: `-D clippy::slow-symbol-comparisons` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::slow_symbol_comparisons)]`
+
+error: comparing `Symbol` via `Symbol::intern`
+  --> tests/ui-internal/slow_symbol_comparisons.rs:16:33
+   |
+LL |     let slow_comparison_macro = symbol == sym!(example);
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"`
+
+error: comparing `Symbol` via `Symbol::intern`
+  --> tests/ui-internal/slow_symbol_comparisons.rs:18:37
+   |
+LL |     let slow_comparison_backwards = sym!(example) == symbol;
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^ help: use `Symbol::as_str` and check the string instead: `symbol.as_str() == "example"`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
index eb79fdbc4b4..8e7f020c1f6 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.fixed
@@ -1,6 +1,7 @@
 #![feature(rustc_private)]
 #![deny(clippy::internal)]
 #![allow(
+    clippy::slow_symbol_comparisons,
     clippy::borrow_deref_ref,
     clippy::unnecessary_operation,
     unused_must_use,
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
index bbea13af92a..9aeeb9aaf3a 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.rs
@@ -1,6 +1,7 @@
 #![feature(rustc_private)]
 #![deny(clippy::internal)]
 #![allow(
+    clippy::slow_symbol_comparisons,
     clippy::borrow_deref_ref,
     clippy::unnecessary_operation,
     unused_must_use,
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
index 551167a9ff5..668c11722f9 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_symbol_str.stderr
@@ -1,5 +1,5 @@
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:15:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:16:5
    |
 LL |     Symbol::intern("foo").as_str() == "clippy";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::sym::clippy`
@@ -12,25 +12,25 @@ LL | #![deny(clippy::internal)]
    = note: `#[deny(clippy::unnecessary_symbol_str)]` implied by `#[deny(clippy::internal)]`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:16:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:17:5
    |
 LL |     Symbol::intern("foo").to_string() == "self";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:17:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:18:5
    |
 LL |     Symbol::intern("foo").to_ident_string() != "Self";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:18:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:19:5
    |
 LL |     &*Ident::empty().as_str() == "clippy";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Ident::empty().name == rustc_span::sym::clippy`
 
 error: unnecessary `Symbol` to string conversion
-  --> tests/ui-internal/unnecessary_symbol_str.rs:19:5
+  --> tests/ui-internal/unnecessary_symbol_str.rs:20:5
    |
 LL |     "clippy" == Ident::empty().to_string();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::sym::clippy == Ident::empty().name`
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1/clippy.toml
new file mode 100644
index 00000000000..fbdb0c9c37d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1/clippy.toml
@@ -0,0 +1 @@
+trait-assoc-item-kinds-order = ["fn", "type", "const", "type"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2/clippy.toml
new file mode 100644
index 00000000000..720655e5cce
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2/clippy.toml
@@ -0,0 +1 @@
+trait-assoc-item-kinds-order = ["const", "type"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3/clippy.toml
new file mode 100644
index 00000000000..0dd5407be10
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3/clippy.toml
@@ -0,0 +1 @@
+source-item-ordering = ["enum", "impl", "module", "struct", "trait", "struct"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default/clippy.toml
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default/clippy.toml
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
new file mode 100644
index 00000000000..ddca5cfa577
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/default_exp/clippy.toml
@@ -0,0 +1,12 @@
+trait-assoc-item-kinds-order = ["const", "type", "fn"]
+source-item-ordering = ["enum", "impl", "module", "struct", "trait"]
+module-item-order-groupings = [
+    ["modules", ["extern_crate", "mod", "foreign_mod"]],
+    ["use", ["use"]],
+    ["macros", ["macro"]],
+    ["global_asm", ["global_asm"]],
+    ["UPPER_SNAKE_CASE", ["static", "const"]],
+    ["PascalCase", ["ty_alias", "enum", "struct", "union", "trait", "trait_alias", "impl"]],
+    ["lower_snake_case", ["fn"]]
+]
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_enum/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_enum/clippy.toml
new file mode 100644
index 00000000000..2144bdc9a0c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_enum/clippy.toml
@@ -0,0 +1 @@
+source-item-ordering = ["enum"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_impl/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_impl/clippy.toml
new file mode 100644
index 00000000000..54b6727fabf
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_impl/clippy.toml
@@ -0,0 +1 @@
+source-item-ordering = ["impl"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_trait/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_trait/clippy.toml
new file mode 100644
index 00000000000..b551611c35e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/only_trait/clippy.toml
@@ -0,0 +1 @@
+source-item-ordering = ["trait"]
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_1.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_1.stderr
new file mode 100644
index 00000000000..e441c7c1241
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_1.stderr
@@ -0,0 +1,8 @@
+error: error reading Clippy's configuration file: Some trait associated item kinds were configured more than once, or were missing, in the source ordering configuration. The trait associated item kinds are: [Const, Fn, Type]
+  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1/clippy.toml:1:32
+   |
+LL | trait-assoc-item-kinds-order = ["fn", "type", "const", "type"]
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_2.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_2.stderr
new file mode 100644
index 00000000000..183f0b03319
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_2.stderr
@@ -0,0 +1,8 @@
+error: error reading Clippy's configuration file: Some trait associated item kinds were configured more than once, or were missing, in the source ordering configuration. The trait associated item kinds are: [Const, Fn, Type]
+  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2/clippy.toml:1:32
+   |
+LL | trait-assoc-item-kinds-order = ["const", "type"]
+   |                                ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_3.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_3.stderr
new file mode 100644
index 00000000000..abf58dbd110
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.bad_conf_3.stderr
@@ -0,0 +1,8 @@
+error: error reading Clippy's configuration file: The category "Struct" was enabled more than once in the source ordering configuration.
+  --> $DIR/tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3/clippy.toml:1:24
+   |
+LL | source-item-ordering = ["enum", "impl", "module", "struct", "trait", "struct"]
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
new file mode 100644
index 00000000000..e9bcc30c15e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good.rs
@@ -0,0 +1,186 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: default default_exp bad_conf_1 bad_conf_2 bad_conf_3
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
+//@[default_exp] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default_exp
+//@[bad_conf_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_1
+//@[bad_conf_2] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_2
+//@[bad_conf_3] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/bad_conf_3
+
+#![allow(dead_code)]
+#![warn(clippy::arbitrary_source_item_ordering)]
+
+/// This module gets linted before clippy gives up.
+mod i_am_just_right {
+    const AFTER: i8 = 0;
+
+    const BEFORE: i8 = 0;
+}
+
+/// Since the upper module passes linting, the lint now recurses into this module.
+mod this_is_in_the_wrong_position {
+    const A: i8 = 1;
+    const C: i8 = 0;
+}
+
+// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.
+use std::rc::{Rc, Weak};
+use std::sync::{Arc, Barrier, RwLock};
+
+const SNAKE_CASE: &str = "zzzzzzzz";
+
+const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+
+const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+
+trait BasicEmptyTrait {}
+
+trait CloneSelf {
+    fn clone_self(&self) -> Self;
+}
+
+enum EnumOrdered {
+    A,
+    B,
+    C,
+}
+
+enum EnumUnordered {
+    A,
+    B,
+    C,
+}
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+enum EnumUnorderedAllowed {
+    A,
+    B,
+    C,
+}
+
+struct StructOrdered {
+    a: bool,
+    b: bool,
+    c: bool,
+}
+
+impl BasicEmptyTrait for StructOrdered {}
+
+impl CloneSelf for StructOrdered {
+    fn clone_self(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl Default for StructOrdered {
+    fn default() -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl std::clone::Clone for StructOrdered {
+    fn clone(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+#[derive(Clone, Default)]
+struct StructUnordered {
+    a: bool,
+    b: bool,
+    c: bool,
+    d: bool,
+}
+
+impl TraitUnordered for StructUnordered {
+    const A: bool = false;
+    const B: bool = false;
+    const C: bool = false;
+
+    type SomeType = ();
+
+    fn a() {}
+    fn b() {}
+    fn c() {}
+}
+
+impl TraitUnorderedItemKinds for StructUnordered {
+    const A: bool = false;
+    const B: bool = false;
+    const C: bool = false;
+
+    type SomeType = ();
+
+    fn a() {}
+    fn b() {}
+    fn c() {}
+}
+
+struct StructUnorderedGeneric<T> {
+    _1: std::marker::PhantomData<T>,
+    a: bool,
+    b: bool,
+    c: bool,
+    d: bool,
+}
+
+trait TraitOrdered {
+    const A: bool;
+    const B: bool;
+    const C: bool;
+
+    type SomeType;
+
+    fn a();
+    fn b();
+    fn c();
+}
+
+trait TraitUnordered {
+    const A: bool;
+    const B: bool;
+    const C: bool;
+
+    type SomeType;
+
+    fn a();
+    fn b();
+    fn c();
+}
+
+trait TraitUnorderedItemKinds {
+    const A: bool;
+    const B: bool;
+    const C: bool;
+
+    type SomeType;
+
+    fn a();
+    fn b();
+    fn c();
+}
+
+#[derive(std::clone::Clone, Default)]
+struct ZisShouldBeBeforeZeMainFn;
+
+fn main() {
+    // test code goes here
+}
+
+#[cfg(test)]
+mod test {
+    const B: i8 = 1;
+
+    const A: i8 = 0;
+}
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs
new file mode 100644
index 00000000000..0fccbd4790b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_good_var_1.rs
@@ -0,0 +1,174 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: var_1
+//@[var_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/var_1
+
+#![allow(dead_code)]
+#![warn(clippy::arbitrary_source_item_ordering)]
+
+/// This module gets linted before clippy gives up.
+mod i_am_just_right {
+    const AFTER: i8 = 0;
+
+    const BEFORE: i8 = 0;
+}
+
+/// Since the upper module passes linting, the lint now recurses into this module.
+mod this_is_in_the_wrong_position {
+    const A: i8 = 1;
+    const C: i8 = 0;
+}
+
+// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.
+use std::rc::{Rc, Weak};
+use std::sync::{Arc, Barrier, RwLock};
+
+const SNAKE_CASE: &str = "zzzzzzzz";
+
+const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+
+const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+
+trait BasicEmptyTrait {}
+
+trait CloneSelf {
+    fn clone_self(&self) -> Self;
+}
+
+enum EnumOrdered {
+    A,
+    B,
+    C,
+}
+
+enum EnumUnordered {
+    A,
+    B,
+    C,
+}
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+enum EnumUnorderedAllowed {
+    A,
+    B,
+    C,
+}
+
+struct StructOrdered {
+    a: bool,
+    b: bool,
+    c: bool,
+}
+
+impl BasicEmptyTrait for StructOrdered {}
+
+impl CloneSelf for StructOrdered {
+    fn clone_self(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl Default for StructOrdered {
+    fn default() -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl std::clone::Clone for StructOrdered {
+    fn clone(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+#[derive(Clone, Default)]
+struct StructUnordered {
+    a: bool,
+    b: bool,
+    c: bool,
+    d: bool,
+}
+
+impl TraitUnordered for StructUnordered {
+    fn a() {}
+    fn b() {}
+    fn c() {}
+
+    type SomeType = ();
+
+    const A: bool = false;
+    const B: bool = false;
+    const C: bool = false;
+}
+
+impl TraitUnorderedItemKinds for StructUnordered {
+    fn a() {}
+
+    type SomeType = ();
+
+    const A: bool = false;
+}
+
+struct StructUnorderedGeneric<T> {
+    _1: std::marker::PhantomData<T>,
+    a: bool,
+    b: bool,
+    c: bool,
+    d: bool,
+}
+
+trait TraitOrdered {
+    fn a();
+    fn b();
+    fn c();
+
+    type SomeType;
+
+    const A: bool;
+    const B: bool;
+    const C: bool;
+}
+
+trait TraitUnordered {
+    fn a();
+    fn b();
+    fn c();
+
+    type SomeType;
+
+    const A: bool;
+    const B: bool;
+    const C: bool;
+}
+
+trait TraitUnorderedItemKinds {
+    fn a();
+
+    type SomeType;
+
+    const A: bool;
+}
+
+#[derive(std::clone::Clone, Default)]
+struct ZisShouldBeBeforeZeMainFn;
+
+fn main() {
+    // test code goes here
+}
+
+#[cfg(test)]
+mod test {
+    const B: i8 = 1;
+
+    const A: i8 = 0;
+}
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
new file mode 100644
index 00000000000..062bf25ea62
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
@@ -0,0 +1,226 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:21:14
+   |
+LL | use std::rc::Weak;
+   |              ^^^^
+   |
+note: should be placed before `SNAKE_CASE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:19:7
+   |
+LL | const SNAKE_CASE: &str = "zzzzzzzz";
+   |       ^^^^^^^^^^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:64:1
+   |
+LL | / impl CloneSelf for StructOrdered {
+LL | |     fn clone_self(&self) -> Self {
+LL | |         Self {
+LL | |             a: true,
+...  |
+LL | |     }
+LL | | }
+   | |_^
+   |
+note: should be placed before the following item
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:54:1
+   |
+LL | / impl Default for StructOrdered {
+LL | |     fn default() -> Self {
+LL | |         Self {
+LL | |             a: true,
+...  |
+LL | |     }
+LL | | }
+   | |_^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:136:7
+   |
+LL | const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `TraitUnorderedItemKinds`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:124:7
+   |
+LL | trait TraitUnorderedItemKinds {
+   |       ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:151:1
+   |
+LL | impl BasicEmptyTrait for StructOrdered {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before the following item
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:138:1
+   |
+LL | / impl TraitUnordered for StructUnordered {
+LL | |     const A: bool = false;
+LL | |     const C: bool = false;
+LL | |     const B: bool = false;
+...  |
+LL | |     fn b() {}
+LL | | }
+   | |_^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:170:5
+   |
+LL | mod this_is_in_the_wrong_position {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `main`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:165:4
+   |
+LL | fn main() {
+   |    ^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:178:7
+   |
+LL | const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `ZisShouldBeBeforeZeMainFn`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:176:8
+   |
+LL | struct ZisShouldBeBeforeZeMainFn;
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:12:11
+   |
+LL |     const AFTER: i8 = 0;
+   |           ^^^^^
+   |
+note: should be placed before `BEFORE`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:10:11
+   |
+LL |     const BEFORE: i8 = 0;
+   |           ^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:38:5
+   |
+LL |     B,
+   |     ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:37:5
+   |
+LL |     C,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:88:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:87:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:96:5
+   |
+LL |     b: bool,
+   |     ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:95:5
+   |
+LL |     c: bool,
+   |     ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:115:11
+   |
+LL |     const B: bool;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:114:11
+   |
+LL |     const C: bool;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:121:8
+   |
+LL |     fn b();
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:120:8
+   |
+LL |     fn c();
+   |        ^
+
+error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:127:5
+   |
+LL |     const A: bool;
+   |     ^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:125:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:141:11
+   |
+LL |     const B: bool = false;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:140:11
+   |
+LL |     const C: bool = false;
+   |           ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:147:8
+   |
+LL |     fn b() {}
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:146:8
+   |
+LL |     fn c() {}
+   |        ^
+
+error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:156:5
+   |
+LL |     const A: bool = false;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:154:5
+   |
+LL |     type SomeType = ();
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:172:11
+   |
+LL |     const A: i8 = 1;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11
+   |
+LL |     const C: i8 = 0;
+   |           ^
+
+error: aborting due to 17 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
new file mode 100644
index 00000000000..2765bf935b7
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs
@@ -0,0 +1,185 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: default
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/default
+
+#![allow(dead_code)]
+#![warn(clippy::arbitrary_source_item_ordering)]
+
+/// This module gets linted before clippy gives up.
+mod i_am_just_right {
+    const BEFORE: i8 = 0;
+
+    const AFTER: i8 = 0;
+}
+
+// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.
+use std::rc::Rc;
+use std::sync::{Arc, Barrier, RwLock};
+
+const SNAKE_CASE: &str = "zzzzzzzz";
+
+use std::rc::Weak;
+
+trait BasicEmptyTrait {}
+
+trait CloneSelf {
+    fn clone_self(&self) -> Self;
+}
+
+enum EnumOrdered {
+    A,
+    B,
+    C,
+}
+
+enum EnumUnordered {
+    A,
+    C,
+    B,
+}
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+enum EnumUnorderedAllowed {
+    A,
+    C,
+    B,
+}
+
+struct StructOrdered {
+    a: bool,
+    b: bool,
+    c: bool,
+}
+
+impl Default for StructOrdered {
+    fn default() -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl CloneSelf for StructOrdered {
+    fn clone_self(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl std::clone::Clone for StructOrdered {
+    fn clone(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+#[derive(Default, Clone)]
+struct StructUnordered {
+    a: bool,
+    c: bool,
+    b: bool,
+    d: bool,
+}
+
+struct StructUnorderedGeneric<T> {
+    _1: std::marker::PhantomData<T>,
+    a: bool,
+    c: bool,
+    b: bool,
+    d: bool,
+}
+
+trait TraitOrdered {
+    const A: bool;
+    const B: bool;
+    const C: bool;
+
+    type SomeType;
+
+    fn a();
+    fn b();
+    fn c();
+}
+
+trait TraitUnordered {
+    const A: bool;
+    const C: bool;
+    const B: bool;
+
+    type SomeType;
+
+    fn a();
+    fn c();
+    fn b();
+}
+
+trait TraitUnorderedItemKinds {
+    type SomeType;
+
+    const A: bool;
+    const B: bool;
+    const C: bool;
+
+    fn a();
+    fn b();
+    fn c();
+}
+
+const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+
+impl TraitUnordered for StructUnordered {
+    const A: bool = false;
+    const C: bool = false;
+    const B: bool = false;
+
+    type SomeType = ();
+
+    fn a() {}
+    fn c() {}
+    fn b() {}
+}
+
+// Trait impls should be located just after the type they implement it for.
+impl BasicEmptyTrait for StructOrdered {}
+
+impl TraitUnorderedItemKinds for StructUnordered {
+    type SomeType = ();
+
+    const A: bool = false;
+    const B: bool = false;
+    const C: bool = false;
+
+    fn a() {}
+    fn b() {}
+    fn c() {}
+}
+
+fn main() {
+    // test code goes here
+}
+
+/// Note that the linting pass is stopped before recursing into this module.
+mod this_is_in_the_wrong_position {
+    const C: i8 = 0;
+    const A: i8 = 1;
+}
+
+#[derive(Default, std::clone::Clone)]
+struct ZisShouldBeBeforeZeMainFn;
+
+const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+
+#[cfg(test)]
+mod test {
+    const B: i8 = 1;
+
+    const A: i8 = 0;
+}
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs
new file mode 100644
index 00000000000..44902336573
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs
@@ -0,0 +1,174 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: var_1
+//@[var_1] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/var_1
+
+#![allow(dead_code)]
+#![warn(clippy::arbitrary_source_item_ordering)]
+
+/// This module gets linted before clippy gives up.
+mod i_am_just_right {
+    const AFTER: i8 = 0;
+
+    const BEFORE: i8 = 0;
+}
+
+/// Since the upper module passes linting, the lint now recurses into this module.
+mod this_is_in_the_wrong_position {
+    const A: i8 = 1;
+    const C: i8 = 0;
+}
+
+// Use statements should not be linted internally - this is normally auto-sorted using rustfmt.
+use std::rc::{Rc, Weak};
+use std::sync::{Arc, Barrier, RwLock};
+
+const SNAKE_CASE: &str = "zzzzzzzz";
+
+const ZIS_SHOULD_BE_EVEN_EARLIER: () = ();
+
+const ZIS_SHOULD_BE_REALLY_EARLY: () = ();
+
+trait BasicEmptyTrait {}
+
+trait CloneSelf {
+    fn clone_self(&self) -> Self;
+}
+
+enum EnumOrdered {
+    A,
+    B,
+    C,
+}
+
+enum EnumUnordered {
+    A,
+    B,
+    C,
+}
+
+#[allow(clippy::arbitrary_source_item_ordering)]
+enum EnumUnorderedAllowed {
+    A,
+    B,
+    C,
+}
+
+struct StructOrdered {
+    a: bool,
+    b: bool,
+    c: bool,
+}
+
+impl BasicEmptyTrait for StructOrdered {}
+
+impl CloneSelf for StructOrdered {
+    fn clone_self(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl Default for StructOrdered {
+    fn default() -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+impl std::clone::Clone for StructOrdered {
+    fn clone(&self) -> Self {
+        Self {
+            a: true,
+            b: true,
+            c: true,
+        }
+    }
+}
+
+#[derive(Clone, Default)]
+struct StructUnordered {
+    a: bool,
+    b: bool,
+    c: bool,
+    d: bool,
+}
+
+impl TraitUnordered for StructUnordered {
+    fn a() {}
+    fn c() {}
+    fn b() {}
+
+    type SomeType = ();
+
+    const A: bool = false;
+    const C: bool = false;
+    const B: bool = false;
+}
+
+impl TraitUnorderedItemKinds for StructUnordered {
+    const A: bool = false;
+
+    type SomeType = ();
+
+    fn a() {}
+}
+
+struct StructUnorderedGeneric<T> {
+    _1: std::marker::PhantomData<T>,
+    a: bool,
+    b: bool,
+    c: bool,
+    d: bool,
+}
+
+trait TraitOrdered {
+    fn a();
+    fn b();
+    fn c();
+
+    type SomeType;
+
+    const A: bool;
+    const B: bool;
+    const C: bool;
+}
+
+trait TraitUnordered {
+    fn a();
+    fn c();
+    fn b();
+
+    type SomeType;
+
+    const A: bool;
+    const C: bool;
+    const B: bool;
+}
+
+trait TraitUnorderedItemKinds {
+    const A: bool;
+
+    type SomeType;
+
+    fn a();
+}
+
+#[derive(std::clone::Clone, Default)]
+struct ZisShouldBeBeforeZeMainFn;
+
+fn main() {
+    // test code goes here
+}
+
+#[cfg(test)]
+mod test {
+    const B: i8 = 1;
+
+    const A: i8 = 0;
+}
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr
new file mode 100644
index 00000000000..f31f7f68c17
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr
@@ -0,0 +1,100 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:105:8
+   |
+LL |     fn b() {}
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:104:8
+   |
+LL |     fn c() {}
+   |        ^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:111:11
+   |
+LL |     const B: bool = false;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:110:11
+   |
+LL |     const C: bool = false;
+   |           ^
+
+error: incorrect ordering of impl items (defined order: [Fn, Type, Const])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5
+   |
+LL |     type SomeType = ();
+   |     ^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `A`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:115:5
+   |
+LL |     const A: bool = false;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of impl items (defined order: [Fn, Type, Const])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5
+   |
+LL |     fn a() {}
+   |     ^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5
+   |
+LL |     type SomeType = ();
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:145:8
+   |
+LL |     fn b();
+   |        ^
+   |
+note: should be placed before `c`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:144:8
+   |
+LL |     fn c();
+   |        ^
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:151:11
+   |
+LL |     const B: bool;
+   |           ^
+   |
+note: should be placed before `C`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:150:11
+   |
+LL |     const C: bool;
+   |           ^
+
+error: incorrect ordering of trait items (defined order: [Fn, Type, Const])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:157:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+   |
+note: should be placed before `A`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:155:5
+   |
+LL |     const A: bool;
+   |     ^^^^^^^^^^^^^^
+
+error: incorrect ordering of trait items (defined order: [Fn, Type, Const])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:159:5
+   |
+LL |     fn a();
+   |     ^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:157:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.only_enum.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.only_enum.stderr
new file mode 100644
index 00000000000..57069fd8fee
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.only_enum.stderr
@@ -0,0 +1,16 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs:22:5
+   |
+LL |     A,
+   |     ^
+   |
+note: should be placed before `B`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs:21:5
+   |
+LL |     B,
+   |     ^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs
new file mode 100644
index 00000000000..e8002c4a163
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_enum.rs
@@ -0,0 +1,43 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: only_enum
+//@[only_enum] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/only_enum
+
+#![allow(dead_code)]
+#![warn(clippy::arbitrary_source_item_ordering)]
+
+fn main() {}
+
+struct StructUnordered {
+    b: bool,
+    a: bool,
+}
+
+enum EnumOrdered {
+    A,
+    B,
+}
+
+enum EnumUnordered {
+    B,
+    A,
+}
+
+trait TraitUnordered {
+    const B: bool;
+    const A: bool;
+
+    type SomeType;
+
+    fn b();
+    fn a();
+}
+
+trait TraitUnorderedItemKinds {
+    type SomeType;
+
+    const A: bool;
+
+    fn a();
+}
+
+const ZIS_SHOULD_BE_AT_THE_TOP: () = ();
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr
new file mode 100644
index 00000000000..40348ecbdae
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr
@@ -0,0 +1,40 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:43:8
+   |
+LL |     fn a() {}
+   |        ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:42:8
+   |
+LL |     fn b() {}
+   |        ^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:45:5
+   |
+LL |     type SomeType = i8;
+   |     ^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `a`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:43:5
+   |
+LL |     fn a() {}
+   |     ^^^^^^^^^
+
+error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:47:5
+   |
+LL |     const A: bool = true;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:45:5
+   |
+LL |     type SomeType = i8;
+   |     ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs
new file mode 100644
index 00000000000..bd969c865b5
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs
@@ -0,0 +1,67 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: only_impl
+//@[only_impl] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/only_impl
+
+#![allow(dead_code)]
+#![warn(clippy::arbitrary_source_item_ordering)]
+
+fn main() {}
+
+struct StructUnordered {
+    b: bool,
+    a: bool,
+}
+
+struct BasicStruct {}
+
+trait BasicTrait {
+    const A: bool;
+
+    type SomeType;
+
+    fn b();
+    fn a();
+}
+
+enum EnumUnordered {
+    B,
+    A,
+}
+
+trait TraitUnordered {
+    const B: bool;
+    const A: bool;
+
+    type SomeType;
+
+    fn b();
+    fn a();
+}
+
+impl BasicTrait for StructUnordered {
+    fn b() {}
+    fn a() {}
+
+    type SomeType = i8;
+
+    const A: bool = true;
+}
+
+trait TraitUnorderedItemKinds {
+    type SomeType;
+
+    const A: bool;
+
+    fn a();
+}
+
+const ZIS_SHOULD_BE_AT_THE_TOP: () = ();
+
+impl BasicTrait for BasicStruct {
+    const A: bool = true;
+
+    type SomeType = i8;
+
+    fn a() {}
+    fn b() {}
+}
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr
new file mode 100644
index 00000000000..9b86ebd48e3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr
@@ -0,0 +1,40 @@
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:32:11
+   |
+LL |     const A: bool;
+   |           ^
+   |
+note: should be placed before `B`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:31:11
+   |
+LL |     const B: bool;
+   |           ^
+   = note: `-D clippy::arbitrary-source-item-ordering` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::arbitrary_source_item_ordering)]`
+
+error: incorrect ordering of items (must be alphabetically ordered)
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:37:8
+   |
+LL |     fn a();
+   |        ^
+   |
+note: should be placed before `b`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:36:8
+   |
+LL |     fn b();
+   |        ^
+
+error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:43:5
+   |
+LL |     const A: bool;
+   |     ^^^^^^^^^^^^^^
+   |
+note: should be placed before `SomeType`
+  --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:41:5
+   |
+LL |     type SomeType;
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs
new file mode 100644
index 00000000000..979a52ecb10
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs
@@ -0,0 +1,48 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
+//@revisions: only_trait
+//@[only_trait] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/arbitrary_source_item_ordering/only_trait
+
+#![allow(dead_code)]
+#![warn(clippy::arbitrary_source_item_ordering)]
+
+fn main() {}
+
+struct StructUnordered {
+    b: bool,
+    a: bool,
+}
+
+trait TraitOrdered {
+    const A: bool;
+    const B: bool;
+
+    type SomeType;
+
+    fn a();
+    fn b();
+}
+
+enum EnumUnordered {
+    B,
+    A,
+}
+
+trait TraitUnordered {
+    const B: bool;
+    const A: bool;
+
+    type SomeType;
+
+    fn b();
+    fn a();
+}
+
+trait TraitUnorderedItemKinds {
+    type SomeType;
+
+    const A: bool;
+
+    fn a();
+}
+
+const ZIS_SHOULD_BE_AT_THE_TOP: () = ();
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/var_1/clippy.toml b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/var_1/clippy.toml
new file mode 100644
index 00000000000..bede035e388
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/var_1/clippy.toml
@@ -0,0 +1 @@
+trait-assoc-item-kinds-order = ["fn", "type", "const"]
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
index ddeb2f8cc70..2e3386628b4 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
+++ b/src/tools/clippy/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
@@ -1,11 +1,39 @@
+error: use of a disallowed macro `std::vec`
+  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:16:5
+   |
+LL |     vec![1, 2, 3];
+   |     ^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::disallowed-macros` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`
+
+error: use of a disallowed macro `serde::Serialize`
+  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:18:14
+   |
+LL |     #[derive(Serialize)]
+   |              ^^^^^^^^^
+   |
+   = note: no serializing
+
+error: use of a disallowed macro `macros::attr`
+  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:31:1
+   |
+LL | / macros::attr! {
+LL | |     struct S;
+LL | | }
+   | |_^
+
+error: use of a disallowed macro `proc_macros::Derive`
+  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:47:10
+   |
+LL | #[derive(Derive)]
+   |          ^^^^^^
+
 error: use of a disallowed macro `std::println`
   --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:13:5
    |
 LL |     println!("one");
    |     ^^^^^^^^^^^^^^^
-   |
-   = note: `-D clippy::disallowed-macros` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`
 
 error: use of a disallowed macro `std::println`
   --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:14:5
@@ -19,20 +47,6 @@ error: use of a disallowed macro `std::cfg`
 LL |     cfg!(unix);
    |     ^^^^^^^^^^
 
-error: use of a disallowed macro `std::vec`
-  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:16:5
-   |
-LL |     vec![1, 2, 3];
-   |     ^^^^^^^^^^^^^
-
-error: use of a disallowed macro `serde::Serialize`
-  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:18:14
-   |
-LL |     #[derive(Serialize)]
-   |              ^^^^^^^^^
-   |
-   = note: no serializing
-
 error: use of a disallowed macro `macros::expr`
   --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:21:13
    |
@@ -69,14 +83,6 @@ error: use of a disallowed macro `macros::binop`
 LL |     let _ = macros::binop!(1);
    |             ^^^^^^^^^^^^^^^^^
 
-error: use of a disallowed macro `macros::attr`
-  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:31:1
-   |
-LL | / macros::attr! {
-LL | |     struct S;
-LL | | }
-   | |_^
-
 error: use of a disallowed macro `macros::item`
   --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:36:5
    |
@@ -95,11 +101,5 @@ error: use of a disallowed macro `macros::item`
 LL |     macros::item!();
    |     ^^^^^^^^^^^^^^^
 
-error: use of a disallowed macro `proc_macros::Derive`
-  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:47:10
-   |
-LL | #[derive(Derive)]
-   |          ^^^^^^
-
 error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
index f3dbb6ad1cf..dc9349f75a0 100644
--- a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
@@ -1,8 +1,8 @@
 #![warn(clippy::large_include_file)]
 
 // Good
-const GOOD_INCLUDE_BYTES: &[u8; 581] = include_bytes!("large_include_file.rs");
-const GOOD_INCLUDE_STR: &str = include_str!("large_include_file.rs");
+const GOOD_INCLUDE_BYTES: &[u8; 68] = include_bytes!("../../ui/author.rs");
+const GOOD_INCLUDE_STR: &str = include_str!("../../ui/author.rs");
 
 #[allow(clippy::large_include_file)]
 const ALLOWED_TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
@@ -11,6 +11,9 @@ const ALLOWED_TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
 
 // Bad
 const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
+//~^ large_include_file
 const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
+//~^ large_include_file
 
+#[doc = include_str!("too_big.txt")] //~ large_include_file
 fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
index 34224065f07..9e1494a47bb 100644
--- a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
@@ -9,12 +9,20 @@ LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
    = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]`
 
 error: attempted to include a large file
-  --> tests/ui-toml/large_include_file/large_include_file.rs:14:35
+  --> tests/ui-toml/large_include_file/large_include_file.rs:15:35
    |
 LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the configuration allows a maximum size of 600 bytes
 
-error: aborting due to 2 previous errors
+error: attempted to include a large file
+  --> tests/ui-toml/large_include_file/large_include_file.rs:18:1
+   |
+LL | #[doc = include_str!("too_big.txt")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the configuration allows a maximum size of 600 bytes
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/private-doc-errors/doc_lints.rs b/src/tools/clippy/tests/ui-toml/private-doc-errors/doc_lints.rs
index 79c8751468d..c5d00c91b05 100644
--- a/src/tools/clippy/tests/ui-toml/private-doc-errors/doc_lints.rs
+++ b/src/tools/clippy/tests/ui-toml/private-doc-errors/doc_lints.rs
@@ -51,4 +51,10 @@ pub mod __macro {
     }
 }
 
+#[warn(clippy::missing_errors_doc)]
+#[test]
+fn test() -> Result<(), ()> {
+    Ok(())
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index 5cf9c0fb271..6fa583fc041 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -54,12 +54,14 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            max-trait-bounds
            min-ident-chars-threshold
            missing-docs-in-crate-items
+           module-item-order-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
            semicolon-inside-block-ignore-singleline
            semicolon-outside-block-ignore-multiline
            single-char-binding-names-threshold
+           source-item-ordering
            stack-size-threshold
            standard-macro-braces
            struct-field-name-threshold
@@ -68,6 +70,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            too-large-for-stack
            too-many-arguments-threshold
            too-many-lines-threshold
+           trait-assoc-item-kinds-order
            trivial-copy-size-limit
            type-complexity-threshold
            unnecessary-box-size
@@ -138,12 +141,14 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            max-trait-bounds
            min-ident-chars-threshold
            missing-docs-in-crate-items
+           module-item-order-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
            semicolon-inside-block-ignore-singleline
            semicolon-outside-block-ignore-multiline
            single-char-binding-names-threshold
+           source-item-ordering
            stack-size-threshold
            standard-macro-braces
            struct-field-name-threshold
@@ -152,6 +157,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            too-large-for-stack
            too-many-arguments-threshold
            too-many-lines-threshold
+           trait-assoc-item-kinds-order
            trivial-copy-size-limit
            type-complexity-threshold
            unnecessary-box-size
@@ -222,12 +228,14 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            max-trait-bounds
            min-ident-chars-threshold
            missing-docs-in-crate-items
+           module-item-order-groupings
            msrv
            pass-by-value-size-limit
            pub-underscore-fields-behavior
            semicolon-inside-block-ignore-singleline
            semicolon-outside-block-ignore-multiline
            single-char-binding-names-threshold
+           source-item-ordering
            stack-size-threshold
            standard-macro-braces
            struct-field-name-threshold
@@ -236,6 +244,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            too-large-for-stack
            too-many-arguments-threshold
            too-many-lines-threshold
+           trait-assoc-item-kinds-order
            trivial-copy-size-limit
            type-complexity-threshold
            unnecessary-box-size
diff --git a/src/tools/clippy/tests/ui/allow_attributes.fixed b/src/tools/clippy/tests/ui/allow_attributes.fixed
index 058dbb77a32..8f6c962e2f5 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.fixed
+++ b/src/tools/clippy/tests/ui/allow_attributes.fixed
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@aux-build:proc_macro_derive.rs
 #![allow(unused)]
 #![warn(clippy::allow_attributes)]
 #![no_main]
@@ -65,3 +66,9 @@ fn deny_allow_attributes() -> Option<u8> {
     allow?;
     Some(42)
 }
+
+// Edge case where the generated tokens spans match on #[repr(transparent)] which tricks the proc
+// macro check
+#[repr(transparent)]
+#[derive(proc_macro_derive::AllowLintSameSpan)] // This macro generates tokens with the same span as the whole struct and repr
+struct IgnoreDerived;
diff --git a/src/tools/clippy/tests/ui/allow_attributes.rs b/src/tools/clippy/tests/ui/allow_attributes.rs
index 6d94ce50e4c..cb6c4dcf715 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.rs
+++ b/src/tools/clippy/tests/ui/allow_attributes.rs
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@aux-build:proc_macro_derive.rs
 #![allow(unused)]
 #![warn(clippy::allow_attributes)]
 #![no_main]
@@ -65,3 +66,9 @@ fn deny_allow_attributes() -> Option<u8> {
     allow?;
     Some(42)
 }
+
+// Edge case where the generated tokens spans match on #[repr(transparent)] which tricks the proc
+// macro check
+#[repr(transparent)]
+#[derive(proc_macro_derive::AllowLintSameSpan)] // This macro generates tokens with the same span as the whole struct and repr
+struct IgnoreDerived;
diff --git a/src/tools/clippy/tests/ui/allow_attributes.stderr b/src/tools/clippy/tests/ui/allow_attributes.stderr
index 023b4d7e404..5a4ff287acd 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.stderr
+++ b/src/tools/clippy/tests/ui/allow_attributes.stderr
@@ -1,5 +1,5 @@
 error: #[allow] attribute found
-  --> tests/ui/allow_attributes.rs:12:3
+  --> tests/ui/allow_attributes.rs:13:3
    |
 LL | #[allow(dead_code)]
    |   ^^^^^ help: replace it with: `expect`
@@ -8,13 +8,13 @@ LL | #[allow(dead_code)]
    = help: to override `-D warnings` add `#[allow(clippy::allow_attributes)]`
 
 error: #[allow] attribute found
-  --> tests/ui/allow_attributes.rs:21:30
+  --> tests/ui/allow_attributes.rs:22:30
    |
 LL | #[cfg_attr(panic = "unwind", allow(dead_code))]
    |                              ^^^^^ help: replace it with: `expect`
 
 error: #[allow] attribute found
-  --> tests/ui/allow_attributes.rs:52:7
+  --> tests/ui/allow_attributes.rs:53:7
    |
 LL |     #[allow(unused)]
    |       ^^^^^ help: replace it with: `expect`
diff --git a/src/tools/clippy/tests/ui-internal/author.rs b/src/tools/clippy/tests/ui/author.rs
index eb1f3e3f870..0a1be356896 100644
--- a/src/tools/clippy/tests/ui-internal/author.rs
+++ b/src/tools/clippy/tests/ui/author.rs
@@ -1,5 +1,3 @@
-#![warn(clippy::author)]
-
 fn main() {
     #[clippy::author]
     let x: char = 0x45 as char;
diff --git a/src/tools/clippy/tests/ui-internal/author.stdout b/src/tools/clippy/tests/ui/author.stdout
index eed704e82fe..eed704e82fe 100644
--- a/src/tools/clippy/tests/ui-internal/author.stdout
+++ b/src/tools/clippy/tests/ui/author.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/blocks.rs b/src/tools/clippy/tests/ui/author/blocks.rs
index 164f7d0d9d6..164f7d0d9d6 100644
--- a/src/tools/clippy/tests/ui-internal/author/blocks.rs
+++ b/src/tools/clippy/tests/ui/author/blocks.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/blocks.stdout b/src/tools/clippy/tests/ui/author/blocks.stdout
index 6bf48d5ba4e..6bf48d5ba4e 100644
--- a/src/tools/clippy/tests/ui-internal/author/blocks.stdout
+++ b/src/tools/clippy/tests/ui/author/blocks.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/call.rs b/src/tools/clippy/tests/ui/author/call.rs
index e99c3c41dc4..e99c3c41dc4 100644
--- a/src/tools/clippy/tests/ui-internal/author/call.rs
+++ b/src/tools/clippy/tests/ui/author/call.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/call.stdout b/src/tools/clippy/tests/ui/author/call.stdout
index 59d4da490fe..59d4da490fe 100644
--- a/src/tools/clippy/tests/ui-internal/author/call.stdout
+++ b/src/tools/clippy/tests/ui/author/call.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/if.rs b/src/tools/clippy/tests/ui/author/if.rs
index 946088ab346..946088ab346 100644
--- a/src/tools/clippy/tests/ui-internal/author/if.rs
+++ b/src/tools/clippy/tests/ui/author/if.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/if.stdout b/src/tools/clippy/tests/ui/author/if.stdout
index a85dcddd331..a85dcddd331 100644
--- a/src/tools/clippy/tests/ui-internal/author/if.stdout
+++ b/src/tools/clippy/tests/ui/author/if.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/issue_3849.rs b/src/tools/clippy/tests/ui/author/issue_3849.rs
index 5f65746d71f..5f65746d71f 100644
--- a/src/tools/clippy/tests/ui-internal/author/issue_3849.rs
+++ b/src/tools/clippy/tests/ui/author/issue_3849.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/issue_3849.stdout b/src/tools/clippy/tests/ui/author/issue_3849.stdout
index a5a8c0304ee..a5a8c0304ee 100644
--- a/src/tools/clippy/tests/ui-internal/author/issue_3849.stdout
+++ b/src/tools/clippy/tests/ui/author/issue_3849.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/loop.rs b/src/tools/clippy/tests/ui/author/loop.rs
index ff5b6100117..ff5b6100117 100644
--- a/src/tools/clippy/tests/ui-internal/author/loop.rs
+++ b/src/tools/clippy/tests/ui/author/loop.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/loop.stdout b/src/tools/clippy/tests/ui/author/loop.stdout
index 609d2491061..609d2491061 100644
--- a/src/tools/clippy/tests/ui-internal/author/loop.stdout
+++ b/src/tools/clippy/tests/ui/author/loop.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/macro_in_closure.rs b/src/tools/clippy/tests/ui/author/macro_in_closure.rs
index 444e6a12165..444e6a12165 100644
--- a/src/tools/clippy/tests/ui-internal/author/macro_in_closure.rs
+++ b/src/tools/clippy/tests/ui/author/macro_in_closure.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/macro_in_closure.stdout b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout
index 66caf382d89..66caf382d89 100644
--- a/src/tools/clippy/tests/ui-internal/author/macro_in_closure.stdout
+++ b/src/tools/clippy/tests/ui/author/macro_in_closure.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/macro_in_loop.rs b/src/tools/clippy/tests/ui/author/macro_in_loop.rs
index 8a520501f8d..8a520501f8d 100644
--- a/src/tools/clippy/tests/ui-internal/author/macro_in_loop.rs
+++ b/src/tools/clippy/tests/ui/author/macro_in_loop.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/macro_in_loop.stdout b/src/tools/clippy/tests/ui/author/macro_in_loop.stdout
index 3f9be297c33..3f9be297c33 100644
--- a/src/tools/clippy/tests/ui-internal/author/macro_in_loop.stdout
+++ b/src/tools/clippy/tests/ui/author/macro_in_loop.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/matches.rs b/src/tools/clippy/tests/ui/author/matches.rs
index 674e07ec2d3..674e07ec2d3 100644
--- a/src/tools/clippy/tests/ui-internal/author/matches.rs
+++ b/src/tools/clippy/tests/ui/author/matches.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/matches.stdout b/src/tools/clippy/tests/ui/author/matches.stdout
index 91b3b6f6877..91b3b6f6877 100644
--- a/src/tools/clippy/tests/ui-internal/author/matches.stdout
+++ b/src/tools/clippy/tests/ui/author/matches.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/repeat.rs b/src/tools/clippy/tests/ui/author/repeat.rs
index d8e9d589e68..d8e9d589e68 100644
--- a/src/tools/clippy/tests/ui-internal/author/repeat.rs
+++ b/src/tools/clippy/tests/ui/author/repeat.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/repeat.stdout b/src/tools/clippy/tests/ui/author/repeat.stdout
index d9e3f864f12..d9e3f864f12 100644
--- a/src/tools/clippy/tests/ui-internal/author/repeat.stdout
+++ b/src/tools/clippy/tests/ui/author/repeat.stdout
diff --git a/src/tools/clippy/tests/ui-internal/author/struct.rs b/src/tools/clippy/tests/ui/author/struct.rs
index a99bdfc1313..a99bdfc1313 100644
--- a/src/tools/clippy/tests/ui-internal/author/struct.rs
+++ b/src/tools/clippy/tests/ui/author/struct.rs
diff --git a/src/tools/clippy/tests/ui-internal/author/struct.stdout b/src/tools/clippy/tests/ui/author/struct.stdout
index 0b332d5e7d0..0b332d5e7d0 100644
--- a/src/tools/clippy/tests/ui-internal/author/struct.stdout
+++ b/src/tools/clippy/tests/ui/author/struct.stdout
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
index bd90042c1da..fbf84337382 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
@@ -1,4 +1,4 @@
-#![feature(repr128, proc_macro_quote)]
+#![feature(repr128, proc_macro_quote, proc_macro_span)]
 #![allow(incomplete_features)]
 #![allow(clippy::field_reassign_with_default)]
 #![allow(clippy::eq_op)]
@@ -182,3 +182,51 @@ pub fn non_canonical_clone_derive(_: TokenStream) -> TokenStream {
         impl Copy for NonCanonicalClone {}
     }
 }
+
+// Derive macro that generates the following but where all generated spans are set to the entire
+// input span.
+//
+// ```
+// #[allow(clippy::missing_const_for_fn)]
+// fn check() {}
+// ```
+#[proc_macro_derive(AllowLintSameSpan)]
+pub fn allow_lint_same_span_derive(input: TokenStream) -> TokenStream {
+    let mut iter = input.into_iter();
+    let first = iter.next().unwrap();
+    let last = iter.last().unwrap();
+    let span = first.span().join(last.span()).unwrap();
+    let span_help = |mut t: TokenTree| -> TokenTree {
+        t.set_span(span);
+        t
+    };
+    // Generate the TokenStream but setting all the spans to the entire input span
+    <TokenStream as FromIterator<TokenTree>>::from_iter([
+        span_help(Punct::new('#', Spacing::Alone).into()),
+        span_help(
+            Group::new(
+                Delimiter::Bracket,
+                <TokenStream as FromIterator<TokenTree>>::from_iter([
+                    Ident::new("allow", span).into(),
+                    span_help(
+                        Group::new(
+                            Delimiter::Parenthesis,
+                            <TokenStream as FromIterator<TokenTree>>::from_iter([
+                                Ident::new("clippy", span).into(),
+                                span_help(Punct::new(':', Spacing::Joint).into()),
+                                span_help(Punct::new(':', Spacing::Alone).into()),
+                                Ident::new("missing_const_for_fn", span).into(),
+                            ]),
+                        )
+                        .into(),
+                    ),
+                ]),
+            )
+            .into(),
+        ),
+        Ident::new("fn", span).into(),
+        Ident::new("check", span).into(),
+        span_help(Group::new(Delimiter::Parenthesis, TokenStream::new()).into()),
+        span_help(Group::new(Delimiter::Brace, TokenStream::new()).into()),
+    ])
+}
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed
index ea5e983de3b..22e984c46d2 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref.fixed
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref.fixed
@@ -71,3 +71,9 @@ mod false_negative {
         assert_ne!(addr_x, addr_y);
     }
 }
+
+fn issue_13584() {
+    let s = "Hello, world!\n";
+    let p = &raw const *s;
+    let _ = p as *const i8;
+}
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref.rs b/src/tools/clippy/tests/ui/borrow_deref_ref.rs
index 8c8905b150e..61d89193f42 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref.rs
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref.rs
@@ -71,3 +71,9 @@ mod false_negative {
         assert_ne!(addr_x, addr_y);
     }
 }
+
+fn issue_13584() {
+    let s = "Hello, world!\n";
+    let p = &raw const *s;
+    let _ = p as *const i8;
+}
diff --git a/src/tools/clippy/tests/ui/const_is_empty.rs b/src/tools/clippy/tests/ui/const_is_empty.rs
index 04e0de91ecf..b5e27b61548 100644
--- a/src/tools/clippy/tests/ui/const_is_empty.rs
+++ b/src/tools/clippy/tests/ui/const_is_empty.rs
@@ -171,3 +171,17 @@ fn constant_from_external_crate() {
     let _ = std::env::consts::EXE_EXTENSION.is_empty();
     // Do not lint, `exe_ext` comes from the `std` crate
 }
+
+fn issue_13106() {
+    const {
+        assert!(!NON_EMPTY_STR.is_empty());
+    }
+
+    const {
+        assert!(EMPTY_STR.is_empty());
+    }
+
+    const {
+        EMPTY_STR.is_empty();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/const_is_empty.stderr b/src/tools/clippy/tests/ui/const_is_empty.stderr
index 7f80b520b1a..0afba940d8b 100644
--- a/src/tools/clippy/tests/ui/const_is_empty.stderr
+++ b/src/tools/clippy/tests/ui/const_is_empty.stderr
@@ -157,5 +157,11 @@ error: this expression always evaluates to true
 LL |     let _ = val.is_empty();
    |             ^^^^^^^^^^^^^^
 
-error: aborting due to 26 previous errors
+error: this expression always evaluates to true
+  --> tests/ui/const_is_empty.rs:185:9
+   |
+LL |         EMPTY_STR.is_empty();
+   |         ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 27 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 355f2bc7736..5cf5c608a85 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -54,8 +54,9 @@ fn test_units() {
 
 /// This tests allowed identifiers.
 /// KiB MiB GiB TiB PiB EiB
+/// MHz GHz THz
 /// AccessKit
-/// CoreFoundation CoreGraphics CoreText
+/// CoAP CoreFoundation CoreGraphics CoreText
 /// Direct2D Direct3D DirectWrite DirectX
 /// ECMAScript
 /// GPLv2 GPLv3
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 9ced2677622..420211c6539 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -54,8 +54,9 @@ fn test_units() {
 
 /// This tests allowed identifiers.
 /// KiB MiB GiB TiB PiB EiB
+/// MHz GHz THz
 /// AccessKit
-/// CoreFoundation CoreGraphics CoreText
+/// CoAP CoreFoundation CoreGraphics CoreText
 /// Direct2D Direct3D DirectWrite DirectX
 /// ECMAScript
 /// GPLv2 GPLv3
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
index 67c0464149c..27a04e4b558 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
@@ -133,7 +133,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:78:5
+  --> tests/ui/doc/doc-fixable.rs:79:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:95:5
+  --> tests/ui/doc/doc-fixable.rs:96:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -155,7 +155,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:103:8
+  --> tests/ui/doc/doc-fixable.rs:104:8
    |
 LL | /// ## CamelCaseThing
    |        ^^^^^^^^^^^^^^
@@ -166,7 +166,7 @@ LL | /// ## `CamelCaseThing`
    |        ~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:106:7
+  --> tests/ui/doc/doc-fixable.rs:107:7
    |
 LL | /// # CamelCaseThing
    |       ^^^^^^^^^^^^^^
@@ -177,7 +177,7 @@ LL | /// # `CamelCaseThing`
    |       ~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:108:22
+  --> tests/ui/doc/doc-fixable.rs:109:22
    |
 LL | /// Not a title #897 CamelCaseThing
    |                      ^^^^^^^^^^^^^^
@@ -188,7 +188,7 @@ LL | /// Not a title #897 `CamelCaseThing`
    |                      ~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:109:5
+  --> tests/ui/doc/doc-fixable.rs:110:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -199,7 +199,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:116:5
+  --> tests/ui/doc/doc-fixable.rs:117:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -210,7 +210,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:129:5
+  --> tests/ui/doc/doc-fixable.rs:130:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -221,7 +221,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:140:43
+  --> tests/ui/doc/doc-fixable.rs:141:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
@@ -232,7 +232,7 @@ LL | /** E.g., serialization of an empty list: `FooBar`
    |                                           ~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:145:5
+  --> tests/ui/doc/doc-fixable.rs:146:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
@@ -243,7 +243,7 @@ LL | And `BarQuz` too.
    |     ~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:146:1
+  --> tests/ui/doc/doc-fixable.rs:147:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -254,7 +254,7 @@ LL | `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:151:43
+  --> tests/ui/doc/doc-fixable.rs:152:43
    |
 LL | /** E.g., serialization of an empty list: FooBar
    |                                           ^^^^^^
@@ -265,7 +265,7 @@ LL | /** E.g., serialization of an empty list: `FooBar`
    |                                           ~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:156:5
+  --> tests/ui/doc/doc-fixable.rs:157:5
    |
 LL | And BarQuz too.
    |     ^^^^^^
@@ -276,7 +276,7 @@ LL | And `BarQuz` too.
    |     ~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:157:1
+  --> tests/ui/doc/doc-fixable.rs:158:1
    |
 LL | be_sure_we_got_to_the_end_of_it
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -287,7 +287,7 @@ LL | `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:168:5
+  --> tests/ui/doc/doc-fixable.rs:169:5
    |
 LL | /// be_sure_we_got_to_the_end_of_it
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -298,7 +298,7 @@ LL | /// `be_sure_we_got_to_the_end_of_it`
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:187:22
+  --> tests/ui/doc/doc-fixable.rs:188:22
    |
 LL | /// An iterator over mycrate::Collection's values.
    |                      ^^^^^^^^^^^^^^^^^^^
@@ -309,7 +309,7 @@ LL | /// An iterator over `mycrate::Collection`'s values.
    |                      ~~~~~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:211:34
+  --> tests/ui/doc/doc-fixable.rs:212:34
    |
 LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint
    |                                  ^^^^^^^^^^^^^^^
@@ -320,7 +320,7 @@ LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
    |                                  ~~~~~~~~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:234:22
+  --> tests/ui/doc/doc-fixable.rs:235:22
    |
 LL | /// There is no try (do() or do_not()).
    |                      ^^^^
@@ -331,7 +331,7 @@ LL | /// There is no try (`do()` or do_not()).
    |                      ~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:234:30
+  --> tests/ui/doc/doc-fixable.rs:235:30
    |
 LL | /// There is no try (do() or do_not()).
    |                              ^^^^^^^^
@@ -342,7 +342,7 @@ LL | /// There is no try (do() or `do_not()`).
    |                              ~~~~~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:237:5
+  --> tests/ui/doc/doc-fixable.rs:238:5
    |
 LL | /// ABes
    |     ^^^^
@@ -353,7 +353,7 @@ LL | /// `ABes`
    |     ~~~~~~
 
 error: item in documentation is missing backticks
-  --> tests/ui/doc/doc-fixable.rs:243:9
+  --> tests/ui/doc/doc-fixable.rs:244:9
    |
 LL |     /// foo()
    |         ^^^^^
@@ -364,7 +364,7 @@ LL |     /// `foo()`
    |         ~~~~~~~
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
-  --> tests/ui/doc/doc-fixable.rs:247:5
+  --> tests/ui/doc/doc-fixable.rs:248:5
    |
 LL | /// https://github.com/rust-lang/rust-clippy/pull/12836
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<https://github.com/rust-lang/rust-clippy/pull/12836>`
diff --git a/src/tools/clippy/tests/ui/infinite_loops.rs b/src/tools/clippy/tests/ui/infinite_loops.rs
index b6cb7ff49b0..0613eddce26 100644
--- a/src/tools/clippy/tests/ui/infinite_loops.rs
+++ b/src/tools/clippy/tests/ui/infinite_loops.rs
@@ -3,6 +3,7 @@
 
 #![allow(clippy::never_loop)]
 #![warn(clippy::infinite_loop)]
+#![feature(async_closure)]
 
 extern crate proc_macros;
 use proc_macros::{external, with_span};
@@ -428,4 +429,23 @@ fn continue_outer() {
     }
 }
 
+// don't suggest adding `-> !` to async fn/closure that already returning `-> !`
+mod issue_12338 {
+    use super::do_something;
+
+    async fn foo() -> ! {
+        loop {
+            do_something();
+        }
+    }
+
+    fn bar() {
+        let _ = async || -> ! {
+            loop {
+                do_something();
+            }
+        };
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/infinite_loops.stderr b/src/tools/clippy/tests/ui/infinite_loops.stderr
index 7635a7442f4..3a3ed7d0fe8 100644
--- a/src/tools/clippy/tests/ui/infinite_loops.stderr
+++ b/src/tools/clippy/tests/ui/infinite_loops.stderr
@@ -1,5 +1,5 @@
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:13:5
+  --> tests/ui/infinite_loops.rs:14:5
    |
 LL | /     loop {
 LL | |
@@ -15,7 +15,7 @@ LL | fn no_break() -> ! {
    |               ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:20:5
+  --> tests/ui/infinite_loops.rs:21:5
    |
 LL | /     loop {
 LL | |
@@ -32,7 +32,7 @@ LL | fn all_inf() -> ! {
    |              ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:22:9
+  --> tests/ui/infinite_loops.rs:23:9
    |
 LL | /         loop {
 LL | |
@@ -49,7 +49,7 @@ LL | fn all_inf() -> ! {
    |              ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:24:13
+  --> tests/ui/infinite_loops.rs:25:13
    |
 LL | /             loop {
 LL | |
@@ -63,7 +63,7 @@ LL | fn all_inf() -> ! {
    |              ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:38:5
+  --> tests/ui/infinite_loops.rs:39:5
    |
 LL | /     loop {
 LL | |
@@ -74,7 +74,7 @@ LL | |     }
    = help: if this is not intended, try adding a `break` or `return` condition in the loop
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:51:5
+  --> tests/ui/infinite_loops.rs:52:5
    |
 LL | /     loop {
 LL | |         fn inner_fn() -> ! {
@@ -90,7 +90,7 @@ LL | fn no_break_never_ret_noise() -> ! {
    |                               ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:94:5
+  --> tests/ui/infinite_loops.rs:95:5
    |
 LL | /     loop {
 LL | |
@@ -107,7 +107,7 @@ LL | fn break_inner_but_not_outer_1(cond: bool) -> ! {
    |                                            ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:105:5
+  --> tests/ui/infinite_loops.rs:106:5
    |
 LL | /     loop {
 LL | |
@@ -124,7 +124,7 @@ LL | fn break_inner_but_not_outer_2(cond: bool) -> ! {
    |                                            ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:119:9
+  --> tests/ui/infinite_loops.rs:120:9
    |
 LL | /         loop {
 LL | |
@@ -138,7 +138,7 @@ LL | fn break_outer_but_not_inner() -> ! {
    |                                ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:142:9
+  --> tests/ui/infinite_loops.rs:143:9
    |
 LL | /         loop {
 LL | |
@@ -155,7 +155,7 @@ LL | fn break_wrong_loop(cond: bool) -> ! {
    |                                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:182:5
+  --> tests/ui/infinite_loops.rs:183:5
    |
 LL | /     loop {
 LL | |
@@ -172,7 +172,7 @@ LL | fn match_like() -> ! {
    |                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:223:5
+  --> tests/ui/infinite_loops.rs:224:5
    |
 LL | /     loop {
 LL | |
@@ -186,7 +186,7 @@ LL | fn match_like() -> ! {
    |                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:228:5
+  --> tests/ui/infinite_loops.rs:229:5
    |
 LL | /     loop {
 LL | |
@@ -203,7 +203,7 @@ LL | fn match_like() -> ! {
    |                 ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:333:9
+  --> tests/ui/infinite_loops.rs:334:9
    |
 LL | /         loop {
 LL | |
@@ -217,7 +217,7 @@ LL |     fn problematic_trait_method() -> ! {
    |                                   ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:343:9
+  --> tests/ui/infinite_loops.rs:344:9
    |
 LL | /         loop {
 LL | |
@@ -231,7 +231,7 @@ LL |     fn could_be_problematic() -> ! {
    |                               ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:352:9
+  --> tests/ui/infinite_loops.rs:353:9
    |
 LL | /         loop {
 LL | |
@@ -245,7 +245,7 @@ LL |     let _loop_forever = || -> ! {
    |                            ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:366:8
+  --> tests/ui/infinite_loops.rs:367:8
    |
 LL |       Ok(loop {
    |  ________^
@@ -256,7 +256,7 @@ LL | |     })
    = help: if this is not intended, try adding a `break` or `return` condition in the loop
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:408:5
+  --> tests/ui/infinite_loops.rs:409:5
    |
 LL | /     'infinite: loop {
 LL | |
@@ -272,7 +272,7 @@ LL | fn continue_outer() -> ! {
    |                     ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:415:5
+  --> tests/ui/infinite_loops.rs:416:5
    |
 LL | /     loop {
 LL | |
@@ -289,7 +289,7 @@ LL | fn continue_outer() -> ! {
    |                     ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:417:9
+  --> tests/ui/infinite_loops.rs:418:9
    |
 LL | /         'inner: loop {
 LL | |             loop {
@@ -304,7 +304,7 @@ LL | fn continue_outer() -> ! {
    |                     ++++
 
 error: infinite loop detected
-  --> tests/ui/infinite_loops.rs:425:5
+  --> tests/ui/infinite_loops.rs:426:5
    |
 LL | /     loop {
 LL | |
diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.stderr b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
index 7c42fa1dd89..d748c85003b 100644
--- a/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
+++ b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
@@ -13,8 +13,8 @@ help: consider implementing `IntoIterator` for `&S1`
    |
 LL + 
 LL + impl IntoIterator for &S1 {
-LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     type Item = &u8;
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -34,8 +34,8 @@ help: consider implementing `IntoIterator` for `&mut S1`
    |
 LL + 
 LL + impl IntoIterator for &mut S1 {
-LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     type Item = &mut u8;
+LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -55,8 +55,8 @@ help: consider implementing `IntoIterator` for `&S3<'a>`
    |
 LL + 
 LL + impl IntoIterator for &S3<'a> {
-LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     type Item = &u8;
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -76,8 +76,8 @@ help: consider implementing `IntoIterator` for `&mut S3<'a>`
    |
 LL + 
 LL + impl IntoIterator for &mut S3<'a> {
-LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     type Item = &mut u8;
+LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -96,8 +96,8 @@ help: consider implementing `IntoIterator` for `&S8<T>`
    |
 LL + 
 LL + impl IntoIterator for &S8<T> {
-LL +     type IntoIter = std::slice::Iter<'static, T>;
 LL +     type Item = &T;
+LL +     type IntoIter = std::slice::Iter<'static, T>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -117,8 +117,8 @@ help: consider implementing `IntoIterator` for `&S9<T>`
    |
 LL + 
 LL + impl IntoIterator for &S9<T> {
-LL +     type IntoIter = std::slice::Iter<'_, T>;
 LL +     type Item = &T;
+LL +     type IntoIter = std::slice::Iter<'_, T>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -138,8 +138,8 @@ help: consider implementing `IntoIterator` for `&mut S9<T>`
    |
 LL + 
 LL + impl IntoIterator for &mut S9<T> {
-LL +     type IntoIter = std::slice::IterMut<'_, T>;
 LL +     type Item = &mut T;
+LL +     type IntoIter = std::slice::IterMut<'_, T>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -162,8 +162,8 @@ help: consider implementing `IntoIterator` for `&Issue12037`
    |
 LL ~         
 LL + impl IntoIterator for &Issue12037 {
-LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     type Item = &u8;
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
diff --git a/src/tools/clippy/tests/ui/large_const_arrays.fixed b/src/tools/clippy/tests/ui/large_const_arrays.fixed
index 543ce460e7b..e5b28cb6a9d 100644
--- a/src/tools/clippy/tests/ui/large_const_arrays.fixed
+++ b/src/tools/clippy/tests/ui/large_const_arrays.fixed
@@ -9,11 +9,13 @@ pub struct S {
 // Should lint
 pub(crate) static FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];
 pub static FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
+static FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];
 static FOO: [u32; 1_000_000] = [0u32; 1_000_000];
 
 // Good
 pub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250];
 pub const G_FOO_PUB: [u32; 250] = [0u32; 250];
+const G_FOO_COMPUTED: [u32; 25 * 10] = [0u32; 25 * 10];
 const G_FOO: [u32; 250] = [0u32; 250];
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/large_const_arrays.rs b/src/tools/clippy/tests/ui/large_const_arrays.rs
index e23a8081171..b9593225da2 100644
--- a/src/tools/clippy/tests/ui/large_const_arrays.rs
+++ b/src/tools/clippy/tests/ui/large_const_arrays.rs
@@ -9,11 +9,13 @@ pub struct S {
 // Should lint
 pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];
 pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
+const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];
 const FOO: [u32; 1_000_000] = [0u32; 1_000_000];
 
 // Good
 pub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250];
 pub const G_FOO_PUB: [u32; 250] = [0u32; 250];
+const G_FOO_COMPUTED: [u32; 25 * 10] = [0u32; 25 * 10];
 const G_FOO: [u32; 250] = [0u32; 250];
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/large_const_arrays.stderr b/src/tools/clippy/tests/ui/large_const_arrays.stderr
index 88f921b81f7..27112205390 100644
--- a/src/tools/clippy/tests/ui/large_const_arrays.stderr
+++ b/src/tools/clippy/tests/ui/large_const_arrays.stderr
@@ -20,13 +20,21 @@ LL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
 error: large array defined as const
   --> tests/ui/large_const_arrays.rs:12:1
    |
+LL | const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];
+   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | help: make this a static item: `static`
+
+error: large array defined as const
+  --> tests/ui/large_const_arrays.rs:13:1
+   |
 LL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000];
    | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | |
    | help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:21:5
+  --> tests/ui/large_const_arrays.rs:23:5
    |
 LL |     pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
    |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,7 +42,7 @@ LL |     pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
    |         help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:22:5
+  --> tests/ui/large_const_arrays.rs:24:5
    |
 LL |     const BAR: [u32; 1_000_000] = [0u32; 1_000_000];
    |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +50,7 @@ LL |     const BAR: [u32; 1_000_000] = [0u32; 1_000_000];
    |     help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:23:5
+  --> tests/ui/large_const_arrays.rs:25:5
    |
 LL |     pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +58,7 @@ LL |     pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |         help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:24:5
+  --> tests/ui/large_const_arrays.rs:26:5
    |
 LL |     const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -58,7 +66,7 @@ LL |     const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |     help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:25:5
+  --> tests/ui/large_const_arrays.rs:27:5
    |
 LL |     pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000];
    |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -66,12 +74,12 @@ LL |     pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000];
    |         help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:26:5
+  --> tests/ui/large_const_arrays.rs:28:5
    |
 LL |     const BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000];
    |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |
    |     help: make this a static item: `static`
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_bits.fixed b/src/tools/clippy/tests/ui/manual_bits.fixed
index 4de01905e8a..8e5cb7d38b9 100644
--- a/src/tools/clippy/tests/ui/manual_bits.fixed
+++ b/src/tools/clippy/tests/ui/manual_bits.fixed
@@ -56,3 +56,14 @@ fn main() {
     let _ = (u128::BITS as usize).pow(5);
     let _ = &(u128::BITS as usize);
 }
+
+fn should_not_lint() {
+    macro_rules! bits_via_macro {
+        ($T: ty) => {
+            size_of::<$T>() * 8;
+        };
+    }
+
+    bits_via_macro!(u8);
+    bits_via_macro!(String);
+}
diff --git a/src/tools/clippy/tests/ui/manual_bits.rs b/src/tools/clippy/tests/ui/manual_bits.rs
index d4f369fcf87..5e492ed15d2 100644
--- a/src/tools/clippy/tests/ui/manual_bits.rs
+++ b/src/tools/clippy/tests/ui/manual_bits.rs
@@ -56,3 +56,14 @@ fn main() {
     let _ = (size_of::<u128>() * 8).pow(5);
     let _ = &(size_of::<u128>() * 8);
 }
+
+fn should_not_lint() {
+    macro_rules! bits_via_macro {
+        ($T: ty) => {
+            size_of::<$T>() * 8;
+        };
+    }
+
+    bits_via_macro!(u8);
+    bits_via_macro!(String);
+}
diff --git a/src/tools/clippy/tests/ui/map_all_any_identity.fixed b/src/tools/clippy/tests/ui/map_all_any_identity.fixed
new file mode 100644
index 00000000000..c92462ab9c2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_all_any_identity.fixed
@@ -0,0 +1,21 @@
+#![warn(clippy::map_all_any_identity)]
+
+fn main() {
+    let _ = ["foo"].into_iter().any(|s| s == "foo");
+    //~^ map_all_any_identity
+    let _ = ["foo"].into_iter().all(|s| s == "foo");
+    //~^ map_all_any_identity
+
+    //
+    // Do not lint
+    //
+    // Not identity
+    let _ = ["foo"].into_iter().map(|s| s.len()).any(|n| n > 0);
+    // Macro
+    macro_rules! map {
+        ($x:expr) => {
+            $x.into_iter().map(|s| s == "foo")
+        };
+    }
+    map!(["foo"]).any(|a| a);
+}
diff --git a/src/tools/clippy/tests/ui/map_all_any_identity.rs b/src/tools/clippy/tests/ui/map_all_any_identity.rs
new file mode 100644
index 00000000000..0e4a564ca04
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_all_any_identity.rs
@@ -0,0 +1,21 @@
+#![warn(clippy::map_all_any_identity)]
+
+fn main() {
+    let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a);
+    //~^ map_all_any_identity
+    let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity);
+    //~^ map_all_any_identity
+
+    //
+    // Do not lint
+    //
+    // Not identity
+    let _ = ["foo"].into_iter().map(|s| s.len()).any(|n| n > 0);
+    // Macro
+    macro_rules! map {
+        ($x:expr) => {
+            $x.into_iter().map(|s| s == "foo")
+        };
+    }
+    map!(["foo"]).any(|a| a);
+}
diff --git a/src/tools/clippy/tests/ui/map_all_any_identity.stderr b/src/tools/clippy/tests/ui/map_all_any_identity.stderr
new file mode 100644
index 00000000000..98fdcc2a939
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_all_any_identity.stderr
@@ -0,0 +1,26 @@
+error: usage of `.map(...).any(identity)`
+  --> tests/ui/map_all_any_identity.rs:4:33
+   |
+LL |     let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a);
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::map-all-any-identity` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::map_all_any_identity)]`
+help: use `.any(...)` instead
+   |
+LL |     let _ = ["foo"].into_iter().any(|s| s == "foo");
+   |                                 ~~~~~~~~~~~~~~~~~~~
+
+error: usage of `.map(...).all(identity)`
+  --> tests/ui/map_all_any_identity.rs:6:33
+   |
+LL |     let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity);
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `.all(...)` instead
+   |
+LL |     let _ = ["foo"].into_iter().all(|s| s == "foo");
+   |                                 ~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed
new file mode 100644
index 00000000000..cf520e71a64
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed
@@ -0,0 +1,73 @@
+#![allow(
+    unused,
+    clippy::redundant_closure,
+    clippy::reversed_empty_ranges,
+    clippy::identity_op
+)]
+#![warn(clippy::map_with_unused_argument_over_ranges)]
+
+fn do_something() -> usize {
+    todo!()
+}
+
+fn do_something_interesting(x: usize, y: usize) -> usize {
+    todo!()
+}
+
+macro_rules! gen {
+    () => {
+        (0..10).map(|_| do_something());
+    };
+}
+
+fn main() {
+    // These should be raised
+    std::iter::repeat_with(|| do_something()).take(10);
+    std::iter::repeat_with(|| do_something()).take(10);
+    std::iter::repeat_with(|| do_something()).take(11);
+    std::iter::repeat_with(|| do_something()).take(7);
+    std::iter::repeat_with(|| do_something()).take(8);
+    std::iter::repeat_n(3, 10);
+    std::iter::repeat_with(|| {
+        let x = 3;
+        x + 2
+    }).take(10);
+    std::iter::repeat_with(|| do_something()).take(10).collect::<Vec<_>>();
+    let upper = 4;
+    std::iter::repeat_with(|| do_something()).take(upper);
+    let upper_fn = || 4;
+    std::iter::repeat_with(|| do_something()).take(upper_fn());
+    std::iter::repeat_with(|| do_something()).take(upper_fn() + 1);
+    std::iter::repeat_with(|| do_something()).take(upper_fn() - 2);
+    std::iter::repeat_with(|| do_something()).take(upper_fn() - 1);
+    (-3..9).map(|_| do_something());
+    std::iter::repeat_with(|| do_something()).take(0);
+    std::iter::repeat_with(|| do_something()).take(1);
+    std::iter::repeat_with(|| do_something()).take((1 << 4) - 0);
+    // These should not be raised
+    gen!();
+    let lower = 2;
+    let lower_fn = || 2;
+    (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..=upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (0..10).map(|x| do_something_interesting(x, 4)); // Actual map over range
+    "Foobar".chars().map(|_| do_something()); // Not a map over range
+    // i128::MAX == 340282366920938463463374607431768211455
+    (0..=340282366920938463463374607431768211455).map(|_: u128| do_something()); // Can't be replaced due to overflow
+}
+
+#[clippy::msrv = "1.27"]
+fn msrv_1_27() {
+    (0..10).map(|_| do_something());
+}
+
+#[clippy::msrv = "1.28"]
+fn msrv_1_28() {
+    std::iter::repeat_with(|| do_something()).take(10);
+}
+
+#[clippy::msrv = "1.81"]
+fn msrv_1_82() {
+    std::iter::repeat(3).take(10);
+}
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs
new file mode 100644
index 00000000000..298eee9ca3f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs
@@ -0,0 +1,73 @@
+#![allow(
+    unused,
+    clippy::redundant_closure,
+    clippy::reversed_empty_ranges,
+    clippy::identity_op
+)]
+#![warn(clippy::map_with_unused_argument_over_ranges)]
+
+fn do_something() -> usize {
+    todo!()
+}
+
+fn do_something_interesting(x: usize, y: usize) -> usize {
+    todo!()
+}
+
+macro_rules! gen {
+    () => {
+        (0..10).map(|_| do_something());
+    };
+}
+
+fn main() {
+    // These should be raised
+    (0..10).map(|_| do_something());
+    (0..10).map(|_foo| do_something());
+    (0..=10).map(|_| do_something());
+    (3..10).map(|_| do_something());
+    (3..=10).map(|_| do_something());
+    (0..10).map(|_| 3);
+    (0..10).map(|_| {
+        let x = 3;
+        x + 2
+    });
+    (0..10).map(|_| do_something()).collect::<Vec<_>>();
+    let upper = 4;
+    (0..upper).map(|_| do_something());
+    let upper_fn = || 4;
+    (0..upper_fn()).map(|_| do_something());
+    (0..=upper_fn()).map(|_| do_something());
+    (2..upper_fn()).map(|_| do_something());
+    (2..=upper_fn()).map(|_| do_something());
+    (-3..9).map(|_| do_something());
+    (9..3).map(|_| do_something());
+    (9..=9).map(|_| do_something());
+    (1..=1 << 4).map(|_| do_something());
+    // These should not be raised
+    gen!();
+    let lower = 2;
+    let lower_fn = || 2;
+    (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..=upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (0..10).map(|x| do_something_interesting(x, 4)); // Actual map over range
+    "Foobar".chars().map(|_| do_something()); // Not a map over range
+    // i128::MAX == 340282366920938463463374607431768211455
+    (0..=340282366920938463463374607431768211455).map(|_: u128| do_something()); // Can't be replaced due to overflow
+}
+
+#[clippy::msrv = "1.27"]
+fn msrv_1_27() {
+    (0..10).map(|_| do_something());
+}
+
+#[clippy::msrv = "1.28"]
+fn msrv_1_28() {
+    (0..10).map(|_| do_something());
+}
+
+#[clippy::msrv = "1.81"]
+fn msrv_1_82() {
+    (0..10).map(|_| 3);
+}
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr
new file mode 100644
index 00000000000..0b56c6d9521
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr
@@ -0,0 +1,223 @@
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:25:5
+   |
+LL |     (0..10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::map-with-unused-argument-over-ranges` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::map_with_unused_argument_over_ranges)]`
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:26:5
+   |
+LL |     (0..10).map(|_foo| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_foo| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:27:5
+   |
+LL |     (0..=10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..=10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(11);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:28:5
+   |
+LL |     (3..10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (3..10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(7);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:29:5
+   |
+LL |     (3..=10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (3..=10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(8);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:30:5
+   |
+LL |     (0..10).map(|_| 3);
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_n`
+   |
+LL |     std::iter::repeat_n(3, 10);
+   |     ~~~~~~~~~~~~~~~~~~~ ~~~~~
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5
+   |
+LL | /     (0..10).map(|_| {
+LL | |         let x = 3;
+LL | |         x + 2
+LL | |     });
+   | |______^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL ~     std::iter::repeat_with(|| {
+LL |         let x = 3;
+LL |         x + 2
+LL ~     }).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:35:5
+   |
+LL |     (0..10).map(|_| do_something()).collect::<Vec<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_| do_something()).collect::<Vec<_>>();
+LL +     std::iter::repeat_with(|| do_something()).take(10).collect::<Vec<_>>();
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:37:5
+   |
+LL |     (0..upper).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..upper).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:39:5
+   |
+LL |     (0..upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn());
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:40:5
+   |
+LL |     (0..=upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..=upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn() + 1);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:41:5
+   |
+LL |     (2..upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (2..upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn() - 2);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:42:5
+   |
+LL |     (2..=upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (2..=upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn() - 1);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:44:5
+   |
+LL |     (9..3).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (9..3).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(0);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:45:5
+   |
+LL |     (9..=9).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (9..=9).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(1);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:46:5
+   |
+LL |     (1..=1 << 4).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (1..=1 << 4).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take((1 << 4) - 0);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:67:5
+   |
+LL |     (0..10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:72:5
+   |
+LL |     (0..10).map(|_| 3);
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat` and `take`
+   |
+LL |     std::iter::repeat(3).take(10);
+   |     ~~~~~~~~~~~~~~~~~ ~ +++++++++
+
+error: aborting due to 18 previous errors
+
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
index 7c882789511..754fe061c4a 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
@@ -2,7 +2,6 @@
 #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
 #![feature(const_trait_impl, abi_vectorcall)]
 
-
 use std::mem::transmute;
 
 struct Game {
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
index 48312d48ed3..460be0733e0 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
@@ -2,7 +2,6 @@
 #![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
 #![feature(const_trait_impl, abi_vectorcall)]
 
-
 use std::mem::transmute;
 
 struct Game {
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
index f28dec5c7f1..d553c522556 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
@@ -1,5 +1,5 @@
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:14:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:13:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -16,7 +16,7 @@ LL |     pub const fn new() -> Self {
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:20:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:19:5
    |
 LL | /     fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T; N]) -> &'a [T; N] {
 LL | |
@@ -30,7 +30,7 @@ LL |     const fn const_generic_params<'a, T, const N: usize>(&self, b: &'a [T;
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:27:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:26:1
    |
 LL | / fn one() -> i32 {
 LL | |
@@ -44,7 +44,7 @@ LL | const fn one() -> i32 {
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:33:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:32:1
    |
 LL | / fn two() -> i32 {
 LL | |
@@ -59,7 +59,7 @@ LL | const fn two() -> i32 {
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:40:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:39:1
    |
 LL | / fn string() -> String {
 LL | |
@@ -73,7 +73,7 @@ LL | const fn string() -> String {
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:46:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:45:1
    |
 LL | / unsafe fn four() -> i32 {
 LL | |
@@ -87,7 +87,7 @@ LL | const unsafe fn four() -> i32 {
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:52:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:51:1
    |
 LL | / fn generic<T>(t: T) -> T {
 LL | |
@@ -101,7 +101,7 @@ LL | const fn generic<T>(t: T) -> T {
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:61:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:60:1
    |
 LL | / fn generic_arr<T: Copy>(t: [T; 1]) -> T {
 LL | |
@@ -115,7 +115,7 @@ LL | const fn generic_arr<T: Copy>(t: [T; 1]) -> T {
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:75:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:74:9
    |
 LL | /         pub fn b(self, a: &A) -> B {
 LL | |
@@ -129,7 +129,7 @@ LL |         pub const fn b(self, a: &A) -> B {
    |             +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:85:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:84:5
    |
 LL | /     fn const_fn_stabilized_before_msrv(byte: u8) {
 LL | |
@@ -143,7 +143,7 @@ LL |     const fn const_fn_stabilized_before_msrv(byte: u8) {
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:97:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:96:1
    |
 LL | / fn msrv_1_46() -> i32 {
 LL | |
@@ -157,7 +157,7 @@ LL | const fn msrv_1_46() -> i32 {
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:117:1
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:116:1
    |
 LL | fn d(this: D) {}
    | ^^^^^^^^^^^^^^^^
@@ -168,7 +168,7 @@ LL | const fn d(this: D) {}
    | +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:125:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:124:9
    |
 LL | /         fn deref_ptr_can_be_const(self) -> usize {
 LL | |
@@ -182,7 +182,7 @@ LL |         const fn deref_ptr_can_be_const(self) -> usize {
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:130:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:129:9
    |
 LL | /         fn deref_copied_val(self) -> usize {
 LL | |
@@ -196,7 +196,7 @@ LL |         const fn deref_copied_val(self) -> usize {
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:141:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:140:5
    |
 LL | /     fn union_access_can_be_const() {
 LL | |
@@ -211,7 +211,7 @@ LL |     const fn union_access_can_be_const() {
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:149:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:148:9
    |
 LL |         extern "C" fn c() {}
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -222,7 +222,7 @@ LL |         const extern "C" fn c() {}
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:153:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:152:9
    |
 LL |         extern fn implicit_c() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |         const extern fn implicit_c() {}
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:170:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:169:9
    |
 LL | /         pub fn new(strings: Vec<String>) -> Self {
 LL | |             Self { strings }
@@ -246,7 +246,7 @@ LL |         pub const fn new(strings: Vec<String>) -> Self {
    |             +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:175:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:174:9
    |
 LL | /         pub fn empty() -> Self {
 LL | |             Self { strings: Vec::new() }
@@ -259,7 +259,7 @@ LL |         pub const fn empty() -> Self {
    |             +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:186:9
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:185:9
    |
 LL | /         pub fn new(text: String) -> Self {
 LL | |             let vec = Vec::new();
@@ -273,7 +273,7 @@ LL |         pub const fn new(text: String) -> Self {
    |             +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:205:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:204:5
    |
 LL |     fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -284,7 +284,7 @@ LL |     const fn alias_ty_is_projection(bar: <() as FooTrait>::Foo) {}
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:209:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:208:5
    |
 LL |     extern "C-unwind" fn c_unwind() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -295,7 +295,7 @@ LL |     const extern "C-unwind" fn c_unwind() {}
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:211:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:210:5
    |
 LL |     extern "system" fn system() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -306,7 +306,7 @@ LL |     const extern "system" fn system() {}
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:213:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:212:5
    |
 LL |     extern "system-unwind" fn system_unwind() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -317,7 +317,7 @@ LL |     const extern "system-unwind" fn system_unwind() {}
    |     +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:215:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:214:5
    |
 LL |     pub extern "vectorcall" fn std_call() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -328,7 +328,7 @@ LL |     pub const extern "vectorcall" fn std_call() {}
    |         +++++
 
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/could_be_const.rs:217:5
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:216:5
    |
 LL |     pub extern "vectorcall-unwind" fn std_call_unwind() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/missing_doc.rs b/src/tools/clippy/tests/ui/missing_doc.rs
index 9c936d7fa23..31bc4309582 100644
--- a/src/tools/clippy/tests/ui/missing_doc.rs
+++ b/src/tools/clippy/tests/ui/missing_doc.rs
@@ -116,6 +116,14 @@ with_span!(span pub fn foo_pm() {});
 with_span!(span pub static FOO_PM: u32 = 0;);
 with_span!(span pub const FOO2_PM: u32 = 0;);
 
+// Don't lint unnamed constants
+const _: () = ();
+
+fn issue13298() {
+    // Rustdoc doesn't generate documentation for items within other items like fns or consts
+    const MSG: &str = "Hello, world!";
+}
+
 // issue #12197
 // Undocumented field originated inside of spanned proc-macro attribute
 /// Some dox for struct.
diff --git a/src/tools/clippy/tests/ui/missing_doc.stderr b/src/tools/clippy/tests/ui/missing_doc.stderr
index ef0f96a5b71..133c76ac9d4 100644
--- a/src/tools/clippy/tests/ui/missing_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_doc.stderr
@@ -88,5 +88,14 @@ error: missing documentation for a function
 LL |         fn also_undocumented2() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 13 previous errors
+error: missing documentation for a function
+  --> tests/ui/missing_doc.rs:122:1
+   |
+LL | / fn issue13298() {
+LL | |     // Rustdoc doesn't generate documentation for items within other items like fns or consts
+LL | |     const MSG: &str = "Hello, world!";
+LL | | }
+   | |_^
+
+error: aborting due to 14 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_as_bytes.fixed b/src/tools/clippy/tests/ui/needless_as_bytes.fixed
new file mode 100644
index 00000000000..042342311fd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_as_bytes.fixed
@@ -0,0 +1,50 @@
+#![warn(clippy::needless_as_bytes)]
+#![allow(clippy::const_is_empty)]
+
+struct S;
+
+impl S {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
+
+fn main() {
+    if "some string".is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", "some string".len());
+        //~^ needless_as_bytes
+    }
+
+    let s = String::from("yet another string");
+    if s.is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", s.len());
+        //~^ needless_as_bytes
+    }
+
+    // Do not lint
+    let _ = S.as_bytes().is_empty();
+    let _ = S.as_bytes().len();
+    let _ = (&String::new() as &dyn AsBytes).as_bytes().len();
+    macro_rules! m {
+        (1) => {
+            ""
+        };
+        (2) => {
+            "".as_bytes()
+        };
+    }
+    m!(1).as_bytes().len();
+    m!(2).len();
+}
+
+pub trait AsBytes {
+    fn as_bytes(&self) -> &[u8];
+}
+
+impl AsBytes for String {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_as_bytes.rs b/src/tools/clippy/tests/ui/needless_as_bytes.rs
new file mode 100644
index 00000000000..c481e041e0a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_as_bytes.rs
@@ -0,0 +1,50 @@
+#![warn(clippy::needless_as_bytes)]
+#![allow(clippy::const_is_empty)]
+
+struct S;
+
+impl S {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
+
+fn main() {
+    if "some string".as_bytes().is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", "some string".as_bytes().len());
+        //~^ needless_as_bytes
+    }
+
+    let s = String::from("yet another string");
+    if s.as_bytes().is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", s.as_bytes().len());
+        //~^ needless_as_bytes
+    }
+
+    // Do not lint
+    let _ = S.as_bytes().is_empty();
+    let _ = S.as_bytes().len();
+    let _ = (&String::new() as &dyn AsBytes).as_bytes().len();
+    macro_rules! m {
+        (1) => {
+            ""
+        };
+        (2) => {
+            "".as_bytes()
+        };
+    }
+    m!(1).as_bytes().len();
+    m!(2).len();
+}
+
+pub trait AsBytes {
+    fn as_bytes(&self) -> &[u8];
+}
+
+impl AsBytes for String {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_as_bytes.stderr b/src/tools/clippy/tests/ui/needless_as_bytes.stderr
new file mode 100644
index 00000000000..3391238a142
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_as_bytes.stderr
@@ -0,0 +1,29 @@
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:13:8
+   |
+LL |     if "some string".as_bytes().is_empty() {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()`
+   |
+   = note: `-D clippy::needless-as-bytes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_as_bytes)]`
+
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:15:30
+   |
+LL |         println!("len = {}", "some string".as_bytes().len());
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()`
+
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:20:8
+   |
+LL |     if s.as_bytes().is_empty() {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`
+
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:22:30
+   |
+LL |         println!("len = {}", s.as_bytes().len());
+   |                              ^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/needless_continue.rs b/src/tools/clippy/tests/ui/needless_continue.rs
index c26a292c8cb..b6d8a8f61ae 100644
--- a/src/tools/clippy/tests/ui/needless_continue.rs
+++ b/src/tools/clippy/tests/ui/needless_continue.rs
@@ -151,3 +151,20 @@ mod issue_2329 {
         }
     }
 }
+
+fn issue_13641() {
+    'a: while std::hint::black_box(true) {
+        #[allow(clippy::never_loop)]
+        loop {
+            continue 'a;
+        }
+    }
+
+    #[allow(clippy::never_loop)]
+    while std::hint::black_box(true) {
+        'b: loop {
+            continue 'b;
+            //~^ ERROR: this `continue` expression is redundant
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_continue.stderr b/src/tools/clippy/tests/ui/needless_continue.stderr
index ec7c9ba39a7..0741ba69248 100644
--- a/src/tools/clippy/tests/ui/needless_continue.stderr
+++ b/src/tools/clippy/tests/ui/needless_continue.stderr
@@ -136,5 +136,13 @@ LL | |                 }
                                println!("bar-5");
                            }
 
-error: aborting due to 8 previous errors
+error: this `continue` expression is redundant
+  --> tests/ui/needless_continue.rs:166:13
+   |
+LL |             continue 'b;
+   |             ^^^^^^^^^^^^
+   |
+   = help: consider dropping the `continue` expression
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/no_lints.rs b/src/tools/clippy/tests/ui/no_lints.rs
deleted file mode 100644
index a8467bb6ef7..00000000000
--- a/src/tools/clippy/tests/ui/no_lints.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-#![deny(clippy::all)]
-
-fn main() {}
\ No newline at end of file
diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs
index 8c1ea81d2ac..8be149d1863 100644
--- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs
+++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.rs
@@ -2,30 +2,30 @@
 #![allow(unused)]
 #![warn(clippy::no_mangle_with_rust_abi)]
 
-#[no_mangle]
+#[unsafe(no_mangle)]
 fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
-//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
 //~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
 
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
-//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
 
 /// # Safety
 /// This function shouldn't be called unless the horsemen are ready
-#[no_mangle]
+#[unsafe(no_mangle)]
 pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
-//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
 
 /// # Safety
 /// This function shouldn't be called unless the horsemen are ready
-#[no_mangle]
+#[unsafe(no_mangle)]
 unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
-//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+//~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
 
-#[no_mangle]
+#[unsafe(no_mangle)]
 fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
-    //~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+    //~^ ERROR: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
     arg_one: u32,
     arg_two: usize,
 ) -> u32 {
@@ -33,13 +33,13 @@ fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lin
 }
 
 // Must not run on functions that explicitly opt in to using the Rust ABI with `extern "Rust"`
-#[no_mangle]
+#[unsafe(no_mangle)]
 #[rustfmt::skip]
 extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {}
 
 fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {}
 
-#[no_mangle]
+#[unsafe(no_mangle)]
 extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {}
 
 extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {}
@@ -48,6 +48,11 @@ extern "C" {
     fn c_abi_in_block(arg_one: u32, arg_two: usize);
 }
 
+mod r#fn {
+    #[unsafe(no_mangle)]
+    pub(in super::r#fn) fn with_some_fn_around() {}
+}
+
 fn main() {
     // test code goes here
 }
diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr
index 27b8b39a21a..a00ebe5e1ac 100644
--- a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr
+++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi.stderr
@@ -1,4 +1,4 @@
-error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
   --> tests/ui/no_mangle_with_rust_abi.rs:6:1
    |
 LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
@@ -15,7 +15,7 @@ help: or explicitly set the default
 LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
    | +++++++++++++
 
-error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
   --> tests/ui/no_mangle_with_rust_abi.rs:11:1
    |
 LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
@@ -30,7 +30,7 @@ help: or explicitly set the default
 LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
    |     +++++++++++++
 
-error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
   --> tests/ui/no_mangle_with_rust_abi.rs:17:1
    |
 LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
@@ -45,7 +45,7 @@ help: or explicitly set the default
 LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
    |            +++++++++++++
 
-error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
   --> tests/ui/no_mangle_with_rust_abi.rs:23:1
    |
 LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
@@ -60,7 +60,7 @@ help: or explicitly set the default
 LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
    |        +++++++++++++
 
-error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
   --> tests/ui/no_mangle_with_rust_abi.rs:27:1
    |
 LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
@@ -79,5 +79,20 @@ help: or explicitly set the default
 LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
    | +++++++++++++
 
-error: aborting due to 5 previous errors
+error: `#[unsafe(no_mangle)]` set on a function with the default (`Rust`) ABI
+  --> tests/ui/no_mangle_with_rust_abi.rs:53:5
+   |
+LL |     pub(in super::r#fn) fn with_some_fn_around() {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: set an ABI
+   |
+LL |     pub(in super::r#fn) extern "C" fn with_some_fn_around() {}
+   |                         ++++++++++
+help: or explicitly set the default
+   |
+LL |     pub(in super::r#fn) extern "Rust" fn with_some_fn_around() {}
+   |                         +++++++++++++
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.rs b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.rs
new file mode 100644
index 00000000000..c7c97335348
--- /dev/null
+++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.rs
@@ -0,0 +1,57 @@
+//@edition:2021
+//
+// Edition 2024 requires the use of #[unsafe(no_mangle)]
+
+//@no-rustfix: overlapping suggestions
+#![allow(unused)]
+#![warn(clippy::no_mangle_with_rust_abi)]
+
+#[no_mangle]
+fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+//~| NOTE: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
+
+#[no_mangle]
+pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+
+/// # Safety
+/// This function shouldn't be called unless the horsemen are ready
+#[no_mangle]
+pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+
+/// # Safety
+/// This function shouldn't be called unless the horsemen are ready
+#[no_mangle]
+unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
+//~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+
+#[no_mangle]
+fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
+    //~^ ERROR: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+    arg_one: u32,
+    arg_two: usize,
+) -> u32 {
+    0
+}
+
+// Must not run on functions that explicitly opt in to using the Rust ABI with `extern "Rust"`
+#[no_mangle]
+#[rustfmt::skip]
+extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {}
+
+fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {}
+
+#[no_mangle]
+extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {}
+
+extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {}
+
+extern "C" {
+    fn c_abi_in_block(arg_one: u32, arg_two: usize);
+}
+
+fn main() {
+    // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.stderr b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.stderr
new file mode 100644
index 00000000000..15075be72d0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/no_mangle_with_rust_abi_2021.stderr
@@ -0,0 +1,83 @@
+error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+  --> tests/ui/no_mangle_with_rust_abi_2021.rs:10:1
+   |
+LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::no_mangle_with_rust_abi)]`
+help: set an ABI
+   |
+LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
+   | ++++++++++
+help: or explicitly set the default
+   |
+LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
+   | +++++++++++++
+
+error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+  --> tests/ui/no_mangle_with_rust_abi_2021.rs:15:1
+   |
+LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: set an ABI
+   |
+LL | pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
+   |     ++++++++++
+help: or explicitly set the default
+   |
+LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
+   |     +++++++++++++
+
+error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+  --> tests/ui/no_mangle_with_rust_abi_2021.rs:21:1
+   |
+LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: set an ABI
+   |
+LL | pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
+   |            ++++++++++
+help: or explicitly set the default
+   |
+LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
+   |            +++++++++++++
+
+error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+  --> tests/ui/no_mangle_with_rust_abi_2021.rs:27:1
+   |
+LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: set an ABI
+   |
+LL | unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
+   |        ++++++++++
+help: or explicitly set the default
+   |
+LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
+   |        +++++++++++++
+
+error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
+  --> tests/ui/no_mangle_with_rust_abi_2021.rs:31:1
+   |
+LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
+LL | |
+LL | |     arg_one: u32,
+LL | |     arg_two: usize,
+LL | | ) -> u32 {
+   | |________^
+   |
+help: set an ABI
+   |
+LL | extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
+   | ++++++++++
+help: or explicitly set the default
+   |
+LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
+   | +++++++++++++
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
index eafffdaf8a6..578f918f013 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
@@ -118,25 +118,25 @@ error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:161:8
    |
 LL |     if !(12 == a) {}
-   |        ^^^^^^^^^^ help: try: `12 != a`
+   |        ^^^^^^^^^^ help: try: `(12 != a)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:162:8
    |
 LL |     if !(a == 12) {}
-   |        ^^^^^^^^^^ help: try: `a != 12`
+   |        ^^^^^^^^^^ help: try: `(a != 12)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:163:8
    |
 LL |     if !(12 != a) {}
-   |        ^^^^^^^^^^ help: try: `12 == a`
+   |        ^^^^^^^^^^ help: try: `(12 == a)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:164:8
    |
 LL |     if !(a != 12) {}
-   |        ^^^^^^^^^^ help: try: `a == 12`
+   |        ^^^^^^^^^^ help: try: `(a == 12)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:168:8
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
index a23310c1ad9..65ccaaca891 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
@@ -110,9 +110,33 @@ fn dont_warn_for_negated_partial_ord_comparison() {
 fn issue_12625() {
     let a = 0;
     let b = 0;
-    if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified
-    if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified
-    if a as u64 > b {} //~ ERROR: this boolean expression can be simplified
+    if ((a as u64) < b) {} //~ ERROR: this boolean expression can be simplified
+    if ((a as u64) < b) {} //~ ERROR: this boolean expression can be simplified
+    if (a as u64 > b) {} //~ ERROR: this boolean expression can be simplified
+}
+
+fn issue_12761() {
+    let a = 0;
+    let b = 0;
+    let c = 0;
+    if (a < b) as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if (a < b) | (a > c) {} //~ ERROR: this boolean expression can be simplified
+    let opt: Option<usize> = Some(1);
+    let res: Result<usize, usize> = Ok(1);
+    if res.is_err() as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if res.is_err() | opt.is_some() {} //~ ERROR: this boolean expression can be simplified
+
+    fn a(a: bool) -> bool {
+        (4 <= 3).b() //~ ERROR: this boolean expression can be simplified
+    }
+
+    trait B {
+        fn b(&self) -> bool {
+            true
+        }
+    }
+
+    impl B for bool {}
 }
 
 fn issue_13436() {
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
index 6c844373af7..06db3a1d4a5 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
@@ -115,6 +115,30 @@ fn issue_12625() {
     if !(a as u64 <= b) {} //~ ERROR: this boolean expression can be simplified
 }
 
+fn issue_12761() {
+    let a = 0;
+    let b = 0;
+    let c = 0;
+    if !(a >= b) as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if !(a >= b) | !(a <= c) {} //~ ERROR: this boolean expression can be simplified
+    let opt: Option<usize> = Some(1);
+    let res: Result<usize, usize> = Ok(1);
+    if !res.is_ok() as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if !res.is_ok() | !opt.is_none() {} //~ ERROR: this boolean expression can be simplified
+
+    fn a(a: bool) -> bool {
+        (!(4 > 3)).b() //~ ERROR: this boolean expression can be simplified
+    }
+
+    trait B {
+        fn b(&self) -> bool {
+            true
+        }
+    }
+
+    impl B for bool {}
+}
+
 fn issue_13436() {
     fn not_zero(x: i32) -> bool {
         x != 0
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
index 52803e828ae..66c50f9ff1e 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
@@ -83,127 +83,169 @@ error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool_methods.rs:113:8
    |
 LL |     if !(a as u64 >= b) {}
-   |        ^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
+   |        ^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool_methods.rs:114:8
    |
 LL |     if !((a as u64) >= b) {}
-   |        ^^^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
+   |        ^^^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool_methods.rs:115:8
    |
 LL |     if !(a as u64 <= b) {}
-   |        ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b`
+   |        ^^^^^^^^^^^^^^^^ help: try: `(a as u64 > b)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:131:9
+  --> tests/ui/nonminimal_bool_methods.rs:122:8
+   |
+LL |     if !(a >= b) as i32 == c {}
+   |        ^^^^^^^^^ help: try: `(a < b)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:123:8
+   |
+LL |     if !(a >= b) | !(a <= c) {}
+   |        ^^^^^^^^^ help: try: `(a < b)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:123:20
+   |
+LL |     if !(a >= b) | !(a <= c) {}
+   |                    ^^^^^^^^^ help: try: `(a > c)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:126:8
+   |
+LL |     if !res.is_ok() as i32 == c {}
+   |        ^^^^^^^^^^^^ help: try: `res.is_err()`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:127:8
+   |
+LL |     if !res.is_ok() | !opt.is_none() {}
+   |        ^^^^^^^^^^^^ help: try: `res.is_err()`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:127:23
+   |
+LL |     if !res.is_ok() | !opt.is_none() {}
+   |                       ^^^^^^^^^^^^^^ help: try: `opt.is_some()`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:130:9
+   |
+LL |         (!(4 > 3)).b()
+   |         ^^^^^^^^^^ help: try: `(4 <= 3)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:155:9
    |
 LL |     _ = !opt.is_some_and(|x| x < 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:132:9
+  --> tests/ui/nonminimal_bool_methods.rs:156:9
    |
 LL |     _ = !opt.is_some_and(|x| x <= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:133:9
+  --> tests/ui/nonminimal_bool_methods.rs:157:9
    |
 LL |     _ = !opt.is_some_and(|x| x > 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:134:9
+  --> tests/ui/nonminimal_bool_methods.rs:158:9
    |
 LL |     _ = !opt.is_some_and(|x| x >= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:135:9
+  --> tests/ui/nonminimal_bool_methods.rs:159:9
    |
 LL |     _ = !opt.is_some_and(|x| x == 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:136:9
+  --> tests/ui/nonminimal_bool_methods.rs:160:9
    |
 LL |     _ = !opt.is_some_and(|x| x != 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:145:9
+  --> tests/ui/nonminimal_bool_methods.rs:169:9
    |
 LL |     _ = !opt.is_none_or(|x| x < 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:146:9
+  --> tests/ui/nonminimal_bool_methods.rs:170:9
    |
 LL |     _ = !opt.is_none_or(|x| x <= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:147:9
+  --> tests/ui/nonminimal_bool_methods.rs:171:9
    |
 LL |     _ = !opt.is_none_or(|x| x > 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:148:9
+  --> tests/ui/nonminimal_bool_methods.rs:172:9
    |
 LL |     _ = !opt.is_none_or(|x| x >= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:149:9
+  --> tests/ui/nonminimal_bool_methods.rs:173:9
    |
 LL |     _ = !opt.is_none_or(|x| x == 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:150:9
+  --> tests/ui/nonminimal_bool_methods.rs:174:9
    |
 LL |     _ = !opt.is_none_or(|x| x != 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:157:9
+  --> tests/ui/nonminimal_bool_methods.rs:181:9
    |
 LL |     _ = !opt.is_some_and(|x| !x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:161:9
+  --> tests/ui/nonminimal_bool_methods.rs:185:9
    |
 LL |     _ = !opt.is_none_or(|x| !x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:168:9
+  --> tests/ui/nonminimal_bool_methods.rs:192:9
    |
 LL |     _ = !opt.is_some_and(|x| x.is_ok());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:169:9
+  --> tests/ui/nonminimal_bool_methods.rs:193:9
    |
 LL |     _ = !opt.is_some_and(|x| x.is_err());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:170:9
+  --> tests/ui/nonminimal_bool_methods.rs:194:9
    |
 LL |     _ = !opt.is_none_or(|x| x.is_ok());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:171:9
+  --> tests/ui/nonminimal_bool_methods.rs:195:9
    |
 LL |     _ = !opt.is_none_or(|x| x.is_err());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())`
 
-error: aborting due to 34 previous errors
+error: aborting due to 41 previous errors
 
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index e03df1658ee..2ac59718786 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -54,7 +54,7 @@
 #![allow(enum_intrinsics_non_enums)]
 #![allow(non_fmt_panics)]
 #![allow(named_arguments_used_positionally)]
-#![allow(temporary_cstring_as_ptr)]
+#![allow(dangling_pointers_from_temporaries)]
 #![allow(undropped_manually_drops)]
 #![allow(unknown_lints)]
 #![allow(unused_labels)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index b906079d7df..a5ae727b7ee 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -1,17 +1,11 @@
-error: lint `temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`
-  --> tests/ui/rename.rs:57:10
-   |
-LL | #![allow(temporary_cstring_as_ptr)]
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`
-   |
-   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
-
 error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
   --> tests/ui/rename.rs:63:9
    |
 LL | #![warn(clippy::almost_complete_letter_range)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
+   |
+   = note: `-D renamed-and-removed-lints` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
 
 error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
   --> tests/ui/rename.rs:64:9
@@ -403,5 +397,5 @@ error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_e
 LL | #![warn(clippy::reverse_range_loop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges`
 
-error: aborting due to 67 previous errors
+error: aborting due to 66 previous errors
 
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed
index 2afe2f43325..f72b61b5f6c 100644
--- a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed
@@ -1,3 +1,4 @@
+#![allow(clippy::map_with_unused_argument_over_ranges)]
 #![warn(clippy::repeat_vec_with_capacity)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs
index 659f2a3953d..c0cc81f7843 100644
--- a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::map_with_unused_argument_over_ranges)]
 #![warn(clippy::repeat_vec_with_capacity)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
index cec9c6ea84a..43027c9cb89 100644
--- a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
@@ -1,5 +1,5 @@
 error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
-  --> tests/ui/repeat_vec_with_capacity.rs:5:9
+  --> tests/ui/repeat_vec_with_capacity.rs:6:9
    |
 LL |         vec![Vec::<()>::with_capacity(42); 123];
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL |         (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
    |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
-  --> tests/ui/repeat_vec_with_capacity.rs:11:9
+  --> tests/ui/repeat_vec_with_capacity.rs:12:9
    |
 LL |         vec![Vec::<()>::with_capacity(42); n];
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |         (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
    |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity
-  --> tests/ui/repeat_vec_with_capacity.rs:26:9
+  --> tests/ui/repeat_vec_with_capacity.rs:27:9
    |
 LL |         std::iter::repeat(Vec::<()>::with_capacity(42));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.fixed b/src/tools/clippy/tests/ui/semicolon_outside_block.fixed
index 148e112e0bc..ac7e86631ca 100644
--- a/src/tools/clippy/tests/ui/semicolon_outside_block.fixed
+++ b/src/tools/clippy/tests/ui/semicolon_outside_block.fixed
@@ -80,5 +80,13 @@ fn main() {
 
     { unit_fn_block(); };
 
+    unsafe {
+        std::arch::asm!("")
+    };
+
+    {
+        line!()
+    };
+
     unit_fn_block()
 }
diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.rs b/src/tools/clippy/tests/ui/semicolon_outside_block.rs
index c767201469a..68f25339e32 100644
--- a/src/tools/clippy/tests/ui/semicolon_outside_block.rs
+++ b/src/tools/clippy/tests/ui/semicolon_outside_block.rs
@@ -80,5 +80,13 @@ fn main() {
 
     { unit_fn_block(); };
 
+    unsafe {
+        std::arch::asm!("");
+    }
+
+    {
+        line!();
+    }
+
     unit_fn_block()
 }
diff --git a/src/tools/clippy/tests/ui/semicolon_outside_block.stderr b/src/tools/clippy/tests/ui/semicolon_outside_block.stderr
index 68b44c8f980..ff8c00048f6 100644
--- a/src/tools/clippy/tests/ui/semicolon_outside_block.stderr
+++ b/src/tools/clippy/tests/ui/semicolon_outside_block.stderr
@@ -51,5 +51,33 @@ LL -     { m!(()); }
 LL +     { m!(()) };
    |
 
-error: aborting due to 4 previous errors
+error: consider moving the `;` outside the block for consistent formatting
+  --> tests/ui/semicolon_outside_block.rs:83:5
+   |
+LL | /     unsafe {
+LL | |         std::arch::asm!("");
+LL | |     }
+   | |_____^
+   |
+help: put the `;` here
+   |
+LL ~         std::arch::asm!("")
+LL ~     };
+   |
+
+error: consider moving the `;` outside the block for consistent formatting
+  --> tests/ui/semicolon_outside_block.rs:87:5
+   |
+LL | /     {
+LL | |         line!();
+LL | |     }
+   | |_____^
+   |
+help: put the `;` here
+   |
+LL ~         line!()
+LL ~     };
+   |
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_map.rs b/src/tools/clippy/tests/ui/suspicious_map.rs
index d4247fcd926..d4a52cb110f 100644
--- a/src/tools/clippy/tests/ui/suspicious_map.rs
+++ b/src/tools/clippy/tests/ui/suspicious_map.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::map_with_unused_argument_over_ranges)]
 #![warn(clippy::suspicious_map)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/suspicious_map.stderr b/src/tools/clippy/tests/ui/suspicious_map.stderr
index 2a5e2bf2a34..769adebaede 100644
--- a/src/tools/clippy/tests/ui/suspicious_map.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_map.stderr
@@ -1,5 +1,5 @@
 error: this call to `map()` won't have an effect on the call to `count()`
-  --> tests/ui/suspicious_map.rs:4:13
+  --> tests/ui/suspicious_map.rs:5:13
    |
 LL |     let _ = (0..3).map(|x| x + 2).count();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     let _ = (0..3).map(|x| x + 2).count();
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]`
 
 error: this call to `map()` won't have an effect on the call to `count()`
-  --> tests/ui/suspicious_map.rs:8:13
+  --> tests/ui/suspicious_map.rs:9:13
    |
 LL |     let _ = (0..3).map(f).count();
    |             ^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_filter_map.rs b/src/tools/clippy/tests/ui/unnecessary_filter_map.rs
index 1e0d7d12965..8cf102ab0a5 100644
--- a/src/tools/clippy/tests/ui/unnecessary_filter_map.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_filter_map.rs
@@ -1,26 +1,31 @@
+//@no-rustfix
 #![allow(dead_code)]
 
 fn main() {
     let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });
-    //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
+    //~^ ERROR: this `.filter_map` can be written more simply
     //~| NOTE: `-D clippy::unnecessary-filter-map` implied by `-D warnings`
     let _ = (0..4).filter_map(|x| {
-        //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
+        //~^ ERROR: this `.filter_map` can be written more simply
         if x > 1 {
             return Some(x);
         };
         None
     });
     let _ = (0..4).filter_map(|x| match x {
-        //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
+        //~^ ERROR: this `.filter_map` can be written more simply
         0 | 1 => None,
         _ => Some(x),
     });
 
     let _ = (0..4).filter_map(|x| Some(x + 1));
-    //~^ ERROR: this `.filter_map` can be written more simply using `.map`
+    //~^ ERROR: this `.filter_map` can be written more simply
 
     let _ = (0..4).filter_map(i32::checked_abs);
+
+    let _ = (0..4).filter_map(Some);
+
+    let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
 }
 
 fn filter_map_none_changes_item_type() -> impl Iterator<Item = bool> {
diff --git a/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr b/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr
index f32d444ba9e..b21589c5f84 100644
--- a/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_filter_map.stderr
@@ -1,14 +1,14 @@
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:4:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:5:13
    |
 LL |     let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter`
    |
    = note: `-D clippy::unnecessary-filter-map` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]`
 
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:7:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:8:13
    |
 LL |       let _ = (0..4).filter_map(|x| {
    |  _____________^
@@ -18,10 +18,10 @@ LL | |             return Some(x);
 LL | |         };
 LL | |         None
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `filter`
 
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:14:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:15:13
    |
 LL |       let _ = (0..4).filter_map(|x| match x {
    |  _____________^
@@ -29,19 +29,40 @@ LL | |
 LL | |         0 | 1 => None,
 LL | |         _ => Some(x),
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `filter`
 
-error: this `.filter_map` can be written more simply using `.map`
-  --> tests/ui/unnecessary_filter_map.rs:20:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:21:13
    |
 LL |     let _ = (0..4).filter_map(|x| Some(x + 1));
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map`
 
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:160:14
+error: redundant closure
+  --> tests/ui/unnecessary_filter_map.rs:28:57
+   |
+LL |     let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
+   |                                                         ^^^^^^^^^^^ help: replace the closure with the function itself: `Some`
+   |
+   = note: `-D clippy::redundant-closure` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
+
+error: filter_map is unnecessary
+  --> tests/ui/unnecessary_filter_map.rs:28:61
+   |
+LL |     let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
+   |                                                             ^^^^ help: try removing the filter_map
+
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:28:13
+   |
+LL |     let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map`
+
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:165:14
    |
 LL |     let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n));
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter`
 
-error: aborting due to 5 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_find_map.rs b/src/tools/clippy/tests/ui/unnecessary_find_map.rs
index 9972b68092a..c357d853248 100644
--- a/src/tools/clippy/tests/ui/unnecessary_find_map.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_find_map.rs
@@ -1,24 +1,25 @@
+//@no-rustfix
 #![allow(dead_code)]
 
 fn main() {
     let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });
-    //~^ ERROR: this `.find_map` can be written more simply using `.find`
+    //~^ ERROR: this `.find_map` can be written more simply
     //~| NOTE: `-D clippy::unnecessary-find-map` implied by `-D warnings`
     let _ = (0..4).find_map(|x| {
-        //~^ ERROR: this `.find_map` can be written more simply using `.find`
+        //~^ ERROR: this `.find_map` can be written more simply
         if x > 1 {
             return Some(x);
         };
         None
     });
     let _ = (0..4).find_map(|x| match x {
-        //~^ ERROR: this `.find_map` can be written more simply using `.find`
+        //~^ ERROR: this `.find_map` can be written more simply
         0 | 1 => None,
         _ => Some(x),
     });
 
     let _ = (0..4).find_map(|x| Some(x + 1));
-    //~^ ERROR: this `.find_map` can be written more simply using `.map(..).next()`
+    //~^ ERROR: this `.find_map` can be written more simply
 
     let _ = (0..4).find_map(i32::checked_abs);
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_find_map.stderr b/src/tools/clippy/tests/ui/unnecessary_find_map.stderr
index bb939a99214..98a6c3d164a 100644
--- a/src/tools/clippy/tests/ui/unnecessary_find_map.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_find_map.stderr
@@ -1,14 +1,14 @@
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:4:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:5:13
    |
 LL |     let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find`
    |
    = note: `-D clippy::unnecessary-find-map` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]`
 
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:7:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:8:13
    |
 LL |       let _ = (0..4).find_map(|x| {
    |  _____________^
@@ -18,10 +18,10 @@ LL | |             return Some(x);
 LL | |         };
 LL | |         None
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `find`
 
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:14:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:15:13
    |
 LL |       let _ = (0..4).find_map(|x| match x {
    |  _____________^
@@ -29,19 +29,19 @@ LL | |
 LL | |         0 | 1 => None,
 LL | |         _ => Some(x),
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `find`
 
-error: this `.find_map` can be written more simply using `.map(..).next()`
-  --> tests/ui/unnecessary_find_map.rs:20:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:21:13
    |
 LL |     let _ = (0..4).find_map(|x| Some(x + 1));
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map(..).next()`
 
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:32:14
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:33:14
    |
 LL |     let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n));
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find`
 
 error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unused_io_amount.rs b/src/tools/clippy/tests/ui/unused_io_amount.rs
index f5b200d5ffe..175c4ca7689 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.rs
+++ b/src/tools/clippy/tests/ui/unused_io_amount.rs
@@ -277,4 +277,18 @@ fn allow_works<F: std::io::Read>(mut f: F) {
     f.read(&mut data).unwrap();
 }
 
+struct Reader {}
+
+impl Read for Reader {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        todo!()
+    }
+
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        // We shouldn't recommend using Read::read_exact inside Read::read_exact!
+        self.read(buf).unwrap();
+        Ok(())
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index cd9641eedd8..eadfd7107c7 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -21,13 +21,11 @@ new_pr = true
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
     "matthiaskrgr",
-    "giraffate",
 ]
 
 [assign.owners]
 "/.github" = ["@flip1995"]
 "/book" = ["@flip1995"]
-"/util/gh-pages" = ["@xFrednet"]
 "*" = [
     "@Manishearth",
     "@llogiq",
diff --git a/src/tools/clippy/util/gh-pages/index_template.html b/src/tools/clippy/util/gh-pages/index_template.html
index 2412f0fd181..deb0ef0b499 100644
--- a/src/tools/clippy/util/gh-pages/index_template.html
+++ b/src/tools/clippy/util/gh-pages/index_template.html
@@ -52,12 +52,12 @@ Otherwise, have a great day =^.^=
 
         <noscript> {# #}
             <div class="alert alert-danger" role="alert"> {# #}
-                Sorry, this site only works with JavaScript! :( {# #}
+                Lints search and filtering only works with JS enabled. :( {# #}
             </div> {# #}
         </noscript> {# #}
 
         <div> {# #}
-            <div class="panel panel-default"> {# #}
+            <div class="panel panel-default" id="menu-filters"> {# #}
                 <div class="panel-body row"> {# #}
                     <div id="upper-filters" class="col-12 col-md-5"> {# #}
                         <div class="btn-group" id="lint-levels" tabindex="-1"> {# #}
@@ -104,7 +104,7 @@ Otherwise, have a great day =^.^=
                                 <li role="separator" class="divider"></li> {# #}
                             </ul> {# #}
                         </div> {# #}
-                        <div class="btn-group", id="lint-applicabilities" tabindex="-1"> {# #}
+                        <div class="btn-group" id="lint-applicabilities" tabindex="-1"> {# #}
                             <button type="button" class="btn btn-default dropdown-toggle"> {# #}
                                 Applicability {#+ #}
                                 <span class="badge">4</span> {#+ #}
@@ -143,26 +143,29 @@ Otherwise, have a great day =^.^=
                 </div> {# #}
             </div>
             {% for lint in lints %}
-                <article class="panel panel-default collapsed" id="{{lint.id}}"> {# #}
-                    <header class="panel-heading" onclick="expandLint('{{lint.id}}')"> {# #}
-                        <h2 class="panel-title"> {# #}
-                            <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
-                                <span>{{lint.id}}</span> {#+ #}
-                                <a href="#{{lint.id}}" class="anchor label label-default" onclick="openLint(event)">&para;</a> {#+ #}
-                                <a href="" class="anchor label label-default" onclick="copyToClipboard(event)"> {# #}
-                                    &#128203; {# #}
-                                </a> {# #}
-                            </div> {# #}
+                <article class="panel panel-default" id="{{lint.id}}"> {# #}
+                    <input id="label-{{lint.id}}" type="checkbox"> {# #}
+                    <label for="label-{{lint.id}}" onclick="highlightIfNeeded('{{lint.id}}')"> {# #}
+                        <header class="panel-heading"> {# #}
+                            <h2 class="panel-title"> {# #}
+                                <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
+                                    <span>{{lint.id}}</span> {#+ #}
+                                    <a href="#{{lint.id}}" onclick="lintAnchor(event)" class="anchor label label-default">&para;</a> {#+ #}
+                                    <a href="" class="anchor label label-default" onclick="copyToClipboard(event)"> {# #}
+                                        &#128203; {# #}
+                                    </a> {# #}
+                                </div> {# #}
 
-                            <div class="panel-title-addons"> {# #}
-                                <span class="label label-lint-group label-default label-group-{{lint.group}}">{{lint.group}}</span> {#+ #}
+                                <div class="panel-title-addons"> {# #}
+                                    <span class="label label-lint-group label-default label-group-{{lint.group}}">{{lint.group}}</span> {#+ #}
 
-                                <span class="label label-lint-level label-lint-level-{{lint.level}}">{{lint.level}}</span> {#+ #}
+                                    <span class="label label-lint-level label-lint-level-{{lint.level}}">{{lint.level}}</span> {#+ #}
 
-                                <span class="label label-doc-folding">&plus;</span> {# #}
-                            </div> {# #}
-                        </h2> {# #}
-                    </header> {# #}
+                                    <span class="label label-doc-folding"></span> {# #}
+                                </div> {# #}
+                            </h2> {# #}
+                        </header> {# #}
+                    </label> {# #}
 
                     <div class="list-group lint-docs"> {# #}
                         <div class="list-group-item lint-doc-md">{{Self::markdown(lint.docs)}}</div> {# #}
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index cc22a39b3d1..9a5365b2158 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -138,25 +138,27 @@ function onEachLazy(lazyArray, func) {
     }
 }
 
-function highlightIfNeeded(elem) {
-    onEachLazy(elem.querySelectorAll("pre > code.language-rust:not(.highlighted)"), el => {
+function highlightIfNeeded(lintId) {
+    onEachLazy(document.querySelectorAll(`#${lintId} pre > code:not(.hljs)`), el => {
         hljs.highlightElement(el.parentElement)
         el.classList.add("highlighted");
     });
 }
 
 function expandLint(lintId) {
-    const lintElem = document.getElementById(lintId);
-    const isCollapsed = lintElem.classList.toggle("collapsed");
-    lintElem.querySelector(".label-doc-folding").innerText = isCollapsed ? "+" : "−";
-    highlightIfNeeded(lintElem);
+    const elem = document.querySelector(`#${lintId} > input[type="checkbox"]`);
+    elem.checked = true;
+    highlightIfNeeded(lintId);
 }
 
-// Show details for one lint
-function openLint(event) {
+function lintAnchor(event) {
     event.preventDefault();
     event.stopPropagation();
-    expandLint(event.target.getAttribute("href").slice(1));
+
+    const id = event.target.getAttribute("href").replace("#", "");
+    window.location.hash = id;
+
+    expandLint(id);
 }
 
 function copyToClipboard(event) {
@@ -520,7 +522,7 @@ function scrollToLint(lintId) {
 
 // If the page we arrive on has link to a given lint, we scroll to it.
 function scrollToLintByURL() {
-    const lintId = window.location.hash.substring(2);
+    const lintId = window.location.hash.substring(1);
     if (lintId.length > 0) {
         scrollToLint(lintId);
     }
diff --git a/src/tools/clippy/util/gh-pages/style.css b/src/tools/clippy/util/gh-pages/style.css
index a68a10b1401..896f2fdac76 100644
--- a/src/tools/clippy/util/gh-pages/style.css
+++ b/src/tools/clippy/util/gh-pages/style.css
@@ -204,7 +204,7 @@ details[open] {
 }
 
 /* Expanding the mdBook theme*/
-.light {
+.light, body:not([class]) {
     --inline-code-bg: #f6f7f6;
 }
 .rust {
@@ -220,6 +220,21 @@ details[open] {
     --inline-code-bg: #191f26;
 }
 
+@media (prefers-color-scheme: dark) {
+    body:not([class]) {
+        /*
+        In case JS is disabled and the user's system is in dark mode, we take "coal" as default
+        dark theme.
+        */
+        --inline-code-bg: #1d1f21;
+    }
+}
+
+html:not(.js) #settings-dropdown,
+html:not(.js)#menu-filters {
+    display: none;
+}
+
 #settings-dropdown {
     position: absolute;
     margin: 0.7em;
@@ -309,12 +324,12 @@ L4.75,12h2.5l0.5393066-2.1572876  c0.2276001-0.1062012,0.4459839-0.2269287,0.649
 .page-header {
     border-color: var(--theme-popup-border);
 }
-.panel-default > .panel-heading {
+.panel-default .panel-heading {
     background: var(--theme-hover);
     color: var(--fg);
     border: 1px solid var(--theme-popup-border);
 }
-.panel-default > .panel-heading:hover {
+.panel-default .panel-heading:hover {
     filter: brightness(90%);
 }
 .list-group-item {
@@ -410,9 +425,25 @@ body {
     color: var(--fg);
 }
 
-article.collapsed .lint-docs {
+article > label {
+    width: 100%;
+    margin: 0;
+}
+article > input[type="checkbox"] {
     display: none;
 }
+article > input[type="checkbox"] + label .label-doc-folding::before {
+    content: "+";
+}
+article > input[type="checkbox"]:checked + label .label-doc-folding::before {
+    content: "−";
+}
+.lint-docs {
+    display: none;
+}
+article > input[type="checkbox"]:checked ~ .lint-docs {
+    display: block;
+}
 
 .github-corner svg {
     fill: var(--fg);
diff --git a/src/tools/clippy/util/gh-pages/theme.js b/src/tools/clippy/util/gh-pages/theme.js
index bc296955ddf..90f57d4469d 100644
--- a/src/tools/clippy/util/gh-pages/theme.js
+++ b/src/tools/clippy/util/gh-pages/theme.js
@@ -45,6 +45,10 @@ function setTheme(theme, store) {
 }
 
 (function() {
+    // This file is loaded first. If so, we add the `js` class on the `<html>`
+    // element.
+    document.documentElement.classList.add("js");
+
     // loading the theme after the initial load
     const prefersDark = window.matchMedia("(prefers-color-scheme: dark)");
     const theme = loadValue("theme");