about summary refs log tree commit diff
path: root/src/tools/clippy
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy')
-rw-r--r--src/tools/clippy/.github/deploy.sh9
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml4
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml2
-rw-r--r--src/tools/clippy/CHANGELOG.md66
-rw-r--r--src/tools/clippy/Cargo.toml4
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md2
-rw-r--r--src/tools/clippy/clippy_config/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs6
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs7
-rw-r--r--src/tools/clippy/clippy_config/src/types.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/fmt.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/new_lint.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/serve.rs3
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs30
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/absolute_paths.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/almost_complete_range.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/assertions_on_constants.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs52
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/inline_always.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs101
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/utils.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/box_default.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/byte_char_slices.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs79
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/utils.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cfg_not_test.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/collection_is_never_read.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/comparison_chain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/copies.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/dbg_macro.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/default.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs73
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs342
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/link_with_quotes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/missing_headers.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs95
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_enum.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_clike.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_bools.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_nesting.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/fallible_impl_from.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/format_impl.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/format_push_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/from_str_radix_10.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/mod.rs62
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/ref_option.rs122
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/future_not_send.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs359
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/ineffective_open_options.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/instant_subtraction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/item_name_repetitions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/items_after_test_module.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_arrays.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs449
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_find.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/utils.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_clamp.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_div_ceil.rs158
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_hash_one.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs142
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs186
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_range_patterns.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_string_new.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/map_unit_fn.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_filter.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_utils.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/drain_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/err_expect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/inspect_for_each.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_filter.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_nth.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_clone.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_flatten.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_identity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs63
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/open_options.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/search_is_some.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_fallible_conversions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_first_then_check.rs56
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs66
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs45
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/useless_asref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/utils.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs186
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_assert_message.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_key.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_mut.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_for_each.rs6
-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.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_expressive_names.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs143
-rw-r--r--src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/option_if_let_else.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/panic_unimplemented.rs78
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/pointers_in_nomem_asm_block.rs88
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs114
-rw-r--r--src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/ranges.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_else.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/reference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/regex.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/set_contains_or_insert.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/single_component_path_imports.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/string_patterns.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/to_digit_is_some.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/box_collection.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs121
-rw-r--r--src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/type_complexity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/vec_box.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unconditional_recursion.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/uninhabited_references.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/uninit_vec.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.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.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_async.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_peekable.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_trait_names.rs94
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_unit.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap_in_result.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs4
-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/interning_defined_symbol.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/vec.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_init_then_push.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/visibility.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/zombie_processes.rs341
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs124
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs26
-rw-r--r--src/tools/clippy/clippy_utils/src/eager_or_lazy.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs64
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs96
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs16
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/possible_origin.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/ptr.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs82
-rw-r--r--src/tools/clippy/clippy_utils/src/str_utils.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs38
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs17
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs8
-rw-r--r--src/tools/clippy/declare_clippy_lint/Cargo.toml2
-rw-r--r--src/tools/clippy/declare_clippy_lint/src/lib.rs17
-rw-r--r--src/tools/clippy/lintcheck/src/driver.rs2
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs4
-rw-r--r--src/tools/clippy/lintcheck/src/recursive.rs2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/driver.rs65
-rw-r--r--src/tools/clippy/tests/compile-test.rs20
-rw-r--r--src/tools/clippy/tests/config-metadata.rs2
-rw-r--r--src/tools/clippy/tests/dogfood.rs49
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed4
-rw-r--r--src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs4
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed2
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr6
-rw-r--r--src/tools/clippy/tests/ui-toml/panic/panic.rs5
-rw-r--r--src/tools/clippy/tests/ui-toml/panic/panic.stderr10
-rw-r--r--src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs3
-rw-r--r--src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed1
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr2
-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_without_reason.rs1
-rw-r--r--src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr4
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.rs1
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.stderr246
-rw-r--r--src/tools/clippy/tests/ui/as_ptr_cast_mut.rs2
-rw-r--r--src/tools/clippy/tests/ui/asm_syntax_not_x86.rs3
-rw-r--r--src/tools/clippy/tests/ui/asm_syntax_x86.rs4
-rw-r--r--src/tools/clippy/tests/ui/asm_syntax_x86.stderr70
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/external_item.rs7
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs4
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs2
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs2
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macros.rs2
-rw-r--r--src/tools/clippy/tests/ui/borrow_box.fixed133
-rw-r--r--src/tools/clippy/tests/ui/borrow_box.rs20
-rw-r--r--src/tools/clippy/tests/ui/borrow_box.stderr14
-rw-r--r--src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs2
-rw-r--r--src/tools/clippy/tests/ui/boxed_local.rs3
-rw-r--r--src/tools/clippy/tests/ui/boxed_local.stderr8
-rw-r--r--src/tools/clippy/tests/ui/bytecount.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.rs8
-rw-r--r--src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs4
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.fixed5
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.rs5
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.stderr16
-rw-r--r--src/tools/clippy/tests/ui/comparison_to_empty.fixed8
-rw-r--r--src/tools/clippy/tests/ui/comparison_to_empty.rs8
-rw-r--r--src/tools/clippy/tests/ui/comparison_to_empty.stderr26
-rw-r--r--src/tools/clippy/tests/ui/crashes/associated-constant-ice.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/cc_seme.rs4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11230.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-1588.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-1969.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2499.rs6
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2594.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2727.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2760.rs8
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2862.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2865.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3151.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3462.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3747.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3969.rs4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6251.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6251.stderr4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-700.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7410.rs3
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice_exact_size.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/if_same_then_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/inherent_impl.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/issue-825.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/match_same_arms_const.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed2
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr20
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/returns.rs2
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs2
-rw-r--r--src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs2
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs2
-rw-r--r--src/tools/clippy/tests/ui/def_id_nocore.rs2
-rw-r--r--src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs4
-rw-r--r--src/tools/clippy/tests/ui/derive.rs7
-rw-r--r--src/tools/clippy/tests/ui/derive.stderr20
-rw-r--r--src/tools/clippy/tests/ui/diverging_sub_expression.rs6
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.fixed47
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.rs43
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.stderr56
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed9
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr27
-rw-r--r--src/tools/clippy/tests/ui/duplicate_underscore_argument.rs1
-rw-r--r--src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr2
-rw-r--r--src/tools/clippy/tests/ui/duplicated_attributes.rs4
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed135
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed144
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs147
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr176
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed108
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed111
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs119
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr116
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs132
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr37
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs120
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr54
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_no_std.rs2
-rw-r--r--src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs2
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed3
-rw-r--r--src/tools/clippy/tests/ui/eta.rs3
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr68
-rw-r--r--src/tools/clippy/tests/ui/exit1.rs2
-rw-r--r--src/tools/clippy/tests/ui/exit2.rs2
-rw-r--r--src/tools/clippy/tests/ui/exit3.rs2
-rw-r--r--src/tools/clippy/tests/ui/expect_fun_call.fixed2
-rw-r--r--src/tools/clippy/tests/ui/expect_fun_call.rs2
-rw-r--r--src/tools/clippy/tests/ui/expect_fun_call.stderr30
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.fixed3
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.rs3
-rw-r--r--src/tools/clippy/tests/ui/explicit_auto_deref.stderr92
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_lifetimes.rs8
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr8
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.rs2
-rw-r--r--src/tools/clippy/tests/ui/float_cmp.rs2
-rw-r--r--src/tools/clippy/tests/ui/float_cmp_const.rs3
-rw-r--r--src/tools/clippy/tests/ui/float_cmp_const.stderr16
-rw-r--r--src/tools/clippy/tests/ui/float_equality_without_abs.rs2
-rw-r--r--src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs2
-rw-r--r--src/tools/clippy/tests/ui/format_args.fixed2
-rw-r--r--src/tools/clippy/tests/ui/format_args.rs2
-rw-r--r--src/tools/clippy/tests/ui/format_args_unfixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.fixed1
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.rs1
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.stderr8
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.fixed4
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.rs4
-rw-r--r--src/tools/clippy/tests/ui/if_then_some_else_none.stderr8
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.fixed15
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.rs15
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.stderr18
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.fixed13
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.rs13
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.rs2
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs2
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed7
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs5
-rw-r--r--src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr36
-rw-r--r--src/tools/clippy/tests/ui/iter_without_into_iter.rs1
-rw-r--r--src/tools/clippy/tests/ui/iter_without_into_iter.stderr16
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants.fixed4
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants.rs4
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.fixed2
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports.rs2
-rw-r--r--src/tools/clippy/tests/ui/macro_use_imports_expect.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs35
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr75
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check.fixed24
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check.rs24
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check.stderr29
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil.fixed30
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil.rs30
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil.stderr35
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil_with_feature.fixed25
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil_with_feature.rs25
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil_with_feature.stderr47
-rw-r--r--src/tools/clippy/tests/ui/manual_is_power_of_two.fixed20
-rw-r--r--src/tools/clippy/tests/ui/manual_is_power_of_two.rs20
-rw-r--r--src/tools/clippy/tests/ui/manual_is_power_of_two.stderr41
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs24
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr22
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs50
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr64
-rw-r--r--src/tools/clippy/tests/ui/manual_range_patterns.fixed8
-rw-r--r--src/tools/clippy/tests/ui/manual_range_patterns.rs8
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_overlapping_arm.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_overlapping_arm.stderr32
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.fixed3
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.rs3
-rw-r--r--src/tools/clippy/tests/ui/mem_replace.stderr48
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_no_std.fixed3
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_no_std.rs3
-rw-r--r--src/tools/clippy/tests/ui/mem_replace_no_std.stderr14
-rw-r--r--src/tools/clippy/tests/ui/mismatching_type_param_order.rs2
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.rs3
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.stderr3
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.fixed2
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_key.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.fixed12
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.rs12
-rw-r--r--src/tools/clippy/tests/ui/mut_mutex_lock.stderr8
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr56
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.fixed23
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.rs21
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.stderr24
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.rs15
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.stderr70
-rw-r--r--src/tools/clippy/tests/ui/needless_return.fixed24
-rw-r--r--src/tools/clippy/tests/ui/needless_return.rs24
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr14
-rw-r--r--src/tools/clippy/tests/ui/new_without_default.fixed3
-rw-r--r--src/tools/clippy/tests/ui/new_without_default.rs3
-rw-r--r--src/tools/clippy/tests/ui/new_without_default.stderr18
-rw-r--r--src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed2
-rw-r--r--src/tools/clippy/tests/ui/non_octal_unix_permissions.rs2
-rw-r--r--src/tools/clippy/tests/ui/non_zero_suggestions.fixed65
-rw-r--r--src/tools/clippy/tests/ui/non_zero_suggestions.rs65
-rw-r--r--src/tools/clippy/tests/ui/non_zero_suggestions.stderr41
-rw-r--r--src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.rs23
-rw-r--r--src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.stderr23
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed62
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.rs62
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr110
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.rs9
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.stderr17
-rw-r--r--src/tools/clippy/tests/ui/panic_in_result_fn.rs9
-rw-r--r--src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.rs33
-rw-r--r--src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.stderr34
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.rs22
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.stderr14
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.fixed17
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.rs17
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.stderr42
-rw-r--r--src/tools/clippy/tests/ui/ref_as_ptr.fixed2
-rw-r--r--src/tools/clippy/tests/ui/ref_as_ptr.rs2
-rw-r--r--src/tools/clippy/tests/ui/ref_option/all/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui/ref_option/private/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option.all.fixed62
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr162
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option.private.fixed62
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr108
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option.rs62
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option_traits.all.stderr37
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option_traits.private.stderr21
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option_traits.rs37
-rw-r--r--src/tools/clippy/tests/ui/result_large_err.rs2
-rw-r--r--src/tools/clippy/tests/ui/serde.rs2
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs7
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr58
-rw-r--r--src/tools/clippy/tests/ui/single_call_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_match.fixed26
-rw-r--r--src/tools/clippy/tests/ui/single_match.rs44
-rw-r--r--src/tools/clippy/tests/ui/single_match.stderr67
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.fixed4
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.rs10
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr14
-rw-r--r--src/tools/clippy/tests/ui/str_split.fixed1
-rw-r--r--src/tools/clippy/tests/ui/str_split.rs1
-rw-r--r--src/tools/clippy/tests/ui/str_split.stderr20
-rw-r--r--src/tools/clippy/tests/ui/string_slice.rs6
-rw-r--r--src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_command_arg_space.rs1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr4
-rw-r--r--src/tools/clippy/tests/ui/suspicious_to_owned.rs2
-rw-r--r--src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed1
-rw-r--r--src/tools/clippy/tests/ui/tabs_in_doc_comments.rs1
-rw-r--r--src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr16
-rw-r--r--src/tools/clippy/tests/ui/temporary_assignment.rs2
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs10
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr28
-rw-r--r--src/tools/clippy/tests/ui/transmute_32bit.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_64bit.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_collection.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.fixed4
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.rs4
-rw-r--r--src/tools/clippy/tests/ui/transmute_undefined_repr.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed9
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs9
-rw-r--r--src/tools/clippy/tests/ui/unconditional_recursion.rs3
-rw-r--r--src/tools/clippy/tests/ui/unconditional_recursion.stderr90
-rw-r--r--src/tools/clippy/tests/ui/uninit_vec.rs32
-rw-r--r--src/tools/clippy/tests/ui/uninit_vec.stderr24
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_first_then_check.fixed22
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_first_then_check.rs22
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_first_then_check.stderr47
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_min_or_max.fixed29
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_min_or_max.rs29
-rw-r--r--src/tools/clippy/tests/ui/unsafe_removed_from_name.rs2
-rw-r--r--src/tools/clippy/tests/ui/unused_async.rs16
-rw-r--r--src/tools/clippy/tests/ui/unused_async.stderr4
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.1.fixed35
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.2.fixed35
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.rs (renamed from src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs)2
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.stderr (renamed from src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr)8
-rw-r--r--src/tools/clippy/tests/ui/unused_trait_names.fixed286
-rw-r--r--src/tools/clippy/tests/ui/unused_trait_names.rs286
-rw-r--r--src/tools/clippy/tests/ui/unused_trait_names.stderr73
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.stderr24
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_items.rs63
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_items.stderr112
-rw-r--r--src/tools/clippy/tests/ui/useful_asref.rs1
-rw-r--r--src/tools/clippy/tests/ui/wild_in_or_pats.rs68
-rw-r--r--src/tools/clippy/tests/ui/wild_in_or_pats.stderr18
-rw-r--r--src/tools/clippy/tests/ui/zombie_processes.rs145
-rw-r--r--src/tools/clippy/tests/ui/zombie_processes.stderr64
-rw-r--r--src/tools/clippy/tests/ui/zombie_processes_fixable.fixed26
-rw-r--r--src/tools/clippy/tests/ui/zombie_processes_fixable.rs26
-rw-r--r--src/tools/clippy/tests/ui/zombie_processes_fixable.stderr40
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/clippy/util/gh-pages/versions.html121
-rwxr-xr-xsrc/tools/clippy/util/versions.py42
680 files changed, 9971 insertions, 3494 deletions
diff --git a/src/tools/clippy/.github/deploy.sh b/src/tools/clippy/.github/deploy.sh
index d937661c0f8..5b4b4be4e36 100644
--- a/src/tools/clippy/.github/deploy.sh
+++ b/src/tools/clippy/.github/deploy.sh
@@ -25,16 +25,15 @@ if [[ $BETA = "true" ]]; then
 fi
 
 # Generate version index that is shown as root index page
-cp util/gh-pages/versions.html out/index.html
-
-echo "Making the versions.json file"
-python3 ./util/versions.py out
+python3 ./util/versions.py ./util/gh-pages/versions.html out
 
 # Now let's go have some fun with the cloned repo
 cd out
 git config user.name "GHA CI"
 git config user.email "gha@ci.invalid"
 
+git status
+
 if [[ -n $TAG_NAME ]]; then
   # track files, so that the following check works
   git add --intent-to-add "$TAG_NAME"
@@ -46,8 +45,6 @@ if [[ -n $TAG_NAME ]]; then
   git add "$TAG_NAME"
   # Update the symlink
   git add stable
-  # Update versions file
-  git add versions.json
   git commit -m "Add documentation for ${TAG_NAME} release: ${SHA}"
 elif [[ $BETA = "true" ]]; then
   if git diff --exit-code --quiet -- beta/; then
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index 2aa13313fa5..026771e6fcf 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -162,7 +162,7 @@ jobs:
         find $DIR ! -executable -o -type d ! -path $DIR | xargs rm -rf
 
     - name: Upload Binaries
-      uses: actions/upload-artifact@v3
+      uses: actions/upload-artifact@v4
       with:
         name: binaries
         path: target/debug
@@ -202,7 +202,7 @@ jobs:
 
     # Download
     - name: Download target dir
-      uses: actions/download-artifact@v3
+      uses: actions/download-artifact@v4
       with:
         name: binaries
         path: target/debug
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 348d52020fd..a1b011dc32d 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -19,7 +19,7 @@ jobs:
       uses: actions/checkout@v4
 
     - name: Setup Node.js
-      uses: actions/setup-node@v3
+      uses: actions/setup-node@v4
       with:
         node-version: '18.x'
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 9bc4ad9698d..5d253d52531 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,7 +6,61 @@ document.
 
 ## Unreleased / Beta / In Rust Nightly
 
-[c9139bd5...master](https://github.com/rust-lang/rust-clippy/compare/c9139bd5...master)
+[b794b8e0...master](https://github.com/rust-lang/rust-clippy/compare/b794b8e0...master)
+
+## Rust 1.81
+
+Current stable, released 2024-09-05
+
+### New Lints
+
+* Added [`cfg_not_test`] to `restriction`
+  [#11293](https://github.com/rust-lang/rust-clippy/pull/11293)
+* Added [`byte_char_slices`] to `style`
+  [#10155](https://github.com/rust-lang/rust-clippy/pull/10155)
+* Added [`set_contains_or_insert`] to `nursery`
+  [#12873](https://github.com/rust-lang/rust-clippy/pull/12873)
+* Added [`manual_rotate`] to `style`
+  [#12983](https://github.com/rust-lang/rust-clippy/pull/12983)
+* Added [`unnecessary_min_or_max`] to `complexity`
+  [#12368](https://github.com/rust-lang/rust-clippy/pull/12368)
+* Added [`manual_inspect`] to `complexity`
+  [#12287](https://github.com/rust-lang/rust-clippy/pull/12287)
+* Added [`field_scoped_visibility_modifiers`] to `restriction`
+  [#12893](https://github.com/rust-lang/rust-clippy/pull/12893)
+* Added [`manual_pattern_char_comparison`] to `style`
+  [#12849](https://github.com/rust-lang/rust-clippy/pull/12849)
+* Added [`needless_maybe_sized`] to `suspicious`
+  [#10632](https://github.com/rust-lang/rust-clippy/pull/10632)
+* Added [`needless_character_iteration`] to `suspicious`
+  [#12815](https://github.com/rust-lang/rust-clippy/pull/12815)
+
+### Moves and Deprecations
+
+* [`allow_attributes`], [`allow_attributes_without_reason`]: Now work on stable
+  [rust#120924](https://github.com/rust-lang/rust/pull/120924)
+* Renamed `overflow_check_conditional` to [`panicking_overflow_checks`]
+  [#12944](https://github.com/rust-lang/rust-clippy/pull/12944)
+* Moved [`panicking_overflow_checks`] to `correctness` (From `complexity` now deny-by-default)
+  [#12944](https://github.com/rust-lang/rust-clippy/pull/12944)
+* Renamed `thread_local_initializer_can_be_made_const` to [`missing_const_for_thread_local`]
+  [#12974](https://github.com/rust-lang/rust-clippy/pull/12974)
+* Deprecated [`maybe_misused_cfg`] and [`mismatched_target_os`] as they are now caught by cargo
+  and rustc
+  [#12875](https://github.com/rust-lang/rust-clippy/pull/12875)
+
+### Enhancements
+
+* [`significant_drop_in_scrutinee`]: Now also checks scrutinies of `while let` and `for let`
+  expressions
+  [#12870](https://github.com/rust-lang/rust-clippy/pull/12870)
+* [`std_instead_of_core`]: Now respects the `msrv` configuration
+  [#13168](https://github.com/rust-lang/rust-clippy/pull/13168)
+
+### ICE Fixes
+
+* [`suboptimal_flops`]: No longer crashes on custom `.log()` functions
+  [#12884](https://github.com/rust-lang/rust-clippy/pull/12884)
 
 ## Rust 1.80
 
@@ -5500,6 +5554,7 @@ Released 2018-09-13
 [`invalid_regex`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_regex
 [`invalid_upcast_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_upcast_comparisons
 [`invalid_utf8_in_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_utf8_in_unchecked
+[`inverted_saturating_sub`]: https://rust-lang.github.io/rust-clippy/master/index.html#inverted_saturating_sub
 [`invisible_characters`]: https://rust-lang.github.io/rust-clippy/master/index.html#invisible_characters
 [`is_digit_ascii_radix`]: https://rust-lang.github.io/rust-clippy/master/index.html#is_digit_ascii_radix
 [`items_after_statements`]: https://rust-lang.github.io/rust-clippy/master/index.html#items_after_statements
@@ -5559,6 +5614,7 @@ Released 2018-09-13
 [`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits
 [`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals
 [`manual_clamp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp
+[`manual_div_ceil`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_div_ceil
 [`manual_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter
 [`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map
 [`manual_find`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find
@@ -5570,6 +5626,7 @@ Released 2018-09-13
 [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check
 [`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite
 [`manual_is_infinite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_infinite
+[`manual_is_power_of_two`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_power_of_two
 [`manual_is_variant_and`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_variant_and
 [`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
 [`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str
@@ -5716,6 +5773,7 @@ Released 2018-09-13
 [`non_minimal_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_minimal_cfg
 [`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions
 [`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty
+[`non_zero_suggestions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_zero_suggestions
 [`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool
 [`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options
 [`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
@@ -5757,6 +5815,7 @@ Released 2018-09-13
 [`pathbuf_init_then_push`]: https://rust-lang.github.io/rust-clippy/master/index.html#pathbuf_init_then_push
 [`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch
 [`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false
+[`pointers_in_nomem_asm_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#pointers_in_nomem_asm_block
 [`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters
 [`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma
 [`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence
@@ -5812,6 +5871,7 @@ Released 2018-09-13
 [`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr
 [`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference
 [`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
+[`ref_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option
 [`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref
 [`ref_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_patterns
 [`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro
@@ -5962,6 +6022,7 @@ Released 2018-09-13
 [`unnecessary_fallible_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fallible_conversions
 [`unnecessary_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_filter_map
 [`unnecessary_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_find_map
+[`unnecessary_first_then_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_first_then_check
 [`unnecessary_fold`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_fold
 [`unnecessary_get_then_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_get_then_check
 [`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join
@@ -6003,6 +6064,7 @@ Released 2018-09-13
 [`unused_result_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_result_ok
 [`unused_rounding`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_rounding
 [`unused_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_self
+[`unused_trait_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names
 [`unused_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#unused_unit
 [`unusual_byte_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unusual_byte_groupings
 [`unwrap_in_result`]: https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_in_result
@@ -6013,6 +6075,7 @@ Released 2018-09-13
 [`use_debug`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_debug
 [`use_self`]: https://rust-lang.github.io/rust-clippy/master/index.html#use_self
 [`used_underscore_binding`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_binding
+[`used_underscore_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_items
 [`useless_asref`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_asref
 [`useless_attribute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_attribute
 [`useless_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
@@ -6047,6 +6110,7 @@ Released 2018-09-13
 [`zero_repeat_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_repeat_side_effects
 [`zero_sized_map_values`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_sized_map_values
 [`zero_width_space`]: https://rust-lang.github.io/rust-clippy/master/index.html#zero_width_space
+[`zombie_processes`]: https://rust-lang.github.io/rust-clippy/master/index.html#zombie_processes
 [`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
 <!-- end autogenerated links to lint list -->
 <!-- begin autogenerated links to configuration documentation -->
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index b48b881097f..cf810798d8c 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.1.82"
+version = "0.1.83"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
@@ -31,7 +31,7 @@ anstream = "0.6.0"
 
 [dev-dependencies]
 cargo_metadata = "0.18.1"
-ui_test = "0.25"
+ui_test = "0.26.4"
 regex = "1.5.5"
 serde = { version = "1.0.145", features = ["derive"] }
 serde_json = "1.0.122"
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 78348797588..07a56fb33df 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -353,6 +353,7 @@ Suppress lints whenever the suggested change would cause breakage for other crat
 * [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)
 * [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)
 * [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)
+* [`ref_option`](https://rust-lang.github.io/rust-clippy/master/index.html#ref_option)
 * [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn)
 * [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
 * [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
@@ -727,6 +728,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
 * [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations)
 * [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
+* [`unused_trait_names`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names)
 * [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
 
 
diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml
index 5c4e0761dbc..9da7112345d 100644
--- a/src/tools/clippy/clippy_config/Cargo.toml
+++ b/src/tools/clippy/clippy_config/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_config"
-version = "0.1.82"
+version = "0.1.83"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index a6f1b958bfb..e4e2c97fdc1 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -1,6 +1,6 @@
+use crate::ClippyConfiguration;
 use crate::msrvs::Msrv;
 use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename};
-use crate::ClippyConfiguration;
 use rustc_errors::Applicability;
 use rustc_session::Session;
 use rustc_span::edit_distance::edit_distance;
@@ -378,6 +378,7 @@ define_Conf! {
         rc_buffer,
         rc_mutex,
         redundant_allocation,
+        ref_option,
         single_call_fn,
         trivially_copy_pass_by_ref,
         unnecessary_box_returns,
@@ -563,6 +564,7 @@ define_Conf! {
         uninlined_format_args,
         unnecessary_lazy_evaluations,
         unnested_or_patterns,
+        unused_trait_names,
         use_self,
     )]
     msrv: Msrv = Msrv::empty(),
@@ -864,7 +866,7 @@ fn calculate_dimensions(fields: &[&str]) -> (usize, Vec<usize>) {
             cmp::max(1, terminal_width / (SEPARATOR_WIDTH + max_field_width))
         });
 
-    let rows = (fields.len() + (columns - 1)) / columns;
+    let rows = fields.len().div_ceil(columns);
 
     let column_widths = (0..columns)
         .map(|column| {
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index ac838cc81d2..c63d98a0a13 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -26,5 +26,5 @@ mod metadata;
 pub mod msrvs;
 pub mod types;
 
-pub use conf::{get_configuration_metadata, lookup_conf_file, Conf};
+pub use conf::{Conf, get_configuration_metadata, lookup_conf_file};
 pub use metadata::ClippyConfiguration;
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index a2b4b6e256f..68a3b11d384 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -1,7 +1,7 @@
 use rustc_ast::Attribute;
 use rustc_attr::parse_version;
 use rustc_session::{RustcVersion, Session};
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 use serde::Deserialize;
 use std::fmt;
 
@@ -19,10 +19,12 @@ macro_rules! msrv_aliases {
 msrv_aliases! {
     1,83,0 { CONST_EXTERN_FN }
     1,83,0 { CONST_FLOAT_BITS_CONV }
+    1,82,0 { IS_NONE_OR }
     1,81,0 { LINT_REASONS_STABILIZATION }
     1,80,0 { BOX_INTO_ITER}
     1,77,0 { C_STR_LITERALS }
     1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
+    1,73,0 { MANUAL_DIV_CEIL }
     1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
     1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }
     1,68,0 { PATH_MAIN_SEPARATOR_STR }
@@ -38,7 +40,7 @@ msrv_aliases! {
     1,52,0 { STR_SPLIT_ONCE, REM_EUCLID_CONST }
     1,51,0 { BORROW_AS_PTR, SEEK_FROM_CURRENT, UNSIGNED_ABS }
     1,50,0 { BOOL_THEN, CLAMP }
-    1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN }
+    1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN, SATURATING_SUB_CONST }
     1,46,0 { CONST_IF_MATCH }
     1,45,0 { STR_STRIP_PREFIX }
     1,43,0 { LOG2_10, LOG10_2, NUMERIC_ASSOCIATED_CONSTANTS }
@@ -50,6 +52,7 @@ msrv_aliases! {
     1,36,0 { ITERATOR_COPIED }
     1,35,0 { OPTION_COPIED, RANGE_CONTAINS }
     1,34,0 { TRY_FROM }
+    1,33,0 { UNDERSCORE_IMPORTS }
     1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES }
     1,29,0 { ITER_FLATTEN }
     1,28,0 { FROM_BOOL }
diff --git a/src/tools/clippy/clippy_config/src/types.rs b/src/tools/clippy/clippy_config/src/types.rs
index d47e34bb5bc..bab63911182 100644
--- a/src/tools/clippy/clippy_config/src/types.rs
+++ b/src/tools/clippy/clippy_config/src/types.rs
@@ -1,5 +1,5 @@
 use serde::de::{self, Deserializer, Visitor};
-use serde::{ser, Deserialize, Serialize};
+use serde::{Deserialize, Serialize, ser};
 use std::fmt;
 
 #[derive(Debug, Deserialize)]
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index 5fc4365c6e7..8c61c35533c 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -1,6 +1,6 @@
 use crate::clippy_project_root;
 use itertools::Itertools;
-use rustc_lexer::{tokenize, TokenKind};
+use rustc_lexer::{TokenKind, tokenize};
 use shell_escape::escape;
 use std::ffi::{OsStr, OsString};
 use std::ops::ControlFlow;
diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs
index 87117832fb9..5fd65017cfb 100644
--- a/src/tools/clippy/clippy_dev/src/new_lint.rs
+++ b/src/tools/clippy/clippy_dev/src/new_lint.rs
@@ -441,7 +441,7 @@ fn create_lint_for_ty(lint: &LintData<'_>, enable_msrv: bool, ty: &str) -> io::R
 
 #[allow(clippy::too_many_lines)]
 fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str> {
-    use super::update_lints::{match_tokens, LintDeclSearchResult};
+    use super::update_lints::{LintDeclSearchResult, match_tokens};
     use rustc_lexer::TokenKind;
 
     let lint_name_upper = lint.name.to_uppercase();
diff --git a/src/tools/clippy/clippy_dev/src/serve.rs b/src/tools/clippy/clippy_dev/src/serve.rs
index 19560b31fd3..cc14cd8dae6 100644
--- a/src/tools/clippy/clippy_dev/src/serve.rs
+++ b/src/tools/clippy/clippy_dev/src/serve.rs
@@ -29,7 +29,7 @@ pub fn run(port: u16, lint: Option<String>) -> ! {
         }
         if let Some(url) = url.take() {
             thread::spawn(move || {
-                Command::new(PYTHON)
+                let mut child = Command::new(PYTHON)
                     .arg("-m")
                     .arg("http.server")
                     .arg(port.to_string())
@@ -40,6 +40,7 @@ pub fn run(port: u16, lint: Option<String>) -> ! {
                 thread::sleep(Duration::from_millis(500));
                 // Launch browser after first export.py has completed and http.server is up
                 let _result = opener::open(url);
+                child.wait().unwrap();
             });
         }
         thread::sleep(Duration::from_millis(1000));
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index 8dbda1c634c..d6ed36d52f4 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -1,7 +1,7 @@
 use crate::clippy_project_root;
 use aho_corasick::AhoCorasickBuilder;
 use itertools::Itertools;
-use rustc_lexer::{tokenize, unescape, LiteralKind, TokenKind};
+use rustc_lexer::{LiteralKind, TokenKind, tokenize, unescape};
 use std::collections::{HashMap, HashSet};
 use std::ffi::OsStr;
 use std::fmt::{self, Write};
@@ -1048,23 +1048,17 @@ mod tests {
             Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
         ];
         let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
-        expected.insert(
-            "group1".to_string(),
-            vec![
-                Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
-                Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
-            ],
-        );
-        expected.insert(
-            "group2".to_string(),
-            vec![Lint::new(
-                "should_assert_eq2",
-                "group2",
-                "\"abc\"",
-                "module_name",
-                Range::default(),
-            )],
-        );
+        expected.insert("group1".to_string(), vec![
+            Lint::new("should_assert_eq", "group1", "\"abc\"", "module_name", Range::default()),
+            Lint::new("incorrect_match", "group1", "\"abc\"", "module_name", Range::default()),
+        ]);
+        expected.insert("group2".to_string(), vec![Lint::new(
+            "should_assert_eq2",
+            "group2",
+            "\"abc\"",
+            "module_name",
+            Range::default(),
+        )]);
         assert_eq!(expected, Lint::by_lint_group(lints.into_iter()));
     }
 }
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index fbd4566da58..d1188940b46 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_lints"
-version = "0.1.82"
+version = "0.1.83"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/clippy_lints/src/absolute_paths.rs b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
index c72b3f1318c..1af6d448a93 100644
--- a/src/tools/clippy/clippy_lints/src/absolute_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
@@ -3,12 +3,12 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_from_proc_macro;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc_hir::{HirId, ItemKind, Node, Path};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::kw;
 use rustc_span::Symbol;
+use rustc_span::symbol::kw;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
index 451bae95987..370f0c482fd 100644
--- a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
+++ b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{trim_span, walk_span_to_context};
 use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 56f5e903dc3..4f8f091a095 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -1,10 +1,10 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{impl_lint_pass, RustcVersion};
+use rustc_session::{RustcVersion, impl_lint_pass};
 use rustc_span::symbol;
 use std::f64::consts as f64;
 
diff --git a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
index 4eafa330faf..2643f850879 100644
--- a/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
+++ b/src/tools/clippy/clippy_lints/src/arc_with_non_send_sync.rs
@@ -4,8 +4,8 @@ use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
-use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::GenericArgKind;
+use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
 
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
index 7eaac80f969..b6684825835 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
@@ -1,7 +1,7 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_inside_always_const_context;
-use clippy_utils::macros::{find_assert_args, root_macro_call_first_node, PanicExpn};
+use clippy_utils::macros::{PanicExpn, find_assert_args, root_macro_call_first_node};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
index f1cb4a05af8..c073dee855e 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::macros::{find_assert_args, root_macro_call_first_node, PanicExpn};
+use clippy_utils::macros::{PanicExpn, find_assert_args, root_macro_call_first_node};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{has_debug_impl, is_copy, is_type_diagnostic_item};
 use clippy_utils::usage::local_used_after_expr;
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
index 55645d04eef..0b82c0cd04c 100644
--- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -1,7 +1,7 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::mir::{enclosing_mir, PossibleBorrowerMap};
+use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{is_diag_trait_item, is_in_test, last_path_segment, local_is_initialized, path_to_local};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
index 4ab97118df1..5d4e864b9b0 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
@@ -1,15 +1,15 @@
-use super::{Attribute, ALLOW_ATTRIBUTES_WITHOUT_REASON};
+use super::{ALLOW_ATTRIBUTES_WITHOUT_REASON, Attribute};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
-use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_ast::{MetaItemInner, MetaItemKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 use rustc_span::symbol::Symbol;
 
-pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) {
+pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[MetaItemInner], attr: &'cx Attribute) {
     // Check if the reason is present
-    if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
+    if let Some(item) = items.last().and_then(MetaItemInner::meta_item)
         && let MetaItemKind::NameValue(_) = &item.kind
         && item.path == sym::reason
     {
@@ -26,7 +26,7 @@ pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMet
         cx,
         ALLOW_ATTRIBUTES_WITHOUT_REASON,
         attr.span,
-        format!("`{}` attribute without specifying a reason", name.as_str()),
+        format!("`{name}` attribute without specifying a reason"),
         |diag| {
             diag.help("try adding a reason at the end with `, reason = \"..\"`");
         },
diff --git a/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs b/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
index 9b08fd6d654..0baf889faa0 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
@@ -1,12 +1,12 @@
-use super::utils::extract_clippy_lint;
 use super::BLANKET_CLIPPY_RESTRICTION_LINTS;
+use super::utils::extract_clippy_lint;
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
-use rustc_ast::NestedMetaItem;
+use rustc_ast::MetaItemInner;
 use rustc_lint::{LateContext, Level, LintContext};
 use rustc_span::symbol::Symbol;
-use rustc_span::{sym, DUMMY_SP};
+use rustc_span::{DUMMY_SP, sym};
 
-pub(super) fn check(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
+pub(super) fn check(cx: &LateContext<'_>, name: Symbol, items: &[MetaItemInner]) {
     for lint in items {
         if let Some(lint_name) = extract_clippy_lint(lint) {
             if lint_name.as_str() == "restriction" && name != sym::allow {
diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
index e872ab6b4b5..abf924f7542 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
@@ -1,4 +1,4 @@
-use super::{unnecessary_clippy_cfg, Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR};
+use super::{Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR, unnecessary_clippy_cfg};
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_ast::AttrStyle;
diff --git a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
index 40a1c4e2884..55f8e1072db 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::{Attribute, MetaItem};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::collections::hash_map::Entry;
 
 fn emit_if_duplicated(
@@ -36,7 +36,7 @@ fn check_duplicated_attr(
     }
     let Some(ident) = attr.ident() else { return };
     let name = ident.name;
-    if name == sym::doc || name == sym::cfg_attr || name == sym::rustc_on_unimplemented {
+    if name == sym::doc || name == sym::cfg_attr || name == sym::rustc_on_unimplemented || name == sym::reason {
         // FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg
         // conditions are the same.
         // `#[rustc_on_unimplemented]` contains duplicated subattributes, that's expected.
diff --git a/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
deleted file mode 100644
index 7ff644b4c44..00000000000
--- a/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::source::{is_present_in_source, without_block_comments, SpanRangeExt};
-use rustc_ast::{AttrKind, AttrStyle};
-use rustc_lint::EarlyContext;
-use rustc_span::Span;
-
-/// Check for empty lines after outer attributes.
-///
-/// Attributes and documentation comments are both considered outer attributes
-/// by the AST. However, the average user likely considers them to be different.
-/// Checking for empty lines after each of these attributes is split into two different
-/// lints but can share the same logic.
-pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
-    let mut iter = item.attrs.iter().peekable();
-    while let Some(attr) = iter.next() {
-        if (matches!(attr.kind, AttrKind::Normal(..)) || matches!(attr.kind, AttrKind::DocComment(..)))
-            && attr.style == AttrStyle::Outer
-            && is_present_in_source(cx, attr.span)
-        {
-            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
-            let end_of_attr_to_next_attr_or_item = Span::new(
-                attr.span.hi(),
-                iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
-                item.span.ctxt(),
-                item.span.parent(),
-            );
-
-            if let Some(snippet) = end_of_attr_to_next_attr_or_item.get_source_text(cx) {
-                let lines = snippet.split('\n').collect::<Vec<_>>();
-                let lines = without_block_comments(lines);
-
-                if lines.iter().filter(|l| l.trim().is_empty()).count() > 2 {
-                    let (lint_msg, lint_type) = match attr.kind {
-                        AttrKind::DocComment(..) => (
-                            "found an empty line after a doc comment. \
-                            Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?",
-                            EMPTY_LINE_AFTER_DOC_COMMENTS,
-                        ),
-                        AttrKind::Normal(..) => (
-                            "found an empty line after an outer attribute. \
-                            Perhaps you forgot to add a `!` to make it an inner attribute?",
-                            EMPTY_LINE_AFTER_OUTER_ATTR,
-                        ),
-                    };
-
-                    span_lint(cx, lint_type, begin_of_attr_to_item, lint_msg);
-                }
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
index 3b5b80ffefa..d41bb580c6c 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
@@ -1,10 +1,10 @@
-use super::utils::is_word;
 use super::INLINE_ALWAYS;
+use super::utils::is_word;
 use clippy_utils::diagnostics::span_lint;
 use rustc_ast::Attribute;
 use rustc_lint::LateContext;
 use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
     if span.from_expansion() {
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
index 3b14e9aee7f..1a34ca99fc2 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -4,7 +4,6 @@ mod blanket_clippy_restriction_lints;
 mod deprecated_cfg_attr;
 mod deprecated_semver;
 mod duplicated_attributes;
-mod empty_line_after;
 mod inline_always;
 mod mixed_attributes_style;
 mod non_minimal_cfg;
@@ -13,9 +12,9 @@ mod unnecessary_clippy_cfg;
 mod useless_attribute;
 mod utils;
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
-use rustc_ast::{Attribute, MetaItemKind, NestedMetaItem};
+use clippy_config::msrvs::{self, Msrv};
+use rustc_ast::{Attribute, MetaItemInner, MetaItemKind};
 use rustc_hir::{ImplItem, Item, ItemKind, TraitItem};
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
@@ -128,94 +127,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for empty lines after outer attributes
-    ///
-    /// ### Why is this bad?
-    /// Most likely the attribute was meant to be an inner attribute using a '!'.
-    /// If it was meant to be an outer attribute, then the following item
-    /// should not be separated by empty lines.
-    ///
-    /// ### Known problems
-    /// Can cause false positives.
-    ///
-    /// From the clippy side it's difficult to detect empty lines between an attributes and the
-    /// following item because empty lines and comments are not part of the AST. The parsing
-    /// currently works for basic cases but is not perfect.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[allow(dead_code)]
-    ///
-    /// fn not_quite_good_code() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// // Good (as inner attribute)
-    /// #![allow(dead_code)]
-    ///
-    /// fn this_is_fine() { }
-    ///
-    /// // or
-    ///
-    /// // Good (as outer attribute)
-    /// #[allow(dead_code)]
-    /// fn this_is_fine_too() { }
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub EMPTY_LINE_AFTER_OUTER_ATTR,
-    nursery,
-    "empty line after outer attribute"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for empty lines after documentation comments.
-    ///
-    /// ### Why is this bad?
-    /// The documentation comment was most likely meant to be an inner attribute or regular comment.
-    /// If it was intended to be a documentation comment, then the empty line should be removed to
-    /// be more idiomatic.
-    ///
-    /// ### Known problems
-    /// Only detects empty lines immediately following the documentation. If the doc comment is followed
-    /// by an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr`
-    /// in combination with this lint to detect both cases.
-    ///
-    /// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
-    ///
-    /// ### Example
-    /// ```no_run
-    /// /// Some doc comment with a blank line after it.
-    ///
-    /// fn not_quite_good_code() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// /// Good (no blank line)
-    /// fn this_is_fine() { }
-    /// ```
-    ///
-    /// ```no_run
-    /// // Good (convert to a regular comment)
-    ///
-    /// fn this_is_fine_too() { }
-    /// ```
-    ///
-    /// ```no_run
-    /// //! Good (convert to a comment on an inner attribute)
-    ///
-    /// fn this_is_fine_as_well() { }
-    /// ```
-    #[clippy::version = "1.70.0"]
-    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
-    nursery,
-    "empty line after documentation comments"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
     ///
     /// ### Why is this bad?
@@ -545,7 +456,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
                     return;
                 }
                 for item in items {
-                    if let NestedMetaItem::MetaItem(mi) = &item
+                    if let MetaItemInner::MetaItem(mi) = &item
                         && let MetaItemKind::NameValue(lit) = &mi.kind
                         && mi.has_name(sym::since)
                     {
@@ -601,18 +512,12 @@ impl EarlyAttributes {
 
 impl_lint_pass!(EarlyAttributes => [
     DEPRECATED_CFG_ATTR,
-    EMPTY_LINE_AFTER_OUTER_ATTR,
-    EMPTY_LINE_AFTER_DOC_COMMENTS,
     NON_MINIMAL_CFG,
     DEPRECATED_CLIPPY_CFG_ATTR,
     UNNECESSARY_CLIPPY_CFG,
 ]);
 
 impl EarlyLintPass for EarlyAttributes {
-    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
-        empty_line_after::check(cx, item);
-    }
-
     fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
         deprecated_cfg_attr::check(cx, attr, &self.msrv);
         deprecated_cfg_attr::check_clippy(cx, attr);
diff --git a/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
index 877025cce4c..7eff5eccfa1 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
@@ -1,7 +1,7 @@
 use super::{Attribute, NON_MINIMAL_CFG};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::SpanRangeExt;
-use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_ast::{MetaItemInner, MetaItemKind};
 use rustc_errors::Applicability;
 use rustc_lint::EarlyContext;
 use rustc_span::sym;
@@ -14,9 +14,9 @@ pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
     }
 }
 
-fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
+fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[MetaItemInner]) {
     for item in items {
-        if let NestedMetaItem::MetaItem(meta) = item {
+        if let MetaItemInner::MetaItem(meta) = item {
             if !meta.has_name(sym::any) && !meta.has_name(sym::all) {
                 continue;
             }
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 67ba605a59f..72e6ce59d59 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -1,8 +1,8 @@
 use super::utils::{extract_clippy_lint, is_lint_level, is_word};
 use super::{Attribute, USELESS_ATTRIBUTE};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{first_line_of_span, SpanRangeExt};
-use rustc_ast::NestedMetaItem;
+use clippy_utils::source::{SpanRangeExt, first_line_of_span};
+use rustc_ast::MetaItemInner;
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LintContext};
@@ -21,7 +21,7 @@ pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute])
                 for lint in lint_list {
                     match item.kind {
                         ItemKind::Use(..) => {
-                            if let NestedMetaItem::MetaItem(meta_item) = lint
+                            if let MetaItemInner::MetaItem(meta_item) = lint
                                 && meta_item.is_word()
                                 && let Some(ident) = meta_item.ident()
                                 && matches!(
@@ -51,6 +51,7 @@ pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute])
                                         | "module_name_repetitions"
                                         | "single_component_path_imports"
                                         | "disallowed_types"
+                                        | "unused_trait_names"
                                 )
                             }) {
                                 return;
diff --git a/src/tools/clippy/clippy_lints/src/attrs/utils.rs b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
index 91ae19acbf7..9b10ae83651 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
@@ -1,5 +1,5 @@
 use clippy_utils::macros::{is_panic, macro_backtrace};
-use rustc_ast::{AttrId, NestedMetaItem};
+use rustc_ast::{AttrId, MetaItemInner};
 use rustc_hir::{
     Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
 };
@@ -8,8 +8,8 @@ use rustc_middle::ty;
 use rustc_span::sym;
 use rustc_span::symbol::Symbol;
 
-pub(super) fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
-    if let NestedMetaItem::MetaItem(mi) = &nmi {
+pub(super) fn is_word(nmi: &MetaItemInner, expected: Symbol) -> bool {
+    if let MetaItemInner::MetaItem(mi) = &nmi {
         mi.is_word() && mi.has_name(expected)
     } else {
         false
@@ -74,7 +74,7 @@ fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>
 }
 
 /// Returns the lint name if it is clippy lint.
-pub(super) fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
+pub(super) fn extract_clippy_lint(lint: &MetaItemInner) -> Option<Symbol> {
     if let Some(meta_item) = lint.meta_item()
         && meta_item.path.segments.len() > 1
         && let tool_name = meta_item.path.segments[0].ident
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 d5f017b2650..9952d0af99e 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -7,7 +7,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::CoroutineLayout;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index e933fdf1d6e..26888f7e3a0 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -1,15 +1,17 @@
+use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::eq_expr_value;
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
+use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
 use rustc_lint::{LateContext, LateLintPass, Level};
-use rustc_session::declare_lint_pass;
+use rustc_session::{RustcVersion, impl_lint_pass};
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -69,9 +71,25 @@ declare_clippy_lint! {
 }
 
 // For each pairs, both orders are considered.
-const METHODS_WITH_NEGATION: [(&str, &str); 2] = [("is_some", "is_none"), ("is_err", "is_ok")];
+const METHODS_WITH_NEGATION: [(Option<RustcVersion>, &str, &str); 3] = [
+    (None, "is_some", "is_none"),
+    (None, "is_err", "is_ok"),
+    (Some(msrvs::IS_NONE_OR), "is_some_and", "is_none_or"),
+];
+
+pub struct NonminimalBool {
+    msrv: Msrv,
+}
+
+impl NonminimalBool {
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+        }
+    }
+}
 
-declare_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, OVERLY_COMPLEX_BOOL_EXPR]);
+impl_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, OVERLY_COMPLEX_BOOL_EXPR]);
 
 impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
     fn check_fn(
@@ -83,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
         _: Span,
         _: LocalDefId,
     ) {
-        NonminimalBoolVisitor { cx }.visit_body(body);
+        NonminimalBoolVisitor { cx, msrv: &self.msrv }.visit_body(body);
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
@@ -100,6 +118,8 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
             _ => {},
         }
     }
+
+    extract_msrv_attr!(LateContext);
 }
 
 fn inverted_bin_op_eq_str(op: BinOpKind) -> Option<&'static str> {
@@ -176,11 +196,11 @@ fn check_inverted_bool_in_condition(
     );
 }
 
-fn check_simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) {
+fn check_simplify_not(cx: &LateContext<'_>, msrv: &Msrv, expr: &Expr<'_>) {
     if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind
         && !expr.span.from_expansion()
         && !inner.span.from_expansion()
-        && let Some(suggestion) = simplify_not(cx, inner)
+        && let Some(suggestion) = simplify_not(cx, msrv, inner)
         && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
     {
         span_lint_and_sugg(
@@ -197,6 +217,7 @@ fn check_simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) {
 
 struct NonminimalBoolVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
+    msrv: &'a Msrv,
 }
 
 use quine_mc_cluskey::Bool;
@@ -205,7 +226,7 @@ struct Hir2Qmm<'a, 'tcx, 'v> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
+impl<'v> Hir2Qmm<'_, '_, 'v> {
     fn extract(&mut self, op: BinOpKind, a: &[&'v Expr<'_>], mut v: Vec<Bool>) -> Result<Vec<Bool>, String> {
         for a in a {
             if let ExprKind::Binary(binop, lhs, rhs) = &a.kind {
@@ -289,10 +310,11 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
 struct SuggestContext<'a, 'tcx, 'v> {
     terminals: &'v [&'v Expr<'v>],
     cx: &'a LateContext<'tcx>,
+    msrv: &'a Msrv,
     output: String,
 }
 
-impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
+impl SuggestContext<'_, '_, '_> {
     fn recurse(&mut self, suggestion: &Bool) -> Option<()> {
         use quine_mc_cluskey::Bool::{And, False, Not, Or, Term, True};
         match suggestion {
@@ -311,7 +333,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
                 },
                 Term(n) => {
                     let terminal = self.terminals[n as usize];
-                    if let Some(str) = simplify_not(self.cx, terminal) {
+                    if let Some(str) = simplify_not(self.cx, self.msrv, terminal) {
                         self.output.push_str(&str);
                     } else {
                         self.output.push('!');
@@ -358,7 +380,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
     }
 }
 
-fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
+fn simplify_not(cx: &LateContext<'_>, curr_msrv: &Msrv, expr: &Expr<'_>) -> Option<String> {
     match &expr.kind {
         ExprKind::Binary(binop, lhs, rhs) => {
             if !implements_ord(cx, lhs) {
@@ -389,7 +411,7 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
                 Some(format!("{lhs_snippet}{op}{rhs_snippet}"))
             })
         },
-        ExprKind::MethodCall(path, receiver, [], _) => {
+        ExprKind::MethodCall(path, receiver, args, _) => {
             let type_of_receiver = cx.typeck_results().expr_ty(receiver);
             if !is_type_diagnostic_item(cx, type_of_receiver, sym::Option)
                 && !is_type_diagnostic_item(cx, type_of_receiver, sym::Result)
@@ -399,21 +421,41 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
             METHODS_WITH_NEGATION
                 .iter()
                 .copied()
-                .flat_map(|(a, b)| vec![(a, b), (b, a)])
-                .find(|&(a, _)| {
-                    let path: &str = path.ident.name.as_str();
-                    a == path
+                .flat_map(|(msrv, a, b)| vec![(msrv, a, b), (msrv, b, a)])
+                .find(|&(msrv, a, _)| msrv.is_none_or(|msrv| curr_msrv.meets(msrv)) && a == path.ident.name.as_str())
+                .and_then(|(_, _, neg_method)| {
+                    let negated_args = args
+                        .iter()
+                        .map(|arg| simplify_not(cx, curr_msrv, arg))
+                        .collect::<Option<Vec<_>>>()?
+                        .join(", ");
+                    Some(format!(
+                        "{}.{neg_method}({negated_args})",
+                        receiver.span.get_source_text(cx)?
+                    ))
                 })
-                .and_then(|(_, neg_method)| Some(format!("{}.{neg_method}()", receiver.span.get_source_text(cx)?)))
         },
+        ExprKind::Closure(closure) => {
+            let body = cx.tcx.hir().body(closure.body);
+            let params = body
+                .params
+                .iter()
+                .map(|param| param.span.get_source_text(cx).map(|t| t.to_string()))
+                .collect::<Option<Vec<_>>>()?
+                .join(", ");
+            let negated = simplify_not(cx, curr_msrv, body.value)?;
+            Some(format!("|{params}| {negated}"))
+        },
+        ExprKind::Unary(UnOp::Not, expr) => expr.span.get_source_text(cx).map(|t| t.to_string()),
         _ => None,
     }
 }
 
-fn suggest(cx: &LateContext<'_>, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String {
+fn suggest(cx: &LateContext<'_>, msrv: &Msrv, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String {
     let mut suggest_context = SuggestContext {
         terminals,
         cx,
+        msrv,
         output: String::new(),
     };
     suggest_context.recurse(suggestion);
@@ -475,7 +517,7 @@ fn terminal_stats(b: &Bool) -> Stats {
     stats
 }
 
-impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
+impl<'tcx> NonminimalBoolVisitor<'_, 'tcx> {
     fn bool_expr(&self, e: &'tcx Expr<'_>) {
         let mut h2q = Hir2Qmm {
             terminals: Vec::new(),
@@ -526,7 +568,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
                                 diag.span_suggestion(
                                     e.span,
                                     "it would look like the following",
-                                    suggest(self.cx, suggestion, &h2q.terminals),
+                                    suggest(self.cx, self.msrv, suggestion, &h2q.terminals),
                                     // nonminimal_bool can produce minimal but
                                     // not human readable expressions (#3141)
                                     Applicability::Unspecified,
@@ -569,12 +611,12 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
                 }
             };
             if improvements.is_empty() {
-                check_simplify_not(self.cx, e);
+                check_simplify_not(self.cx, self.msrv, e);
             } else {
                 nonminimal_bool_lint(
                     improvements
                         .into_iter()
-                        .map(|suggestion| suggest(self.cx, suggestion, &h2q.terminals))
+                        .map(|suggestion| suggest(self.cx, self.msrv, suggestion, &h2q.terminals))
                         .collect(),
                 );
             }
@@ -582,7 +624,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
         if !e.span.from_expansion() {
             match &e.kind {
diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs
index 8459f051d3d..40d154c0bdf 100644
--- a/src/tools/clippy/clippy_lints/src/box_default.rs
+++ b/src/tools/clippy/clippy_lints/src/box_default.rs
@@ -4,7 +4,7 @@ use clippy_utils::ty::expr_sig;
 use clippy_utils::{is_default_equivalent, path_def_id};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::intravisit::{walk_ty, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_ty};
 use rustc_hir::{Block, Expr, ExprKind, LetStmt, Node, QPath, Ty, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -91,7 +91,7 @@ fn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>)
 #[derive(Default)]
 struct InferVisitor(bool);
 
-impl<'tcx> Visitor<'tcx> for InferVisitor {
+impl Visitor<'_> for InferVisitor {
     fn visit_ty(&mut self, t: &Ty<'_>) {
         self.0 |= matches!(t.kind, TyKind::Infer | TyKind::OpaqueDef(..) | TyKind::TraitObject(..));
         if !self.0 {
diff --git a/src/tools/clippy/clippy_lints/src/byte_char_slices.rs b/src/tools/clippy/clippy_lints/src/byte_char_slices.rs
index a9fe190f177..dd2620b0b9d 100644
--- a/src/tools/clippy/clippy_lints/src/byte_char_slices.rs
+++ b/src/tools/clippy/clippy_lints/src/byte_char_slices.rs
@@ -22,7 +22,7 @@ declare_clippy_lint! {
     /// ```ignore
     /// b"Hello"
     /// ```
-    #[clippy::version = "1.68.0"]
+    #[clippy::version = "1.81.0"]
     pub BYTE_CHAR_SLICES,
     style,
     "hard to read byte char slice"
diff --git a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
index fed0aa8b275..6714c053913 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
@@ -10,27 +10,27 @@ pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, ignore_publish: b
         // only run the lint if publish is `None` (`publish = true` or skipped entirely)
         // or if the vector isn't empty (`publish = ["something"]`)
         if package.publish.as_ref().filter(|publish| publish.is_empty()).is_none() || ignore_publish {
-            if is_empty_str(&package.description) {
+            if is_empty_str(package.description.as_ref()) {
                 missing_warning(cx, package, "package.description");
             }
 
-            if is_empty_str(&package.license) && is_empty_str(&package.license_file) {
+            if is_empty_str(package.license.as_ref()) && is_empty_str(package.license_file.as_ref()) {
                 missing_warning(cx, package, "either package.license or package.license_file");
             }
 
-            if is_empty_str(&package.repository) {
+            if is_empty_str(package.repository.as_ref()) {
                 missing_warning(cx, package, "package.repository");
             }
 
-            if is_empty_str(&package.readme) {
+            if is_empty_str(package.readme.as_ref()) {
                 missing_warning(cx, package, "package.readme");
             }
 
-            if is_empty_vec(&package.keywords) {
+            if is_empty_vec(package.keywords.as_ref()) {
                 missing_warning(cx, package, "package.keywords");
             }
 
-            if is_empty_vec(&package.categories) {
+            if is_empty_vec(package.categories.as_ref()) {
                 missing_warning(cx, package, "package.categories");
             }
         }
@@ -42,8 +42,8 @@ fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, fiel
     span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, message);
 }
 
-fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: &Option<T>) -> bool {
-    value.as_ref().map_or(true, |s| s.as_ref().is_empty())
+fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: Option<&T>) -> bool {
+    value.map_or(true, |s| s.as_ref().is_empty())
 }
 
 fn is_empty_vec(value: &[String]) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs b/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
index e924542fea2..ffd6c520c9a 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
@@ -2,7 +2,7 @@ use super::LINT_GROUPS_PRIORITY;
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_lint::{unerased_lint_store, LateContext};
+use rustc_lint::{LateContext, unerased_lint_store};
 use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
 use serde::{Deserialize, Serialize};
 use std::collections::BTreeMap;
diff --git a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
index b7256dd2eae..4dd51dcbc9a 100644
--- a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_no_std_crate;
 use clippy_utils::source::snippet_with_context;
+use clippy_utils::std_or_core;
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
@@ -16,8 +16,8 @@ pub(super) fn check<'tcx>(
 ) {
     if matches!(cast_to.kind, TyKind::Ptr(_))
         && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
+        && let Some(std_or_core) = std_or_core(cx)
     {
-        let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
         let macro_name = match mutability {
             Mutability::Not => "addr_of",
             Mutability::Mut => "addr_of_mut",
@@ -40,7 +40,7 @@ pub(super) fn check<'tcx>(
             expr.span,
             "borrow as raw pointer",
             "try",
-            format!("{core_or_std}::ptr::{macro_name}!({snip})"),
+            format!("{std_or_core}::ptr::{macro_name}!({snip})"),
             Applicability::MachineApplicable,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
index 346aed7e9f1..84a44b14dde 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -10,7 +10,7 @@ use rustc_lint::LateContext;
 use rustc_middle::ty::{self, FloatTy, Ty};
 use rustc_span::hygiene;
 
-use super::{utils, CAST_LOSSLESS};
+use super::{CAST_LOSSLESS, utils};
 
 pub(super) fn check(
     cx: &LateContext<'_>,
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 5708aae3f3e..40a1a9d1ce8 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::{self, FloatTy, Ty};
 use rustc_span::Span;
 use rustc_target::abi::IntegerType;
 
-use super::{utils, CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION};
+use super::{CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION, utils};
 
 fn constant_int(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<u128> {
     if let Some(Constant::Int(c)) = ConstEvalCtxt::new(cx).eval(expr) {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs
index 11274383595..3cf4a43b0d4 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs
@@ -3,7 +3,7 @@ use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
 
-use super::{utils, CAST_POSSIBLE_WRAP};
+use super::{CAST_POSSIBLE_WRAP, utils};
 
 // this should be kept in sync with the allowed bit widths of `usize` and `isize`
 const ALLOWED_POINTER_SIZES: [u64; 3] = [16, 32, 64];
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs b/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs
index 035666e4d4c..1eb115ce6bd 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs
@@ -4,7 +4,7 @@ use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, FloatTy, Ty};
 
-use super::{utils, CAST_PRECISION_LOSS};
+use super::{CAST_PRECISION_LOSS, utils};
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
     if !cast_from.is_integral() || cast_to.is_integral() {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs b/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
index 9daf237344a..4be53ace687 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
@@ -3,7 +3,7 @@ use std::ops::ControlFlow;
 
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::visitors::{for_each_expr_without_closures, Descend};
+use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
 use clippy_utils::{method_chain_args, sext};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
index dbe03e4ae80..ac1a355c8d9 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
@@ -5,7 +5,7 @@ use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty, UintTy};
 
-use super::{utils, FN_TO_NUMERIC_CAST};
+use super::{FN_TO_NUMERIC_CAST, utils};
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
     // We only want to check casts to `ty::Uint` or `ty::Int`
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
index dfbae1618ac..18e7798452e 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
@@ -5,7 +5,7 @@ use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty};
 
-use super::{utils, FN_TO_NUMERIC_CAST_WITH_TRUNCATION};
+use super::{FN_TO_NUMERIC_CAST_WITH_TRUNCATION, utils};
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
     // We only want to check casts to `ty::Uint` or `ty::Int`
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index c31716fbcee..3acd4eca420 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -23,8 +23,8 @@ mod unnecessary_cast;
 mod utils;
 mod zero_ptr;
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::is_hir_ty_cfg_dependant;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -410,19 +410,27 @@ declare_clippy_lint! {
     /// ### Why is this bad?
     /// Though `as` casts between raw pointers are not terrible, `pointer::cast_mut` and
     /// `pointer::cast_const` are safer because they cannot accidentally cast the pointer to another
-    /// type.
+    /// type. Or, when null pointers are involved, `null()` and `null_mut()` can be used directly.
     ///
     /// ### Example
     /// ```no_run
     /// let ptr: *const u32 = &42_u32;
     /// let mut_ptr = ptr as *mut u32;
     /// let ptr = mut_ptr as *const u32;
+    /// let ptr1 = std::ptr::null::<u32>() as *mut u32;
+    /// let ptr2 = std::ptr::null_mut::<u32>() as *const u32;
+    /// let ptr3 = std::ptr::null::<u32>().cast_mut();
+    /// let ptr4 = std::ptr::null_mut::<u32>().cast_const();
     /// ```
     /// Use instead:
     /// ```no_run
     /// let ptr: *const u32 = &42_u32;
     /// let mut_ptr = ptr.cast_mut();
     /// let ptr = mut_ptr.cast_const();
+    /// let ptr1 = std::ptr::null_mut::<u32>();
+    /// let ptr2 = std::ptr::null::<u32>();
+    /// let ptr3 = std::ptr::null_mut::<u32>();
+    /// let ptr4 = std::ptr::null::<u32>();
     /// ```
     #[clippy::version = "1.72.0"]
     pub PTR_CAST_CONSTNESS,
@@ -809,6 +817,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
         char_lit_as_u8::check(cx, expr);
         ptr_as_ptr::check(cx, expr, &self.msrv);
         cast_slice_different_sizes::check(cx, expr, &self.msrv);
+        ptr_cast_constness::check_null_ptr_cast_method(cx, expr);
     }
 
     extract_msrv_attr!(LateContext);
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
index 7513e18d408..7518dd2435a 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
@@ -1,10 +1,12 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::std_or_core;
 use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, Mutability};
+use rustc_hir::{Expr, ExprKind, Mutability, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
+use rustc_span::sym;
 
 use super::PTR_CAST_CONSTNESS;
 
@@ -16,8 +18,7 @@ pub(super) fn check<'tcx>(
     cast_to: Ty<'tcx>,
     msrv: &Msrv,
 ) {
-    if msrv.meets(msrvs::POINTER_CAST_CONSTNESS)
-        && let ty::RawPtr(from_ty, from_mutbl) = cast_from.kind()
+    if let ty::RawPtr(from_ty, from_mutbl) = cast_from.kind()
         && let ty::RawPtr(to_ty, to_mutbl) = cast_to.kind()
         && matches!(
             (from_mutbl, to_mutbl),
@@ -26,20 +27,74 @@ pub(super) fn check<'tcx>(
         && from_ty == to_ty
         && !from_ty.has_erased_regions()
     {
-        let sugg = Sugg::hir(cx, cast_expr, "_");
-        let constness = match *to_mutbl {
-            Mutability::Not => "const",
-            Mutability::Mut => "mut",
-        };
+        if let ExprKind::Call(func, []) = cast_expr.kind
+            && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
+            && let Some(defid) = path.res.opt_def_id()
+            && let Some(prefix) = std_or_core(cx)
+            && let mut app = Applicability::MachineApplicable
+            && let sugg = format!("{}", Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app))
+            && let Some((_, after_lt)) = sugg.split_once("::<")
+            && let Some((source, target, target_func)) = match cx.tcx.get_diagnostic_name(defid) {
+                Some(sym::ptr_null) => Some(("const", "mutable", "null_mut")),
+                Some(sym::ptr_null_mut) => Some(("mutable", "const", "null")),
+                _ => None,
+            }
+        {
+            span_lint_and_sugg(
+                cx,
+                PTR_CAST_CONSTNESS,
+                expr.span,
+                format!("`as` casting to make a {source} null pointer into a {target} null pointer"),
+                format!("use `{target_func}()` directly instead"),
+                format!("{prefix}::ptr::{target_func}::<{after_lt}"),
+                app,
+            );
+            return;
+        }
 
+        if msrv.meets(msrvs::POINTER_CAST_CONSTNESS) {
+            let sugg = Sugg::hir(cx, cast_expr, "_");
+            let constness = match *to_mutbl {
+                Mutability::Not => "const",
+                Mutability::Mut => "mut",
+            };
+
+            span_lint_and_sugg(
+                cx,
+                PTR_CAST_CONSTNESS,
+                expr.span,
+                "`as` casting between raw pointers while changing only its constness",
+                format!("try `pointer::cast_{constness}`, a safer alternative"),
+                format!("{}.cast_{constness}()", sugg.maybe_par()),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
+
+pub(super) fn check_null_ptr_cast_method(cx: &LateContext<'_>, expr: &Expr<'_>) {
+    if let ExprKind::MethodCall(method, cast_expr, [], _) = expr.kind
+        && let ExprKind::Call(func, []) = cast_expr.kind
+        && let ExprKind::Path(QPath::Resolved(None, path)) = func.kind
+        && let Some(defid) = path.res.opt_def_id()
+        && let method = match (cx.tcx.get_diagnostic_name(defid), method.ident.as_str()) {
+            (Some(sym::ptr_null), "cast_mut") => "null_mut",
+            (Some(sym::ptr_null_mut), "cast_const") => "null",
+            _ => return,
+        }
+        && let Some(prefix) = std_or_core(cx)
+        && let mut app = Applicability::MachineApplicable
+        && let sugg = format!("{}", Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app))
+        && let Some((_, after_lt)) = sugg.split_once("::<")
+    {
         span_lint_and_sugg(
             cx,
             PTR_CAST_CONSTNESS,
             expr.span,
-            "`as` casting between raw pointers while changing only its constness",
-            format!("try `pointer::cast_{constness}`, a safer alternative"),
-            format!("{}.cast_{constness}()", sugg.maybe_par()),
-            Applicability::MachineApplicable,
+            "changing constness of a null pointer",
+            format!("use `{method}()` directly instead"),
+            format!("{prefix}::ptr::{method}::<{after_lt}"),
+            app,
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
index 5f48b8bd206..f699bba20ed 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{expr_use_ctxt, is_no_std_crate, ExprUseNode};
+use clippy_utils::{ExprUseNode, expr_use_ctxt, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
@@ -25,8 +25,8 @@ pub(super) fn check<'tcx>(
         && let use_cx = expr_use_ctxt(cx, expr)
         // TODO: only block the lint if `cast_expr` is a temporary
         && !matches!(use_cx.use_node(cx), ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_))
+        && let Some(std_or_core) = std_or_core(cx)
     {
-        let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
         let fn_name = match to_mutbl {
             Mutability::Not => "from_ref",
             Mutability::Mut => "from_mut",
@@ -56,7 +56,7 @@ pub(super) fn check<'tcx>(
             expr.span,
             "reference as raw pointer",
             "try",
-            format!("{core_or_std}::ptr::{fn_name}{turbofish}({cast_expr_sugg})"),
+            format!("{std_or_core}::ptr::{fn_name}{turbofish}({cast_expr_sugg})"),
             app,
         );
     }
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 566adc83d69..811d33c8bde 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::numeric_literal::NumericLiteral;
-use clippy_utils::source::{snippet_opt, SpanRangeExt};
-use clippy_utils::visitors::{for_each_expr_without_closures, Visitable};
+use clippy_utils::source::{SpanRangeExt, snippet_opt};
+use clippy_utils::visitors::{Visitable, for_each_expr_without_closures};
 use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias, path_to_local};
 use rustc_ast::{LitFloatType, LitIntType, LitKind};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/casts/utils.rs b/src/tools/clippy/clippy_lints/src/casts/utils.rs
index 5a4f20f0990..5ccba92a0af 100644
--- a/src/tools/clippy/clippy_lints/src/casts/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/utils.rs
@@ -1,4 +1,4 @@
-use clippy_utils::ty::{read_explicit_enum_value, EnumValue};
+use clippy_utils::ty::{EnumValue, read_explicit_enum_value};
 use rustc_middle::ty::{self, AdtDef, IntTy, Ty, TyCtxt, UintTy, VariantDiscr};
 
 /// Returns the size in bits of an integral type.
diff --git a/src/tools/clippy/clippy_lints/src/cfg_not_test.rs b/src/tools/clippy/clippy_lints/src/cfg_not_test.rs
index d820c1e0720..84136a2e6c2 100644
--- a/src/tools/clippy/clippy_lints/src/cfg_not_test.rs
+++ b/src/tools/clippy/clippy_lints/src/cfg_not_test.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use rustc_ast::NestedMetaItem;
+use rustc_ast::MetaItemInner;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
 
@@ -22,7 +22,7 @@ declare_clippy_lint! {
     /// # fn important_check() {}
     /// important_check();
     /// ```
-    #[clippy::version = "1.73.0"]
+    #[clippy::version = "1.81.0"]
     pub CFG_NOT_TEST,
     restriction,
     "enforce against excluding code from test builds"
@@ -47,7 +47,7 @@ impl EarlyLintPass for CfgNotTest {
     }
 }
 
-fn contains_not_test(list: Option<&[NestedMetaItem]>, not: bool) -> bool {
+fn contains_not_test(list: Option<&[MetaItemInner]>, not: bool) -> bool {
     list.is_some_and(|list| {
         list.iter().any(|item| {
             item.ident().is_some_and(|ident| match ident.name {
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index dd7c34d1e46..2e7f91a842e 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -1,8 +1,8 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_in_const_context, is_integer_literal, SpanlessEq};
+use clippy_utils::{SpanlessEq, is_in_const_context, is_integer_literal};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -48,7 +48,7 @@ impl CheckedConversions {
 
 impl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
 
-impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
+impl LateLintPass<'_> for CheckedConversions {
     fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
         if let ExprKind::Binary(op, lhs, rhs) = item.kind
             && let (lt1, gt1, op2) = match op.node {
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 0099eefbc8d..495d8ce3fa7 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::source::{IntoSpan, SpanRangeExt};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::for_each_expr_without_closures;
-use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack};
+use clippy_utils::{LimitStack, get_async_fn_body, is_async_fn};
 use core::ops::ControlFlow;
 use rustc_ast::ast::Attribute;
 use rustc_hir::intravisit::FnKind;
@@ -11,7 +11,7 @@ use rustc_hir::{Body, Expr, ExprKind, FnDecl};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
index c6847411c75..8276e53648c 100644
--- a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
+++ b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
-use clippy_utils::visitors::{for_each_expr, Visitable};
+use clippy_utils::visitors::{Visitable, for_each_expr};
 use clippy_utils::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
 use rustc_hir::{Body, ExprKind, HirId, LangItem, LetStmt, Node, PatKind};
diff --git a/src/tools/clippy/clippy_lints/src/comparison_chain.rs b/src/tools/clippy/clippy_lints/src/comparison_chain.rs
index 5d78744e9b5..b9baf9af248 100644
--- a/src/tools/clippy/clippy_lints/src/comparison_chain.rs
+++ b/src/tools/clippy/clippy_lints/src/comparison_chain.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{if_sequence, is_else_clause, is_in_const_context, SpanlessEq};
+use clippy_utils::{SpanlessEq, if_sequence, is_else_clause, is_in_const_context};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs
index 86e0368c4e4..d90a22bb62a 100644
--- a/src/tools/clippy/clippy_lints/src/copies.rs
+++ b/src/tools/clippy/clippy_lints/src/copies.rs
@@ -1,16 +1,17 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then};
-use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, IntoSpan, SpanRangeExt};
-use clippy_utils::ty::{needs_ordered_drop, InteriorMut};
+use clippy_utils::source::{IntoSpan, SpanRangeExt, first_line_of_span, indent_of, reindent_multiline, snippet};
+use clippy_utils::ty::{InteriorMut, needs_ordered_drop};
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{
-    capture_local_usage, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, if_sequence,
-    is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq,
+    ContainsName, HirEqInterExpr, SpanlessEq, capture_local_usage, eq_expr_value, find_binding_init,
+    get_enclosing_block, hash_expr, hash_stmt, if_sequence, is_else_clause, is_lint_allowed, path_to_local,
+    search_same,
 };
 use core::iter;
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
-use rustc_hir::{intravisit, BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind};
+use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind, intravisit};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
index 678bdbc0ffb..c8f81413728 100644
--- a/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
+++ b/src/tools/clippy/clippy_lints/src/crate_in_macro_def.rs
@@ -5,8 +5,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
index 93c8fff05e9..a96c86f0765 100644
--- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs
+++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_in_test;
-use clippy_utils::macros::{macro_backtrace, MacroCall};
+use clippy_utils::macros::{MacroCall, macro_backtrace};
 use clippy_utils::source::snippet_with_applicability;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
@@ -9,7 +9,7 @@ use rustc_hir::{Expr, ExprKind, Node};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span, SyntaxContext};
+use rustc_span::{Span, SyntaxContext, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 60e51713173..9cec672beb0 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -49,8 +49,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::attrs::DEPRECATED_CLIPPY_CFG_ATTR_INFO,
     crate::attrs::DEPRECATED_SEMVER_INFO,
     crate::attrs::DUPLICATED_ATTRIBUTES_INFO,
-    crate::attrs::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
-    crate::attrs::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
     crate::attrs::INLINE_ALWAYS_INFO,
     crate::attrs::MIXED_ATTRIBUTES_STYLE_INFO,
     crate::attrs::NON_MINIMAL_CFG_INFO,
@@ -138,6 +136,8 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::doc::DOC_LINK_WITH_QUOTES_INFO,
     crate::doc::DOC_MARKDOWN_INFO,
     crate::doc::EMPTY_DOCS_INFO,
+    crate::doc::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
+    crate::doc::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
     crate::doc::MISSING_ERRORS_DOC_INFO,
     crate::doc::MISSING_PANICS_DOC_INFO,
     crate::doc::MISSING_SAFETY_DOC_INFO,
@@ -202,6 +202,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::functions::MUST_USE_CANDIDATE_INFO,
     crate::functions::MUST_USE_UNIT_INFO,
     crate::functions::NOT_UNSAFE_PTR_ARG_DEREF_INFO,
+    crate::functions::REF_OPTION_INFO,
     crate::functions::RENAMED_FUNCTION_PARAMS_INFO,
     crate::functions::RESULT_LARGE_ERR_INFO,
     crate::functions::RESULT_UNIT_ERR_INFO,
@@ -217,6 +218,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::implicit_return::IMPLICIT_RETURN_INFO,
     crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
     crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
+    crate::implicit_saturating_sub::INVERTED_SATURATING_SUB_INFO,
     crate::implied_bounds_in_impls::IMPLIED_BOUNDS_IN_IMPLS_INFO,
     crate::incompatible_msrv::INCOMPATIBLE_MSRV_INFO,
     crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
@@ -300,10 +302,12 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::manual_async_fn::MANUAL_ASYNC_FN_INFO,
     crate::manual_bits::MANUAL_BITS_INFO,
     crate::manual_clamp::MANUAL_CLAMP_INFO,
+    crate::manual_div_ceil::MANUAL_DIV_CEIL_INFO,
     crate::manual_float_methods::MANUAL_IS_FINITE_INFO,
     crate::manual_float_methods::MANUAL_IS_INFINITE_INFO,
     crate::manual_hash_one::MANUAL_HASH_ONE_INFO,
     crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO,
+    crate::manual_is_power_of_two::MANUAL_IS_POWER_OF_TWO_INFO,
     crate::manual_let_else::MANUAL_LET_ELSE_INFO,
     crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO,
     crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO,
@@ -464,6 +468,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::methods::UNNECESSARY_FALLIBLE_CONVERSIONS_INFO,
     crate::methods::UNNECESSARY_FILTER_MAP_INFO,
     crate::methods::UNNECESSARY_FIND_MAP_INFO,
+    crate::methods::UNNECESSARY_FIRST_THEN_CHECK_INFO,
     crate::methods::UNNECESSARY_FOLD_INFO,
     crate::methods::UNNECESSARY_GET_THEN_CHECK_INFO,
     crate::methods::UNNECESSARY_JOIN_INFO,
@@ -486,6 +491,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
     crate::misc::TOPLEVEL_REF_ARG_INFO,
     crate::misc::USED_UNDERSCORE_BINDING_INFO,
+    crate::misc::USED_UNDERSCORE_ITEMS_INFO,
     crate::misc_early::BUILTIN_TYPE_SHADOW_INFO,
     crate::misc_early::DOUBLE_NEG_INFO,
     crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO,
@@ -553,6 +559,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::non_expressive_names::SIMILAR_NAMES_INFO,
     crate::non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS_INFO,
     crate::non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY_INFO,
+    crate::non_zero_suggestions::NON_ZERO_SUGGESTIONS_INFO,
     crate::nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES_INFO,
     crate::octal_escapes::OCTAL_ESCAPES_INFO,
     crate::only_used_in_recursion::ONLY_USED_IN_RECURSION_INFO,
@@ -598,6 +605,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::pathbuf_init_then_push::PATHBUF_INIT_THEN_PUSH_INFO,
     crate::pattern_type_mismatch::PATTERN_TYPE_MISMATCH_INFO,
     crate::permissions_set_readonly_false::PERMISSIONS_SET_READONLY_FALSE_INFO,
+    crate::pointers_in_nomem_asm_block::POINTERS_IN_NOMEM_ASM_BLOCK_INFO,
     crate::precedence::PRECEDENCE_INFO,
     crate::ptr::CMP_NULL_INFO,
     crate::ptr::INVALID_NULL_PTR_USAGE_INFO,
@@ -741,6 +749,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::unused_result_ok::UNUSED_RESULT_OK_INFO,
     crate::unused_rounding::UNUSED_ROUNDING_INFO,
     crate::unused_self::UNUSED_SELF_INFO,
+    crate::unused_trait_names::UNUSED_TRAIT_NAMES_INFO,
     crate::unused_unit::UNUSED_UNIT_INFO,
     crate::unwrap::PANICKING_UNWRAP_INFO,
     crate::unwrap::UNNECESSARY_UNWRAP_INFO,
@@ -767,4 +776,5 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::zero_div_zero::ZERO_DIVIDED_BY_ZERO_INFO,
     crate::zero_repeat_side_effects::ZERO_REPEAT_SIDE_EFFECTS_INFO,
     crate::zero_sized_map_values::ZERO_SIZED_MAP_VALUES_INFO,
+    crate::zombie_processes::ZOMBIE_PROCESSES_INFO,
 ];
diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs
index 0b7279f2b36..dc10b64698b 100644
--- a/src/tools/clippy/clippy_lints/src/default.rs
+++ b/src/tools/clippy/clippy_lints/src/default.rs
@@ -11,7 +11,7 @@ use rustc_middle::ty;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs
index 13778175496..33a97222b8f 100644
--- a/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs
+++ b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_ty_alias;
-use hir::def::Res;
 use hir::ExprKind;
+use hir::def::Res;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
index ac49e6f1a48..056e39c02af 100644
--- a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
+++ b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
@@ -2,10 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::{last_path_segment, std_or_core};
 use rustc_errors::Applicability;
-use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind};
+use rustc_hir::{Expr, ExprKind, GenericArg, QPath, TyKind, def};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, SyntaxContext};
+use rustc_span::{SyntaxContext, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index 05c3cd3c814..4808c372754 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -3,7 +3,7 @@ use clippy_utils::numeric_literal;
 use clippy_utils::source::snippet_opt;
 use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_expr, walk_stmt, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr, walk_stmt};
 use rustc_hir::{Block, Body, ConstContext, Expr, ExprKind, FnRetTy, HirId, Lit, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -119,7 +119,7 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for NumericFallbackVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         match &expr.kind {
             ExprKind::Block(
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 0e55d3db469..f34f5e05606 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -3,14 +3,14 @@ use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
 use clippy_utils::ty::{implements_trait, is_manually_drop};
 use clippy_utils::{
-    expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local, peel_middle_ty_refs, DefinedTy,
-    ExprUseNode,
+    DefinedTy, ExprUseNode, expr_use_ctxt, get_parent_expr, is_block_like, is_lint_allowed, path_to_local,
+    peel_middle_ty_refs,
 };
 use core::mem;
 use rustc_ast::util::parser::{PREC_PREFIX, PREC_UNAMBIGUOUS};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_ty, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_ty};
 use rustc_hir::{
     self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat,
     PatKind, Path, QPath, TyKind, UnOp,
@@ -290,13 +290,10 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                             && let Some(ty) = use_node.defined_ty(cx)
                             && TyCoercionStability::for_defined_ty(cx, ty, use_node.is_return()).is_deref_stable()
                         {
-                            self.state = Some((
-                                State::ExplicitDeref { mutability: None },
-                                StateData {
-                                    first_expr: expr,
-                                    adjusted_ty,
-                                },
-                            ));
+                            self.state = Some((State::ExplicitDeref { mutability: None }, StateData {
+                                first_expr: expr,
+                                adjusted_ty,
+                            }));
                         }
                     },
                     RefOp::Method { mutbl, is_ufcs }
@@ -458,13 +455,10 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                             && next_adjust.map_or(true, |a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))
                             && iter.all(|a| matches!(a.kind, Adjust::Deref(_) | Adjust::Borrow(_)))
                         {
-                            self.state = Some((
-                                State::Borrow { mutability },
-                                StateData {
-                                    first_expr: expr,
-                                    adjusted_ty,
-                                },
-                            ));
+                            self.state = Some((State::Borrow { mutability }, StateData {
+                                first_expr: expr,
+                                adjusted_ty,
+                            }));
                         }
                     },
                     _ => {},
@@ -508,13 +502,10 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                 let stability = state.stability;
                 report(cx, expr, State::DerefedBorrow(state), data, typeck);
                 if stability.is_deref_stable() {
-                    self.state = Some((
-                        State::Borrow { mutability },
-                        StateData {
-                            first_expr: expr,
-                            adjusted_ty,
-                        },
-                    ));
+                    self.state = Some((State::Borrow { mutability }, StateData {
+                        first_expr: expr,
+                        adjusted_ty,
+                    }));
                 }
             },
             (Some((State::DerefedBorrow(state), data)), RefOp::Deref) => {
@@ -539,13 +530,10 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                 } else if stability.is_deref_stable()
                     && let Some(parent) = get_parent_expr(cx, expr)
                 {
-                    self.state = Some((
-                        State::ExplicitDeref { mutability: None },
-                        StateData {
-                            first_expr: parent,
-                            adjusted_ty,
-                        },
-                    ));
+                    self.state = Some((State::ExplicitDeref { mutability: None }, StateData {
+                        first_expr: parent,
+                        adjusted_ty,
+                    }));
                 }
             },
 
@@ -1138,20 +1126,17 @@ impl<'tcx> Dereferencing<'tcx> {
         if let Some(outer_pat) = self.ref_locals.get_mut(&local) {
             if let Some(pat) = outer_pat {
                 // Check for auto-deref
-                if !matches!(
-                    cx.typeck_results().expr_adjustments(e),
-                    [
-                        Adjustment {
-                            kind: Adjust::Deref(_),
-                            ..
-                        },
-                        Adjustment {
-                            kind: Adjust::Deref(_),
-                            ..
-                        },
+                if !matches!(cx.typeck_results().expr_adjustments(e), [
+                    Adjustment {
+                        kind: Adjust::Deref(_),
+                        ..
+                    },
+                    Adjustment {
+                        kind: Adjust::Deref(_),
                         ..
-                    ]
-                ) {
+                    },
+                    ..
+                ]) {
                     match get_parent_expr(cx, e) {
                         // Field accesses are the same no matter the number of references.
                         Some(Expr {
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index f27f68e2cbc..2920bbb4c81 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::indent_of;
 use clippy_utils::{is_default_equivalent, peel_blocks};
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 649c480fb92..82a66cc9202 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -3,7 +3,7 @@ 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};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
-use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
+use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item};
 use rustc_hir::{
     self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, Safety, UnsafeSource,
 };
@@ -15,7 +15,7 @@ use rustc_middle::ty::{
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -385,7 +385,7 @@ fn check_unsafe_derive_deserialize<'tcx>(
         && cx
             .tcx
             .inherent_impls(def.did())
-            .into_iter()
+            .iter()
             .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
             .any(|imp| has_unsafe(cx, imp))
     {
diff --git a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
new file mode 100644
index 00000000000..de7a2c2433f
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
@@ -0,0 +1,342 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::{SpanRangeExt, snippet_indent};
+use clippy_utils::tokenize_with_text;
+use itertools::Itertools;
+use rustc_ast::token::CommentKind;
+use rustc_ast::{AttrKind, AttrStyle, Attribute};
+use rustc_errors::{Applicability, Diag, SuggestionStyle};
+use rustc_hir::{ItemKind, Node};
+use rustc_lexer::TokenKind;
+use rustc_lint::LateContext;
+use rustc_span::{BytePos, ExpnKind, InnerSpan, Span, SpanData};
+
+use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
+
+#[derive(Debug, PartialEq, Clone, Copy)]
+enum StopKind {
+    Attr,
+    Doc(CommentKind),
+}
+
+impl StopKind {
+    fn is_doc(self) -> bool {
+        matches!(self, StopKind::Doc(_))
+    }
+}
+
+#[derive(Debug)]
+struct Stop {
+    span: Span,
+    kind: StopKind,
+    first: usize,
+    last: usize,
+}
+
+impl Stop {
+    fn convert_to_inner(&self) -> (Span, String) {
+        let inner = match self.kind {
+            // #|[...]
+            StopKind::Attr => InnerSpan::new(1, 1),
+            // /// or /**
+            //   ^      ^
+            StopKind::Doc(_) => InnerSpan::new(2, 3),
+        };
+        (self.span.from_inner(inner), "!".into())
+    }
+
+    fn comment_out(&self, cx: &LateContext<'_>, suggestions: &mut Vec<(Span, String)>) {
+        match self.kind {
+            StopKind::Attr => {
+                if cx.tcx.sess.source_map().is_multiline(self.span) {
+                    suggestions.extend([
+                        (self.span.shrink_to_lo(), "/* ".into()),
+                        (self.span.shrink_to_hi(), " */".into()),
+                    ]);
+                } else {
+                    suggestions.push((self.span.shrink_to_lo(), "// ".into()));
+                }
+            },
+            StopKind::Doc(CommentKind::Line) => suggestions.push((self.span.shrink_to_lo(), "// ".into())),
+            StopKind::Doc(CommentKind::Block) => {
+                // /** outer */  /*! inner */
+                //  ^             ^
+                let asterisk = self.span.from_inner(InnerSpan::new(1, 2));
+                suggestions.push((asterisk, String::new()));
+            },
+        }
+    }
+
+    fn from_attr(cx: &LateContext<'_>, attr: &Attribute) -> Option<Self> {
+        let SpanData { lo, hi, .. } = attr.span.data();
+        let file = cx.tcx.sess.source_map().lookup_source_file(lo);
+
+        Some(Self {
+            span: attr.span,
+            kind: match attr.kind {
+                AttrKind::Normal(_) => StopKind::Attr,
+                AttrKind::DocComment(comment_kind, _) => StopKind::Doc(comment_kind),
+            },
+            first: file.lookup_line(file.relative_position(lo))?,
+            last: file.lookup_line(file.relative_position(hi))?,
+        })
+    }
+}
+
+/// Represents a set of attrs/doc comments separated by 1 or more empty lines
+///
+/// ```ignore
+/// /// chunk 1 docs
+/// // not an empty line so also part of chunk 1
+/// #[chunk_1_attrs] // <-- prev_stop
+///
+/// /* gap */
+///
+/// /// chunk 2 docs // <-- next_stop
+/// #[chunk_2_attrs]
+/// ```
+struct Gap<'a> {
+    /// The span of individual empty lines including the newline at the end of the line
+    empty_lines: Vec<Span>,
+    has_comment: bool,
+    next_stop: &'a Stop,
+    prev_stop: &'a Stop,
+    /// The chunk that includes [`prev_stop`](Self::prev_stop)
+    prev_chunk: &'a [Stop],
+}
+
+impl<'a> Gap<'a> {
+    fn new(cx: &LateContext<'_>, prev_chunk: &'a [Stop], next_chunk: &'a [Stop]) -> Option<Self> {
+        let prev_stop = prev_chunk.last()?;
+        let next_stop = next_chunk.first()?;
+        let gap_span = prev_stop.span.between(next_stop.span);
+        let gap_snippet = gap_span.get_source_text(cx)?;
+
+        let mut has_comment = false;
+        let mut empty_lines = Vec::new();
+
+        for (token, source, inner_span) in tokenize_with_text(&gap_snippet) {
+            match token {
+                TokenKind::BlockComment {
+                    doc_style: None,
+                    terminated: true,
+                }
+                | TokenKind::LineComment { doc_style: None } => has_comment = true,
+                TokenKind::Whitespace => {
+                    let newlines = source.bytes().positions(|b| b == b'\n');
+                    empty_lines.extend(
+                        newlines
+                            .tuple_windows()
+                            .map(|(a, b)| InnerSpan::new(inner_span.start + a + 1, inner_span.start + b))
+                            .map(|inner_span| gap_span.from_inner(inner_span)),
+                    );
+                },
+                // Ignore cfg_attr'd out attributes as they may contain empty lines, could also be from macro
+                // shenanigans
+                _ => return None,
+            }
+        }
+
+        (!empty_lines.is_empty()).then_some(Self {
+            empty_lines,
+            has_comment,
+            next_stop,
+            prev_stop,
+            prev_chunk,
+        })
+    }
+
+    fn contiguous_empty_lines(&self) -> impl Iterator<Item = Span> + '_ {
+        self.empty_lines
+            // The `+ BytePos(1)` means "next line", because each empty line span is "N:1-N:1".
+            .chunk_by(|a, b| a.hi() + BytePos(1) == b.lo())
+            .map(|chunk| {
+                let first = chunk.first().expect("at least one empty line");
+                let last = chunk.last().expect("at least one empty line");
+                // The BytePos subtraction here is safe, as before an empty line, there must be at least one
+                // attribute/comment. The span needs to start at the end of the previous line.
+                first.with_lo(first.lo() - BytePos(1)).with_hi(last.hi())
+            })
+    }
+}
+
+/// If the node the attributes/docs apply to is the first in the module/crate suggest converting
+/// them to inner attributes/docs
+fn suggest_inner(cx: &LateContext<'_>, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>]) {
+    let Some(owner) = cx.last_node_with_lint_attrs.as_owner() else {
+        return;
+    };
+    let parent_desc = match cx.tcx.parent_hir_node(owner.into()) {
+        Node::Item(item)
+            if let ItemKind::Mod(parent_mod) = item.kind
+                && let [first, ..] = parent_mod.item_ids
+                && first.owner_id == owner =>
+        {
+            "parent module"
+        },
+        Node::Crate(crate_mod)
+            if let Some(first) = crate_mod
+                .item_ids
+                .iter()
+                .map(|&id| cx.tcx.hir().item(id))
+                // skip prelude imports
+                .find(|item| !matches!(item.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
+                && first.owner_id == owner =>
+        {
+            "crate"
+        },
+        _ => return,
+    };
+
+    diag.multipart_suggestion_verbose(
+        match kind {
+            StopKind::Attr => format!("if the attribute should apply to the {parent_desc} use an inner attribute"),
+            StopKind::Doc(_) => format!("if the comment should document the {parent_desc} use an inner doc comment"),
+        },
+        gaps.iter()
+            .flat_map(|gap| gap.prev_chunk)
+            .map(Stop::convert_to_inner)
+            .collect(),
+        Applicability::MaybeIncorrect,
+    );
+}
+
+fn check_gaps(cx: &LateContext<'_>, gaps: &[Gap<'_>]) -> bool {
+    let Some(first_gap) = gaps.first() else {
+        return false;
+    };
+    let empty_lines = || gaps.iter().flat_map(|gap| gap.empty_lines.iter().copied());
+    let contiguous_empty_lines = || gaps.iter().flat_map(Gap::contiguous_empty_lines);
+    let mut has_comment = false;
+    let mut has_attr = false;
+    for gap in gaps {
+        has_comment |= gap.has_comment;
+        if !has_attr {
+            has_attr = gap.prev_chunk.iter().any(|stop| stop.kind == StopKind::Attr);
+        }
+    }
+    let kind = first_gap.prev_stop.kind;
+    let (lint, kind_desc) = match kind {
+        StopKind::Attr => (EMPTY_LINE_AFTER_OUTER_ATTR, "outer attribute"),
+        StopKind::Doc(_) => (EMPTY_LINE_AFTER_DOC_COMMENTS, "doc comment"),
+    };
+    let (lines, are, them) = if empty_lines().nth(1).is_some() {
+        ("lines", "are", "them")
+    } else {
+        ("line", "is", "it")
+    };
+    span_lint_and_then(
+        cx,
+        lint,
+        first_gap.prev_stop.span.to(empty_lines().last().unwrap()),
+        format!("empty {lines} after {kind_desc}"),
+        |diag| {
+            if let Some(owner) = cx.last_node_with_lint_attrs.as_owner() {
+                let def_id = owner.to_def_id();
+                let def_descr = cx.tcx.def_descr(def_id);
+                diag.span_label(cx.tcx.def_span(def_id), match kind {
+                    StopKind::Attr => format!("the attribute applies to this {def_descr}"),
+                    StopKind::Doc(_) => format!("the comment documents this {def_descr}"),
+                });
+            }
+
+            diag.multipart_suggestion_with_style(
+                format!("if the empty {lines} {are} unintentional remove {them}"),
+                contiguous_empty_lines()
+                    .map(|empty_lines| (empty_lines, String::new()))
+                    .collect(),
+                Applicability::MaybeIncorrect,
+                SuggestionStyle::HideCodeAlways,
+            );
+
+            if has_comment && kind.is_doc() {
+                // Likely doc comments that applied to some now commented out code
+                //
+                // /// Old docs for Foo
+                // // struct Foo;
+
+                let mut suggestions = Vec::new();
+                for stop in gaps.iter().flat_map(|gap| gap.prev_chunk) {
+                    stop.comment_out(cx, &mut suggestions);
+                }
+                let name = match cx.tcx.hir().opt_name(cx.last_node_with_lint_attrs) {
+                    Some(name) => format!("`{name}`"),
+                    None => "this".into(),
+                };
+                diag.multipart_suggestion_verbose(
+                    format!("if the doc comment should not document {name} comment it out"),
+                    suggestions,
+                    Applicability::MaybeIncorrect,
+                );
+            } else {
+                suggest_inner(cx, diag, kind, gaps);
+            }
+
+            if kind == StopKind::Doc(CommentKind::Line)
+                && gaps
+                    .iter()
+                    .all(|gap| !gap.has_comment && gap.next_stop.kind == StopKind::Doc(CommentKind::Line))
+            {
+                // Commentless empty gaps between line doc comments, possibly intended to be part of the markdown
+
+                let indent = snippet_indent(cx, first_gap.prev_stop.span).unwrap_or_default();
+                diag.multipart_suggestion_verbose(
+                    format!("if the documentation should include the empty {lines} include {them} in the comment"),
+                    empty_lines()
+                        .map(|empty_line| (empty_line, format!("{indent}///")))
+                        .collect(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        },
+    );
+    kind.is_doc()
+}
+
+/// Returns `true` if [`EMPTY_LINE_AFTER_DOC_COMMENTS`] triggered, used to skip other doc comment
+/// lints where they would be confusing
+///
+/// [`EMPTY_LINE_AFTER_OUTER_ATTR`] is also here to share an implementation but does not return
+/// `true` if it triggers
+pub(super) fn check(cx: &LateContext<'_>, attrs: &[Attribute]) -> bool {
+    let mut outer = attrs
+        .iter()
+        .filter(|attr| attr.style == AttrStyle::Outer && !attr.span.from_expansion())
+        .map(|attr| Stop::from_attr(cx, attr))
+        .collect::<Option<Vec<_>>>()
+        .unwrap_or_default();
+
+    if outer.is_empty() {
+        return false;
+    }
+
+    // Push a fake attribute Stop for the item itself so we check for gaps between the last outer
+    // attr/doc comment and the item they apply to
+    let span = cx.tcx.hir().span(cx.last_node_with_lint_attrs);
+    if !span.from_expansion()
+        && let Ok(line) = cx.tcx.sess.source_map().lookup_line(span.lo())
+    {
+        outer.push(Stop {
+            span,
+            kind: StopKind::Attr,
+            first: line.line,
+            // last doesn't need to be accurate here, we don't compare it with anything
+            last: line.line,
+        });
+    }
+
+    let mut gaps = Vec::new();
+    let mut last = 0;
+    for pos in outer
+        .array_windows()
+        .positions(|[a, b]| b.first.saturating_sub(a.last) > 1)
+    {
+        // we want to be after the first stop in the window
+        let pos = pos + 1;
+        if let Some(gap) = Gap::new(cx, &outer[last..pos], &outer[pos..]) {
+            last = pos;
+            gaps.push(gap);
+        }
+    }
+
+    check_gaps(cx, &gaps)
+}
diff --git a/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs b/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
index 771bcac2441..f9e4a43c0e7 100644
--- a/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
@@ -22,7 +22,6 @@ pub(super) fn check(
     range: Range<usize>,
     mut span: Span,
     containers: &[super::Container],
-    line_break_span: Span,
 ) {
     if doc[range.clone()].contains('\t') {
         // We don't do tab stops correctly.
@@ -52,29 +51,6 @@ pub(super) fn check(
             "doc list item without indentation"
         };
         span_lint_and_then(cx, DOC_LAZY_CONTINUATION, span, msg, |diag| {
-            let snippet = clippy_utils::source::snippet(cx, line_break_span, "");
-            if snippet.chars().filter(|&c| c == '\n').count() > 1
-                && let Some(doc_comment_start) = snippet.rfind('\n')
-                && let doc_comment = snippet[doc_comment_start..].trim()
-                && (doc_comment == "///" || doc_comment == "//!")
-            {
-                // suggest filling in a blank line
-                diag.span_suggestion_verbose(
-                    line_break_span.shrink_to_lo(),
-                    "if this should be its own paragraph, add a blank doc comment line",
-                    format!("\n{doc_comment}"),
-                    Applicability::MaybeIncorrect,
-                );
-                if ccount > 0 || blockquote_level > 0 {
-                    diag.help("if this not intended to be a quote at all, escape it with `\\>`");
-                } else {
-                    let indent = list_indentation - lcount;
-                    diag.help(format!(
-                        "if this is intended to be part of the list, indent {indent} spaces"
-                    ));
-                }
-                return;
-            }
             if ccount == 0 && blockquote_level == 0 {
                 // simpler suggestion style for indentation
                 let indent = list_indentation - lcount;
diff --git a/src/tools/clippy/clippy_lints/src/doc/link_with_quotes.rs b/src/tools/clippy/clippy_lints/src/doc/link_with_quotes.rs
index 01191e811b0..1d4345e4541 100644
--- a/src/tools/clippy/clippy_lints/src/doc/link_with_quotes.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/link_with_quotes.rs
@@ -3,7 +3,7 @@ use std::ops::Range;
 use clippy_utils::diagnostics::span_lint;
 use rustc_lint::LateContext;
 
-use super::{Fragments, DOC_LINK_WITH_QUOTES};
+use super::{DOC_LINK_WITH_QUOTES, Fragments};
 
 pub fn check(cx: &LateContext<'_>, trimmed_text: &str, range: Range<usize>, fragments: Fragments<'_>) {
     if ((trimmed_text.starts_with('\'') && trimmed_text.ends_with('\''))
diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
index e3d74840726..c9173030a55 100644
--- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
@@ -5,7 +5,7 @@ use clippy_utils::{is_doc_hidden, return_ty};
 use rustc_hir::{BodyId, FnSig, OwnerId, Safety};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 pub fn check(
     cx: &LateContext<'_>,
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 790579b21c9..e090644ae44 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -23,15 +23,16 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_resolve::rustdoc::{
-    add_doc_fragment, attrs_to_doc_fragments, main_body_opts, source_span_for_markdown_range, span_of_fragments,
-    DocFragment,
+    DocFragment, add_doc_fragment, attrs_to_doc_fragments, main_body_opts, source_span_for_markdown_range,
+    span_of_fragments,
 };
 use rustc_session::impl_lint_pass;
 use rustc_span::edition::Edition;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::ops::Range;
 use url::Url;
 
+mod empty_line_after;
 mod link_with_quotes;
 mod markdown;
 mod missing_headers;
@@ -449,13 +450,88 @@ declare_clippy_lint! {
     /// /// and probably spanning a many rows.
     /// struct Foo {}
     /// ```
-    #[clippy::version = "1.81.0"]
+    #[clippy::version = "1.82.0"]
     pub TOO_LONG_FIRST_DOC_PARAGRAPH,
     style,
     "ensure that the first line of a documentation paragraph isn't too long"
 }
 
-#[derive(Clone)]
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after outer attributes
+    ///
+    /// ### Why is this bad?
+    /// The attribute may have meant to be an inner attribute (`#![attr]`). If
+    /// it was meant to be an outer attribute (`#[attr]`) then the empty line
+    /// should be removed
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[allow(dead_code)]
+    ///
+    /// fn not_quite_good_code() {}
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// // Good (as inner attribute)
+    /// #![allow(dead_code)]
+    ///
+    /// fn this_is_fine() {}
+    ///
+    /// // or
+    ///
+    /// // Good (as outer attribute)
+    /// #[allow(dead_code)]
+    /// fn this_is_fine_too() {}
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub EMPTY_LINE_AFTER_OUTER_ATTR,
+    suspicious,
+    "empty line after outer attribute"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after doc comments.
+    ///
+    /// ### Why is this bad?
+    /// The doc comment may have meant to be an inner doc comment, regular
+    /// comment or applied to some old code that is now commented out. If it was
+    /// intended to be a doc comment, then the empty line should be removed.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// /// Some doc comment with a blank line after it.
+    ///
+    /// fn f() {}
+    ///
+    /// /// Docs for `old_code`
+    /// // fn old_code() {}
+    ///
+    /// fn new_code() {}
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// //! Convert it to an inner doc comment
+    ///
+    /// // Or a regular comment
+    ///
+    /// /// Or remove the empty line
+    /// fn f() {}
+    ///
+    /// // /// Docs for `old_code`
+    /// // fn old_code() {}
+    ///
+    /// fn new_code() {}
+    /// ```
+    #[clippy::version = "1.70.0"]
+    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
+    suspicious,
+    "empty line after doc comments"
+}
+
 pub struct Documentation {
     valid_idents: FxHashSet<String>,
     check_private_items: bool,
@@ -482,6 +558,8 @@ impl_lint_pass!(Documentation => [
     SUSPICIOUS_DOC_COMMENTS,
     EMPTY_DOCS,
     DOC_LAZY_CONTINUATION,
+    EMPTY_LINE_AFTER_OUTER_ATTR,
+    EMPTY_LINE_AFTER_DOC_COMMENTS,
     TOO_LONG_FIRST_DOC_PARAGRAPH,
 ]);
 
@@ -612,12 +690,10 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
         Some(("fake".into(), "fake".into()))
     }
 
-    if is_doc_hidden(attrs) {
+    if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) {
         return None;
     }
 
-    suspicious_doc_comments::check(cx, attrs);
-
     let (fragments, _) = attrs_to_doc_fragments(
         attrs.iter().filter_map(|attr| {
             if in_external_macro(cx.sess(), attr.span) {
@@ -816,7 +892,6 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                         range.end..next_range.start,
                         Span::new(span.hi(), next_span.lo(), span.ctxt(), span.parent()),
                         &containers[..],
-                        span,
                     );
                 }
             },
@@ -895,7 +970,7 @@ impl<'a, 'tcx> FindPanicUnwrap<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
index c3e3c0431e6..9ba2723157a 100644
--- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs
@@ -13,7 +13,7 @@ use rustc_parse::parser::ForceCollect;
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
 use rustc_span::source_map::{FilePathMapping, SourceMap};
-use rustc_span::{sym, FileName, Pos};
+use rustc_span::{FileName, Pos, sym};
 
 use super::Fragments;
 
diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
index d7ad30efec3..f6f942b10ca 100644
--- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
@@ -7,7 +7,7 @@ use rustc_span::Span;
 
 use super::SUSPICIOUS_DOC_COMMENTS;
 
-pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
+pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) -> bool {
     let replacements: Vec<_> = collect_doc_replacements(attrs);
 
     if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) {
@@ -24,6 +24,10 @@ pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
                 );
             },
         );
+
+        true
+    } else {
+        false
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
index 7bb3bb12f2c..0165d24c7df 100644
--- a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
@@ -79,10 +79,17 @@ pub(super) fn check(
                 && let new_span = first_span.with_hi(second_span.lo()).with_lo(first_span.hi())
                 && let Some(snippet) = snippet_opt(cx, new_span)
             {
+                let Some(first) = snippet_opt(cx, first_span) else {
+                    return;
+                };
+                let Some(comment_form) = first.get(..3) else {
+                    return;
+                };
+
                 diag.span_suggestion(
                     new_span,
                     "add an empty line",
-                    format!("{snippet}///\n"),
+                    format!("{snippet}{comment_form}{snippet}"),
                     Applicability::MachineApplicable,
                 );
             }
diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs
index f4c55738cb8..70eb81fa09c 100644
--- a/src/tools/clippy/clippy_lints/src/empty_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs
@@ -60,7 +60,7 @@ declare_clippy_lint! {
 
 declare_lint_pass!(EmptyEnum => [EMPTY_ENUM]);
 
-impl<'tcx> LateLintPass<'tcx> for EmptyEnum {
+impl LateLintPass<'_> for EmptyEnum {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         if let ItemKind::Enum(..) = item.kind
             // Only suggest the `never_type` if the feature is enabled
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index 9c5100a8c1a..70524e458c7 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -1,17 +1,17 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context};
 use clippy_utils::{
-    can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified,
-    peel_hir_expr_while, SpanlessEq,
+    SpanlessEq, can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified,
+    peel_hir_expr_while,
 };
 use core::fmt::{self, Write};
 use rustc_errors::Applicability;
 use rustc_hir::hir_id::HirIdSet;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span, SyntaxContext, DUMMY_SP};
+use rustc_span::{DUMMY_SP, Span, SyntaxContext, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs
index 4755cefe784..e9e9d00907e 100644
--- a/src/tools/clippy/clippy_lints/src/enum_clike.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs
@@ -1,4 +1,4 @@
-use clippy_utils::consts::{mir_to_const, Constant};
+use clippy_utils::consts::{Constant, mir_to_const};
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 80360697941..a89f0d9c432 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -1,15 +1,15 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_hir;
-use rustc_hir::{intravisit, AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind};
+use rustc_hir::{AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind, intravisit};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
-use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
 pub struct BoxedLocal {
@@ -141,7 +141,7 @@ fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {
     matches!(tcx.parent_hir_node(id), Node::Param(_))
 }
 
-impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
+impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> {
     fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {
         if cmt.place.projections.is_empty() {
             if let PlaceBase::Local(lid) = cmt.place.base {
@@ -188,7 +188,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
     fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
-impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
+impl<'tcx> EscapeDelegate<'_, 'tcx> {
     fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
         // Large types need to be boxed to avoid stack overflows.
         if let Some(boxed_ty) = ty.boxed_ty() {
diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
index 8f469efb1b5..c88fb50b5af 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
@@ -5,8 +5,8 @@ use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl, Item, ItemKind, TraitFn, TraitItem, TraitItemKind, Ty};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
 use rustc_target::spec::abi::Abi;
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
index 5154edd4399..ffc76366983 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
@@ -2,7 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::source::snippet;
 use rustc_ast::node_id::NodeSet;
-use rustc_ast::visit::{walk_block, walk_item, Visitor};
+use rustc_ast::visit::{Visitor, walk_block, walk_item};
 use rustc_ast::{Block, Crate, Inline, Item, ItemKind, ModKind, NodeId};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -135,7 +135,7 @@ impl NestingVisitor<'_, '_> {
     }
 }
 
-impl<'conf, 'cx> Visitor<'_> for NestingVisitor<'conf, 'cx> {
+impl Visitor<'_> for NestingVisitor<'_, '_> {
     fn visit_block(&mut self, block: &Block) {
         if block.span.from_expansion() {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 3c4a043a732..5b423a96918 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::macros::{format_args_inputs_span, FormatArgsStorage};
+use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::{is_expn_of, path_def_id};
 use rustc_errors::Applicability;
@@ -7,7 +7,7 @@ use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Block, BlockCheckMode, Expr, ExprKind, Node, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, ExpnId};
+use rustc_span::{ExpnId, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index bfe4e253ae4..6ad879b9fe7 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -3,17 +3,17 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
 use clippy_utils::{is_from_proc_macro, trait_ref_of_method};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_impl_item, walk_item, walk_param_bound, walk_ty, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
 use rustc_hir::{
     BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
-    PredicateOrigin, Ty, TyKind, WherePredicate,
+    PredicateOrigin, Ty, WherePredicate,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::{DefId, LocalDefId};
 use rustc_span::Span;
+use rustc_span::def_id::{DefId, LocalDefId};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -193,18 +193,12 @@ fn bound_to_trait_def_id(bound: &GenericBound<'_>) -> Option<LocalDefId> {
     bound.trait_ref()?.trait_def_id()?.as_local()
 }
 
-impl<'cx, 'tcx> Visitor<'tcx> for TypeWalker<'cx, 'tcx> {
+impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
         if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
             self.ty_params.remove(&def_id);
-        } else if let TyKind::OpaqueDef(id, _, _) = t.kind {
-            // Explicitly walk OpaqueDef. Normally `walk_ty` would do the job, but it calls
-            // `visit_nested_item`, which checks that `Self::NestedFilter::INTER` is set. We're
-            // using `OnlyBodies`, so the check ends up failing and the type isn't fully walked.
-            let item = self.nested_visit_map().item(id);
-            walk_item(self, item);
         } else {
             walk_ty(self, t);
         }
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index 0446943321a..f822432cce6 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -6,7 +6,7 @@ use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -73,7 +73,7 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl
         result: Vec<Span>,
     }
 
-    impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> {
         fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
             if let Some(macro_call) = root_macro_call_first_node(self.lcx, expr) {
                 if is_panic(self.lcx, macro_call.def_id) {
diff --git a/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs b/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs
index 95b8e882da7..ba2b37fbf11 100644
--- a/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs
+++ b/src/tools/clippy/clippy_lints/src/field_scoped_visibility_modifiers.rs
@@ -41,7 +41,7 @@ declare_clippy_lint! {
     ///     }
     /// }
     /// ```
-    #[clippy::version = "1.78.0"]
+    #[clippy::version = "1.81.0"]
     pub FIELD_SCOPED_VISIBILITY_MODIFIERS,
     restriction,
     "checks for usage of a scoped visibility modifier, like `pub(crate)`, on fields"
diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
index bf4bcabfe89..8da6623f34d 100644
--- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
@@ -1,4 +1,4 @@
-use clippy_utils::consts::Constant::{Int, F32, F64};
+use clippy_utils::consts::Constant::{F32, F64, Int};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::{
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index 4dedff69b9a..5e3f6b6a137 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::macros::{find_format_arg_expr, root_macro_call_first_node, FormatArgsStorage};
-use clippy_utils::source::{snippet_with_context, SpanRangeExt};
+use clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, root_macro_call_first_node};
+use clippy_utils::source::{SpanRangeExt, snippet_with_context};
 use clippy_utils::sugg::Sugg;
 use rustc_ast::{FormatArgsPiece, FormatOptions, FormatTrait};
 use rustc_errors::Applicability;
@@ -8,7 +8,7 @@ use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 020c0c5440d..4c043f8dc14 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -1,11 +1,12 @@
 use arrayvec::ArrayVec;
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::is_diag_trait_item;
 use clippy_utils::macros::{
-    find_format_arg_expr, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, is_format_macro,
-    is_panic, matching_root_macro_call, root_macro_call_first_node, FormatArgsStorage, FormatParamUsage, MacroCall,
+    FormatArgsStorage, FormatParamUsage, MacroCall, find_format_arg_expr, format_arg_removal_span,
+    format_placeholder_format_span, is_assert_macro, is_format_macro, is_panic, matching_root_macro_call,
+    root_macro_call_first_node,
 };
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{implements_trait, is_type_lang_item};
@@ -18,11 +19,11 @@ use rustc_errors::Applicability;
 use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode};
 use rustc_hir::{Expr, ExprKind, LangItem};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::adjustment::{Adjust, Adjustment};
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::adjustment::{Adjust, Adjustment};
 use rustc_session::impl_lint_pass;
 use rustc_span::edition::Edition::Edition2021;
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{Span, Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -218,7 +219,7 @@ struct FormatArgsExpr<'a, 'tcx> {
     ignore_mixed: bool,
 }
 
-impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
+impl FormatArgsExpr<'_, '_> {
     fn check_templates(&self) {
         for piece in &self.format_args.template {
             if let FormatArgsPiece::Placeholder(placeholder) = piece
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index 7cd12ac7db8..7c0515b8c56 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
-use clippy_utils::macros::{find_format_arg_expr, is_format_macro, root_macro_call_first_node, FormatArgsStorage};
+use clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};
 use clippy_utils::{get_parent_as_impl, is_diag_trait_item, path_to_local, peel_ref_operators};
 use rustc_ast::{FormatArgsPiece, FormatTrait};
 use rustc_errors::Applicability;
@@ -7,7 +7,7 @@ use rustc_hir::{Expr, ExprKind, Impl, ImplItem, ImplItemKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -148,7 +148,7 @@ struct FormatImplExpr<'a, 'tcx> {
     format_trait_impl: FormatTraitNames,
 }
 
-impl<'a, 'tcx> FormatImplExpr<'a, 'tcx> {
+impl FormatImplExpr<'_, '_> {
     fn check_to_string_in_display(&self) {
         if self.format_trait_impl.name == sym::Display
             && let ExprKind::MethodCall(path, self_arg, ..) = self.expr.kind
diff --git a/src/tools/clippy/clippy_lints/src/format_push_string.rs b/src/tools/clippy/clippy_lints/src/format_push_string.rs
index c6f03c3a7cf..8b1f86cbb91 100644
--- a/src/tools/clippy/clippy_lints/src/format_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/format_push_string.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::ty::is_type_lang_item;
 use clippy_utils::higher;
+use clippy_utils::ty::is_type_lang_item;
 use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
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 b84bf7c821c..d5a2e06863d 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -1,11 +1,11 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::span_is_local;
 use clippy_utils::path_def_id;
 use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_path, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_path};
 use rustc_hir::{
     FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path,
     PathSegment, Ty, TyKind,
@@ -126,7 +126,7 @@ struct SelfFinder<'a, 'tcx> {
     invalid: bool,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SelfFinder<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SelfFinder<'_, 'tcx> {
     type NestedFilter = OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
diff --git a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
index e5fa67d6964..7361546153c 100644
--- a/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
+++ b/src/tools/clippy/clippy_lints/src/from_str_radix_10.rs
@@ -3,7 +3,7 @@ use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::{is_in_const_context, is_integer_literal};
 use rustc_errors::Applicability;
-use rustc_hir::{def, Expr, ExprKind, LangItem, PrimTy, QPath, TyKind};
+use rustc_hir::{Expr, ExprKind, LangItem, PrimTy, QPath, TyKind, def};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs
index 0f48941783b..91d73c2a9c9 100644
--- a/src/tools/clippy/clippy_lints/src/functions/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs
@@ -2,6 +2,7 @@ mod impl_trait_in_params;
 mod misnamed_getters;
 mod must_use;
 mod not_unsafe_ptr_arg_deref;
+mod ref_option;
 mod renamed_function_params;
 mod result;
 mod too_many_arguments;
@@ -14,8 +15,8 @@ use rustc_hir::intravisit;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::{DefIdSet, LocalDefId};
 use rustc_span::Span;
+use rustc_span::def_id::{DefIdSet, LocalDefId};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -399,6 +400,53 @@ declare_clippy_lint! {
     "renamed function parameters in trait implementation"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Warns when a function signature uses `&Option<T>` instead of `Option<&T>`.
+    ///
+    /// ### Why is this bad?
+    /// More flexibility, better memory optimization, and more idiomatic Rust code.
+    ///
+    /// `&Option<T>` in a function signature breaks encapsulation because the caller must own T
+    /// and move it into an Option to call with it. When returned, the owner must internally store
+    /// it as `Option<T>` in order to return it.
+    /// At a lower level, `&Option<T>` points to memory with the `presence` bit flag plus the `T` value,
+    /// whereas `Option<&T>` is usually [optimized](https://doc.rust-lang.org/1.81.0/std/option/index.html#representation)
+    /// to a single pointer, so it may be more optimal.
+    ///
+    /// See this [YouTube video](https://www.youtube.com/watch?v=6c7pZYP_iIE) by
+    /// Logan Smith for an in-depth explanation of why this is important.
+    ///
+    /// ### Known problems
+    /// This lint recommends changing the function signatures, but it cannot
+    /// automatically change the function calls or the function implementations.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// // caller uses  foo(&opt)
+    /// fn foo(a: &Option<String>) {}
+    /// # struct Unit {}
+    /// # impl Unit {
+    /// fn bar(&self) -> &Option<String> { &None }
+    /// # }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// // caller should use  `foo1(opt.as_ref())`
+    /// fn foo1(a: Option<&String>) {}
+    /// // better yet, use string slice  `foo2(opt.as_deref())`
+    /// fn foo2(a: Option<&str>) {}
+    /// # struct Unit {}
+    /// # impl Unit {
+    /// fn bar(&self) -> Option<&String> { None }
+    /// # }
+    /// ```
+    #[clippy::version = "1.82.0"]
+    pub REF_OPTION,
+    pedantic,
+    "function signature uses `&Option<T>` instead of `Option<&T>`"
+}
+
 pub struct Functions {
     too_many_arguments_threshold: u64,
     too_many_lines_threshold: u64,
@@ -437,6 +485,7 @@ impl_lint_pass!(Functions => [
     MISNAMED_GETTERS,
     IMPL_TRAIT_IN_PARAMS,
     RENAMED_FUNCTION_PARAMS,
+    REF_OPTION,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Functions {
@@ -455,6 +504,16 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
         not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, def_id);
         misnamed_getters::check_fn(cx, kind, decl, body, span);
         impl_trait_in_params::check_fn(cx, &kind, body, hir_id);
+        ref_option::check_fn(
+            cx,
+            kind,
+            decl,
+            span,
+            hir_id,
+            def_id,
+            body,
+            self.avoid_breaking_exported_api,
+        );
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
@@ -475,5 +534,6 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
         must_use::check_trait_item(cx, item);
         result::check_trait_item(cx, item, self.large_error_threshold);
         impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api);
+        ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api);
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index 93828121047..cfd11e9339f 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -8,7 +8,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use clippy_utils::attrs::is_proc_macro;
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index 1aeefe73cf6..c2b40ae01d4 100644
--- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -1,4 +1,4 @@
-use rustc_hir::{self as hir, intravisit, HirId, HirIdSet};
+use rustc_hir::{self as hir, HirId, HirIdSet, intravisit};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::def_id::LocalDefId;
diff --git a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs
new file mode 100644
index 00000000000..373ecd74cb3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs
@@ -0,0 +1,122 @@
+use crate::functions::REF_OPTION;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_trait_impl_item;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_hir::intravisit::FnKind;
+use rustc_hir::{FnDecl, HirId};
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self, GenericArgKind, Mutability, Ty};
+use rustc_span::def_id::LocalDefId;
+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()
+        && !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
+        && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
+        && let (Some(first), Some(last)) = (path.segments.first(), path.segments.last())
+        && let Some(hir::GenericArgs {
+            args: [hir::GenericArg::Type(opt_ty)],
+            ..
+        }) = last.args
+    {
+        let lifetime = snippet(cx, lifetime.ident.span, "..");
+        fixes.push((
+            param.span,
+            format!(
+                "{}<&{lifetime}{}{}>",
+                snippet(cx, first.ident.span.to(last.ident.span), ".."),
+                if lifetime.is_empty() { "" } else { " " },
+                snippet(cx, opt_ty.span, "..")
+            ),
+        ));
+    }
+}
+
+fn check_fn_sig<'a>(cx: &LateContext<'a>, decl: &FnDecl<'a>, span: Span, sig: ty::FnSig<'a>) {
+    let mut fixes = Vec::new();
+    // Check function arguments' types
+    for (param, param_ty) in decl.inputs.iter().zip(sig.inputs()) {
+        check_ty(cx, param, *param_ty, &mut fixes);
+    }
+    // Check return type
+    if let hir::FnRetTy::Return(ty) = &decl.output {
+        check_ty(cx, ty, sig.output(), &mut fixes);
+    }
+    if !fixes.is_empty() {
+        span_lint_and_then(
+            cx,
+            REF_OPTION,
+            span,
+            "it is more idiomatic to use `Option<&T>` instead of `&Option<T>`",
+            |diag| {
+                diag.multipart_suggestion("change this to", fixes, Applicability::Unspecified);
+            },
+        );
+    }
+}
+
+#[allow(clippy::too_many_arguments)]
+pub(crate) fn check_fn<'a>(
+    cx: &LateContext<'a>,
+    kind: FnKind<'_>,
+    decl: &FnDecl<'a>,
+    span: Span,
+    hir_id: HirId,
+    def_id: LocalDefId,
+    body: &hir::Body<'_>,
+    avoid_breaking_exported_api: bool,
+) {
+    if avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
+        return;
+    }
+
+    if let FnKind::Closure = kind {
+        // Compute the span of the closure parameters + return type if set
+        let span = if let hir::FnRetTy::Return(out_ty) = &decl.output {
+            if decl.inputs.is_empty() {
+                out_ty.span
+            } else {
+                span.with_hi(out_ty.span.hi())
+            }
+        } else if let (Some(first), Some(last)) = (decl.inputs.first(), decl.inputs.last()) {
+            first.span.to(last.span)
+        } else {
+            // No parameters - no point in checking
+            return;
+        };
+
+        // Figure out the signature of the closure
+        let ty::Closure(_, args) = cx.typeck_results().expr_ty(body.value).kind() else {
+            return;
+        };
+        let sig = args.as_closure().sig().skip_binder();
+
+        check_fn_sig(cx, decl, span, sig);
+    } else if !is_trait_impl_item(cx, hir_id) {
+        let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+        check_fn_sig(cx, decl, span, sig);
+    }
+}
+
+pub(super) fn check_trait_item<'a>(
+    cx: &LateContext<'a>,
+    trait_item: &hir::TraitItem<'a>,
+    avoid_breaking_exported_api: bool,
+) {
+    if let hir::TraitItemKind::Fn(ref sig, _) = trait_item.kind
+        && !(avoid_breaking_exported_api && cx.effective_visibilities.is_exported(trait_item.owner_id.def_id))
+    {
+        let def_id = trait_item.owner_id.def_id;
+        let ty_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+        check_fn_sig(cx, sig.decl, sig.span, ty_sig);
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
index c7de0385c02..ac2e866e4ff 100644
--- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
@@ -4,8 +4,8 @@ use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::hir_id::OwnerId;
 use rustc_hir::{Impl, ImplItem, ImplItemKind, ImplItemRef, ItemKind, Node, TraitRef};
 use rustc_lint::LateContext;
-use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{Ident, Symbol, kw};
 
 use super::RENAMED_FUNCTION_PARAMS;
 
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
index c3a0b40a677..d4eaa166320 100644
--- a/src/tools/clippy/clippy_lints/src/functions/result.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -3,11 +3,11 @@ use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
 use clippy_utils::trait_ref_of_method;
-use clippy_utils::ty::{approx_ty_size, is_type_diagnostic_item, AdtVariantInfo};
+use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_type_diagnostic_item};
 
 use super::{RESULT_LARGE_ERR, RESULT_UNIT_ERR};
 
diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs
index 9488ba75686..a4dbe134f36 100644
--- a/src/tools/clippy/clippy_lints/src/future_not_send.rs
+++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::print::PrintTraitRefExt;
 use rustc_middle::ty::{self, AliasTy, ClauseKind, PredicateKind};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
 use rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt};
 
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index 0bca53c1536..d63c18c0eda 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::eager_or_lazy::switch_to_eager_eval;
 use clippy_utils::source::snippet_with_context;
@@ -105,6 +105,8 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
                             snippet_with_context(cx, first_stmt.span.until(then_arg.span), ctxt, "..", &mut app);
                         let closure = if method_name == "then" { "|| " } else { "" };
                         format!("{closure} {{ {block_snippet}; {arg_snip} }}")
+                    } else if method_name == "then" {
+                        (std::borrow::Cow::Borrowed("|| ") + arg_snip).into_owned()
                     } else {
                         arg_snip.into_owned()
                     };
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index e56f33f8dcf..4c5375730b8 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -3,18 +3,18 @@ use std::collections::BTreeMap;
 
 use rustc_errors::{Applicability, Diag};
 use rustc_hir as hir;
-use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_body, walk_expr, walk_inf, walk_ty};
 use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{Ty, TypeckResults};
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{snippet, IntoSpan, SpanRangeExt};
+use clippy_utils::source::{IntoSpan, SpanRangeExt, snippet};
 use clippy_utils::ty::is_type_diagnostic_item;
 
 declare_clippy_lint! {
@@ -281,7 +281,7 @@ impl<'a, 'tcx> ImplicitHasherTypeVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'_, 'tcx> {
     fn visit_ty(&mut self, t: &'tcx hir::Ty<'_>) {
         if let Some(target) = ImplicitHasherType::new(self.cx, t) {
             self.found.push(target);
@@ -318,7 +318,7 @@ impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_body(&mut self, body: &Body<'tcx>) {
diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
index 127c73ed637..f4a64f5c20b 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
@@ -1,11 +1,17 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{higher, is_integer_literal, peel_blocks_with_stmt, SpanlessEq};
+use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::source::snippet_opt;
+use clippy_utils::{
+    SpanlessEq, higher, is_in_const_context, is_integer_literal, path_to_local, peel_blocks, peel_blocks_with_stmt,
+};
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind, QPath};
+use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind, HirId, QPath};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::declare_lint_pass;
+use rustc_session::impl_lint_pass;
+use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -39,7 +45,49 @@ declare_clippy_lint! {
     "Perform saturating subtraction instead of implicitly checking lower bound of data type"
 }
 
-declare_lint_pass!(ImplicitSaturatingSub => [IMPLICIT_SATURATING_SUB]);
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for comparisons between integers, followed by subtracting the greater value from the
+    /// lower one.
+    ///
+    /// ### Why is this bad?
+    /// This could result in an underflow and is most likely not what the user wants. If this was
+    /// intended to be a saturated subtraction, consider using the `saturating_sub` method directly.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let a = 12u32;
+    /// let b = 13u32;
+    ///
+    /// let result = if a > b { b - a } else { 0 };
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// let a = 12u32;
+    /// let b = 13u32;
+    ///
+    /// let result = a.saturating_sub(b);
+    /// ```
+    #[clippy::version = "1.44.0"]
+    pub INVERTED_SATURATING_SUB,
+    correctness,
+    "Check if a variable is smaller than another one and still subtract from it even if smaller"
+}
+
+pub struct ImplicitSaturatingSub {
+    msrv: Msrv,
+}
+
+impl_lint_pass!(ImplicitSaturatingSub => [IMPLICIT_SATURATING_SUB, INVERTED_SATURATING_SUB]);
+
+impl ImplicitSaturatingSub {
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+        }
+    }
+}
 
 impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
@@ -50,73 +98,260 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub {
 
             // Check if the conditional expression is a binary operation
             && let ExprKind::Binary(ref cond_op, cond_left, cond_right) = cond.kind
+        {
+            check_with_condition(cx, expr, cond_op.node, cond_left, cond_right, then);
+        } else if let Some(higher::If {
+            cond,
+            then: if_block,
+            r#else: Some(else_block),
+        }) = higher::If::hir(expr)
+            && let ExprKind::Binary(ref cond_op, cond_left, cond_right) = cond.kind
+        {
+            check_manual_check(
+                cx, expr, cond_op, cond_left, cond_right, if_block, else_block, &self.msrv,
+            );
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
 
-            // Ensure that the binary operator is >, !=, or <
-            && (BinOpKind::Ne == cond_op.node || BinOpKind::Gt == cond_op.node || BinOpKind::Lt == cond_op.node)
+#[allow(clippy::too_many_arguments)]
+fn check_manual_check<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &Expr<'tcx>,
+    condition: &BinOp,
+    left_hand: &Expr<'tcx>,
+    right_hand: &Expr<'tcx>,
+    if_block: &Expr<'tcx>,
+    else_block: &Expr<'tcx>,
+    msrv: &Msrv,
+) {
+    let ty = cx.typeck_results().expr_ty(left_hand);
+    if ty.is_numeric() && !ty.is_signed() {
+        match condition.node {
+            BinOpKind::Gt | BinOpKind::Ge => check_gt(
+                cx,
+                condition.span,
+                expr.span,
+                left_hand,
+                right_hand,
+                if_block,
+                else_block,
+                msrv,
+            ),
+            BinOpKind::Lt | BinOpKind::Le => check_gt(
+                cx,
+                condition.span,
+                expr.span,
+                right_hand,
+                left_hand,
+                if_block,
+                else_block,
+                msrv,
+            ),
+            _ => {},
+        }
+    }
+}
 
-            // Check if assign operation is done
-            && let Some(target) = subtracts_one(cx, then)
+#[allow(clippy::too_many_arguments)]
+fn check_gt(
+    cx: &LateContext<'_>,
+    condition_span: Span,
+    expr_span: Span,
+    big_var: &Expr<'_>,
+    little_var: &Expr<'_>,
+    if_block: &Expr<'_>,
+    else_block: &Expr<'_>,
+    msrv: &Msrv,
+) {
+    if let Some(big_var) = Var::new(big_var)
+        && let Some(little_var) = Var::new(little_var)
+    {
+        check_subtraction(
+            cx,
+            condition_span,
+            expr_span,
+            big_var,
+            little_var,
+            if_block,
+            else_block,
+            msrv,
+        );
+    }
+}
 
-            // Extracting out the variable name
-            && let ExprKind::Path(QPath::Resolved(_, ares_path)) = target.kind
+struct Var {
+    span: Span,
+    hir_id: HirId,
+}
+
+impl Var {
+    fn new(expr: &Expr<'_>) -> Option<Self> {
+        path_to_local(expr).map(|hir_id| Self {
+            span: expr.span,
+            hir_id,
+        })
+    }
+}
+
+#[allow(clippy::too_many_arguments)]
+fn check_subtraction(
+    cx: &LateContext<'_>,
+    condition_span: Span,
+    expr_span: Span,
+    big_var: Var,
+    little_var: Var,
+    if_block: &Expr<'_>,
+    else_block: &Expr<'_>,
+    msrv: &Msrv,
+) {
+    let if_block = peel_blocks(if_block);
+    let else_block = peel_blocks(else_block);
+    if is_integer_literal(if_block, 0) {
+        // We need to check this case as well to prevent infinite recursion.
+        if is_integer_literal(else_block, 0) {
+            // Well, seems weird but who knows?
+            return;
+        }
+        // If the subtraction is done in the `else` block, then we need to also revert the two
+        // variables as it means that the check was reverted too.
+        check_subtraction(
+            cx,
+            condition_span,
+            expr_span,
+            little_var,
+            big_var,
+            else_block,
+            if_block,
+            msrv,
+        );
+        return;
+    }
+    if is_integer_literal(else_block, 0)
+        && let ExprKind::Binary(op, left, right) = if_block.kind
+        && let BinOpKind::Sub = op.node
+    {
+        let local_left = path_to_local(left);
+        let local_right = path_to_local(right);
+        if Some(big_var.hir_id) == local_left && Some(little_var.hir_id) == local_right {
+            // This part of the condition is voluntarily split from the one before to ensure that
+            // if `snippet_opt` fails, it won't try the next conditions.
+            if let Some(big_var_snippet) = snippet_opt(cx, big_var.span)
+                && let Some(little_var_snippet) = snippet_opt(cx, little_var.span)
+                && (!is_in_const_context(cx) || msrv.meets(msrvs::SATURATING_SUB_CONST))
+            {
+                span_lint_and_sugg(
+                    cx,
+                    IMPLICIT_SATURATING_SUB,
+                    expr_span,
+                    "manual arithmetic check found",
+                    "replace it with",
+                    format!("{big_var_snippet}.saturating_sub({little_var_snippet})"),
+                    Applicability::MachineApplicable,
+                );
+            }
+        } else if Some(little_var.hir_id) == local_left
+            && Some(big_var.hir_id) == local_right
+            && let Some(big_var_snippet) = snippet_opt(cx, big_var.span)
+            && let Some(little_var_snippet) = snippet_opt(cx, little_var.span)
         {
-            // Handle symmetric conditions in the if statement
-            let (cond_var, cond_num_val) = if SpanlessEq::new(cx).eq_expr(cond_left, target) {
-                if BinOpKind::Gt == cond_op.node || BinOpKind::Ne == cond_op.node {
-                    (cond_left, cond_right)
-                } else {
-                    return;
-                }
-            } else if SpanlessEq::new(cx).eq_expr(cond_right, target) {
-                if BinOpKind::Lt == cond_op.node || BinOpKind::Ne == cond_op.node {
-                    (cond_right, cond_left)
-                } else {
-                    return;
-                }
+            span_lint_and_then(
+                cx,
+                INVERTED_SATURATING_SUB,
+                condition_span,
+                "inverted arithmetic check before subtraction",
+                |diag| {
+                    diag.span_note(
+                        if_block.span,
+                        format!("this subtraction underflows when `{little_var_snippet} < {big_var_snippet}`"),
+                    );
+                    diag.span_suggestion(
+                        if_block.span,
+                        "try replacing it with",
+                        format!("{big_var_snippet} - {little_var_snippet}"),
+                        Applicability::MaybeIncorrect,
+                    );
+                },
+            );
+        }
+    }
+}
+
+fn check_with_condition<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &Expr<'tcx>,
+    cond_op: BinOpKind,
+    cond_left: &Expr<'tcx>,
+    cond_right: &Expr<'tcx>,
+    then: &Expr<'tcx>,
+) {
+    // Ensure that the binary operator is >, !=, or <
+    if (BinOpKind::Ne == cond_op || BinOpKind::Gt == cond_op || BinOpKind::Lt == cond_op)
+
+        // Check if assign operation is done
+        && let Some(target) = subtracts_one(cx, then)
+
+        // Extracting out the variable name
+        && let ExprKind::Path(QPath::Resolved(_, ares_path)) = target.kind
+    {
+        // Handle symmetric conditions in the if statement
+        let (cond_var, cond_num_val) = if SpanlessEq::new(cx).eq_expr(cond_left, target) {
+            if BinOpKind::Gt == cond_op || BinOpKind::Ne == cond_op {
+                (cond_left, cond_right)
             } else {
                 return;
-            };
-
-            // Check if the variable in the condition statement is an integer
-            if !cx.typeck_results().expr_ty(cond_var).is_integral() {
+            }
+        } else if SpanlessEq::new(cx).eq_expr(cond_right, target) {
+            if BinOpKind::Lt == cond_op || BinOpKind::Ne == cond_op {
+                (cond_right, cond_left)
+            } else {
                 return;
             }
+        } else {
+            return;
+        };
 
-            // Get the variable name
-            let var_name = ares_path.segments[0].ident.name.as_str();
-            match cond_num_val.kind {
-                ExprKind::Lit(cond_lit) => {
-                    // Check if the constant is zero
-                    if let LitKind::Int(Pu128(0), _) = cond_lit.node {
-                        if cx.typeck_results().expr_ty(cond_left).is_signed() {
-                        } else {
-                            print_lint_and_sugg(cx, var_name, expr);
-                        };
-                    }
-                },
-                ExprKind::Path(QPath::TypeRelative(_, name)) => {
-                    if name.ident.as_str() == "MIN"
-                        && let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id)
-                        && let Some(impl_id) = cx.tcx.impl_of_method(const_id)
-                        && let None = cx.tcx.impl_trait_ref(impl_id) // An inherent impl
-                        && cx.tcx.type_of(impl_id).instantiate_identity().is_integral()
-                    {
-                        print_lint_and_sugg(cx, var_name, expr);
-                    }
-                },
-                ExprKind::Call(func, []) => {
-                    if let ExprKind::Path(QPath::TypeRelative(_, name)) = func.kind
-                        && name.ident.as_str() == "min_value"
-                        && let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id)
-                        && let Some(impl_id) = cx.tcx.impl_of_method(func_id)
-                        && let None = cx.tcx.impl_trait_ref(impl_id) // An inherent impl
-                        && cx.tcx.type_of(impl_id).instantiate_identity().is_integral()
-                    {
+        // Check if the variable in the condition statement is an integer
+        if !cx.typeck_results().expr_ty(cond_var).is_integral() {
+            return;
+        }
+
+        // Get the variable name
+        let var_name = ares_path.segments[0].ident.name.as_str();
+        match cond_num_val.kind {
+            ExprKind::Lit(cond_lit) => {
+                // Check if the constant is zero
+                if let LitKind::Int(Pu128(0), _) = cond_lit.node {
+                    if cx.typeck_results().expr_ty(cond_left).is_signed() {
+                    } else {
                         print_lint_and_sugg(cx, var_name, expr);
-                    }
-                },
-                _ => (),
-            }
+                    };
+                }
+            },
+            ExprKind::Path(QPath::TypeRelative(_, name)) => {
+                if name.ident.as_str() == "MIN"
+                    && let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id)
+                    && let Some(impl_id) = cx.tcx.impl_of_method(const_id)
+                    && let None = cx.tcx.impl_trait_ref(impl_id) // An inherent impl
+                    && cx.tcx.type_of(impl_id).instantiate_identity().is_integral()
+                {
+                    print_lint_and_sugg(cx, var_name, expr);
+                }
+            },
+            ExprKind::Call(func, []) => {
+                if let ExprKind::Path(QPath::TypeRelative(_, name)) = func.kind
+                    && name.ident.as_str() == "min_value"
+                    && let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id)
+                    && let Some(impl_id) = cx.tcx.impl_of_method(func_id)
+                    && let None = cx.tcx.impl_trait_ref(impl_id) // An inherent impl
+                    && cx.tcx.type_of(impl_id).instantiate_identity().is_integral()
+                {
+                    print_lint_and_sugg(cx, var_name, expr);
+                }
+            },
+            _ => (),
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 6794c6cabfe..5f349d78053 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
 use rustc_errors::{Applicability, SuggestionStyle};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
-    AssocItemConstraint, GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier,
+    AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifier,
     TyKind, WherePredicate,
 };
 use rustc_hir_analysis::lower_ty;
@@ -342,11 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &rustc_hir::Ty<'_>) {
-        if let TyKind::OpaqueDef(item_id, ..) = ty.kind
-            && let item = cx.tcx.hir().item(item_id)
-            && let ItemKind::OpaqueTy(opaque_ty) = item.kind
-        {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &rustc_hir::Ty<'tcx>) {
+        if let TyKind::OpaqueDef(opaque_ty, ..) = ty.kind {
             check(cx, opaque_ty.bounds);
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index 2ad045e1268..0b3a6ee1bea 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::Msrv;
 use clippy_config::Conf;
+use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_in_test;
 use rustc_attr::{StabilityLevel, StableSince};
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{Expr, ExprKind, HirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
-use rustc_session::{impl_lint_pass, RustcVersion};
+use rustc_session::{RustcVersion, impl_lint_pass};
 use rustc_span::def_id::DefId;
 use rustc_span::{ExpnKind, Span};
 
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index 2f9661c9ea3..73ebe6aec15 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::IfLet;
@@ -8,14 +8,14 @@ use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
-use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
+use rustc_hir::intravisit::{self, Visitor};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::Ident;
 use rustc_span::Span;
+use rustc_span::symbol::Ident;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -226,7 +226,7 @@ struct SliceIndexLintingVisitor<'a, 'tcx> {
     max_suggested_slice: u64,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
diff --git a/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs b/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
index af5b1f95739..3a28553b55e 100644
--- a/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
@@ -7,7 +7,7 @@ use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{BytePos, Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
index 6d6820311b6..66931a7f98c 100644
--- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
+++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::sugg::Sugg;
diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
index 74bf82f58bd..66a8a3167a4 100644
--- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
+++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
@@ -8,8 +8,8 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::Symbol;
 use rustc_span::Span;
+use rustc_span::symbol::Symbol;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
index 8caa484bb99..1ac549b74ac 100644
--- a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
+++ b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
@@ -6,7 +6,7 @@ use rustc_hir::{HirId, Item, ItemKind, Mod};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::hygiene::AstPass;
-use rustc_span::{sym, ExpnKind};
+use rustc_span::{ExpnKind, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
index ba0cd5d6eb3..b19b348c743 100644
--- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
@@ -4,7 +4,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{FnSig, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
index f162948bb44..5131f5b7269 100644
--- a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
@@ -55,7 +55,9 @@ impl LateLintPass<'_> for IterOverHashType {
         if let Some(for_loop) = ForLoop::hir(expr)
             && !for_loop.body.span.from_expansion()
             && let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs()
-            && hash_iter_tys.into_iter().any(|sym| is_type_diagnostic_item(cx, ty, sym))
+            && hash_iter_tys
+                .into_iter()
+                .any(|sym| is_type_diagnostic_item(cx, ty, sym))
         {
             span_lint(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index 2f027c11707..923089c7223 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -1,7 +1,7 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::{approx_ty_size, is_copy, AdtVariantInfo};
+use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_copy};
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
index 15a75b06089..0f061d6de50 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
@@ -8,7 +8,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, ConstKind};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
index ccab1e27d3b..e17d6213679 100644
--- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{Msrv, NUMERIC_ASSOCIATED_CONSTANTS};
 use clippy_config::Conf;
+use clippy_config::msrvs::{Msrv, NUMERIC_ASSOCIATED_CONSTANTS};
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::{get_parent_expr, is_from_proc_macro};
 use hir::def_id::DefId;
@@ -10,7 +10,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 16f86b18e2e..311bbce14bd 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::{snippet_with_context, SpanRangeExt};
-use clippy_utils::sugg::{has_enclosing_paren, Sugg};
-use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators};
+use clippy_utils::source::{SpanRangeExt, snippet_with_context};
+use clippy_utils::sugg::{Sugg, has_enclosing_paren};
+use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, is_trait_method, peel_ref_operators};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
@@ -185,6 +185,19 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
             );
         }
 
+        if let ExprKind::MethodCall(method, lhs_expr, [rhs_expr], _) = expr.kind
+            && is_trait_method(cx, expr, sym::PartialEq)
+            && !expr.span.from_expansion()
+        {
+            check_empty_expr(
+                cx,
+                expr.span,
+                lhs_expr,
+                peel_ref_operators(cx, rhs_expr),
+                (method.ident.name == sym::ne).then_some("!").unwrap_or_default(),
+            );
+        }
+
         if let ExprKind::Binary(Spanned { node: cmp, .. }, left, right) = expr.kind
             && !expr.span.from_expansion()
         {
@@ -295,12 +308,8 @@ enum LenOutput {
 
 fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> {
     if let ty::Alias(_, alias_ty) = ty.kind()
-        && let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
-        && let Item {
-            kind: ItemKind::OpaqueTy(opaque),
-            ..
-        } = item
-        && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin
+        && let Some(Node::OpaqueTy(opaque)) = cx.tcx.hir().get_if_local(alias_ty.def_id)
+        && let OpaqueTyOrigin::AsyncFn { .. } = opaque.origin
         && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
         && let Some(segment) = trait_ref.trait_ref.path.segments.last()
         && let Some(generic_args) = segment.args
@@ -447,7 +456,7 @@ fn check_for_is_empty(
     let is_empty = cx
         .tcx
         .inherent_impls(impl_ty)
-        .into_iter()
+        .iter()
         .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
         .find(|item| item.kind == AssocKind::Fn);
 
@@ -615,7 +624,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     /// Checks the inherent impl's items for an `is_empty(self)` method.
     fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
         let is_empty = sym!(is_empty);
-        cx.tcx.inherent_impls(id).into_iter().any(|imp| {
+        cx.tcx.inherent_impls(id).iter().any(|imp| {
             cx.tcx
                 .associated_items(*imp)
                 .filter_by_name_unhygienic(is_empty)
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 2ac06b360be..012aa689d4b 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -1,7 +1,6 @@
 #![feature(array_windows)]
 #![feature(binary_heap_into_iter_sorted)]
 #![feature(box_patterns)]
-#![feature(control_flow_enum)]
 #![feature(f128)]
 #![feature(f16)]
 #![feature(if_let_guard)]
@@ -203,9 +202,11 @@ mod manual_assert;
 mod manual_async_fn;
 mod manual_bits;
 mod manual_clamp;
+mod manual_div_ceil;
 mod manual_float_methods;
 mod manual_hash_one;
 mod manual_is_ascii_check;
+mod manual_is_power_of_two;
 mod manual_let_else;
 mod manual_main_separator_str;
 mod manual_non_exhaustive;
@@ -271,6 +272,7 @@ mod non_copy_const;
 mod non_expressive_names;
 mod non_octal_unix_permissions;
 mod non_send_fields_in_send_ty;
+mod non_zero_suggestions;
 mod nonstandard_macro_braces;
 mod octal_escapes;
 mod only_used_in_recursion;
@@ -287,6 +289,7 @@ mod pass_by_ref_or_value;
 mod pathbuf_init_then_push;
 mod pattern_type_mismatch;
 mod permissions_set_readonly_false;
+mod pointers_in_nomem_asm_block;
 mod precedence;
 mod ptr;
 mod ptr_offset_with_cast;
@@ -372,6 +375,7 @@ mod unused_peekable;
 mod unused_result_ok;
 mod unused_rounding;
 mod unused_self;
+mod unused_trait_names;
 mod unused_unit;
 mod unwrap;
 mod unwrap_in_result;
@@ -386,9 +390,10 @@ mod write;
 mod zero_div_zero;
 mod zero_repeat_side_effects;
 mod zero_sized_map_values;
+mod zombie_processes;
 // end lints modules, do not remove this comment, it’s used in `update_lints`
 
-use clippy_config::{get_configuration_metadata, Conf};
+use clippy_config::{Conf, get_configuration_metadata};
 use clippy_utils::macros::FormatArgsStorage;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_lint::{Lint, LintId};
@@ -603,7 +608,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |tcx| Box::new(await_holding_invalid::AwaitHolding::new(tcx, conf)));
     store.register_late_pass(|_| Box::new(serde_api::SerdeApi));
     store.register_late_pass(move |_| Box::new(types::Types::new(conf)));
-    store.register_late_pass(|_| Box::new(booleans::NonminimalBool));
+    store.register_late_pass(move |_| Box::new(booleans::NonminimalBool::new(conf)));
     store.register_late_pass(|_| Box::new(enum_clike::UnportableVariant));
     store.register_late_pass(|_| Box::new(float_literal::FloatLiteral));
     store.register_late_pass(|_| Box::new(ptr::Ptr));
@@ -623,7 +628,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
     store.register_late_pass(|_| Box::new(strings::StringAdd));
     store.register_late_pass(|_| Box::new(implicit_return::ImplicitReturn));
-    store.register_late_pass(|_| Box::new(implicit_saturating_sub::ImplicitSaturatingSub));
+    store.register_late_pass(move |_| Box::new(implicit_saturating_sub::ImplicitSaturatingSub::new(conf)));
     store.register_late_pass(|_| Box::new(default_numeric_fallback::DefaultNumericFallback));
     store.register_late_pass(|_| Box::new(inconsistent_struct_constructor::InconsistentStructConstructor));
     store.register_late_pass(|_| Box::new(non_octal_unix_permissions::NonOctalUnixPermissions));
@@ -632,8 +637,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     let format_args = format_args_storage.clone();
     store.register_late_pass(move |_| Box::new(methods::Methods::new(conf, format_args.clone())));
     store.register_late_pass(move |_| Box::new(matches::Matches::new(conf)));
-    store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(conf)));
-    store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(conf)));
+    store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustive::new(conf)));
     store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(conf)));
     store.register_early_pass(move || Box::new(redundant_static_lifetimes::RedundantStaticLifetimes::new(conf)));
     store.register_early_pass(move || Box::new(redundant_field_names::RedundantFieldNames::new(conf)));
@@ -933,5 +937,11 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(set_contains_or_insert::SetContainsOrInsert));
     store.register_early_pass(|| Box::new(byte_char_slices::ByteCharSlice));
     store.register_early_pass(|| Box::new(cfg_not_test::CfgNotTest));
+    store.register_late_pass(|_| Box::new(zombie_processes::ZombieProcesses));
+    store.register_late_pass(|_| Box::new(pointers_in_nomem_asm_block::PointersInNomemAsmBlock));
+    store.register_late_pass(move |_| Box::new(manual_div_ceil::ManualDivCeil::new(conf)));
+    store.register_late_pass(|_| Box::new(manual_is_power_of_two::ManualIsPowerOfTwo));
+    store.register_late_pass(|_| Box::new(non_zero_suggestions::NonZeroSuggestions));
+    store.register_late_pass(move |_| Box::new(unused_trait_names::UnusedTraitNames::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/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index ba34af9c100..7c3ef98fd74 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -3,25 +3,25 @@ use clippy_utils::trait_ref_of_method;
 use itertools::Itertools;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
+use rustc_hir::FnRetTy::Return;
 use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
 use rustc_hir::intravisit::{
-    walk_fn_decl, walk_generic_param, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
-    walk_poly_trait_ref, walk_trait_ref, walk_ty, Visitor,
+    Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_param_bound,
+    walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_where_predicate,
 };
-use rustc_hir::FnRetTy::Return;
 use rustc_hir::{
-    lang_items, BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics,
+    BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics,
     Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
-    PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate,
+    PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, lang_items,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter as middle_nested_filter;
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
-use rustc_span::def_id::LocalDefId;
-use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
+use rustc_span::symbol::{Ident, kw};
 use std::ops::ControlFlow;
 
 declare_clippy_lint! {
@@ -191,45 +191,10 @@ fn check_fn_inner<'tcx>(
         if usages.iter().any(|usage| !usage.ident.span.eq_ctxt(span)) {
             return;
         }
-
-        let lts = elidable_lts
-            .iter()
-            // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
-            // `Node::GenericParam`.
-            .filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())
-            .map(|ident| ident.to_string())
-            .collect::<Vec<_>>()
-            .join(", ");
-
-        span_lint_and_then(
-            cx,
-            NEEDLESS_LIFETIMES,
-            elidable_lts
-                .iter()
-                .map(|&lt| cx.tcx.def_span(lt))
-                .chain(usages.iter().filter_map(|usage| {
-                    if let LifetimeName::Param(def_id) = usage.res
-                        && elidable_lts.contains(&def_id)
-                    {
-                        return Some(usage.ident.span);
-                    }
-
-                    None
-                }))
-                .collect_vec(),
-            format!("the following explicit lifetimes could be elided: {lts}"),
-            |diag| {
-                if sig.header.is_async() {
-                    // async functions have usages whose spans point at the lifetime declaration which messes up
-                    // suggestions
-                    return;
-                };
-
-                if let Some(suggestions) = elision_suggestions(cx, generics, &elidable_lts, &usages) {
-                    diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable);
-                }
-            },
-        );
+        // async functions have usages whose spans point at the lifetime declaration which messes up
+        // suggestions
+        let include_suggestions = !sig.header.is_async();
+        report_elidable_lifetimes(cx, generics, &elidable_lts, &usages, include_suggestions);
     }
 
     if report_extra_lifetimes {
@@ -237,97 +202,6 @@ fn check_fn_inner<'tcx>(
     }
 }
 
-fn elision_suggestions(
-    cx: &LateContext<'_>,
-    generics: &Generics<'_>,
-    elidable_lts: &[LocalDefId],
-    usages: &[Lifetime],
-) -> Option<Vec<(Span, String)>> {
-    let explicit_params = generics
-        .params
-        .iter()
-        .filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())
-        .collect::<Vec<_>>();
-
-    let mut suggestions = if elidable_lts.len() == explicit_params.len() {
-        // if all the params are elided remove the whole generic block
-        //
-        // fn x<'a>() {}
-        //     ^^^^
-        vec![(generics.span, String::new())]
-    } else {
-        elidable_lts
-            .iter()
-            .map(|&id| {
-                let pos = explicit_params.iter().position(|param| param.def_id == id)?;
-                let param = explicit_params.get(pos)?;
-
-                let span = if let Some(next) = explicit_params.get(pos + 1) {
-                    // fn x<'prev, 'a, 'next>() {}
-                    //             ^^^^
-                    param.span.until(next.span)
-                } else {
-                    // `pos` should be at least 1 here, because the param in position 0 would either have a `next`
-                    // param or would have taken the `elidable_lts.len() == explicit_params.len()` branch.
-                    let prev = explicit_params.get(pos - 1)?;
-
-                    // fn x<'prev, 'a>() {}
-                    //           ^^^^
-                    param.span.with_lo(prev.span.hi())
-                };
-
-                Some((span, String::new()))
-            })
-            .collect::<Option<Vec<_>>>()?
-    };
-
-    suggestions.extend(
-        usages
-            .iter()
-            .filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
-            .map(|usage| {
-                match cx.tcx.parent_hir_node(usage.hir_id) {
-                    Node::Ty(Ty {
-                        kind: TyKind::Ref(..), ..
-                    }) => {
-                        // expand `&'a T` to `&'a T`
-                        //          ^^         ^^^
-                        let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span);
-
-                        (span, String::new())
-                    },
-                    // `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
-                    _ => (usage.ident.span, String::from("'_")),
-                }
-            }),
-    );
-
-    Some(suggestions)
-}
-
-// elision doesn't work for explicit self types, see rust-lang/rust#69064
-fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>) -> bool {
-    if let Some(ident) = ident
-        && ident.name == kw::SelfLower
-        && !func.implicit_self.has_implicit_self()
-        && let Some(self_ty) = func.inputs.first()
-    {
-        let mut visitor = RefVisitor::new(cx);
-        visitor.visit_ty(self_ty);
-
-        !visitor.all_lts().is_empty()
-    } else {
-        false
-    }
-}
-
-fn named_lifetime(lt: &Lifetime) -> Option<LocalDefId> {
-    match lt.res {
-        LifetimeName::Param(id) if !lt.is_anonymous() => Some(id),
-        _ => None,
-    }
-}
-
 fn could_use_elision<'tcx>(
     cx: &LateContext<'tcx>,
     func: &'tcx FnDecl<'_>,
@@ -450,6 +324,22 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<LocalDefId
         .collect()
 }
 
+// elision doesn't work for explicit self types, see rust-lang/rust#69064
+fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>) -> bool {
+    if let Some(ident) = ident
+        && ident.name == kw::SelfLower
+        && !func.implicit_self.has_implicit_self()
+        && let Some(self_ty) = func.inputs.first()
+    {
+        let mut visitor = RefVisitor::new(cx);
+        visitor.visit_ty(self_ty);
+
+        !visitor.all_lts().is_empty()
+    } else {
+        false
+    }
+}
+
 /// Number of times each named lifetime occurs in the given slice. Returns a vector to preserve
 /// relative order.
 #[must_use]
@@ -470,6 +360,13 @@ fn named_lifetime_occurrences(lts: &[Lifetime]) -> Vec<(LocalDefId, usize)> {
     occurrences
 }
 
+fn named_lifetime(lt: &Lifetime) -> Option<LocalDefId> {
+    match lt.res {
+        LifetimeName::Param(id) if !lt.is_anonymous() => Some(id),
+        _ => None,
+    }
+}
+
 struct RefVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     lts: Vec<Lifetime>,
@@ -500,7 +397,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
     // for lifetimes as parameters of generics
     fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
         self.lts.push(*lifetime);
@@ -523,11 +420,9 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
 
     fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
         match ty.kind {
-            TyKind::OpaqueDef(item, bounds, _) => {
-                let map = self.cx.tcx.hir();
-                let item = map.item(item);
+            TyKind::OpaqueDef(opaque, bounds) => {
                 let len = self.lts.len();
-                walk_item(self, item);
+                self.visit_opaque_ty(opaque);
                 self.lts.truncate(len);
                 self.lts.extend(bounds.iter().filter_map(|bound| match bound {
                     GenericArg::Lifetime(&l) => Some(l),
@@ -594,23 +489,43 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
     false
 }
 
+struct Usage {
+    lifetime: Lifetime,
+    in_where_predicate: bool,
+    in_generics_arg: bool,
+}
+
 struct LifetimeChecker<'cx, 'tcx, F> {
     cx: &'cx LateContext<'tcx>,
-    map: FxHashMap<Symbol, Span>,
+    map: FxHashMap<LocalDefId, Vec<Usage>>,
+    where_predicate_depth: usize,
+    generic_args_depth: usize,
     phantom: std::marker::PhantomData<F>,
 }
 
 impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> {
-    fn new(cx: &'cx LateContext<'tcx>, map: FxHashMap<Symbol, Span>) -> LifetimeChecker<'cx, 'tcx, F> {
+    fn new(cx: &'cx LateContext<'tcx>, generics: &'tcx Generics<'_>) -> LifetimeChecker<'cx, 'tcx, F> {
+        let map = generics
+            .params
+            .iter()
+            .filter_map(|par| match par.kind {
+                GenericParamKind::Lifetime {
+                    kind: LifetimeParamKind::Explicit,
+                } => Some((par.def_id, Vec::new())),
+                _ => None,
+            })
+            .collect();
         Self {
             cx,
             map,
+            where_predicate_depth: 0,
+            generic_args_depth: 0,
             phantom: std::marker::PhantomData,
         }
     }
 }
 
-impl<'cx, 'tcx, F> Visitor<'tcx> for LifetimeChecker<'cx, 'tcx, F>
+impl<'tcx, F> Visitor<'tcx> for LifetimeChecker<'_, 'tcx, F>
 where
     F: NestedFilter<'tcx>,
 {
@@ -619,18 +534,27 @@ where
 
     // for lifetimes as parameters of generics
     fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
-        self.map.remove(&lifetime.ident.name);
+        if let LifetimeName::Param(def_id) = lifetime.res
+            && let Some(usages) = self.map.get_mut(&def_id)
+        {
+            usages.push(Usage {
+                lifetime: *lifetime,
+                in_where_predicate: self.where_predicate_depth != 0,
+                in_generics_arg: self.generic_args_depth != 0,
+            });
+        }
     }
 
-    fn visit_generic_param(&mut self, param: &'tcx GenericParam<'_>) {
-        // don't actually visit `<'a>` or `<'a: 'b>`
-        // we've already visited the `'a` declarations and
-        // don't want to spuriously remove them
-        // `'b` in `'a: 'b` is useless unless used elsewhere in
-        // a non-lifetime bound
-        if let GenericParamKind::Type { .. } = param.kind {
-            walk_generic_param(self, param);
-        }
+    fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {
+        self.where_predicate_depth += 1;
+        walk_where_predicate(self, predicate);
+        self.where_predicate_depth -= 1;
+    }
+
+    fn visit_generic_args(&mut self, generic_args: &'tcx GenericArgs<'tcx>) -> Self::Result {
+        self.generic_args_depth += 1;
+        walk_generic_args(self, generic_args);
+        self.generic_args_depth -= 1;
     }
 
     fn nested_visit_map(&mut self) -> Self::Map {
@@ -639,44 +563,28 @@ where
 }
 
 fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, generics: &'tcx Generics<'_>) {
-    let hs = generics
-        .params
-        .iter()
-        .filter_map(|par| match par.kind {
-            GenericParamKind::Lifetime {
-                kind: LifetimeParamKind::Explicit,
-            } => Some((par.name.ident().name, par.span)),
-            _ => None,
-        })
-        .collect();
-    let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, hs);
+    let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, generics);
 
     walk_generics(&mut checker, generics);
     walk_fn_decl(&mut checker, func);
 
-    for &v in checker.map.values() {
-        span_lint(
-            cx,
-            EXTRA_UNUSED_LIFETIMES,
-            v,
-            "this lifetime isn't used in the function definition",
-        );
+    for (def_id, usages) in checker.map {
+        if usages
+            .iter()
+            .all(|usage| usage.in_where_predicate && !usage.in_generics_arg)
+        {
+            span_lint(
+                cx,
+                EXTRA_UNUSED_LIFETIMES,
+                cx.tcx.def_span(def_id),
+                "this lifetime isn't used in the function definition",
+            );
+        }
     }
 }
 
 fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'_>) {
-    let hs = impl_
-        .generics
-        .params
-        .iter()
-        .filter_map(|par| match par.kind {
-            GenericParamKind::Lifetime {
-                kind: LifetimeParamKind::Explicit,
-            } => Some((par.name.ident().name, par.span)),
-            _ => None,
-        })
-        .collect();
-    let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, hs);
+    let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, impl_.generics);
 
     walk_generics(&mut checker, impl_.generics);
     if let Some(ref trait_ref) = impl_.of_trait {
@@ -687,9 +595,176 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
         walk_impl_item_ref(&mut checker, item);
     }
 
-    for &v in checker.map.values() {
-        span_lint(cx, EXTRA_UNUSED_LIFETIMES, v, "this lifetime isn't used in the impl");
+    for (&def_id, usages) in &checker.map {
+        if usages
+            .iter()
+            .all(|usage| usage.in_where_predicate && !usage.in_generics_arg)
+        {
+            span_lint(
+                cx,
+                EXTRA_UNUSED_LIFETIMES,
+                cx.tcx.def_span(def_id),
+                "this lifetime isn't used in the impl",
+            );
+        }
     }
+
+    report_elidable_impl_lifetimes(cx, impl_, &checker.map);
+}
+
+// An `impl` lifetime is elidable if it satisfies the following conditions:
+// - It is used exactly once.
+// - That single use is not in `GenericArgs` in a `WherePredicate`. (Note that `GenericArgs` are
+//   different from `GenericParam`s.)
+fn report_elidable_impl_lifetimes<'tcx>(
+    cx: &LateContext<'tcx>,
+    impl_: &'tcx Impl<'_>,
+    map: &FxHashMap<LocalDefId, Vec<Usage>>,
+) {
+    let single_usages = map
+        .iter()
+        .filter_map(|(def_id, usages)| {
+            if let [
+                Usage {
+                    lifetime,
+                    in_where_predicate: false,
+                    ..
+                }
+                | Usage {
+                    lifetime,
+                    in_generics_arg: false,
+                    ..
+                },
+            ] = usages.as_slice()
+            {
+                Some((def_id, lifetime))
+            } else {
+                None
+            }
+        })
+        .collect::<Vec<_>>();
+
+    if single_usages.is_empty() {
+        return;
+    }
+
+    let (elidable_lts, usages): (Vec<_>, Vec<_>) = single_usages.into_iter().unzip();
+
+    report_elidable_lifetimes(cx, impl_.generics, &elidable_lts, &usages, true);
+}
+
+/// Generate diagnostic messages for elidable lifetimes.
+fn report_elidable_lifetimes(
+    cx: &LateContext<'_>,
+    generics: &Generics<'_>,
+    elidable_lts: &[LocalDefId],
+    usages: &[Lifetime],
+    include_suggestions: bool,
+) {
+    let lts = elidable_lts
+        .iter()
+        // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
+        // `Node::GenericParam`.
+        .filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())
+        .map(|ident| ident.to_string())
+        .collect::<Vec<_>>()
+        .join(", ");
+
+    span_lint_and_then(
+        cx,
+        NEEDLESS_LIFETIMES,
+        elidable_lts
+            .iter()
+            .map(|&lt| cx.tcx.def_span(lt))
+            .chain(usages.iter().filter_map(|usage| {
+                if let LifetimeName::Param(def_id) = usage.res
+                    && elidable_lts.contains(&def_id)
+                {
+                    return Some(usage.ident.span);
+                }
+
+                None
+            }))
+            .collect_vec(),
+        format!("the following explicit lifetimes could be elided: {lts}"),
+        |diag| {
+            if !include_suggestions {
+                return;
+            };
+
+            if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, usages) {
+                diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable);
+            }
+        },
+    );
+}
+
+fn elision_suggestions(
+    cx: &LateContext<'_>,
+    generics: &Generics<'_>,
+    elidable_lts: &[LocalDefId],
+    usages: &[Lifetime],
+) -> Option<Vec<(Span, String)>> {
+    let explicit_params = generics
+        .params
+        .iter()
+        .filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())
+        .collect::<Vec<_>>();
+
+    let mut suggestions = if elidable_lts.len() == explicit_params.len() {
+        // if all the params are elided remove the whole generic block
+        //
+        // fn x<'a>() {}
+        //     ^^^^
+        vec![(generics.span, String::new())]
+    } else {
+        elidable_lts
+            .iter()
+            .map(|&id| {
+                let pos = explicit_params.iter().position(|param| param.def_id == id)?;
+                let param = explicit_params.get(pos)?;
+
+                let span = if let Some(next) = explicit_params.get(pos + 1) {
+                    // fn x<'prev, 'a, 'next>() {}
+                    //             ^^^^
+                    param.span.until(next.span)
+                } else {
+                    // `pos` should be at least 1 here, because the param in position 0 would either have a `next`
+                    // param or would have taken the `elidable_lts.len() == explicit_params.len()` branch.
+                    let prev = explicit_params.get(pos - 1)?;
+
+                    // fn x<'prev, 'a>() {}
+                    //           ^^^^
+                    param.span.with_lo(prev.span.hi())
+                };
+
+                Some((span, String::new()))
+            })
+            .collect::<Option<Vec<_>>>()?
+    };
+
+    suggestions.extend(
+        usages
+            .iter()
+            .filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
+            .map(|usage| {
+                match cx.tcx.parent_hir_node(usage.hir_id) {
+                    Node::Ty(Ty {
+                        kind: TyKind::Ref(..), ..
+                    }) => {
+                        // expand `&'a T` to `&'a T`
+                        //          ^^         ^^^
+                        let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span);
+
+                        (span, String::new())
+                    },
+                    // `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
+                    _ => (usage.ident.span, String::from("'_")),
+                }
+            }),
+    );
+
+    Some(suggestions)
 }
 
 struct BodyLifetimeChecker;
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs
index 73a23615c2d..9aa4d2f0adc 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs
@@ -1,4 +1,4 @@
-use super::{make_iterator_snippet, IncrementVisitor, InitializeVisitor, EXPLICIT_COUNTER_LOOP};
+use super::{EXPLICIT_COUNTER_LOOP, IncrementVisitor, InitializeVisitor, make_iterator_snippet};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::{get_enclosing_block, is_integer_const};
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 5b5bb88c179..858e3be5093 100644
--- a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{fn_def_id, is_from_proc_macro, is_lint_allowed};
-use hir::intravisit::{walk_expr, Visitor};
+use hir::intravisit::{Visitor, walk_expr};
 use hir::{Expr, ExprKind, FnRetTy, FnSig, Node};
 use rustc_ast::Label;
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
index b27528c11d4..bfe2e68b5d1 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_find.rs
@@ -1,5 +1,5 @@
-use super::utils::make_iterator_snippet;
 use super::MANUAL_FIND;
+use super::utils::make_iterator_snippet;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::implements_trait;
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs b/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs
index dbc094a6d73..366c310592f 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs
@@ -1,5 +1,5 @@
-use super::utils::make_iterator_snippet;
 use super::MANUAL_FLATTEN;
+use super::utils::make_iterator_snippet;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::visitors::is_local_used;
 use clippy_utils::{higher, path_to_local_id, peel_blocks_with_stmt};
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index a7c1d1bd6cd..68d063ad5e5 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -209,7 +209,7 @@ fn build_manual_memcpy_suggestion<'tcx>(
 #[derive(Clone)]
 struct MinifyingSugg<'a>(Sugg<'a>);
 
-impl<'a> Display for MinifyingSugg<'a> {
+impl Display for MinifyingSugg<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         self.0.fmt(f)
     }
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs b/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs
index 55d1b9ee676..7476a87267f 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs
@@ -1,10 +1,10 @@
+use clippy_utils::SpanlessEq;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
-use clippy_utils::SpanlessEq;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Pat, Stmt, StmtKind, UnOp};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Symbol, Span};
+use rustc_span::{Span, Symbol, sym};
 use std::borrow::Cow;
 
 use super::MANUAL_WHILE_LET_SOME;
diff --git a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
index e405829b2f4..a9944d64ce2 100644
--- a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
@@ -1,6 +1,6 @@
 use super::MISSING_SPIN_LOOP;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_no_std_crate;
+use clippy_utils::std_or_core;
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Expr, ExprKind};
 use rustc_lint::LateContext;
@@ -41,6 +41,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
         && [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name)
         && let ty::Adt(def, _args) = cx.typeck_results().expr_ty(callee).kind()
         && cx.tcx.is_diagnostic_item(sym::AtomicBool, def.did())
+        && let Some(std_or_core) = std_or_core(cx)
     {
         span_lint_and_sugg(
             cx,
@@ -48,12 +49,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
             body.span,
             "busy-waiting loop should at least have a spin loop hint",
             "try",
-            (if is_no_std_crate(cx) {
-                "{ core::hint::spin_loop() }"
-            } else {
-                "{ std::hint::spin_loop() }"
-            })
-            .into(),
+            format!("{{ {std_or_core}::hint::spin_loop() }}"),
             Applicability::MachineApplicable,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index 92ccc0cc0a1..17215621d2a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -22,15 +22,15 @@ mod while_immutable_condition;
 mod while_let_loop;
 mod while_let_on_iterator;
 
-use clippy_config::msrvs::Msrv;
 use clippy_config::Conf;
+use clippy_config::msrvs::Msrv;
 use clippy_utils::higher;
 use rustc_ast::Label;
 use rustc_hir::{Expr, ExprKind, LoopSource, Pat};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
-use utils::{make_iterator_snippet, IncrementVisitor, InitializeVisitor};
+use utils::{IncrementVisitor, InitializeVisitor, make_iterator_snippet};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -188,22 +188,22 @@ declare_clippy_lint! {
     /// The `while let` loop is usually shorter and more
     /// readable.
     ///
-    /// ### Known problems
-    /// Sometimes the wrong binding is displayed ([#383](https://github.com/rust-lang/rust-clippy/issues/383)).
-    ///
     /// ### Example
     /// ```rust,no_run
-    /// # let y = Some(1);
+    /// let y = Some(1);
     /// loop {
     ///     let x = match y {
     ///         Some(x) => x,
     ///         None => break,
     ///     };
-    ///     // .. do something with x
+    ///     // ..
     /// }
-    /// // is easier written as
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// let y = Some(1);
     /// while let Some(x) = y {
-    ///     // .. do something with x
+    ///     // ..
     /// };
     /// ```
     #[clippy::version = "pre 1.29.0"]
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index e18e4374667..745f070a577 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -3,17 +3,17 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::has_iter_method;
 use clippy_utils::visitors::is_local_used;
-use clippy_utils::{contains_name, higher, is_integer_const, sugg, SpanlessEq};
+use clippy_utils::{SpanlessEq, contains_name, higher, is_integer_const, sugg};
 use rustc_ast::ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BinOpKind, BorrowKind, Closure, Expr, ExprKind, HirId, Mutability, Pat, PatKind, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::middle::region;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
 use std::{iter, mem};
 
 /// Checks for looping over a range and then indexing a sequence with it.
@@ -241,7 +241,7 @@ struct VarVisitor<'a, 'tcx> {
     prefer_mutable: bool,
 }
 
-impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
+impl<'tcx> VarVisitor<'_, 'tcx> {
     fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) -> bool {
         if let ExprKind::Path(ref seqpath) = seqexpr.kind
             // the indexed container is referenced by a name
@@ -292,7 +292,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         if let ExprKind::MethodCall(meth, args_0, [args_1, ..], _) = &expr.kind
             // a range index op
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 313a5bfefbc..1c55e3e22e8 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -1,5 +1,5 @@
-use super::utils::make_iterator_snippet;
 use super::NEVER_LOOP;
+use super::utils::make_iterator_snippet;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::ForLoop;
 use clippy_utils::macros::root_macro_call_first_node;
@@ -7,7 +7,7 @@ use clippy_utils::source::snippet;
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::iter::once;
 
 pub(super) fn check<'tcx>(
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index 9185cf1f8b2..f8659897ffe 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -6,11 +6,11 @@ use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind};
 use rustc_lint::LateContext;
-use rustc_span::symbol::sym;
 use rustc_span::SyntaxContext;
+use rustc_span::symbol::sym;
 
 /// Detects for loop pushing the same item into a Vec
 pub(super) fn check<'tcx>(
@@ -123,7 +123,7 @@ impl<'a, 'tcx> SameItemPushVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SameItemPushVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         match &expr.kind {
             // Non-determinism may occur ... don't give a lint
diff --git a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
index 2b41911e8ec..70f76ced09a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
@@ -2,10 +2,10 @@ use super::SINGLE_ELEMENT_LOOP;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{indent_of, snippet, snippet_with_applicability};
 use clippy_utils::visitors::contains_break_or_continue;
-use rustc_ast::util::parser::PREC_PREFIX;
 use rustc_ast::Mutability;
+use rustc_ast::util::parser::PREC_PREFIX;
 use rustc_errors::Applicability;
-use rustc_hir::{is_range_literal, BorrowKind, Expr, ExprKind, Pat, PatKind};
+use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind, is_range_literal};
 use rustc_lint::LateContext;
 use rustc_span::edition::Edition;
 use rustc_span::sym;
diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs
index 7b45cc95431..c4c504e1ae4 100644
--- a/src/tools/clippy/clippy_lints/src/loops/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs
@@ -2,13 +2,13 @@ use clippy_utils::ty::{has_iter_method, implements_trait};
 use clippy_utils::{get_parent_expr, is_integer_const, path_to_local, path_to_local_id, sugg};
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_expr, walk_local, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr, walk_local};
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
 
 #[derive(Debug, PartialEq, Eq)]
 enum IncrementVisitorVarState {
@@ -44,7 +44,7 @@ impl<'a, 'tcx> IncrementVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for IncrementVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         // If node is a variable
         if let Some(def_id) = path_to_local(expr) {
@@ -138,7 +138,7 @@ impl<'a, 'tcx> InitializeVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for InitializeVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
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 cc1bd5929d0..1a1cde3c5bd 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
@@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::usage::mutated_variables;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefIdMap;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Expr, ExprKind, HirIdSet, QPath};
 use rustc_lint::LateContext;
 use std::ops::ControlFlow;
@@ -84,7 +84,7 @@ struct VarCollectorVisitor<'a, 'tcx> {
     skip: bool,
 }
 
-impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
+impl<'tcx> VarCollectorVisitor<'_, 'tcx> {
     fn insert_def_id(&mut self, ex: &'tcx Expr<'_>) {
         if let ExprKind::Path(ref qpath) = ex.kind
             && let QPath::Resolved(None, _) = *qpath
@@ -103,7 +103,7 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for VarCollectorVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
         match ex.kind {
             ExprKind::Path(_) => self.insert_def_id(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 c171fa1c622..74467522619 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
@@ -5,13 +5,13 @@ use clippy_utils::visitors::is_res_used;
 use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutable, is_res_lang_ctor, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, LetStmt, Mutability, PatKind, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::ty::adjustment::Adjust;
-use rustc_span::symbol::sym;
 use rustc_span::Symbol;
+use rustc_span::symbol::sym;
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
     if let Some(higher::WhileLet { if_then, let_pat, let_expr, label, .. }) = higher::WhileLet::hir(expr)
@@ -283,7 +283,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
         found_local: bool,
         used_after: bool,
     }
-    impl<'a, 'b, 'tcx> Visitor<'tcx> for NestedLoopVisitor<'a, 'b, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for NestedLoopVisitor<'_, '_, 'tcx> {
         type NestedFilter = OnlyBodies;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
index e215097142b..312bcb55a95 100644
--- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
@@ -3,13 +3,13 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::is_lint_allowed;
 use itertools::Itertools;
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::intravisit::{walk_block, walk_expr, walk_stmt, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, HirId, Stmt, UnsafeSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span, SyntaxContext};
-use std::collections::btree_map::Entry;
+use rustc_span::{Span, SyntaxContext, sym};
 use std::collections::BTreeMap;
+use std::collections::btree_map::Entry;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -149,7 +149,7 @@ fn is_public_macro(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
         && !cx.tcx.is_doc_hidden(def_id)
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for BodyVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for BodyVisitor<'_, 'tcx> {
     fn visit_stmt(&mut self, s: &'tcx Stmt<'tcx>) {
         let from_expn = s.span.from_expansion();
         if from_expn {
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index 067384b0901..50680331fbc 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -8,7 +8,7 @@ use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::edition::Edition;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::collections::BTreeMap;
 
 declare_clippy_lint! {
@@ -81,7 +81,7 @@ impl MacroUseImports {
     }
 }
 
-impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
+impl LateLintPass<'_> for MacroUseImports {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
         if cx.sess().opts.edition >= Edition::Edition2018
             && let hir::ItemKind::Use(path, _kind) = &item.kind
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 61723aec590..81115cffdca 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -1,15 +1,15 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{position_before_rarrow, snippet_block, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, position_before_rarrow, snippet_block};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     Block, Body, Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, FnDecl,
-    FnRetTy, GenericArg, GenericBound, ImplItem, Item, ItemKind, LifetimeName, Node, TraitRef, Ty, TyKind,
+    FnRetTy, GenericArg, GenericBound, ImplItem, Item, LifetimeName, Node, TraitRef, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -105,9 +105,7 @@ fn future_trait_ref<'tcx>(
     cx: &LateContext<'tcx>,
     ty: &'tcx Ty<'tcx>,
 ) -> Option<(&'tcx TraitRef<'tcx>, Vec<LifetimeName>)> {
-    if let TyKind::OpaqueDef(item_id, bounds, false) = ty.kind
-        && let item = cx.tcx.hir().item(item_id)
-        && let ItemKind::OpaqueTy(opaque) = &item.kind
+    if let TyKind::OpaqueDef(opaque, bounds) = ty.kind
         && let Some(trait_ref) = opaque.bounds.iter().find_map(|bound| {
             if let GenericBound::Trait(poly, _) = bound {
                 Some(&poly.trait_ref)
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index 5cbdc7f864a..c0e87e8a1fa 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::get_parent_expr;
 use clippy_utils::source::snippet_with_context;
diff --git a/src/tools/clippy/clippy_lints/src/manual_clamp.rs b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
index 4123c933660..fd66cacdfe9 100644
--- a/src/tools/clippy/clippy_lints/src/manual_clamp.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::higher::If;
@@ -7,8 +7,8 @@ use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::visitors::is_const_evaluatable;
 use clippy_utils::{
-    eq_expr_value, is_diag_trait_item, is_in_const_context, is_trait_method, path_res, path_to_local_id, peel_blocks,
-    peel_blocks_with_stmt, MaybePath,
+    MaybePath, eq_expr_value, is_diag_trait_item, is_in_const_context, is_trait_method, path_res, path_to_local_id,
+    peel_blocks, peel_blocks_with_stmt,
 };
 use itertools::Itertools;
 use rustc_errors::{Applicability, Diag};
@@ -17,8 +17,8 @@ use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, HirId, PatKind, PathSegme
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 use std::cmp::Ordering;
 use std::ops::Deref;
 
@@ -741,7 +741,7 @@ enum MaybeBorrowedStmtKind<'a> {
     Owned(StmtKind<'a>),
 }
 
-impl<'a> Clone for MaybeBorrowedStmtKind<'a> {
+impl Clone for MaybeBorrowedStmtKind<'_> {
     fn clone(&self) -> Self {
         match self {
             Self::Borrowed(t) => Self::Borrowed(t),
diff --git a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
new file mode 100644
index 00000000000..00e02e2a336
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
@@ -0,0 +1,158 @@
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::SpanlessEq;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
+use rustc_ast::{BinOpKind, LitKind};
+use rustc_data_structures::packed::Pu128;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{self};
+use rustc_session::impl_lint_pass;
+use rustc_span::symbol::Symbol;
+
+use clippy_config::Conf;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for an expression like `(x + (y - 1)) / y` which is a common manual reimplementation
+    /// of `x.div_ceil(y)`.
+    ///
+    /// ### Why is this bad?
+    /// It's simpler, clearer and more readable.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let x: i32 = 7;
+    /// let y: i32 = 4;
+    /// let div = (x + (y - 1)) / y;
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// #![feature(int_roundings)]
+    /// let x: i32 = 7;
+    /// let y: i32 = 4;
+    /// let div = x.div_ceil(y);
+    /// ```
+    #[clippy::version = "1.81.0"]
+    pub MANUAL_DIV_CEIL,
+    complexity,
+    "manually reimplementing `div_ceil`"
+}
+
+pub struct ManualDivCeil {
+    msrv: Msrv,
+}
+
+impl ManualDivCeil {
+    #[must_use]
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+        }
+    }
+}
+
+impl_lint_pass!(ManualDivCeil => [MANUAL_DIV_CEIL]);
+
+impl<'tcx> LateLintPass<'tcx> for ManualDivCeil {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
+        if !self.msrv.meets(msrvs::MANUAL_DIV_CEIL) {
+            return;
+        }
+
+        let mut applicability = Applicability::MachineApplicable;
+
+        if let ExprKind::Binary(div_op, div_lhs, div_rhs) = expr.kind
+            && div_op.node == BinOpKind::Div
+            && check_int_ty_and_feature(cx, div_lhs)
+            && check_int_ty_and_feature(cx, div_rhs)
+            && let ExprKind::Binary(inner_op, inner_lhs, inner_rhs) = div_lhs.kind
+        {
+            // (x + (y - 1)) / y
+            if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind
+                && inner_op.node == BinOpKind::Add
+                && sub_op.node == BinOpKind::Sub
+                && check_literal(sub_rhs)
+                && check_eq_expr(cx, sub_lhs, div_rhs)
+            {
+                build_suggestion(cx, expr, inner_lhs, div_rhs, &mut applicability);
+                return;
+            }
+
+            // ((y - 1) + x) / y
+            if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind
+                && inner_op.node == BinOpKind::Add
+                && sub_op.node == BinOpKind::Sub
+                && check_literal(sub_rhs)
+                && check_eq_expr(cx, sub_lhs, div_rhs)
+            {
+                build_suggestion(cx, expr, inner_rhs, div_rhs, &mut applicability);
+                return;
+            }
+
+            // (x + y - 1) / y
+            if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind
+                && inner_op.node == BinOpKind::Sub
+                && add_op.node == BinOpKind::Add
+                && check_literal(inner_rhs)
+                && check_eq_expr(cx, add_rhs, div_rhs)
+            {
+                build_suggestion(cx, expr, add_lhs, div_rhs, &mut applicability);
+            }
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
+
+fn check_int_ty_and_feature(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    let expr_ty = cx.typeck_results().expr_ty(expr);
+    match expr_ty.peel_refs().kind() {
+        ty::Uint(_) => true,
+        ty::Int(_) => cx
+            .tcx
+            .features()
+            .declared_features
+            .contains(&Symbol::intern("int_roundings")),
+
+        _ => false,
+    }
+}
+
+fn check_literal(expr: &Expr<'_>) -> bool {
+    if let ExprKind::Lit(lit) = expr.kind
+        && let LitKind::Int(Pu128(1), _) = lit.node
+    {
+        return true;
+    }
+    false
+}
+
+fn check_eq_expr(cx: &LateContext<'_>, lhs: &Expr<'_>, rhs: &Expr<'_>) -> bool {
+    SpanlessEq::new(cx).eq_expr(lhs, rhs)
+}
+
+fn build_suggestion(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    lhs: &Expr<'_>,
+    rhs: &Expr<'_>,
+    applicability: &mut Applicability,
+) {
+    let dividend_sugg = Sugg::hir_with_applicability(cx, lhs, "..", applicability).maybe_par();
+    let divisor_snippet = snippet_with_applicability(cx, rhs.span.source_callsite(), "..", applicability);
+
+    let sugg = format!("{dividend_sugg}.div_ceil({divisor_snippet})");
+
+    span_lint_and_sugg(
+        cx,
+        MANUAL_DIV_CEIL,
+        expr.span,
+        "manually reimplementing `div_ceil`",
+        "consider using `.div_ceil()`",
+        sugg,
+        *applicability,
+    );
+}
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 11716a539ab..c62bd65bea6 100644
--- a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::visitors::{is_local_used, local_used_once};
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 31c37c3bc3b..24207705743 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
@@ -1,17 +1,17 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operators};
-use rustc_ast::ast::RangeLimits;
 use rustc_ast::LitKind::{Byte, Char};
+use rustc_ast::ast::RangeLimits;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Node, Param, PatKind, RangeEnd};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs b/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs
new file mode 100644
index 00000000000..da2a982ee17
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_is_power_of_two.rs
@@ -0,0 +1,142 @@
+use clippy_utils::SpanlessEq;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use rustc_ast::LitKind;
+use rustc_data_structures::packed::Pu128;
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::Uint;
+use rustc_session::declare_lint_pass;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for expressions like `x.count_ones() == 1` or `x & (x - 1) == 0`, with x and unsigned integer, which are manual
+    /// reimplementations of `x.is_power_of_two()`.
+    /// ### Why is this bad?
+    /// Manual reimplementations of `is_power_of_two` increase code complexity for little benefit.
+    /// ### Example
+    /// ```no_run
+    /// let a: u32 = 4;
+    /// let result = a.count_ones() == 1;
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let a: u32 = 4;
+    /// let result = a.is_power_of_two();
+    /// ```
+    #[clippy::version = "1.82.0"]
+    pub MANUAL_IS_POWER_OF_TWO,
+    complexity,
+    "manually reimplementing `is_power_of_two`"
+}
+
+declare_lint_pass!(ManualIsPowerOfTwo => [MANUAL_IS_POWER_OF_TWO]);
+
+impl LateLintPass<'_> for ManualIsPowerOfTwo {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        let mut applicability = Applicability::MachineApplicable;
+
+        if let ExprKind::Binary(bin_op, left, right) = expr.kind
+            && bin_op.node == BinOpKind::Eq
+        {
+            // a.count_ones() == 1
+            if let ExprKind::MethodCall(method_name, reciever, _, _) = left.kind
+                && method_name.ident.as_str() == "count_ones"
+                && let &Uint(_) = cx.typeck_results().expr_ty(reciever).kind()
+                && check_lit(right, 1)
+            {
+                build_sugg(cx, expr, reciever, &mut applicability);
+            }
+
+            // 1 == a.count_ones()
+            if let ExprKind::MethodCall(method_name, reciever, _, _) = right.kind
+                && method_name.ident.as_str() == "count_ones"
+                && let &Uint(_) = cx.typeck_results().expr_ty(reciever).kind()
+                && check_lit(left, 1)
+            {
+                build_sugg(cx, expr, reciever, &mut applicability);
+            }
+
+            // a & (a - 1) == 0
+            if let ExprKind::Binary(op1, left1, right1) = left.kind
+                && op1.node == BinOpKind::BitAnd
+                && let ExprKind::Binary(op2, left2, right2) = right1.kind
+                && op2.node == BinOpKind::Sub
+                && check_eq_expr(cx, left1, left2)
+                && let &Uint(_) = cx.typeck_results().expr_ty(left1).kind()
+                && check_lit(right2, 1)
+                && check_lit(right, 0)
+            {
+                build_sugg(cx, expr, left1, &mut applicability);
+            }
+
+            // (a - 1) & a == 0;
+            if let ExprKind::Binary(op1, left1, right1) = left.kind
+                && op1.node == BinOpKind::BitAnd
+                && let ExprKind::Binary(op2, left2, right2) = left1.kind
+                && op2.node == BinOpKind::Sub
+                && check_eq_expr(cx, right1, left2)
+                && let &Uint(_) = cx.typeck_results().expr_ty(right1).kind()
+                && check_lit(right2, 1)
+                && check_lit(right, 0)
+            {
+                build_sugg(cx, expr, right1, &mut applicability);
+            }
+
+            // 0 == a & (a - 1);
+            if let ExprKind::Binary(op1, left1, right1) = right.kind
+                && op1.node == BinOpKind::BitAnd
+                && let ExprKind::Binary(op2, left2, right2) = right1.kind
+                && op2.node == BinOpKind::Sub
+                && check_eq_expr(cx, left1, left2)
+                && let &Uint(_) = cx.typeck_results().expr_ty(left1).kind()
+                && check_lit(right2, 1)
+                && check_lit(left, 0)
+            {
+                build_sugg(cx, expr, left1, &mut applicability);
+            }
+
+            // 0 == (a - 1) & a
+            if let ExprKind::Binary(op1, left1, right1) = right.kind
+                && op1.node == BinOpKind::BitAnd
+                && let ExprKind::Binary(op2, left2, right2) = left1.kind
+                && op2.node == BinOpKind::Sub
+                && check_eq_expr(cx, right1, left2)
+                && let &Uint(_) = cx.typeck_results().expr_ty(right1).kind()
+                && check_lit(right2, 1)
+                && check_lit(left, 0)
+            {
+                build_sugg(cx, expr, right1, &mut applicability);
+            }
+        }
+    }
+}
+
+fn build_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, reciever: &Expr<'_>, applicability: &mut Applicability) {
+    let snippet = snippet_with_applicability(cx, reciever.span, "..", applicability);
+
+    span_lint_and_sugg(
+        cx,
+        MANUAL_IS_POWER_OF_TWO,
+        expr.span,
+        "manually reimplementing `is_power_of_two`",
+        "consider using `.is_power_of_two()`",
+        format!("{snippet}.is_power_of_two()"),
+        *applicability,
+    );
+}
+
+fn check_lit(expr: &Expr<'_>, expected_num: u128) -> bool {
+    if let ExprKind::Lit(lit) = expr.kind
+        && let LitKind::Int(Pu128(num), _) = lit.node
+        && num == expected_num
+    {
+        return true;
+    }
+    false
+}
+
+fn check_eq_expr(cx: &LateContext<'_>, lhs: &Expr<'_>, rhs: &Expr<'_>) -> bool {
+    SpanlessEq::new(cx).eq_expr(lhs, rhs)
+}
diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
index ebebdf679a8..17185df5d76 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -1,4 +1,4 @@
-use crate::question_mark::{QuestionMark, QUESTION_MARK};
+use crate::question_mark::{QUESTION_MARK, QuestionMark};
 use clippy_config::msrvs;
 use clippy_config::types::MatchLintBehaviour;
 use clippy_utils::diagnostics::span_lint_and_then;
@@ -12,8 +12,8 @@ use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
 
-use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{Symbol, sym};
 use std::slice;
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
index 5198d7838a2..85e99a92cf5 100644
--- a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::{is_trait_method, peel_hir_expr_refs};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 6b1d90483cc..25868ccae40 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -1,18 +1,18 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::is_doc_hidden;
-use clippy_utils::source::SpanRangeExt;
-use rustc_ast::ast::{self, VisibilityKind};
+use clippy_utils::source::snippet_indent;
+use itertools::Itertools;
 use rustc_ast::attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
-use rustc_hir::{self as hir, Expr, ExprKind, QPath};
-use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
+use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData};
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::{DefId, LocalDefId};
-use rustc_span::{sym, Span};
+use rustc_span::def_id::LocalDefId;
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -62,29 +62,13 @@ declare_clippy_lint! {
     "manual implementations of the non-exhaustive pattern can be simplified using #[non_exhaustive]"
 }
 
-#[expect(clippy::module_name_repetitions)]
-pub struct ManualNonExhaustiveStruct {
+pub struct ManualNonExhaustive {
     msrv: Msrv,
-}
-
-impl ManualNonExhaustiveStruct {
-    pub fn new(conf: &'static Conf) -> Self {
-        Self {
-            msrv: conf.msrv.clone(),
-        }
-    }
-}
-
-impl_lint_pass!(ManualNonExhaustiveStruct => [MANUAL_NON_EXHAUSTIVE]);
-
-#[expect(clippy::module_name_repetitions)]
-pub struct ManualNonExhaustiveEnum {
-    msrv: Msrv,
-    constructed_enum_variants: FxHashSet<(DefId, DefId)>,
+    constructed_enum_variants: FxHashSet<LocalDefId>,
     potential_enums: Vec<(LocalDefId, LocalDefId, Span, Span)>,
 }
 
-impl ManualNonExhaustiveEnum {
+impl ManualNonExhaustive {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
             msrv: conf.msrv.clone(),
@@ -94,96 +78,78 @@ impl ManualNonExhaustiveEnum {
     }
 }
 
-impl_lint_pass!(ManualNonExhaustiveEnum => [MANUAL_NON_EXHAUSTIVE]);
-
-impl EarlyLintPass for ManualNonExhaustiveStruct {
-    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
-        if let ast::ItemKind::Struct(variant_data, _) = &item.kind
-            && let (fields, delimiter) = match variant_data {
-                ast::VariantData::Struct { fields, .. } => (&**fields, '{'),
-                ast::VariantData::Tuple(fields, _) => (&**fields, '('),
-                ast::VariantData::Unit(_) => return,
-            }
-            && fields.len() > 1
-            && self.msrv.meets(msrvs::NON_EXHAUSTIVE)
-        {
-            let mut iter = fields.iter().filter_map(|f| match f.vis.kind {
-                VisibilityKind::Public => None,
-                VisibilityKind::Inherited => Some(Ok(f)),
-                VisibilityKind::Restricted { .. } => Some(Err(())),
-            });
-            if let Some(Ok(field)) = iter.next()
-                && iter.next().is_none()
-                && field.ty.kind.is_unit()
-            {
-                span_lint_and_then(
-                    cx,
-                    MANUAL_NON_EXHAUSTIVE,
-                    item.span,
-                    "this seems like a manual implementation of the non-exhaustive pattern",
-                    |diag| {
-                        if !item.attrs.iter().any(|attr| attr.has_name(sym::non_exhaustive))
-                            && let header_span = cx.sess().source_map().span_until_char(item.span, delimiter)
-                            && let Some(snippet) = header_span.get_source_text(cx)
-                        {
-                            diag.span_suggestion(
-                                header_span,
-                                "add the attribute",
-                                format!("#[non_exhaustive] {snippet}"),
-                                Applicability::Unspecified,
-                            );
-                        }
-                        diag.span_help(field.span, "remove this field");
-                    },
-                );
-            }
-        }
-    }
-
-    extract_msrv_attr!(EarlyContext);
-}
+impl_lint_pass!(ManualNonExhaustive => [MANUAL_NON_EXHAUSTIVE]);
 
-impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
-    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
-        if !self.msrv.meets(msrvs::NON_EXHAUSTIVE) {
+impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustive {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
+        if !self.msrv.meets(msrvs::NON_EXHAUSTIVE) || !cx.effective_visibilities.is_exported(item.owner_id.def_id) {
             return;
         }
 
-        if let hir::ItemKind::Enum(def, _) = &item.kind
-            && def.variants.len() > 1
-        {
-            let mut iter = def.variants.iter().filter_map(|v| {
-                (matches!(v.data, hir::VariantData::Unit(_, _))
-                    && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id))
-                    && !attr::contains_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive))
-                .then_some((v.def_id, v.span))
-            });
-            if let Some((id, span)) = iter.next()
-                && iter.next().is_none()
-            {
-                self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
-            }
+        match item.kind {
+            ItemKind::Enum(def, _) if def.variants.len() > 1 => {
+                let iter = def.variants.iter().filter_map(|v| {
+                    (matches!(v.data, VariantData::Unit(_, _)) && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id)))
+                        .then_some((v.def_id, v.span))
+                });
+                if let Ok((id, span)) = iter.exactly_one()
+                    && !attr::contains_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive)
+                {
+                    self.potential_enums.push((item.owner_id.def_id, id, item.span, span));
+                }
+            },
+            ItemKind::Struct(variant_data, _) => {
+                let fields = variant_data.fields();
+                let private_fields = fields
+                    .iter()
+                    .filter(|field| !cx.effective_visibilities.is_exported(field.def_id));
+                if fields.len() > 1
+                    && let Ok(field) = private_fields.exactly_one()
+                    && let TyKind::Tup([]) = field.ty.kind
+                {
+                    span_lint_and_then(
+                        cx,
+                        MANUAL_NON_EXHAUSTIVE,
+                        item.span,
+                        "this seems like a manual implementation of the non-exhaustive pattern",
+                        |diag| {
+                            if let Some(non_exhaustive) =
+                                attr::find_by_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive)
+                            {
+                                diag.span_note(non_exhaustive.span, "the struct is already non-exhaustive");
+                            } else {
+                                let indent = snippet_indent(cx, item.span).unwrap_or_default();
+                                diag.span_suggestion_verbose(
+                                    item.span.shrink_to_lo(),
+                                    "use the `#[non_exhaustive]` attribute instead",
+                                    format!("#[non_exhaustive]\n{indent}"),
+                                    Applicability::MaybeIncorrect,
+                                );
+                            }
+                            diag.span_help(field.span, "remove this field");
+                        },
+                    );
+                }
+            },
+            _ => {},
         }
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if let ExprKind::Path(QPath::Resolved(None, p)) = &e.kind
-            && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), id) = p.res
+            && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), ctor_id) = p.res
+            && let Some(local_ctor) = ctor_id.as_local()
         {
-            let variant_id = cx.tcx.parent(id);
-            let enum_id = cx.tcx.parent(variant_id);
-
-            self.constructed_enum_variants.insert((enum_id, variant_id));
+            let variant_id = cx.tcx.local_parent(local_ctor);
+            self.constructed_enum_variants.insert(variant_id);
         }
     }
 
     fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
-        for &(enum_id, _, enum_span, variant_span) in
-            self.potential_enums.iter().filter(|&&(enum_id, variant_id, _, _)| {
-                !self
-                    .constructed_enum_variants
-                    .contains(&(enum_id.to_def_id(), variant_id.to_def_id()))
-            })
+        for &(enum_id, _, enum_span, variant_span) in self
+            .potential_enums
+            .iter()
+            .filter(|(_, variant_id, _, _)| !self.constructed_enum_variants.contains(variant_id))
         {
             let hir_id = cx.tcx.local_def_id_to_hir_id(enum_id);
             span_lint_hir_and_then(
@@ -193,15 +159,13 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
                 enum_span,
                 "this seems like a manual implementation of the non-exhaustive pattern",
                 |diag| {
-                    let header_span = cx.sess().source_map().span_until_char(enum_span, '{');
-                    if let Some(snippet) = header_span.get_source_text(cx) {
-                        diag.span_suggestion(
-                            header_span,
-                            "add the attribute",
-                            format!("#[non_exhaustive] {snippet}"),
-                            Applicability::Unspecified,
-                        );
-                    }
+                    let indent = snippet_indent(cx, enum_span).unwrap_or_default();
+                    diag.span_suggestion_verbose(
+                        enum_span.shrink_to_lo(),
+                        "use the `#[non_exhaustive]` attribute instead",
+                        format!("#[non_exhaustive]\n{indent}"),
+                        Applicability::MaybeIncorrect,
+                    );
                     diag.span_help(variant_span, "remove this variant");
                 },
             );
diff --git a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
index 9afb2b5bc84..ffa3eacf354 100644
--- a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
@@ -7,7 +7,7 @@ use rustc_hir::{Expr, ExprKind, PatKind, RangeEnd, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
-use rustc_span::{Span, DUMMY_SP};
+use rustc_span::{DUMMY_SP, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -77,9 +77,10 @@ impl Num {
 impl LateLintPass<'_> for ManualRangePatterns {
     fn check_pat(&mut self, cx: &LateContext<'_>, pat: &'_ rustc_hir::Pat<'_>) {
         // a pattern like 1 | 2 seems fine, lint if there are at least 3 alternatives
-        // or at least one range
+        // or more then one range (exclude triggering on stylistic using OR with one element
+        // like described https://github.com/rust-lang/rust-clippy/issues/11825)
         if let PatKind::Or(pats) = pat.kind
-            && (pats.len() >= 3 || pats.iter().any(|p| matches!(p.kind, PatKind::Range(..))))
+            && (pats.len() >= 3 || (pats.len() > 1 && pats.iter().any(|p| matches!(p.kind, PatKind::Range(..)))))
             && !in_external_macro(cx.sess(), pat.span)
         {
             let mut min = Num::dummy(i128::MAX);
diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
index 6cf5d272d7d..86293169ea2 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, FullInt};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_context;
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index a35b0f914e0..a60163be770 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -1,17 +1,17 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::SpanlessEq;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
-use clippy_utils::SpanlessEq;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
 use rustc_hir::ExprKind::Assign;
+use rustc_hir::def_id::DefId;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{Symbol, sym};
 
 const ACCEPTABLE_METHODS: [Symbol; 5] = [
     sym::binaryheap_iter,
diff --git a/src/tools/clippy/clippy_lints/src/manual_string_new.rs b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
index 781db4b97f0..198f7aaddc7 100644
--- a/src/tools/clippy/clippy_lints/src/manual_string_new.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
@@ -5,7 +5,7 @@ use rustc_hir::{Expr, ExprKind, PathSegment, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, symbol, Span};
+use rustc_span::{Span, sym, symbol};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 02d433ecc5a..828c5a3f6ff 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
@@ -8,13 +8,13 @@ use clippy_utils::{eq_expr_value, higher};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::iter;
 
 declare_clippy_lint! {
@@ -203,7 +203,7 @@ fn find_stripping<'tcx>(
         results: Vec<Span>,
     }
 
-    impl<'a, 'tcx> Visitor<'tcx> for StrippingFinder<'a, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for StrippingFinder<'_, 'tcx> {
         fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
             if is_ref_str(self.cx, ex)
                 && let unref = peel_ref(ex)
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index 2db71b1f7a3..3221a04d2d0 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -7,7 +7,7 @@ use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -251,7 +251,7 @@ fn lint_map_unit_fn(
     }
 }
 
-impl<'tcx> LateLintPass<'tcx> for MapUnit {
+impl LateLintPass<'_> for MapUnit {
     fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) {
         if let hir::StmtKind::Semi(expr) = stmt.kind
             && !stmt.span.from_expansion()
diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
index b666e77c09e..50e6dfc6298 100644
--- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
@@ -4,7 +4,7 @@ use clippy_utils::higher::IfLetOrMatch;
 use clippy_utils::source::snippet;
 use clippy_utils::visitors::is_local_used;
 use clippy_utils::{
-    is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt, peel_ref_operators, SpanlessEq,
+    SpanlessEq, is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt, peel_ref_operators,
 };
 use rustc_errors::MultiSpan;
 use rustc_hir::LangItem::OptionNone;
@@ -12,7 +12,7 @@ use rustc_hir::{Arm, Expr, HirId, Pat, PatKind};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
-use super::{pat_contains_disallowed_or, COLLAPSIBLE_MATCH};
+use super::{COLLAPSIBLE_MATCH, pat_contains_disallowed_or};
 
 pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], msrv: &Msrv) {
     if let Some(els_arm) = arms.iter().rfind(|arm| arm_is_wild_like(cx, arm)) {
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs b/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
index 619ec83127a..cfa054706d6 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
@@ -6,10 +6,10 @@ use clippy_utils::{is_res_lang_ctor, path_res, path_to_local_id};
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_hir::{Arm, Expr, ExprKind, HirId, Pat, PatKind};
 use rustc_lint::LateContext;
-use rustc_span::{sym, SyntaxContext};
+use rustc_span::{SyntaxContext, sym};
 
-use super::manual_utils::{check_with, SomeExpr};
 use super::MANUAL_FILTER;
+use super::manual_utils::{SomeExpr, check_with};
 
 // Function called on the <expr> of `[&+]Some((ref | ref mut) x) => <expr>`
 // Need to check if it's of the form `<expr>=if <cond> {<then_expr>} else {<else_expr>}`
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_map.rs b/src/tools/clippy/clippy_lints/src/matches/manual_map.rs
index ed3d8b09fdc..de57d1eee92 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_map.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_map.rs
@@ -1,5 +1,5 @@
-use super::manual_utils::{check_with, SomeExpr};
 use super::MANUAL_MAP;
+use super::manual_utils::{SomeExpr, check_with};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 
 use clippy_utils::{is_res_lang_ctor, path_res};
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
index d5d83df9347..59d37520011 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
@@ -1,12 +1,12 @@
 use clippy_utils::consts::ConstEvalCtxt;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{indent_of, reindent_multiline, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, indent_of, reindent_multiline};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::usage::contains_return_break_continue_macro;
 use clippy_utils::{is_res_lang_ctor, path_to_local_id, peel_blocks, sugg};
 use rustc_errors::Applicability;
-use rustc_hir::def::{DefKind, Res};
 use rustc_hir::LangItem::{OptionNone, ResultErr};
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Arm, Expr, Pat, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
index be80aebed6d..d38560998a5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
@@ -4,16 +4,16 @@ use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{is_copy, is_type_diagnostic_item, peel_mid_ty_refs_is_mutable, type_is_unsafe_function};
 use clippy_utils::{
-    can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res, path_to_local_id,
-    peel_blocks, peel_hir_expr_refs, peel_hir_expr_while, CaptureKind,
+    CaptureKind, can_move_expr_to_closure, is_else_clause, is_lint_allowed, is_res_lang_ctor, path_res,
+    path_to_local_id, peel_blocks, peel_hir_expr_refs, peel_hir_expr_while,
 };
 use rustc_ast::util::parser::PREC_UNAMBIGUOUS;
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
+use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatKind, Path, QPath};
 use rustc_lint::LateContext;
-use rustc_span::{sym, SyntaxContext};
+use rustc_span::{SyntaxContext, sym};
 
 #[expect(clippy::too_many_arguments)]
 #[expect(clippy::too_many_lines)]
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index da8c918a62b..f9ffbc5dc0b 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_lint_allowed, path_to_local, search_same, SpanlessEq, SpanlessHash};
+use clippy_utils::{SpanlessEq, SpanlessHash, is_lint_allowed, path_to_local, search_same};
 use core::cmp::Ordering;
 use core::{iter, slice};
 use rustc_arena::DroplessArena;
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 322e9c3ebe5..463aa602bc8 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
@@ -2,12 +2,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::is_type_lang_item;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Arm, Expr, ExprKind, LangItem, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::symbol::Symbol;
 use rustc_span::Span;
+use rustc_span::symbol::Symbol;
 
 use super::MATCH_STR_CASE_MISMATCH;
 
@@ -40,7 +40,7 @@ struct MatchExprVisitor<'a, 'tcx> {
     case_method: Option<CaseMethod>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for MatchExprVisitor<'a, 'tcx> {
+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) => {},
@@ -49,7 +49,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchExprVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> MatchExprVisitor<'a, 'tcx> {
+impl MatchExprVisitor<'_, '_> {
     fn case_altered(&mut self, segment_ident: &str, receiver: &Expr<'_>) -> bool {
         if let Some(case_method) = get_case_method(segment_ident) {
             let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index cf5377e0725..28adcc2f227 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -24,8 +24,8 @@ mod single_match;
 mod try_err;
 mod wild_in_or_pats;
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::source::walk_span_to_context;
 use clippy_utils::{higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg};
 use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
@@ -1045,7 +1045,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
             if !from_expansion {
                 // These don't depend on a relationship between multiple arms
                 match_wild_err_arm::check(cx, ex, arms);
-                wild_in_or_pats::check(cx, arms);
+                wild_in_or_pats::check(cx, ex, arms);
             }
 
             if let MatchSource::TryDesugar(_) = source {
diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
index 71f211be925..856311899f2 100644
--- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
@@ -1,4 +1,4 @@
-use clippy_utils::consts::{mir_to_const, ConstEvalCtxt, FullInt};
+use clippy_utils::consts::{ConstEvalCtxt, FullInt, mir_to_const};
 use clippy_utils::diagnostics::span_lint_and_note;
 use core::cmp::Ordering;
 use rustc_hir::{Arm, Expr, PatKind, RangeEnd};
@@ -96,13 +96,13 @@ where
     #[derive(Copy, Clone, Debug, Eq, PartialEq)]
     struct RangeBound<'a, T>(T, BoundKind, &'a SpannedRange<T>);
 
-    impl<'a, T: Copy + Ord> PartialOrd for RangeBound<'a, T> {
+    impl<T: Copy + Ord> PartialOrd for RangeBound<'_, T> {
         fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
             Some(self.cmp(other))
         }
     }
 
-    impl<'a, T: Copy + Ord> Ord for RangeBound<'a, T> {
+    impl<T: Copy + Ord> Ord for RangeBound<'_, T> {
         fn cmp(&self, RangeBound(other_value, other_kind, _): &Self) -> Ordering {
             let RangeBound(self_value, self_kind, _) = *self;
             (self_value, self_kind).cmp(&(*other_value, *other_kind))
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 8222c3057f7..564c598a334 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -10,11 +10,11 @@ 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::{sym, Span, Symbol};
+use rustc_span::{Span, Symbol, sym};
 use std::borrow::Cow;
 use std::ops::ControlFlow;
 
-use super::{pat_contains_disallowed_or, REDUNDANT_GUARDS};
+use super::{REDUNDANT_GUARDS, pat_contains_disallowed_or};
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>], msrv: &Msrv) {
     for outer_arm in arms {
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 0e4b2d9d34a..b646e87a439 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
@@ -1,18 +1,18 @@
 use super::REDUNDANT_PATTERN_MATCHING;
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::{snippet, walk_span_to_context};
-use clippy_utils::sugg::{make_unop, Sugg};
+use clippy_utils::sugg::{Sugg, make_unop};
 use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop};
 use clippy_utils::visitors::{any_temporaries_need_ordered_drop, for_each_expr_without_closures};
 use clippy_utils::{higher, is_expn_of, is_trait_method};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::def::{DefKind, Res};
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk};
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{Span, Symbol, sym};
 use std::fmt::Write;
 use std::ops::ControlFlow;
 
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 9c2f42d2187..7372f52e1e5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -8,7 +8,7 @@ use clippy_utils::{get_attr, is_lint_allowed};
 use itertools::Itertools;
 use rustc_ast::Mutability;
 use rustc_errors::{Applicability, Diag};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Arm, Expr, ExprKind, MatchSource};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty::{GenericArgKind, Region, RegionKind, Ty, TyCtxt, TypeVisitable, TypeVisitor};
@@ -424,7 +424,7 @@ fn ty_has_erased_regions(ty: Ty<'_>) -> bool {
     ty.visit_with(&mut V).is_break()
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
         // We've emitted a lint on some neighborhood expression. That lint will suggest to move out the
         // _parent_ expression (not the expression itself). Since we decide to move out the parent
@@ -495,7 +495,7 @@ fn has_significant_drop_in_arms<'tcx>(cx: &LateContext<'tcx>, arms: &[&'tcx Expr
     helper.found_sig_drop_spans
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ArmSigDropHelper<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ArmSigDropHelper<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
         if self.sig_drop_checker.is_sig_drop_expr(ex) {
             self.found_sig_drop_spans.insert(ex.span);
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 b6930f7b9d1..2eda238ae8c 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{expr_block, snippet, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, expr_block, snippet, snippet_block_with_context};
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{
     is_lint_allowed, is_unit_expr, peel_blocks, peel_hir_pat_refs, peel_middle_ty_refs, peel_n_hir_expr_refs,
@@ -8,11 +8,11 @@ use core::ops::ControlFlow;
 use rustc_arena::DroplessArena;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::{walk_pat, Visitor};
-use rustc_hir::{Arm, Expr, ExprKind, HirId, Pat, PatKind, QPath};
+use rustc_hir::intravisit::{Visitor, walk_pat};
+use rustc_hir::{Arm, Expr, ExprKind, HirId, Node, Pat, PatKind, QPath, StmtKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, AdtDef, ParamEnv, TyCtxt, TypeckResults, VariantDef};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::{MATCH_BOOL, SINGLE_MATCH, SINGLE_MATCH_ELSE};
 
@@ -91,6 +91,29 @@ fn report_single_pattern(cx: &LateContext<'_>, ex: &Expr<'_>, arm: &Arm<'_>, exp
         format!(" else {}", expr_block(cx, els, ctxt, "..", Some(expr.span), &mut app))
     });
 
+    if snippet(cx, ex.span, "..") == snippet(cx, arm.pat.span, "..") {
+        let msg = "this pattern is irrefutable, `match` is useless";
+        let (sugg, help) = if is_unit_expr(arm.body) {
+            (String::new(), "`match` expression can be removed")
+        } else {
+            let mut sugg = snippet_block_with_context(cx, arm.body.span, ctxt, "..", Some(expr.span), &mut app)
+                .0
+                .to_string();
+            if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id)
+                && let StmtKind::Expr(_) = stmt.kind
+                && match arm.body.kind {
+                    ExprKind::Block(block, _) => block.span.from_expansion(),
+                    _ => true,
+                }
+            {
+                sugg.push(';');
+            }
+            (sugg, "try")
+        };
+        span_lint_and_sugg(cx, lint, expr.span, msg, help, sugg.to_string(), app);
+        return;
+    }
+
     let (pat, pat_ref_count) = peel_hir_pat_refs(arm.pat);
     let (msg, sugg) = if let PatKind::Path(_) | PatKind::Lit(_) = pat.kind
         && let (ty, ty_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(ex))
diff --git a/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs b/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs
index 459513e65bf..390ba889fd2 100644
--- a/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs
@@ -1,11 +1,19 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_wild;
-use rustc_hir::{Arm, PatKind};
+use clippy_utils::{has_non_exhaustive_attr, is_wild};
+use rustc_hir::{Arm, Expr, PatKind};
 use rustc_lint::LateContext;
+use rustc_middle::ty;
 
 use super::WILDCARD_IN_OR_PATTERNS;
 
-pub(crate) fn check(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
+pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arms: &[Arm<'_>]) {
+    // first check if we are matching on an enum that has the non_exhaustive attribute
+    let ty = cx.typeck_results().expr_ty(expr).peel_refs();
+    if let ty::Adt(adt_def, _) = ty.kind()
+        && has_non_exhaustive_attr(cx.tcx, *adt_def)
+    {
+        return;
+    };
     for arm in arms {
         if let PatKind::Or(fields) = arm.pat.kind {
             // look for multiple fields in this arm that contains at least one Wild pattern
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index 72a5945ad9b..146748734cf 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
@@ -13,8 +13,8 @@ use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
index 2a8a5fcc3b6..91a5de16e96 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
@@ -1,4 +1,4 @@
-use super::{contains_return, BIND_INSTEAD_OF_MAP};
+use super::{BIND_INSTEAD_OF_MAP, contains_return};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::peel_blocks;
 use clippy_utils::source::{snippet, snippet_with_context};
diff --git a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
index 740cce0a6c2..76bdbe55e2f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{indent_of, reindent_multiline, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, indent_of, reindent_multiline};
 use clippy_utils::ty::is_type_lang_item;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, LangItem};
 use rustc_lint::LateContext;
-use rustc_span::source_map::Spanned;
 use rustc_span::Span;
+use rustc_span::source_map::Spanned;
 
 use super::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs b/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs
index 5389861245a..6e24cabca8b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs
@@ -4,8 +4,8 @@ use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, LangItem, QPath};
 use rustc_lint::LateContext;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 use super::CLEAR_WITH_DRAIN;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
index e7a2060be04..79a473e0e6f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
@@ -7,7 +7,7 @@ use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::{self};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
 
 use super::CLONE_ON_COPY;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
index e0826b53004..96e2de0dc1c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_ref_ptr.rs
@@ -4,7 +4,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
 
 use super::CLONE_ON_REF_PTR;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
index fcafa162236..fa04f74eec1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::CLONED_INSTEAD_OF_COPIED;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs b/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
index 1fab6c0e499..f7bf8764bde 100644
--- a/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/collapsible_str_replace.rs
@@ -8,7 +8,7 @@ use rustc_hir as hir;
 use rustc_lint::LateContext;
 use std::collections::VecDeque;
 
-use super::{method_call, COLLAPSIBLE_STR_REPLACE};
+use super::{COLLAPSIBLE_STR_REPLACE, method_call};
 
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
diff --git a/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs b/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
index 56171a13452..10360b4817b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
@@ -8,7 +8,7 @@ use rustc_hir::{Expr, ExprKind, LangItem, Path, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_middle::ty::Ty;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 
 /// Checks if both types match the given diagnostic item, e.g.:
 ///
diff --git a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
index dc978c8a584..3b1adb16b80 100644
--- a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_middle::ty::Ty;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 pub(super) fn check(
     cx: &LateContext<'_>,
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
index c9f56e1d980..2922086522c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::macros::{format_args_inputs_span, root_macro_call_first_node, FormatArgsStorage};
+use clippy_utils::macros::{FormatArgsStorage, format_args_inputs_span, root_macro_call_first_node};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 use std::borrow::Cow;
 
 use super::EXPECT_FUN_CALL;
diff --git a/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs b/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs
index 2ab0401947c..35008c39c08 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs
@@ -3,7 +3,7 @@ use clippy_utils::get_parent_expr;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::FILETYPE_IS_FILE;
 
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 02a11257007..06482a743dd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::macros::{is_panic, matching_root_macro_call, root_macro_call};
 use clippy_utils::source::{indent_of, reindent_multiline, snippet};
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{higher, is_trait_method, path_to_local_id, peel_blocks, SpanlessEq};
+use clippy_utils::{SpanlessEq, higher, is_trait_method, path_to_local_id, peel_blocks};
 use hir::{Body, HirId, MatchSource, Pat};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -10,8 +10,8 @@ use rustc_hir::def::Res;
 use rustc_hir::{Closure, Expr, ExprKind, PatKind, PathSegment, QPath, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::Adjust;
-use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{Ident, Symbol, sym};
 use std::borrow::Cow;
 
 use super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP, RESULT_FILTER_MAP};
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index 77a62fbb4fb..129e6925428 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -7,9 +7,9 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::Binder;
-use rustc_span::{sym, Span};
+use rustc_middle::ty::adjustment::Adjust;
+use rustc_span::{Span, sym};
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &Expr<'_>, call_span: Span) {
     if !in_external_macro(cx.sess(), expr.span)
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
index 999df875c75..cf7f276dabb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
@@ -3,7 +3,7 @@ use clippy_utils::{is_expr_identity_function, is_expr_untyped_identity_function,
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::FILTER_MAP_IDENTITY;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs
index 651ea34f9d0..0c2ecfbc8ff 100644
--- a/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/flat_map_identity.rs
@@ -3,7 +3,7 @@ use clippy_utils::{is_expr_untyped_identity_function, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::FLAT_MAP_IDENTITY;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs b/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs
index 0a4a381b861..3242dcadb70 100644
--- a/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs
@@ -4,7 +4,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::FLAT_MAP_OPTION;
 use clippy_utils::ty::is_type_diagnostic_item;
diff --git a/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs b/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
index 62037651134..5f6fb4c821d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_integer_literal, SpanlessEq};
+use clippy_utils::{SpanlessEq, is_integer_literal};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
index 230a8eb2ec4..4ed7de81ea3 100644
--- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
@@ -5,7 +5,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{Symbol, sym};
 
 use super::INEFFICIENT_TO_STRING;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/inspect_for_each.rs b/src/tools/clippy/clippy_lints/src/methods/inspect_for_each.rs
index ad4b6fa130e..3706f3b670b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/inspect_for_each.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/inspect_for_each.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_trait_method;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::INSPECT_FOR_EACH;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs b/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
index bbc7ce8d78a..bedeb63367d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
@@ -5,8 +5,8 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{Symbol, sym};
 
 use super::INTO_ITER_ON_REF;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs
index b93d51eac64..f6612c984a7 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs
@@ -10,8 +10,8 @@ use clippy_utils::{get_parent_expr, is_trait_method, peel_blocks, span_contains_
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::QPath;
-use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{Ident, Symbol, sym};
 use std::borrow::Cow;
 
 ///
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
index 33de3b87abc..390dd24b505 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
@@ -14,7 +14,6 @@ use rustc_span::sym;
 /// - `hashmap.into_iter().map(|(_, v)| v)`
 ///
 /// on `HashMaps` and `BTreeMaps` in std
-
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
     map_type: &'tcx str,     // iter / into_iter
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs b/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs
index e31fa2f777d..82bda5d9512 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs
@@ -3,8 +3,8 @@ use clippy_utils::ty::get_type_diagnostic_name;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 use super::ITER_NTH;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 7f6b666e434..9d562f5e51d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -5,9 +5,9 @@ use clippy_utils::source::snippet;
 use clippy_utils::{get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core};
 
 use rustc_errors::Applicability;
+use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_hir::def_id::DefId;
 use rustc_hir::hir_id::HirId;
-use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_hir::{Expr, ExprKind, Node};
 use rustc_lint::LateContext;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs b/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
index 1378a07cbc4..16305871337 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
@@ -3,8 +3,8 @@ use clippy_utils::is_range_full;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 use super::ITER_WITH_DRAIN;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs b/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
index 2dad7fcf3c1..2ad070793cb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/join_absolute_paths.rs
@@ -6,8 +6,8 @@ use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 use super::JOIN_ABSOLUTE_PATHS;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
index cb9fb373c10..96af9db1af7 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
@@ -6,7 +6,7 @@ use rustc_ast::{LitKind, StrStyle};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Node, QPath, TyKind};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{Span, Symbol, sym};
 
 use super::MANUAL_C_STR_LITERALS;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
index cac2e11f591..64c19c327b2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
@@ -3,13 +3,13 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{IntoSpan, SpanRangeExt};
 use clippy_utils::ty::get_field_by_name;
 use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures};
-use clippy_utils::{expr_use_ctxt, is_diag_item_method, is_diag_trait_item, path_to_local_id, ExprUseNode};
+use clippy_utils::{ExprUseNode, expr_use_ctxt, is_diag_item_method, is_diag_trait_item, path_to_local_id};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::{BindingMode, BorrowKind, ByRef, ClosureKind, Expr, ExprKind, Mutability, Node, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
-use rustc_span::{sym, Span, Symbol, DUMMY_SP};
+use rustc_span::{DUMMY_SP, Span, Symbol, sym};
 
 use super::MANUAL_INSPECT;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
index d29acd4622a..c377abd6237 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::MANUAL_IS_VARIANT_AND;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
index b1a8e1e5e47..4321dd6b0e0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{indent_of, reindent_multiline, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, indent_of, reindent_multiline};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{is_res_lang_ctor, path_res, path_to_local_id};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
index 11fba35c16e..31449d41770 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs
@@ -8,7 +8,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::MANUAL_TRY_FOLD;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
index 08ce7e204dd..ac378ff3702 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
@@ -11,7 +11,7 @@ use rustc_middle::mir::Mutability;
 use rustc_middle::ty;
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::MAP_CLONE;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
index 22a03825194..07a7a12b162 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
@@ -6,8 +6,8 @@ use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 use super::MAP_FLATTEN;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
index 5dd7b1b02ad..1f204de01da 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
@@ -4,7 +4,7 @@ use clippy_utils::{is_expr_untyped_identity_function, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::MAP_IDENTITY;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index f61bb3a6bf4..7696dd16b25 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -111,6 +111,7 @@ mod uninit_assumed_init;
 mod unit_hash;
 mod unnecessary_fallible_conversions;
 mod unnecessary_filter_map;
+mod unnecessary_first_then_check;
 mod unnecessary_fold;
 mod unnecessary_get_then_check;
 mod unnecessary_iter_cloned;
@@ -131,8 +132,8 @@ mod waker_clone_wake;
 mod wrong_self_convention;
 mod zst_offset;
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
 use clippy_utils::macros::FormatArgsStorage;
@@ -146,7 +147,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, TraitRef, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -441,6 +442,17 @@ declare_clippy_lint! {
     ///     }
     /// }
     /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// # struct X;
+    /// impl X {
+    ///     fn as_str(&self) -> &'static str {
+    ///         // ..
+    /// # ""
+    ///     }
+    /// }
+    /// ```
     #[clippy::version = "pre 1.29.0"]
     pub WRONG_SELF_CONVENTION,
     style,
@@ -3964,7 +3976,7 @@ declare_clippy_lint! {
     /// ```no_run
     /// let _ = 0;
     /// ```
-    #[clippy::version = "1.78.0"]
+    #[clippy::version = "1.81.0"]
     pub UNNECESSARY_MIN_OR_MAX,
     complexity,
     "using 'min()/max()' when there is no need for it"
@@ -4025,7 +4037,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.78.0"]
     pub MANUAL_C_STR_LITERALS,
-    pedantic,
+    complexity,
     r#"creating a `CStr` through functions when `c""` literals can be used"#
 }
 
@@ -4099,7 +4111,7 @@ declare_clippy_lint! {
     /// ```no_run
     /// "foo".is_ascii();
     /// ```
-    #[clippy::version = "1.80.0"]
+    #[clippy::version = "1.81.0"]
     pub NEEDLESS_CHARACTER_ITERATION,
     suspicious,
     "is_ascii() called on a char iterator"
@@ -4126,6 +4138,34 @@ declare_clippy_lint! {
     "use of `map` returning the original item"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks the usage of `.first().is_some()` or `.first().is_none()` to check if a slice is
+    /// empty.
+    ///
+    /// ### Why is this bad?
+    /// Using `.is_empty()` is shorter and better communicates the intention.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let v = vec![1, 2, 3];
+    /// if v.first().is_none() {
+    ///     // The vector is empty...
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let v = vec![1, 2, 3];
+    /// if v.is_empty() {
+    ///     // The vector is empty...
+    /// }
+    /// ```
+    #[clippy::version = "1.83.0"]
+    pub UNNECESSARY_FIRST_THEN_CHECK,
+    complexity,
+    "calling `.first().is_some()` or `.first().is_none()` instead of `.is_empty()`"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Msrv,
@@ -4283,6 +4323,7 @@ impl_lint_pass!(Methods => [
     UNNECESSARY_RESULT_MAP_OR_ELSE,
     MANUAL_C_STR_LITERALS,
     UNNECESSARY_GET_THEN_CHECK,
+    UNNECESSARY_FIRST_THEN_CHECK,
     NEEDLESS_CHARACTER_ITERATION,
     MANUAL_INSPECT,
     UNNECESSARY_MIN_OR_MAX,
@@ -5055,6 +5096,9 @@ fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>,
         Some(("get", f_recv, [arg], _, _)) => {
             unnecessary_get_then_check::check(cx, call_span, recv, f_recv, arg, is_some);
         },
+        Some(("first", f_recv, [], _, _)) => {
+            unnecessary_first_then_check::check(cx, call_span, recv, f_recv, is_some);
+        },
         _ => {},
     }
 }
@@ -5130,12 +5174,9 @@ impl ShouldImplTraitCase {
     fn lifetime_param_cond(&self, impl_item: &hir::ImplItem<'_>) -> bool {
         self.lint_explicit_lifetime
             || !impl_item.generics.params.iter().any(|p| {
-                matches!(
-                    p.kind,
-                    hir::GenericParamKind::Lifetime {
-                        kind: hir::LifetimeParamKind::Explicit
-                    }
-                )
+                matches!(p.kind, hir::GenericParamKind::Lifetime {
+                    kind: hir::LifetimeParamKind::Explicit
+                })
             })
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
index 1a0fce2876d..320523aceb6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
@@ -1,17 +1,17 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::expr_custom_deref_adjustment;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
-use rustc_middle::ty;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::MUT_MUTEX_LOCK;
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &'tcx Expr<'tcx>, name_span: Span) {
     if matches!(expr_custom_deref_adjustment(cx, recv), None | Some(Mutability::Mut))
-        && let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind()
+        && let (_, ref_depth, Mutability::Mut) = peel_mid_ty_refs_is_mutable(cx.typeck_results().expr_ty(recv))
+        && ref_depth >= 1
         && let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id)
         && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
         && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Mutex)
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs b/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs
index 332da722a37..348f740e7dd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_character_iteration.rs
@@ -4,8 +4,8 @@ use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::Span;
 
-use super::utils::get_last_chain_binding_hir_id;
 use super::NEEDLESS_CHARACTER_ITERATION;
+use super::utils::get_last_chain_binding_hir_id;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{match_def_path, path_to_local_id, peel_blocks};
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 f61923e5bf5..c58e27e37ad 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -4,12 +4,12 @@ use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{get_type_diagnostic_name, make_normalized_projection, make_projection};
 use clippy_utils::{
-    can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local, path_to_local_id,
-    CaptureKind,
+    CaptureKind, can_move_expr_to_closure, fn_def_id, get_enclosing_block, higher, is_trait_method, path_to_local,
+    path_to_local_id,
 };
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, MultiSpan};
-use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_block, walk_expr};
 use rustc_hir::{
     BindingMode, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, PatKind, Stmt, StmtKind,
 };
@@ -17,7 +17,7 @@ use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, AssocKind, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, Ty};
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed";
 
@@ -441,7 +441,7 @@ struct UsedCountVisitor<'a, 'tcx> {
     count: usize,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for UsedCountVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for UsedCountVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs b/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
index 9f714fdd47b..538aa9097a4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_option_as_deref.rs
@@ -4,8 +4,8 @@ use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::usage::local_used_after_expr;
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
 use rustc_hir::Expr;
+use rustc_hir::def::Res;
 use rustc_lint::LateContext;
 use rustc_span::sym;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs b/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs
index a301a5f7d65..32f32f1b216 100644
--- a/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/no_effect_replace.rs
@@ -1,6 +1,6 @@
+use clippy_utils::SpanlessEq;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::is_type_lang_item;
-use clippy_utils::SpanlessEq;
 use rustc_ast::LitKind;
 use rustc_hir::{ExprKind, LangItem};
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
index f1a3c81cebb..da084871402 100644
--- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
@@ -8,7 +8,7 @@ use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
 use rustc_span::source_map::Spanned;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::{NONSENSICAL_OPEN_OPTIONS, SUSPICIOUS_OPEN_OPTIONS};
 
@@ -126,17 +126,13 @@ fn get_open_options(
         && let ExprKind::Path(path) = callee.kind
         && let Some(did) = cx.qpath_res(&path, callee.hir_id).opt_def_id()
     {
-        let std_file_options = [
-            sym::file_options,
-            sym::open_options_new,
-        ];
+        let std_file_options = [sym::file_options, sym::open_options_new];
 
-        let tokio_file_options: &[&[&str]] = &[
-            &paths::TOKIO_IO_OPEN_OPTIONS_NEW,
-            &paths::TOKIO_FILE_OPTIONS,
-        ];
+        let tokio_file_options: &[&[&str]] = &[&paths::TOKIO_IO_OPEN_OPTIONS_NEW, &paths::TOKIO_FILE_OPTIONS];
 
-        let is_std_options = std_file_options.into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, did));
+        let is_std_options = std_file_options
+            .into_iter()
+            .any(|sym| cx.tcx.is_diagnostic_item(sym, did));
         is_std_options || match_any_def_paths(cx, did, tokio_file_options).is_some()
     } else {
         false
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs
index ba167f9d9c2..9b22494888f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs
@@ -3,9 +3,9 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
-use super::{method_call, OPTION_AS_REF_CLONED};
+use super::{OPTION_AS_REF_CLONED, method_call};
 
 pub(super) fn check(cx: &LateContext<'_>, cloned_recv: &Expr<'_>, cloned_ident_span: Span) {
     if let Some((method @ ("as_ref" | "as_mut"), as_ref_recv, [], as_ref_ident_span, _)) = method_call(cloned_recv)
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 9a18d8a1421..389e02056b2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -7,7 +7,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 
 use super::OPTION_AS_REF_DEREF;
 
@@ -48,7 +48,9 @@ pub(super) fn check(
                 .map_or(false, |fun_def_id| {
                     cx.tcx.is_diagnostic_item(sym::deref_method, fun_def_id)
                         || cx.tcx.is_diagnostic_item(sym::deref_mut_method, fun_def_id)
-                        || deref_aliases.iter().any(|&sym| cx.tcx.is_diagnostic_item(sym, fun_def_id))
+                        || deref_aliases
+                            .iter()
+                            .any(|&sym| cx.tcx.is_diagnostic_item(sym, fun_def_id))
                 })
         },
         hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
@@ -69,7 +71,9 @@ pub(super) fn check(
                         let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap();
                         cx.tcx.is_diagnostic_item(sym::deref_method, method_did)
                             || cx.tcx.is_diagnostic_item(sym::deref_mut_method, method_did)
-                            || deref_aliases.iter().any(|&sym| cx.tcx.is_diagnostic_item(sym, method_did))
+                            || deref_aliases
+                                .iter()
+                                .any(|&sym| cx.tcx.is_diagnostic_item(sym, method_did))
                     } else {
                         false
                     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index ed3bed42eb3..528e2204cf8 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -5,11 +5,11 @@ use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::intravisit::{walk_path, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_path};
 use rustc_hir::{ExprKind, HirId, Node, PatKind, Path, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::ops::ControlFlow;
 
 use super::MAP_UNWRAP_OR;
@@ -130,7 +130,7 @@ struct UnwrapVisitor<'a, 'tcx> {
     identifiers: FxHashSet<HirId>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for UnwrapVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::All;
 
     fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {
@@ -154,7 +154,7 @@ struct ReferenceVisitor<'a, 'tcx> {
     unwrap_or_span: Span,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::All;
     type Result = ControlFlow<()>;
     fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) -> ControlFlow<()> {
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index af71799f0a7..b971f60d416 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -11,8 +11,8 @@ use clippy_utils::{
 use rustc_errors::Applicability;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::symbol::{self, sym, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{self, Symbol, sym};
 use {rustc_ast as ast, rustc_hir as hir};
 
 use super::{OR_FUN_CALL, UNWRAP_OR_DEFAULT};
@@ -77,7 +77,7 @@ pub(super) fn check<'tcx>(
         let Some(suggested_method_def_id) = receiver_ty.ty_adt_def().and_then(|adt_def| {
             cx.tcx
                 .inherent_impls(adt_def.did())
-                .into_iter()
+                .iter()
                 .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
                 .find_map(|assoc| {
                     if assoc.fn_has_self_parameter
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs
index 7b0bdcf99e7..3e64e15dc86 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_then_unwrap.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::OR_THEN_UNWRAP;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs b/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
index 28ca76832eb..f4d206c5307 100644
--- a/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::source::snippet;
-use clippy_utils::{higher, is_integer_const, is_trait_method, SpanlessEq};
+use clippy_utils::{SpanlessEq, higher, is_integer_const, is_trait_method};
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_span::sym;
diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
index 3b2dd285b8c..4ab165a5528 100644
--- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
@@ -8,8 +8,8 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::PatKind;
 use rustc_lint::LateContext;
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 use super::SEARCH_IS_SOME;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
index 8bc535ac47a..7ef07fe899c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
@@ -6,9 +6,9 @@ use rustc_lint::LateContext;
 use rustc_span::sym;
 
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_enum_variant_ctor;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::is_enum_variant_ctor;
 
 use super::SEEK_FROM_CURRENT;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
index 7c09cc252e1..9c966f010f1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{is_expr_used_or_unified, is_enum_variant_ctor};
+use clippy_utils::{is_enum_variant_ctor, is_expr_used_or_unified};
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::SEEK_TO_START_INSTEAD_OF_REWIND;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index 12cabd43cb1..69032776b2b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -3,7 +3,7 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::usage::local_used_after_expr;
-use clippy_utils::visitors::{for_each_expr, Descend};
+use clippy_utils::visitors::{Descend, for_each_expr};
 use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
@@ -12,7 +12,7 @@ use rustc_hir::{
 };
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{sym, Span, Symbol, SyntaxContext};
+use rustc_span::{Span, Symbol, SyntaxContext, sym};
 
 use super::{MANUAL_SPLIT_ONCE, NEEDLESS_SPLITN};
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs
index 38f2c916912..c60a49067ec 100644
--- a/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_command_arg_space.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::{Applicability, Diag};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use {rustc_ast as ast, rustc_hir as hir};
 
 use super::SUSPICIOUS_COMMAND_ARG_SPACE;
diff --git a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs
index db8cc4595d4..e67ba5c4d31 100644
--- a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs
@@ -7,7 +7,7 @@ use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment};
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::{self, ExistentialPredicate, Ty};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 /// Checks if the given type is `dyn Any`, or a trait object that has `Any` as a supertrait.
 /// Only in those cases will its vtable have a `type_id` method that returns the implementor's
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fallible_conversions.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fallible_conversions.rs
index d46b584f8f4..ce81282ddfe 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fallible_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fallible_conversions.rs
@@ -6,7 +6,7 @@ use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::UNNECESSARY_FALLIBLE_CONVERSIONS;
 
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 c9b9d98dbe6..ca46da81fa0 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
@@ -2,7 +2,7 @@ use super::utils::clone_or_copy_needed;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::is_copy;
 use clippy_utils::usage::mutated_variables;
-use clippy_utils::visitors::{for_each_expr_without_closures, Descend};
+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 core::ops::ControlFlow;
 use rustc_hir as hir;
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_first_then_check.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_first_then_check.rs
new file mode 100644
index 00000000000..7ae1bb54e60
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_first_then_check.rs
@@ -0,0 +1,56 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::SpanRangeExt;
+
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+
+use super::UNNECESSARY_FIRST_THEN_CHECK;
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    call_span: Span,
+    first_call: &Expr<'_>,
+    first_caller: &Expr<'_>,
+    is_some: bool,
+) {
+    if !cx
+        .typeck_results()
+        .expr_ty_adjusted(first_caller)
+        .peel_refs()
+        .is_slice()
+    {
+        return;
+    }
+
+    let ExprKind::MethodCall(_, _, _, first_call_span) = first_call.kind else {
+        return;
+    };
+
+    let both_calls_span = first_call_span.with_hi(call_span.hi());
+    if let Some(both_calls_snippet) = both_calls_span.get_source_text(cx)
+        && let Some(first_caller_snippet) = first_caller.span.get_source_text(cx)
+    {
+        let (sugg_span, suggestion) = if is_some {
+            (
+                first_caller.span.with_hi(call_span.hi()),
+                format!("!{first_caller_snippet}.is_empty()"),
+            )
+        } else {
+            (both_calls_span, "is_empty()".to_owned())
+        };
+        span_lint_and_sugg(
+            cx,
+            UNNECESSARY_FIRST_THEN_CHECK,
+            sugg_span,
+            format!(
+                "unnecessary use of `{both_calls_snippet}` to check if slice {}",
+                if is_some { "is not empty" } else { "is empty" }
+            ),
+            "replace this with",
+            suggestion,
+            Applicability::MaybeIncorrect,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
index ccc8d17970e..b5d8972d7aa 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
@@ -8,7 +8,7 @@ use rustc_hir as hir;
 use rustc_hir::PatKind;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::UNNECESSARY_FOLD;
 
@@ -123,58 +123,32 @@ pub(super) fn check(
     if let hir::ExprKind::Lit(lit) = init.kind {
         match lit.node {
             ast::LitKind::Bool(false) => {
-                check_fold_with_op(
-                    cx,
-                    expr,
-                    acc,
-                    fold_span,
-                    hir::BinOpKind::Or,
-                    Replacement {
-                        has_args: true,
-                        has_generic_return: false,
-                        method_name: "any",
-                    },
-                );
+                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Or, Replacement {
+                    has_args: true,
+                    has_generic_return: false,
+                    method_name: "any",
+                });
             },
             ast::LitKind::Bool(true) => {
-                check_fold_with_op(
-                    cx,
-                    expr,
-                    acc,
-                    fold_span,
-                    hir::BinOpKind::And,
-                    Replacement {
-                        has_args: true,
-                        has_generic_return: false,
-                        method_name: "all",
-                    },
-                );
+                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, Replacement {
+                    has_args: true,
+                    has_generic_return: false,
+                    method_name: "all",
+                });
             },
-            ast::LitKind::Int(Pu128(0), _) => check_fold_with_op(
-                cx,
-                expr,
-                acc,
-                fold_span,
-                hir::BinOpKind::Add,
-                Replacement {
+            ast::LitKind::Int(Pu128(0), _) => {
+                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, Replacement {
                     has_args: false,
                     has_generic_return: needs_turbofish(cx, expr),
                     method_name: "sum",
-                },
-            ),
+                });
+            },
             ast::LitKind::Int(Pu128(1), _) => {
-                check_fold_with_op(
-                    cx,
-                    expr,
-                    acc,
-                    fold_span,
-                    hir::BinOpKind::Mul,
-                    Replacement {
-                        has_args: false,
-                        has_generic_return: needs_turbofish(cx, expr),
-                        method_name: "product",
-                    },
-                );
+                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, Replacement {
+                    has_args: false,
+                    has_generic_return: needs_turbofish(cx, expr),
+                    method_name: "product",
+                });
             },
             _ => (),
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
index 64eb8411795..39fce2c40c9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::UNNECESSARY_GET_THEN_CHECK;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 4d18bc7ac77..029704882dd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -10,7 +10,7 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, Expr, ExprKind, Node, PatKind};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 
 use super::UNNECESSARY_TO_OWNED;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
index 494d71fc053..6dc8adb42df 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::{is_res_lang_ctor, last_path_segment, path_res, MaybePath};
+use clippy_utils::{MaybePath, is_res_lang_ctor, last_path_segment, path_res};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs
index 86c0a6322b6..062d1348555 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_min_or_max.rs
@@ -1,16 +1,15 @@
 use std::cmp::Ordering;
 
 use super::UNNECESSARY_MIN_OR_MAX;
-use clippy_utils::diagnostics::span_lint_and_sugg;
-
 use clippy_utils::consts::{ConstEvalCtxt, Constant, ConstantSource, FullInt};
+use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::Span;
+use rustc_span::{Span, sym};
 
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
@@ -21,26 +20,30 @@ pub(super) fn check<'tcx>(
 ) {
     let typeck_results = cx.typeck_results();
     let ecx = ConstEvalCtxt::with_env(cx.tcx, cx.param_env, typeck_results);
-    if let Some((left, ConstantSource::Local | ConstantSource::CoreConstant)) = ecx.eval_with_source(recv)
-        && let Some((right, ConstantSource::Local | ConstantSource::CoreConstant)) = ecx.eval_with_source(arg)
+    if let Some(id) = typeck_results.type_dependent_def_id(expr.hir_id)
+        && (cx.tcx.is_diagnostic_item(sym::cmp_ord_min, id) || cx.tcx.is_diagnostic_item(sym::cmp_ord_max, id))
     {
-        let Some(ord) = Constant::partial_cmp(cx.tcx, typeck_results.expr_ty(recv), &left, &right) else {
-            return;
-        };
+        if let Some((left, ConstantSource::Local | ConstantSource::CoreConstant)) = ecx.eval_with_source(recv)
+            && let Some((right, ConstantSource::Local | ConstantSource::CoreConstant)) = ecx.eval_with_source(arg)
+        {
+            let Some(ord) = Constant::partial_cmp(cx.tcx, typeck_results.expr_ty(recv), &left, &right) else {
+                return;
+            };
 
-        lint(cx, expr, name, recv.span, arg.span, ord);
-    } else if let Some(extrema) = detect_extrema(cx, recv) {
-        let ord = match extrema {
-            Extrema::Minimum => Ordering::Less,
-            Extrema::Maximum => Ordering::Greater,
-        };
-        lint(cx, expr, name, recv.span, arg.span, ord);
-    } else if let Some(extrema) = detect_extrema(cx, arg) {
-        let ord = match extrema {
-            Extrema::Minimum => Ordering::Greater,
-            Extrema::Maximum => Ordering::Less,
-        };
-        lint(cx, expr, name, recv.span, arg.span, ord);
+            lint(cx, expr, name, recv.span, arg.span, ord);
+        } else if let Some(extrema) = detect_extrema(cx, recv) {
+            let ord = match extrema {
+                Extrema::Minimum => Ordering::Less,
+                Extrema::Maximum => Ordering::Greater,
+            };
+            lint(cx, expr, name, recv.span, arg.span, ord);
+        } else if let Some(extrema) = detect_extrema(cx, arg) {
+            let ord = match extrema {
+                Extrema::Minimum => Ordering::Greater,
+                Extrema::Maximum => Ordering::Less,
+            };
+            lint(cx, expr, name, recv.span, arg.span, ord);
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs
index c14a87c1534..dc50717112d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs
@@ -8,8 +8,8 @@ use rustc_hir::{Closure, Expr, ExprKind, HirId, QPath};
 use rustc_lint::LateContext;
 use rustc_span::symbol::sym;
 
-use super::utils::get_last_chain_binding_hir_id;
 use super::UNNECESSARY_RESULT_MAP_OR_ELSE;
+use super::utils::get_last_chain_binding_hir_id;
 
 fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &Expr<'_>) {
     let msg = "unused \"map closure\" when calling `Result::map_or_else` value";
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index bf7555a29e2..cfa1fdb8137 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -2,12 +2,11 @@ use super::implicit_clone::is_clone_like;
 use super::unnecessary_iter_cloned::{self, is_into_iter};
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::{snippet, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::visitors::find_all_ret_expressions;
 use clippy_utils::{
-    fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, peel_middle_ty_refs,
-    return_ty,
+    fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, peel_middle_ty_refs, return_ty,
 };
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -20,7 +19,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
 use rustc_middle::ty::{
     self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,
 };
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{Obligation, ObligationCause};
 
@@ -717,7 +716,7 @@ fn check_if_applicable_to_argument<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'tcx
 // check that:
 // 1. This is a method with only one argument that doesn't come from a trait.
 // 2. That it has `Borrow` in its generic predicates.
-// 3. `Self` is a std "map type" (ie `HashSet`, `HashMap`, BTreeSet`, `BTreeMap`).
+// 3. `Self` is a std "map type" (ie `HashSet`, `HashMap`, `BTreeSet`, `BTreeMap`).
 fn check_borrow_predicate<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
     if let ExprKind::MethodCall(_, caller, &[arg], _) = expr.kind
         && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
diff --git a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
index ee5177d1ffa..6c2ae9cc6bf 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs
@@ -1,11 +1,11 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
-use clippy_utils::source::{snippet, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::{expr_or_init, is_trait_method, pat_is_wild};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, FnDecl, PatKind, TyKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::AdtDef;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use crate::loops::UNUSED_ENUMERATE_INDEX;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
index ebad4ae6ee9..eafe7486bb0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
@@ -9,7 +9,7 @@ use rustc_hir::{self as hir, LangItem};
 use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use core::ops::ControlFlow;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs
index fe860e5ae26..cf0ee569f13 100644
--- a/src/tools/clippy/clippy_lints/src/methods/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs
@@ -1,12 +1,12 @@
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{get_parent_expr, path_to_local_id, usage};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat, QPath, Stmt, StmtKind};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty};
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 
 pub(super) fn derefs_to_slice<'tcx>(
     cx: &LateContext<'tcx>,
@@ -86,7 +86,7 @@ struct CloneOrCopyVisitor<'cx, 'tcx> {
     references_to_binding: Vec<(Span, String)>,
 }
 
-impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> {
+impl<'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
@@ -123,7 +123,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx> CloneOrCopyVisitor<'cx, 'tcx> {
+impl<'tcx> CloneOrCopyVisitor<'_, 'tcx> {
     fn is_binding(&self, expr: &Expr<'tcx>) -> bool {
         self.binding_hir_ids
             .iter()
diff --git a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs
index 3e271a60611..5ea4ada128a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_span::source_map::Spanned;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use super::VEC_RESIZE_TO_ZERO;
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs b/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs
index 9b64cc7589c..b5f34a9be2e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::is_trait_method;
+use clippy_utils::source::snippet_with_applicability;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index c83e5198c27..a99e21d938c 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_from_proc_macro;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::{walk_item, walk_trait_item, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item};
 use rustc_hir::{GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem, UsePath};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index a9aafe7ed56..408dbef9cb1 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -2,11 +2,12 @@ use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir, span_lint_hir
 use clippy_utils::source::{snippet, snippet_with_context};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    fulfill_or_allowed, get_parent_expr, in_automatically_derived, is_lint_allowed, iter_input_pats, last_path_segment,
-    SpanlessEq,
+    SpanlessEq, fulfill_or_allowed, get_parent_expr, in_automatically_derived, is_lint_allowed, iter_input_pats,
+    last_path_segment,
 };
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
+use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
@@ -14,8 +15,8 @@ use rustc_hir::{
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
 
 use crate::ref_patterns::REF_PATTERNS;
 
@@ -82,6 +83,45 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
+    /// Checks for the use of item with a single leading
+    /// underscore.
+    ///
+    /// ### Why is this bad?
+    /// A single leading underscore is usually used to indicate
+    /// that a item will not be used. Using such a item breaks this
+    /// expectation.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// fn _foo() {}
+    ///
+    /// struct _FooStruct {}
+    ///
+    /// fn main() {
+    ///     _foo();
+    ///     let _ = _FooStruct{};
+    /// }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// fn foo() {}
+    ///
+    /// struct FooStruct {}
+    ///
+    /// fn main() {
+    ///     foo();
+    ///     let _ = FooStruct{};
+    /// }
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub USED_UNDERSCORE_ITEMS,
+    pedantic,
+    "using a item which is prefixed with an underscore"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     /// Checks for the use of short circuit boolean conditions as
     /// a
     /// statement.
@@ -104,6 +144,7 @@ declare_clippy_lint! {
 declare_lint_pass!(LintPass => [
     TOPLEVEL_REF_ARG,
     USED_UNDERSCORE_BINDING,
+    USED_UNDERSCORE_ITEMS,
     SHORT_CIRCUIT_STATEMENT,
 ]);
 
@@ -205,51 +246,104 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
         {
             return;
         }
-        let (definition_hir_id, ident) = match expr.kind {
-            ExprKind::Path(ref qpath) => {
-                if let QPath::Resolved(None, path) = qpath
-                    && let Res::Local(id) = path.res
-                    && is_used(cx, expr)
-                {
-                    (id, last_path_segment(qpath).ident)
-                } else {
-                    return;
-                }
-            },
-            ExprKind::Field(recv, ident) => {
-                if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def()
-                    && let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name)
-                    && let Some(local_did) = field.did.as_local()
-                    && !cx.tcx.type_of(field.did).skip_binder().is_phantom_data()
-                {
-                    (cx.tcx.local_def_id_to_hir_id(local_did), ident)
-                } else {
-                    return;
-                }
+
+        used_underscore_binding(cx, expr);
+        used_underscore_items(cx, expr);
+    }
+}
+
+fn used_underscore_items<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+    let (def_id, ident) = match expr.kind {
+        ExprKind::Call(func, ..) => {
+            if let ExprKind::Path(QPath::Resolved(.., path)) = func.kind
+                && let Some(last_segment) = path.segments.last()
+                && let Res::Def(_, def_id) = last_segment.res
+            {
+                (def_id, last_segment.ident)
+            } else {
+                return;
+            }
+        },
+        ExprKind::MethodCall(path, ..) => {
+            if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
+                (def_id, path.ident)
+            } else {
+                return;
+            }
+        },
+        ExprKind::Struct(QPath::Resolved(_, path), ..) => {
+            if let Some(last_segment) = path.segments.last()
+                && let Res::Def(_, def_id) = last_segment.res
+            {
+                (def_id, last_segment.ident)
+            } else {
+                return;
+            }
+        },
+        _ => return,
+    };
+
+    let name = ident.name.as_str();
+    let definition_span = cx.tcx.def_span(def_id);
+    if name.starts_with('_')
+        && !name.starts_with("__")
+        && !definition_span.from_expansion()
+        && def_id.krate == LOCAL_CRATE
+    {
+        span_lint_and_then(
+            cx,
+            USED_UNDERSCORE_ITEMS,
+            expr.span,
+            "used underscore-prefixed item".to_string(),
+            |diag| {
+                diag.span_note(definition_span, "item is defined here".to_string());
             },
-            _ => return,
-        };
+        );
+    }
+}
 
-        let name = ident.name.as_str();
-        if name.starts_with('_')
-            && !name.starts_with("__")
-            && let definition_span = cx.tcx.hir().span(definition_hir_id)
-            && !definition_span.from_expansion()
-            && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id])
-        {
-            span_lint_and_then(
-                cx,
-                USED_UNDERSCORE_BINDING,
-                expr.span,
-                format!(
-                    "used binding `{name}` which is prefixed with an underscore. A leading \
-                     underscore signals that a binding will not be used"
-                ),
-                |diag| {
-                    diag.span_note(definition_span, format!("`{name}` is defined here"));
-                },
-            );
-        }
+fn used_underscore_binding<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+    let (definition_hir_id, ident) = match expr.kind {
+        ExprKind::Path(ref qpath) => {
+            if let QPath::Resolved(None, path) = qpath
+                && let Res::Local(id) = path.res
+                && is_used(cx, expr)
+            {
+                (id, last_path_segment(qpath).ident)
+            } else {
+                return;
+            }
+        },
+        ExprKind::Field(recv, ident) => {
+            if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def()
+                && let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name)
+                && let Some(local_did) = field.did.as_local()
+                && !cx.tcx.type_of(field.did).skip_binder().is_phantom_data()
+            {
+                (cx.tcx.local_def_id_to_hir_id(local_did), ident)
+            } else {
+                return;
+            }
+        },
+        _ => return,
+    };
+
+    let name = ident.name.as_str();
+    if name.starts_with('_')
+        && !name.starts_with("__")
+        && let definition_span = cx.tcx.hir().span(definition_hir_id)
+        && !definition_span.from_expansion()
+        && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id])
+    {
+        span_lint_and_then(
+            cx,
+            USED_UNDERSCORE_BINDING,
+            expr.span,
+            "used underscore-prefixed binding".to_string(),
+            |diag| {
+                diag.span_note(definition_span, "binding is defined here".to_string());
+            },
+        );
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/missing_assert_message.rs b/src/tools/clippy/clippy_lints/src/missing_assert_message.rs
index a9ea11f4c2b..86348f04600 100644
--- a/src/tools/clippy/clippy_lints/src/missing_assert_message.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_assert_message.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_in_test;
-use clippy_utils::macros::{find_assert_args, find_assert_eq_args, root_macro_call_first_node, PanicExpn};
+use clippy_utils::macros::{PanicExpn, find_assert_args, find_assert_eq_args, root_macro_call_first_node};
 use rustc_hir::Expr;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
index 94c91b09517..b40d7eba15e 100644
--- a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
@@ -1,7 +1,7 @@
 use std::mem;
 use std::ops::ControlFlow;
 
-use clippy_utils::comparisons::{normalize_comparison, Rel};
+use clippy_utils::comparisons::{Rel, normalize_comparison};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
 use clippy_utils::visitors::for_each_expr_without_closures;
@@ -14,7 +14,7 @@ use rustc_hir::{BinOp, Block, Body, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 859afe1b963..eea0459e026 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::qualify_min_const_fn::is_min_const_fn;
 use clippy_utils::{fn_has_unsatisfiable_preds, is_entrypoint_fn, is_from_proc_macro, trait_ref_of_method};
@@ -11,8 +11,8 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
 use rustc_target::spec::abi::Abi;
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs
index 954216038fb..c2f524a6353 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_thread_local.rs
@@ -1,12 +1,12 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::macros::macro_backtrace;
 use clippy_utils::qualify_min_const_fn::is_min_const_fn;
 use clippy_utils::source::snippet;
 use clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks};
 use rustc_errors::Applicability;
-use rustc_hir::{intravisit, Expr, ExprKind};
+use rustc_hir::{Expr, ExprKind, intravisit};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym::{self, thread_local_macro};
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 2166b0fe5a0..007bcebdff6 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -17,7 +17,7 @@ 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::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -193,8 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             | hir::ItemKind::Trait(..)
             | hir::ItemKind::TraitAlias(..)
             | hir::ItemKind::TyAlias(..)
-            | hir::ItemKind::Union(..)
-            | hir::ItemKind::OpaqueTy(..) => {},
+            | hir::ItemKind::Union(..) => {}
             hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::ForeignMod { .. }
             | hir::ItemKind::GlobalAsm(..)
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 77595b121aa..fc01b6753f1 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
@@ -3,7 +3,7 @@ use std::ops::ControlFlow;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_path_lang_item;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::visitors::{for_each_expr, Visitable};
+use clippy_utils::visitors::{Visitable, for_each_expr};
 use rustc_ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
@@ -13,7 +13,7 @@ use rustc_hir::{
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{Ty, TypeckResults};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{Span, Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 33a14d8b7fe..f95a0f63fab 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -3,7 +3,7 @@ use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -130,7 +130,6 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
             | hir::ItemKind::GlobalAsm(..)
             | hir::ItemKind::TyAlias(..)
             | hir::ItemKind::Union(..)
-            | hir::ItemKind::OpaqueTy(..)
             | hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::ForeignMod { .. }
             | hir::ItemKind::Impl { .. }
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index 0b3769ecb7c..a7452c8a3c8 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
+use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, LetStmt, Node, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -115,7 +116,7 @@ struct DivergenceVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
+impl<'tcx> DivergenceVisitor<'_, 'tcx> {
     fn maybe_walk_expr(&mut self, e: &'tcx Expr<'_>) {
         match e.kind {
             ExprKind::Closure(..) | ExprKind::If(..) | ExprKind::Loop(..) => {},
@@ -134,6 +135,11 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
     }
 
     fn report_diverging_sub_expr(&mut self, e: &Expr<'_>) {
+        if let Some(macro_call) = root_macro_call_first_node(self.cx, e) {
+            if self.cx.tcx.item_name(macro_call.def_id).as_str() == "todo" {
+                return;
+            }
+        }
         span_lint(self.cx, DIVERGING_SUB_EXPRESSION, e.span, "sub-expression diverges");
     }
 }
@@ -142,7 +148,7 @@ fn stmt_might_diverge(stmt: &Stmt<'_>) -> bool {
     !matches!(stmt.kind, StmtKind::Item(..))
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for DivergenceVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
         match e.kind {
             // fix #10776
@@ -315,7 +321,7 @@ struct ReadVisitor<'a, 'tcx> {
     last_expr: &'tcx Expr<'tcx>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ReadVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         if expr.hir_id == self.last_expr.hir_id {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
index 0bde0da3cd8..12bcc608174 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::visitors::{for_each_expr, Descend, Visitable};
+use clippy_utils::visitors::{Descend, Visitable, for_each_expr};
 use core::ops::ControlFlow::Continue;
 use hir::def::{DefKind, Res};
 use hir::{BlockCheckMode, ExprKind, QPath, Safety, UnOp};
@@ -153,19 +153,16 @@ fn collect_unsafe_exprs<'tcx>(
             ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Assign(lhs, rhs, _) => {
                 if matches!(
                     lhs.kind,
-                    ExprKind::Path(QPath::Resolved(
-                        _,
-                        hir::Path {
-                            res: Res::Def(
-                                DefKind::Static {
-                                    mutability: Mutability::Mut,
-                                    ..
-                                },
-                                _
-                            ),
-                            ..
-                        }
-                    ))
+                    ExprKind::Path(QPath::Resolved(_, hir::Path {
+                        res: Res::Def(
+                            DefKind::Static {
+                                mutability: Mutability::Mut,
+                                ..
+                            },
+                            _
+                        ),
+                        ..
+                    }))
                 ) {
                     unsafe_ops.push(("modification of a mutable static occurs here", expr.span));
                     collect_unsafe_exprs(cx, rhs, unsafe_ops);
diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs
index f52b3a6a5a1..8118c14bd4a 100644
--- a/src/tools/clippy/clippy_lints/src/mut_key.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_key.rs
@@ -6,9 +6,9 @@ use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::sym;
-use rustc_span::Span;
 use std::iter;
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/mut_mut.rs b/src/tools/clippy/clippy_lints/src/mut_mut.rs
index 60372121a7a..6cddd7ea813 100644
--- a/src/tools/clippy/clippy_lints/src/mut_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_mut.rs
@@ -55,7 +55,7 @@ pub struct MutVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
+impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
         if in_external_macro(self.cx.sess(), expr.span) {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
index e92ba93942e..152635a5c35 100644
--- a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
+++ b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::macros::{find_assert_eq_args, root_macro_call_first_node};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BorrowKind, Expr, ExprKind, MatchSource, Mutability};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
@@ -87,7 +87,7 @@ impl<'a, 'tcx> MutArgVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for MutArgVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for MutArgVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs
index 60c44382059..3c47d0edfdc 100644
--- a/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_arbitrary_self_type.rs
@@ -3,8 +3,8 @@ use rustc_ast::ast::{BindingMode, ByRef, Lifetime, Mutability, Param, PatKind, P
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::kw;
 use rustc_span::Span;
+use rustc_span::symbol::kw;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index df155a7a412..2eacd6875d6 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -2,16 +2,16 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt, is_receiver_of_method_call,
-    peel_blocks, peel_blocks_with_stmt, span_extract_comment, SpanlessEq,
+    SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt,
+    is_receiver_of_method_call, peel_blocks, peel_blocks_with_stmt, span_extract_comment,
 };
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::source_map::Spanned;
 use rustc_span::Span;
+use rustc_span::source_map::Spanned;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
index 32e7fde03b2..f6db12ed84e 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -1,10 +1,10 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
+use clippy_utils::mir::{PossibleBorrowerMap, enclosing_mir, expr_local, local_assignments, used_exactly_once};
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{implements_trait, is_copy};
-use clippy_utils::{expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy, ExprUseNode};
+use clippy_utils::{DefinedTy, ExprUseNode, expr_use_ctxt, peel_n_hir_expr_refs};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
diff --git a/src/tools/clippy/clippy_lints/src/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
index 6390e51f916..93e20f37ef8 100644
--- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
@@ -1,9 +1,9 @@
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Block, BlockCheckMode, Closure, Expr, ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_trait_method;
@@ -133,7 +133,7 @@ struct RetCollector {
     loop_depth: u16,
 }
 
-impl<'tcx> Visitor<'tcx> for RetCollector {
+impl Visitor<'_> for RetCollector {
     fn visit_expr(&mut self, expr: &Expr<'_>) {
         match expr.kind {
             ExprKind::Ret(..) => {
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 62e41088f37..bb44ff37b20 100644
--- a/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_maybe_sized.rs
@@ -26,7 +26,7 @@ declare_clippy_lint! {
     ///
     /// // or choose alternative bounds for `T` so that it can be unsized
     /// ```
-    #[clippy::version = "1.79.0"]
+    #[clippy::version = "1.81.0"]
     pub NEEDLESS_MAYBE_SIZED,
     suspicious,
     "a `?Sized` bound that is unusable due to a `Sized` requirement"
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 d543fd467ab..c2facb2fcf6 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
@@ -17,9 +17,9 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath};
 use rustc_session::impl_lint_pass;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
-use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
 declare_clippy_lint! {
@@ -311,7 +311,7 @@ struct MutablyUsedVariablesCtxt<'tcx> {
     tcx: TyCtxt<'tcx>,
 }
 
-impl<'tcx> MutablyUsedVariablesCtxt<'tcx> {
+impl MutablyUsedVariablesCtxt<'_> {
     fn add_mutably_used_var(&mut self, used_id: HirId) {
         self.mutably_used_vars.insert(used_id);
     }
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index addb4b1aee8..0775d7abdbb 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_self;
 use clippy_utils::ptr::get_spans;
-use clippy_utils::source::{snippet, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::ty::{
     implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
 };
@@ -19,7 +19,7 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;
@@ -129,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
             })
             .collect::<Vec<_>>();
 
-        // Collect moved variables and spans which will need dereferencings from the
+        // Collect moved variables and spans which will need dereferencing from the
         // function body.
         let MovedVariablesCtxt { moved_vars } = {
             let mut ctx = MovedVariablesCtxt::default();
@@ -148,12 +148,13 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                 return;
             }
 
-            // Ignore `self`s.
-            if idx == 0 {
-                if let PatKind::Binding(.., ident, _) = arg.pat.kind {
-                    if ident.name == kw::SelfLower {
-                        continue;
-                    }
+            // Ignore `self`s and params whose variable name starts with an underscore
+            if let PatKind::Binding(.., ident, _) = arg.pat.kind {
+                if idx == 0 && ident.name == kw::SelfLower {
+                    continue;
+                }
+                if ident.name.as_str().starts_with('_') {
+                    continue;
                 }
             }
 
@@ -181,14 +182,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                 && !is_copy(cx, ty)
                 && ty.is_sized(cx.tcx, cx.param_env)
                 && !allowed_traits.iter().any(|&t| {
-                    implements_trait_with_env_from_iter(
-                        cx.tcx,
-                        cx.param_env,
-                        ty,
-                        t,
-                        None,
-                        [Option::<ty::GenericArg<'tcx>>::None],
-                    )
+                    implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, t, None, [Option::<
+                        ty::GenericArg<'tcx>,
+                    >::None])
                 })
                 && !implements_borrow_trait
                 && !all_borrowable_trait
@@ -207,7 +203,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                             )
                             .is_ok()
                             {
-                                diag.span_help(span, "consider marking this type as `Copy`");
+                                diag.span_help(span, "or consider marking this type as `Copy`");
                             }
                         }
                     }
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index b181791699a..392cfcb813e 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -7,8 +7,8 @@ use clippy_utils::{
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, LocalSource, Node, PatKind,
-    Stmt, StmtKind, UnsafeSource,
+    BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, LocalSource, Node, PatKind, Stmt, StmtKind,
+    UnsafeSource, is_range_literal,
 };
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 25f547f1a43..5e20b406426 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -4,7 +4,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_in_const_context;
 use clippy_utils::macros::macro_backtrace;
-use clippy_utils::ty::{implements_trait, InteriorMut};
+use clippy_utils::ty::{InteriorMut, implements_trait};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
@@ -15,7 +15,7 @@ use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span, DUMMY_SP};
+use rustc_span::{DUMMY_SP, Span, sym};
 use rustc_target::abi::VariantIdx;
 
 // FIXME: this is a correctness problem but there's no suitable
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index 832518d2d35..2fee1c72a91 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -3,12 +3,12 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use rustc_ast::ast::{
     self, Arm, AssocItem, AssocItemKind, Attribute, Block, FnDecl, Item, ItemKind, Local, Pat, PatKind,
 };
-use rustc_ast::visit::{walk_block, walk_expr, walk_pat, Visitor};
+use rustc_ast::visit::{Visitor, walk_block, walk_expr, walk_pat};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::cmp::Ordering;
 
 declare_clippy_lint! {
@@ -104,7 +104,7 @@ struct SimilarNamesLocalVisitor<'a, 'tcx> {
     single_char_names: Vec<Vec<Ident>>,
 }
 
-impl<'a, 'tcx> SimilarNamesLocalVisitor<'a, 'tcx> {
+impl SimilarNamesLocalVisitor<'_, '_> {
     fn check_single_char_names(&self) {
         if self.single_char_names.last().map(Vec::len) == Some(0) {
             return;
@@ -152,7 +152,7 @@ fn chars_are_similar(a: char, b: char) -> bool {
 
 struct SimilarNamesNameVisitor<'a, 'tcx, 'b>(&'b mut SimilarNamesLocalVisitor<'a, 'tcx>);
 
-impl<'a, 'tcx, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> {
+impl<'tcx> Visitor<'tcx> for SimilarNamesNameVisitor<'_, 'tcx, '_> {
     fn visit_pat(&mut self, pat: &'tcx Pat) {
         match pat.kind {
             PatKind::Ident(_, ident, _) => {
@@ -189,7 +189,7 @@ fn allowed_to_be_similar(interned_name: &str, list: &[&str]) -> bool {
         .any(|&name| interned_name.starts_with(name) || interned_name.ends_with(name))
 }
 
-impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
+impl SimilarNamesNameVisitor<'_, '_, '_> {
     fn check_short_ident(&mut self, ident: Ident) {
         // Ignore shadowing
         if self
@@ -329,7 +329,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
     }
 }
 
-impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
+impl SimilarNamesLocalVisitor<'_, '_> {
     /// ensure scoping rules work
     fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {
         let n = self.names.len();
@@ -340,7 +340,7 @@ impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'_, 'tcx> {
     fn visit_local(&mut self, local: &'tcx Local) {
         if let Some((init, els)) = &local.kind.init_else_opt() {
             self.apply(|this| walk_expr(this, init));
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 cfc15d92715..3f156aa5510 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
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{snippet_with_applicability, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet_with_applicability};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
index a60988ac5db..793eb5d9456 100644
--- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -159,7 +159,7 @@ struct NonSendField<'tcx> {
     generic_params: Vec<Ty<'tcx>>,
 }
 
-impl<'tcx> NonSendField<'tcx> {
+impl NonSendField<'_> {
     fn generic_params_string(&self) -> String {
         self.generic_params
             .iter()
diff --git a/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs
new file mode 100644
index 00000000000..90a9f2e994b
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/non_zero_suggestions.rs
@@ -0,0 +1,143 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet;
+use rustc_ast::ast::BinOpKind;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{self, Ty};
+use rustc_session::declare_lint_pass;
+use rustc_span::symbol::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for conversions from `NonZero` types to regular integer types,
+    /// and suggests using `NonZero` types for the target as well.
+    ///
+    /// ### Why is this bad?
+    /// Converting from `NonZero` types to regular integer types and then back to `NonZero`
+    /// types is less efficient and loses the type-safety guarantees provided by `NonZero` types.
+    /// Using `NonZero` types consistently can lead to more optimized code and prevent
+    /// certain classes of errors related to zero values.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// use std::num::{NonZeroU32, NonZeroU64};
+    ///
+    /// fn example(x: u64, y: NonZeroU32) {
+    ///     // Bad: Converting NonZeroU32 to u64 unnecessarily
+    ///     let r1 = x / u64::from(y.get());
+    ///     let r2 = x % u64::from(y.get());
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// use std::num::{NonZeroU32, NonZeroU64};
+    ///
+    /// fn example(x: u64, y: NonZeroU32) {
+    ///     // Good: Preserving the NonZero property
+    ///     let r1 = x / NonZeroU64::from(y);
+    ///     let r2 = x % NonZeroU64::from(y);
+    /// }
+    /// ```
+    #[clippy::version = "1.81.0"]
+    pub NON_ZERO_SUGGESTIONS,
+    restriction,
+    "suggests using `NonZero#` from `u#` or `i#` for more efficient and type-safe conversions"
+}
+
+declare_lint_pass!(NonZeroSuggestions => [NON_ZERO_SUGGESTIONS]);
+
+impl<'tcx> LateLintPass<'tcx> for NonZeroSuggestions {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if let ExprKind::Binary(op, _, rhs) = expr.kind
+            && matches!(op.node, BinOpKind::Div | BinOpKind::Rem)
+        {
+            check_non_zero_conversion(cx, rhs, Applicability::MachineApplicable);
+        } else {
+            // Check if the parent expression is a binary operation
+            let parent_is_binary = cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| {
+                matches!(node, rustc_hir::Node::Expr(parent_expr) if matches!(parent_expr.kind, ExprKind::Binary(..)))
+            });
+
+            if !parent_is_binary {
+                check_non_zero_conversion(cx, expr, Applicability::MaybeIncorrect);
+            }
+        }
+    }
+}
+
+fn check_non_zero_conversion(cx: &LateContext<'_>, expr: &Expr<'_>, applicability: Applicability) {
+    // Check if the expression is a function call with one argument
+    if let ExprKind::Call(func, [arg]) = expr.kind
+        && let ExprKind::Path(qpath) = &func.kind
+        && let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()
+        && let ExprKind::MethodCall(rcv_path, receiver, _, _) = &arg.kind
+        && rcv_path.ident.name.as_str() == "get"
+    {
+        let fn_name = cx.tcx.item_name(def_id);
+        let target_ty = cx.typeck_results().expr_ty(expr);
+        let receiver_ty = cx.typeck_results().expr_ty(receiver);
+
+        // Check if the receiver type is a NonZero type
+        if let ty::Adt(adt_def, _) = receiver_ty.kind()
+            && adt_def.is_struct()
+            && cx.tcx.get_diagnostic_name(adt_def.did()) == Some(sym::NonZero)
+        {
+            if let Some(target_non_zero_type) = get_target_non_zero_type(target_ty) {
+                let arg_snippet = get_arg_snippet(cx, arg, rcv_path);
+                suggest_non_zero_conversion(cx, expr, fn_name, target_non_zero_type, &arg_snippet, applicability);
+            }
+        }
+    }
+}
+
+fn get_arg_snippet(cx: &LateContext<'_>, arg: &Expr<'_>, rcv_path: &rustc_hir::PathSegment<'_>) -> String {
+    let arg_snippet = snippet(cx, arg.span, "..");
+    if let Some(index) = arg_snippet.rfind(&format!(".{}", rcv_path.ident.name)) {
+        arg_snippet[..index].trim().to_string()
+    } else {
+        arg_snippet.to_string()
+    }
+}
+
+fn suggest_non_zero_conversion(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    fn_name: rustc_span::Symbol,
+    target_non_zero_type: &str,
+    arg_snippet: &str,
+    applicability: Applicability,
+) {
+    let suggestion = format!("{target_non_zero_type}::{fn_name}({arg_snippet})");
+    span_lint_and_sugg(
+        cx,
+        NON_ZERO_SUGGESTIONS,
+        expr.span,
+        format!("consider using `{target_non_zero_type}::{fn_name}()` for more efficient and type-safe conversion"),
+        "replace with",
+        suggestion,
+        applicability,
+    );
+}
+
+fn get_target_non_zero_type(ty: Ty<'_>) -> Option<&'static str> {
+    match ty.kind() {
+        ty::Uint(uint_ty) => Some(match uint_ty {
+            ty::UintTy::U8 => "NonZeroU8",
+            ty::UintTy::U16 => "NonZeroU16",
+            ty::UintTy::U32 => "NonZeroU32",
+            ty::UintTy::U64 => "NonZeroU64",
+            ty::UintTy::U128 => "NonZeroU128",
+            ty::UintTy::Usize => "NonZeroUsize",
+        }),
+        ty::Int(int_ty) => Some(match int_ty {
+            ty::IntTy::I8 => "NonZeroI8",
+            ty::IntTy::I16 => "NonZeroI16",
+            ty::IntTy::I32 => "NonZeroI32",
+            ty::IntTy::I64 => "NonZeroI64",
+            ty::IntTy::I128 => "NonZeroI128",
+            ty::IntTy::Isize => "NonZeroIsize",
+        }),
+        _ => None,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
index 51ba29d7389..a13391a5945 100644
--- a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
+++ b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
@@ -1,5 +1,5 @@
-use clippy_config::types::MacroMatcher;
 use clippy_config::Conf;
+use clippy_config::types::MacroMatcher;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{SourceText, SpanRangeExt};
 use rustc_ast::ast;
@@ -8,8 +8,8 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::Span;
+use rustc_span::hygiene::{ExpnKind, MacroKind};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
index aadd729f32a..372128ac16f 100644
--- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
@@ -9,8 +9,8 @@ use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKi
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, ConstKind, EarlyBinder, GenericArgKind, GenericArgsRef};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::{kw, Ident};
 use rustc_span::Span;
+use rustc_span::symbol::{Ident, kw};
 use std::iter;
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs b/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs
index a0de5ea711c..dbc9948eeed 100644
--- a/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs
@@ -2,7 +2,7 @@ use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 
-use clippy_utils::comparisons::{normalize_comparison, Rel};
+use clippy_utils::comparisons::{Rel, normalize_comparison};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::source::snippet;
diff --git a/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs b/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
index c1317524396..5d94cfab3b0 100644
--- a/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
@@ -7,12 +7,12 @@ use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::layout::HasTyCtxt;
 use rustc_middle::ty::{Ty, TypeckResults};
-use rustc_span::source_map::Spanned;
 use rustc_span::Span;
+use rustc_span::source_map::Spanned;
 
+use clippy_utils::SpanlessEq;
 use clippy_utils::diagnostics::span_lint_and_note;
 use clippy_utils::source::snippet;
-use clippy_utils::SpanlessEq;
 
 use super::{IMPOSSIBLE_COMPARISONS, REDUNDANT_COMPARISONS};
 
diff --git a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
index be97ad389bf..34f7dbea84e 100644
--- a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
@@ -6,7 +6,8 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{sym, source_map::Spanned};
+use rustc_span::source_map::Spanned;
+use rustc_span::sym;
 
 use super::FLOAT_EQUALITY_WITHOUT_ABS;
 
diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
index ae02d22512e..6d9e75f51d6 100644
--- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    can_move_expr_to_closure, eager_or_lazy, higher, is_else_clause, is_in_const_context, is_res_lang_ctor,
-    peel_blocks, peel_hir_expr_while, CaptureKind,
+    CaptureKind, can_move_expr_to_closure, eager_or_lazy, higher, is_else_clause, is_in_const_context,
+    is_res_lang_ctor, peel_blocks, peel_hir_expr_while,
 };
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
 use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
+use rustc_hir::def::Res;
 use rustc_hir::{Arm, BindingMode, Expr, ExprKind, MatchSource, Mutability, Pat, PatKind, Path, QPath, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
index 381975199d2..eebc62e2a5a 100644
--- a/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/panic_in_result_fn.rs
@@ -1,15 +1,15 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::root_macro_call_first_node;
-use clippy_utils::return_ty;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::visitors::{for_each_expr, Descend};
+use clippy_utils::visitors::{Descend, for_each_expr};
+use clippy_utils::{is_inside_always_const_context, return_ty};
 use core::ops::ControlFlow;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -68,10 +68,12 @@ fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, body: &'tcx hir
         let Some(macro_call) = root_macro_call_first_node(cx, e) else {
             return ControlFlow::Continue(Descend::Yes);
         };
-        if matches!(
-            cx.tcx.item_name(macro_call.def_id).as_str(),
-            "panic" | "assert" | "assert_eq" | "assert_ne"
-        ) {
+        if !is_inside_always_const_context(cx.tcx, e.hir_id)
+            && matches!(
+                cx.tcx.item_name(macro_call.def_id).as_str(),
+                "panic" | "assert" | "assert_eq" | "assert_ne"
+            )
+        {
             panics.push(macro_call.span);
             ControlFlow::Continue(Descend::No)
         } else {
diff --git a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
index 4eefd0065f6..fa5b02a5a41 100644
--- a/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
+++ b/src/tools/clippy/clippy_lints/src/panic_unimplemented.rs
@@ -1,8 +1,9 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_in_test;
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
-use rustc_hir::Expr;
+use clippy_utils::{is_in_test, match_def_path, paths};
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 
@@ -95,10 +96,49 @@ impl_lint_pass!(PanicUnimplemented => [UNIMPLEMENTED, UNREACHABLE, TODO, PANIC])
 
 impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
-            return;
-        };
-        if is_panic(cx, macro_call.def_id) {
+        if let Some(macro_call) = root_macro_call_first_node(cx, expr) {
+            if is_panic(cx, macro_call.def_id) {
+                if cx.tcx.hir().is_inside_const_context(expr.hir_id)
+                    || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)
+                {
+                    return;
+                }
+
+                span_lint(
+                    cx,
+                    PANIC,
+                    macro_call.span,
+                    "`panic` should not be present in production code",
+                );
+                return;
+            }
+            match cx.tcx.item_name(macro_call.def_id).as_str() {
+                "todo" => {
+                    span_lint(
+                        cx,
+                        TODO,
+                        macro_call.span,
+                        "`todo` should not be present in production code",
+                    );
+                },
+                "unimplemented" => {
+                    span_lint(
+                        cx,
+                        UNIMPLEMENTED,
+                        macro_call.span,
+                        "`unimplemented` should not be present in production code",
+                    );
+                },
+                "unreachable" => {
+                    span_lint(cx, UNREACHABLE, macro_call.span, "usage of the `unreachable!` macro");
+                },
+                _ => {},
+            }
+        } else if let ExprKind::Call(func, [_]) = expr.kind
+            && let ExprKind::Path(QPath::Resolved(None, expr_path)) = func.kind
+            && let Res::Def(DefKind::Fn, def_id) = expr_path.res
+            && match_def_path(cx, def_id, &paths::PANIC_ANY)
+        {
             if cx.tcx.hir().is_inside_const_context(expr.hir_id)
                 || self.allow_panic_in_tests && is_in_test(cx.tcx, expr.hir_id)
             {
@@ -108,32 +148,10 @@ impl<'tcx> LateLintPass<'tcx> for PanicUnimplemented {
             span_lint(
                 cx,
                 PANIC,
-                macro_call.span,
-                "`panic` should not be present in production code",
+                expr.span,
+                "`panic_any` should not be present in production code",
             );
             return;
         }
-        match cx.tcx.item_name(macro_call.def_id).as_str() {
-            "todo" => {
-                span_lint(
-                    cx,
-                    TODO,
-                    macro_call.span,
-                    "`todo` should not be present in production code",
-                );
-            },
-            "unimplemented" => {
-                span_lint(
-                    cx,
-                    UNIMPLEMENTED,
-                    macro_call.span,
-                    "`unimplemented` should not be present in production code",
-                );
-            },
-            "unreachable" => {
-                span_lint(cx, UNREACHABLE, macro_call.span, "usage of the `unreachable!` macro");
-            },
-            _ => {},
-        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 5ca244f0141..1bddfab39c6 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -18,7 +18,7 @@ use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, RegionKind, TyCtxt};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use rustc_target::spec::abi::Abi;
 
 declare_clippy_lint! {
@@ -110,7 +110,7 @@ pub struct PassByRefOrValue {
     avoid_breaking_exported_api: bool,
 }
 
-impl<'tcx> PassByRefOrValue {
+impl PassByRefOrValue {
     pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
         let ref_min_size = conf.trivial_copy_size_limit.unwrap_or_else(|| {
             let bit_width = u64::from(tcx.sess.target.pointer_width);
@@ -130,7 +130,7 @@ impl<'tcx> PassByRefOrValue {
         }
     }
 
-    fn check_poly_fn(&mut self, cx: &LateContext<'tcx>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {
+    fn check_poly_fn(&mut self, cx: &LateContext<'_>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {
         if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
index d7fa48c1e38..9f84686a0b1 100644
--- a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::path_to_local_id;
-use clippy_utils::source::{snippet, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet};
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_ast::{LitKind, StrStyle};
 use rustc_errors::Applicability;
@@ -9,7 +9,7 @@ use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPa
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{Span, Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -60,7 +60,7 @@ struct PathbufPushSearcher<'tcx> {
     err_span: Span,
 }
 
-impl<'tcx> PathbufPushSearcher<'tcx> {
+impl PathbufPushSearcher<'_> {
     /// Try to generate a suggestion with `PathBuf::from`.
     /// Returns `None` if the suggestion would be invalid.
     fn gen_pathbuf_from(&self, cx: &LateContext<'_>) -> Option<String> {
diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
index c1296b04387..42fbba8ef6d 100644
--- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_hir::{
-    intravisit, Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind,
+    Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind, intravisit,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/pointers_in_nomem_asm_block.rs b/src/tools/clippy/clippy_lints/src/pointers_in_nomem_asm_block.rs
new file mode 100644
index 00000000000..385f634a150
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/pointers_in_nomem_asm_block.rs
@@ -0,0 +1,88 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_ast::InlineAsmOptions;
+use rustc_hir::{Expr, ExprKind, InlineAsm, InlineAsmOperand};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::declare_lint_pass;
+use rustc_span::Span;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks if any pointer is being passed to an asm! block with `nomem` option.
+    ///
+    /// ### Why is this bad?
+    /// `nomem` forbids any reads or writes to memory and passing a pointer suggests
+    /// that either of those will happen.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// fn f(p: *mut u32) {
+    ///     unsafe { core::arch::asm!("mov [{p}], 42", p = in(reg) p, options(nomem, nostack)); }
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// fn f(p: *mut u32) {
+    ///     unsafe { core::arch::asm!("mov [{p}], 42", p = in(reg) p, options(nostack)); }
+    /// }
+    /// ```
+    #[clippy::version = "1.81.0"]
+    pub POINTERS_IN_NOMEM_ASM_BLOCK,
+    suspicious,
+    "pointers in nomem asm block"
+}
+
+declare_lint_pass!(PointersInNomemAsmBlock => [POINTERS_IN_NOMEM_ASM_BLOCK]);
+
+impl<'tcx> LateLintPass<'tcx> for PointersInNomemAsmBlock {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
+        if let ExprKind::InlineAsm(asm) = &expr.kind {
+            check_asm(cx, asm);
+        }
+    }
+}
+
+fn check_asm(cx: &LateContext<'_>, asm: &InlineAsm<'_>) {
+    if !asm.options.contains(InlineAsmOptions::NOMEM) {
+        return;
+    }
+
+    let spans = asm
+        .operands
+        .iter()
+        .filter(|(op, _span)| has_in_operand_pointer(cx, op))
+        .map(|(_op, span)| *span)
+        .collect::<Vec<Span>>();
+
+    if spans.is_empty() {
+        return;
+    }
+
+    span_lint_and_then(
+        cx,
+        POINTERS_IN_NOMEM_ASM_BLOCK,
+        spans,
+        "passing pointers to nomem asm block",
+        additional_notes,
+    );
+}
+
+fn has_in_operand_pointer(cx: &LateContext<'_>, asm_op: &InlineAsmOperand<'_>) -> bool {
+    let asm_in_expr = match asm_op {
+        InlineAsmOperand::SymStatic { .. }
+        | InlineAsmOperand::Out { .. }
+        | InlineAsmOperand::Const { .. }
+        | InlineAsmOperand::SymFn { .. }
+        | InlineAsmOperand::Label { .. } => return false,
+        InlineAsmOperand::SplitInOut { in_expr, .. } => in_expr,
+        InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => expr,
+    };
+
+    // This checks for raw ptrs, refs and function pointers - the last one
+    // also technically counts as reading memory.
+    cx.typeck_results().expr_ty(asm_in_expr).is_any_ptr()
+}
+
+fn additional_notes(diag: &mut rustc_errors::Diag<'_, ()>) {
+    diag.note("`nomem` means that no memory write or read happens inside the asm! block");
+    diag.note("if this is intentional and no pointers are read or written to, consider allowing the lint");
+}
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 125f694996c..bb8a9b6fca8 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -1,13 +1,11 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::source::SpanRangeExt;
-use clippy_utils::ty::expr_sig;
 use clippy_utils::visitors::contains_unsafe_block;
 use clippy_utils::{get_expr_use_or_unification_node, is_lint_allowed, path_def_id, path_to_local};
 use hir::LifetimeName;
 use rustc_errors::{Applicability, MultiSpan};
-use rustc_hir::def_id::DefId;
 use rustc_hir::hir_id::{HirId, HirIdMap};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{
     self as hir, AnonConst, BinOpKind, BindingMode, Body, Expr, ExprKind, FnRetTy, FnSig, GenericArg, ImplItemKind,
     ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, Safety, TraitFn, TraitItem, TraitItemKind, TyKind,
@@ -19,7 +17,7 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Binder, ClauseKind, ExistentialPredicate, List, PredicateKind, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -34,7 +32,7 @@ declare_clippy_lint! {
     /// with the appropriate `.to_owned()`/`to_string()` calls.
     ///
     /// ### Why is this bad?
-    /// Requiring the argument to be of the specific size
+    /// Requiring the argument to be of the specific type
     /// makes the function less useful for no benefit; slices in the form of `&[T]`
     /// or `&str` usually suffice and can be obtained from other types, too.
     ///
@@ -273,14 +271,18 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
         && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id)
     {
+        // TODO: `ptr_slice_from_raw_parts` and its mutable variant should probably still be linted
+        // conditionally based on how the return value is used, but not universally like the other
+        // functions since there are valid uses for null slice pointers.
+        //
+        // See: https://github.com/rust-lang/rust-clippy/pull/13452/files#r1773772034
+
         // `arg` positions where null would cause U.B.
         let arg_indices: &[_] = match name {
             sym::ptr_read
             | sym::ptr_read_unaligned
             | sym::ptr_read_volatile
             | sym::ptr_replace
-            | sym::ptr_slice_from_raw_parts
-            | sym::ptr_slice_from_raw_parts_mut
             | sym::ptr_write
             | sym::ptr_write_bytes
             | sym::ptr_write_unaligned
@@ -323,7 +325,6 @@ struct PtrArg<'tcx> {
     idx: usize,
     emission_id: HirId,
     span: Span,
-    ty_did: DefId,
     ty_name: Symbol,
     method_renames: &'static [(&'static str, &'static str)],
     ref_prefix: RefPrefix,
@@ -411,7 +412,6 @@ impl<'tcx> DerefTy<'tcx> {
     }
 }
 
-#[expect(clippy::too_many_lines)]
 fn check_fn_args<'cx, 'tcx: 'cx>(
     cx: &'cx LateContext<'tcx>,
     fn_sig: ty::FnSig<'tcx>,
@@ -514,7 +514,6 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                     idx: i,
                     emission_id,
                     span: hir_ty.span,
-                    ty_did: adt.did(),
                     ty_name: name.ident.name,
                     method_renames,
                     ref_prefix: RefPrefix { lt: *lt, mutability },
@@ -610,65 +609,50 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &Body<'tcx>, args: &[
                         set_skip_flag();
                     }
                 },
-                Some((Node::Expr(e), child_id)) => match e.kind {
-                    ExprKind::Call(f, expr_args) => {
-                        let i = expr_args.iter().position(|arg| arg.hir_id == child_id).unwrap_or(0);
-                        if expr_sig(self.cx, f).and_then(|sig| sig.input(i)).map_or(true, |ty| {
-                            match *ty.skip_binder().peel_refs().kind() {
-                                ty::Dynamic(preds, _, _) => !matches_preds(self.cx, args.deref_ty.ty(self.cx), preds),
-                                ty::Param(_) => true,
-                                ty::Adt(def, _) => def.did() == args.ty_did,
-                                _ => false,
-                            }
-                        }) {
-                            // Passed to a function taking the non-dereferenced type.
-                            set_skip_flag();
-                        }
-                    },
-                    ExprKind::MethodCall(name, self_arg, expr_args, _) => {
-                        let i = iter::once(self_arg)
-                            .chain(expr_args.iter())
-                            .position(|arg| arg.hir_id == child_id)
-                            .unwrap_or(0);
-                        if i == 0 {
-                            // Check if the method can be renamed.
-                            let name = name.ident.as_str();
-                            if let Some((_, replacement)) = args.method_renames.iter().find(|&&(x, _)| x == name) {
-                                result.replacements.push(PtrArgReplacement {
-                                    expr_span: e.span,
-                                    self_span: self_arg.span,
-                                    replacement,
-                                });
-                                return;
-                            }
+                Some((Node::Expr(use_expr), child_id)) => {
+                    if let ExprKind::Index(e, ..) = use_expr.kind
+                        && e.hir_id == child_id
+                    {
+                        // Indexing works with both owned and its dereferenced type
+                        return;
+                    }
+
+                    if let ExprKind::MethodCall(name, receiver, ..) = use_expr.kind
+                        && receiver.hir_id == child_id
+                    {
+                        let name = name.ident.as_str();
+
+                        // Check if the method can be renamed.
+                        if let Some((_, replacement)) = args.method_renames.iter().find(|&&(x, _)| x == name) {
+                            result.replacements.push(PtrArgReplacement {
+                                expr_span: use_expr.span,
+                                self_span: receiver.span,
+                                replacement,
+                            });
+                            return;
                         }
 
-                        let Some(id) = self.cx.typeck_results().type_dependent_def_id(e.hir_id) else {
-                            set_skip_flag();
+                        // Some methods exist on both `[T]` and `Vec<T>`, such as `len`, where the receiver type
+                        // doesn't coerce to a slice and our adjusted type check below isn't enough,
+                        // but it would still be valid to call with a slice
+                        if is_allowed_vec_method(self.cx, use_expr) {
                             return;
-                        };
-
-                        match *self.cx.tcx.fn_sig(id).instantiate_identity().skip_binder().inputs()[i]
-                            .peel_refs()
-                            .kind()
-                        {
-                            ty::Dynamic(preds, _, _) if !matches_preds(self.cx, args.deref_ty.ty(self.cx), preds) => {
-                                set_skip_flag();
-                            },
-                            ty::Param(_) => {
-                                set_skip_flag();
-                            },
-                            // If the types match check for methods which exist on both types. e.g. `Vec::len` and
-                            // `slice::len`
-                            ty::Adt(def, _) if def.did() == args.ty_did && !is_allowed_vec_method(self.cx, e) => {
-                                set_skip_flag();
-                            },
-                            _ => (),
                         }
-                    },
-                    // Indexing is fine for currently supported types.
-                    ExprKind::Index(e, _, _) if e.hir_id == child_id => (),
-                    _ => set_skip_flag(),
+                    }
+
+                    let deref_ty = args.deref_ty.ty(self.cx);
+                    let adjusted_ty = self.cx.typeck_results().expr_ty_adjusted(e).peel_refs();
+                    if adjusted_ty == deref_ty {
+                        return;
+                    }
+
+                    if let ty::Dynamic(preds, ..) = adjusted_ty.kind()
+                        && matches_preds(self.cx, deref_ty, preds)
+                    {
+                        return;
+                    }
+
+                    set_skip_flag();
                 },
                 _ => set_skip_flag(),
             }
diff --git a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs
index 77b707567e4..db03657c9af 100644
--- a/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs
+++ b/src/tools/clippy/clippy_lints/src/pub_underscore_fields.rs
@@ -1,5 +1,5 @@
-use clippy_config::types::PubUnderscoreFieldsBehaviour;
 use clippy_config::Conf;
+use clippy_config::types::PubUnderscoreFieldsBehaviour;
 use clippy_utils::attrs::is_doc_hidden;
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::is_path_lang_item;
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index e1e3ded2c79..aa9a9001afb 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -1,8 +1,8 @@
 use crate::manual_let_else::MANUAL_LET_ELSE;
 use crate::question_mark_used::QUESTION_MARK_USED;
+use clippy_config::Conf;
 use clippy_config::msrvs::Msrv;
 use clippy_config::types::MatchLintBehaviour;
-use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
@@ -12,8 +12,8 @@ use clippy_utils::{
     span_contains_comment,
 };
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
+use rustc_hir::def::Res;
 use rustc_hir::{
     BindingMode, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath, Stmt,
     StmtKind,
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index 81189fe517c..21cd3367262 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -1,8 +1,8 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::{snippet, snippet_with_applicability, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{get_parent_expr, higher, is_in_const_context, is_integer_const, path_to_local};
 use rustc_ast::ast::RangeLimits;
@@ -11,8 +11,8 @@ use rustc_hir::{BinOpKind, Expr, ExprKind, HirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::source_map::Spanned;
 use rustc_span::Span;
+use rustc_span::source_map::Spanned;
 use std::cmp::Ordering;
 
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs b/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs
index d0b45b59526..e877f5d6ed4 100644
--- a/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs
+++ b/src/tools/clippy/clippy_lints/src/rc_clone_in_vec_init.rs
@@ -8,7 +8,7 @@ use rustc_hir::{Expr, ExprKind, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span, Symbol};
+use rustc_span::{Span, Symbol, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
index 7f4735c6a88..6bd68dd4109 100644
--- a/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
+++ b/src/tools/clippy/clippy_lints/src/read_zero_byte_vec.rs
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::get_enclosing_block;
-use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
+use clippy_utils::higher::{VecInitKind, get_vec_init_kind};
 use clippy_utils::source::snippet;
 
 use hir::{Expr, ExprKind, HirId, LetStmt, PatKind, PathSegment, QPath, StmtKind};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index 4e24ddad83a..b9e0106fc86 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -1,17 +1,17 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
-use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
+use clippy_utils::fn_has_unsatisfiable_preds;
+use clippy_utils::mir::{LocalUsage, PossibleBorrowerMap, visit_local_usage};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
-use clippy_utils::fn_has_unsatisfiable_preds;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{def_id, Body, FnDecl, LangItem};
+use rustc_hir::{Body, FnDecl, LangItem, def_id};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{BytePos, Span, sym};
 
 macro_rules! unwrap_or_continue {
     ($x:expr) => {
@@ -349,14 +349,10 @@ fn visit_clone_usage(cloned: mir::Local, clone: mir::Local, mir: &mir::Body<'_>,
             local_use_locs: _,
             local_consume_or_mutate_locs: clone_consume_or_mutate_locs,
         },
-    )) = visit_local_usage(
-        &[cloned, clone],
-        mir,
-        mir::Location {
-            block: bb,
-            statement_index: mir.basic_blocks[bb].statements.len(),
-        },
-    )
+    )) = visit_local_usage(&[cloned, clone], mir, mir::Location {
+        block: bb,
+        statement_index: mir.basic_blocks[bb].statements.len(),
+    })
     .map(|mut vec| (vec.remove(0), vec.remove(0)))
     {
         CloneUsage {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index bad9b979203..41a44de536b 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
 use rustc_hir::{
-    intravisit as hir_visit, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node,
+    ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node, intravisit as hir_visit,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
@@ -228,7 +228,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                 path: &'tcx hir::Path<'tcx>,
                 count: usize,
             }
-            impl<'a, 'tcx> Visitor<'tcx> for ClosureUsageCount<'a, 'tcx> {
+            impl<'tcx> Visitor<'tcx> for ClosureUsageCount<'_, 'tcx> {
                 type NestedFilter = nested_filter::OnlyBodies;
 
                 fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_else.rs b/src/tools/clippy/clippy_lints/src/redundant_else.rs
index 3bdf13dbbea..6a1d40334e7 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_else.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_else.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_ast::ast::{Block, Expr, ExprKind, Stmt, StmtKind};
-use rustc_ast::visit::{walk_expr, Visitor};
+use rustc_ast::visit::{Visitor, walk_expr};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
index 0e637538615..d0dbff081f9 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index d94ca5bc7ec..4f46ca3c715 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -9,8 +9,8 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::UpvarCapture;
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::Ident;
 use rustc_span::DesugaringKind;
+use rustc_span::symbol::Ident;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
index d6e741dd974..b27bb2e78af 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
 use rustc_ast::ast::{ConstItem, Item, ItemKind, StaticItem, Ty, TyKind};
diff --git a/src/tools/clippy/clippy_lints/src/reference.rs b/src/tools/clippy/clippy_lints/src/reference.rs
index 2b4ef21fc48..4bff37216ed 100644
--- a/src/tools/clippy/clippy_lints/src/reference.rs
+++ b/src/tools/clippy/clippy_lints/src/reference.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{snippet_with_applicability, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet_with_applicability};
 use rustc_ast::ast::{Expr, ExprKind, Mutability, UnOp};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs
index f6ef02b7c23..12cbdb854ef 100644
--- a/src/tools/clippy/clippy_lints/src/regex.rs
+++ b/src/tools/clippy/clippy_lints/src/regex.rs
@@ -3,7 +3,7 @@ use std::fmt::Display;
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
 use clippy_utils::source::SpanRangeExt;
-use clippy_utils::{def_path_def_ids, path_def_id, paths};
+use clippy_utils::{def_path_res_with_base, find_crates, path_def_id, paths};
 use rustc_ast::ast::{LitKind, StrStyle};
 use rustc_hir::def_id::DefIdMap;
 use rustc_hir::{BorrowKind, Expr, ExprKind};
@@ -75,11 +75,14 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
         // We don't use `match_def_path` here because that relies on matching the exact path, which changed
         // between regex 1.8 and 1.9
         //
-        // `def_path_def_ids` will resolve through re-exports but is relatively heavy, so we only perform
-        // the operation once and store the results
-        let mut resolve = |path, kind| {
-            for id in def_path_def_ids(cx.tcx, path) {
-                self.definitions.insert(id, kind);
+        // `def_path_res_with_base` will resolve through re-exports but is relatively heavy, so we only
+        // perform the operation once and store the results
+        let regex_crates = find_crates(cx.tcx, sym!(regex));
+        let mut resolve = |path: &[&str], kind: RegexKind| {
+            for res in def_path_res_with_base(cx.tcx, regex_crates.clone(), &path[1..]) {
+                if let Some(id) = res.opt_def_id() {
+                    self.definitions.insert(id, kind);
+                }
             }
         };
 
diff --git a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
index 08de10f69b0..f54cafffb83 100644
--- a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
+++ b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
@@ -8,7 +8,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs b/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
index caf3fb8707d..6157adad059 100644
--- a/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
+use clippy_utils::higher::{VecInitKind, get_vec_init_kind};
 use clippy_utils::source::snippet;
 use clippy_utils::{is_from_proc_macro, path_to_local_id};
 use rustc_errors::Applicability;
diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
index 5962e8be959..42d9cf2c88c 100644
--- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
@@ -7,7 +7,7 @@ use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 5ce091b7a7a..f6f75d8c798 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -1,16 +1,16 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::source::{snippet_with_context, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::visitors::{for_each_expr, Descend};
+use clippy_utils::visitors::{Descend, for_each_expr, for_each_unconsumed_temporary};
 use clippy_utils::{
     binary_expr_needs_parentheses, fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res,
     path_to_local_id, span_contains_cfg, span_find_starting_semi,
 };
 use core::ops::ControlFlow;
-use rustc_ast::NestedMetaItem;
+use rustc_ast::MetaItemInner;
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::FnKind;
 use rustc_hir::LangItem::ResultErr;
+use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     Block, Body, Expr, ExprKind, FnDecl, HirId, ItemKind, LangItem, MatchSource, Node, OwnerNode, PatKind, QPath, Stmt,
     StmtKind,
@@ -21,7 +21,7 @@ use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, BytePos, Pos, Span};
+use rustc_span::{BytePos, Pos, Span, sym};
 use std::borrow::Cow;
 use std::fmt::Display;
 
@@ -140,7 +140,7 @@ enum RetReplacement<'tcx> {
     Expr(Cow<'tcx, str>, Applicability),
 }
 
-impl<'tcx> RetReplacement<'tcx> {
+impl RetReplacement<'_> {
     fn sugg_help(&self) -> &'static str {
         match self {
             Self::Empty | Self::Expr(..) => "remove `return`",
@@ -158,7 +158,7 @@ impl<'tcx> RetReplacement<'tcx> {
     }
 }
 
-impl<'tcx> Display for RetReplacement<'tcx> {
+impl Display for RetReplacement<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
             Self::Empty => write!(f, ""),
@@ -389,10 +389,24 @@ fn check_final_expr<'tcx>(
                 }
             };
 
-            let borrows = inner.map_or(false, |inner| last_statement_borrows(cx, inner));
-            if borrows {
-                return;
+            if let Some(inner) = inner {
+                if for_each_unconsumed_temporary(cx, inner, |temporary_ty| {
+                    if temporary_ty.has_significant_drop(cx.tcx, cx.param_env)
+                        && temporary_ty
+                            .walk()
+                            .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if !re.is_static()))
+                    {
+                        ControlFlow::Break(())
+                    } else {
+                        ControlFlow::Continue(())
+                    }
+                })
+                .is_break()
+                {
+                    return;
+                }
             }
+
             if ret_span.from_expansion() {
                 return;
             }
@@ -407,7 +421,7 @@ fn check_final_expr<'tcx>(
                     if matches!(Level::from_attr(attr), Some(Level::Expect(_)))
                         && let metas = attr.meta_item_list()
                         && let Some(lst) = metas
-                        && let [NestedMetaItem::MetaItem(meta_item)] = lst.as_slice()
+                        && let [MetaItemInner::MetaItem(meta_item), ..] = lst.as_slice()
                         && let [tool, lint_name] = meta_item.path.segments.as_slice()
                         && tool.ident.name == sym::clippy
                         && matches!(
diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs
index 508f3ae6def..8d31641d483 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -5,8 +5,8 @@ use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::AssocKind;
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::Symbol;
 use rustc_span::Span;
+use rustc_span::symbol::Symbol;
 use std::collections::{BTreeMap, BTreeSet};
 
 declare_clippy_lint! {
@@ -62,13 +62,10 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                 && let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind
             {
                 if !map.contains_key(res) {
-                    map.insert(
-                        *res,
-                        ExistingName {
-                            impl_methods: BTreeMap::new(),
-                            trait_methods: BTreeMap::new(),
-                        },
-                    );
+                    map.insert(*res, ExistingName {
+                        impl_methods: BTreeMap::new(),
+                        trait_methods: BTreeMap::new(),
+                    });
                 }
                 let existing_name = map.get_mut(res).unwrap();
 
diff --git a/src/tools/clippy/clippy_lints/src/set_contains_or_insert.rs b/src/tools/clippy/clippy_lints/src/set_contains_or_insert.rs
index e6fe7649397..1185d67b125 100644
--- a/src/tools/clippy/clippy_lints/src/set_contains_or_insert.rs
+++ b/src/tools/clippy/clippy_lints/src/set_contains_or_insert.rs
@@ -3,12 +3,12 @@ use std::ops::ControlFlow;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::for_each_expr;
-use clippy_utils::{higher, peel_hir_expr_while, SpanlessEq};
+use clippy_utils::{SpanlessEq, higher, peel_hir_expr_while};
 use rustc_hir::{Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -42,7 +42,7 @@ declare_clippy_lint! {
     ///     println!("inserted {value:?}");
     /// }
     /// ```
-    #[clippy::version = "1.80.0"]
+    #[clippy::version = "1.81.0"]
     pub SET_CONTAINS_OR_INSERT,
     nursery,
     "call to `<set>::contains` followed by `<set>::insert`"
diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
index 979d6dc77ae..0eece922143 100644
--- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
+++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
@@ -4,13 +4,13 @@ use clippy_utils::{expr_or_init, get_attr, path_to_local, peel_hir_expr_unary};
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{self as hir, HirId};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::{GenericArgKind, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span, DUMMY_SP};
+use rustc_span::{DUMMY_SP, Span, sym};
 use std::borrow::Cow;
 use std::collections::hash_map::Entry;
 
@@ -249,7 +249,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx
     }
 }
 
-impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> {
+impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
     fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
         self.ap.curr_block_hir_id = block.hir_id;
         self.ap.curr_block_span = block.span;
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 acf44a9bb5a..9fdee8543a8 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
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use rustc_ast::node_id::{NodeId, NodeMap};
 use rustc_ast::ptr::P;
-use rustc_ast::visit::{walk_expr, Visitor};
+use rustc_ast::visit::{Visitor, walk_expr};
 use rustc_ast::{Crate, Expr, ExprKind, Item, ItemKind, MacroDef, ModKind, Ty, TyKind, UseTreeKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
@@ -102,7 +102,7 @@ struct ImportUsageVisitor {
     imports_referenced_with_self: Vec<Symbol>,
 }
 
-impl<'tcx> Visitor<'tcx> for ImportUsageVisitor {
+impl Visitor<'_> for ImportUsageVisitor {
     fn visit_expr(&mut self, expr: &Expr) {
         if let ExprKind::Path(_, path) = &expr.kind
             && path.segments.len() > 1
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 04c16281ec4..fc799cad67e 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -2,11 +2,10 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local,
-    path_to_local_id, SpanlessEq,
+    SpanlessEq, get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local, path_to_local_id,
 };
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_block, walk_expr, walk_stmt, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, PatKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -230,7 +229,7 @@ struct VectorInitializationVisitor<'a, 'tcx> {
     initialization_found: bool,
 }
 
-impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
+impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
     /// Checks if the given expression is extending a vector with `repeat(0).take(..)`
     fn search_slow_extend_filling(&mut self, expr: &'tcx Expr<'_>) {
         if self.initialization_found
@@ -300,7 +299,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for VectorInitializationVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for VectorInitializationVisitor<'_, 'tcx> {
     fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
         if self.initialization_found {
             match stmt.kind {
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 44283a49e84..8dd99858793 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::Msrv;
 use clippy_config::Conf;
+use clippy_config::msrvs::Msrv;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
 use rustc_attr::{StabilityLevel, StableSince};
@@ -11,7 +11,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/string_patterns.rs b/src/tools/clippy/clippy_lints/src/string_patterns.rs
index 7e211d64da1..ba2ddac2ec3 100644
--- a/src/tools/clippy/clippy_lints/src/string_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/string_patterns.rs
@@ -1,13 +1,13 @@
 use std::ops::ControlFlow;
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::eager_or_lazy::switch_to_eager_eval;
 use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::path_to_local_id;
 use clippy_utils::source::{snippet, str_literal_to_char_literal};
-use clippy_utils::visitors::{for_each_expr, Descend};
+use clippy_utils::visitors::{Descend, for_each_expr};
 use itertools::Itertools;
 use rustc_ast::{BinOpKind, LitKind};
 use rustc_errors::Applicability;
@@ -15,7 +15,7 @@ use rustc_hir::{Expr, ExprKind, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -33,7 +33,7 @@ declare_clippy_lint! {
     /// ```no_run
     /// "Hello World!".trim_end_matches(['.', ',', '!', '?']);
     /// ```
-    #[clippy::version = "1.80.0"]
+    #[clippy::version = "1.81.0"]
     pub MANUAL_PATTERN_CHAR_COMPARISON,
     style,
     "manual char comparison in string patterns"
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 6ca4ca000e9..1fb82b66ab8 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -2,8 +2,8 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_the
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::ty::is_type_lang_item;
 use clippy_utils::{
-    get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, is_path_diagnostic_item, method_calls,
-    peel_blocks, SpanlessEq,
+    SpanlessEq, get_expr_use_or_unification_node, get_parent_expr, is_lint_allowed, is_path_diagnostic_item,
+    method_calls, peel_blocks,
 };
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
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 1c1de805db0..be32dc0aab0 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
@@ -1,4 +1,4 @@
-use clippy_utils::ast_utils::{eq_id, is_useless_with_eq_exprs, IdentIter};
+use clippy_utils::ast_utils::{IdentIter, eq_id, is_useless_with_eq_exprs};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use core::ops::{Add, AddAssign};
@@ -7,9 +7,9 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::Span;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Ident;
-use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
index 744d6392e06..e9779d437d4 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::visitors::for_each_expr_without_closures;
-use clippy_utils::{binop_traits, trait_ref_of_method, BINOP_TRAITS, OP_ASSIGN_TRAITS};
+use clippy_utils::{BINOP_TRAITS, OP_ASSIGN_TRAITS, binop_traits, trait_ref_of_method};
 use core::ops::ControlFlow;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index 197011cde3a..a3145c4647c 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -6,7 +6,7 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{can_mut_borrow_both, eq_expr_value, is_in_const_context, std_or_core};
 use itertools::Itertools;
 
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 
 use crate::FxHashSet;
 use rustc_errors::Applicability;
@@ -17,7 +17,7 @@ use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span, SyntaxContext};
+use rustc_span::{Span, SyntaxContext, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -332,7 +332,7 @@ struct IndexBinding<'a, 'tcx> {
     applicability: &'a mut Applicability,
 }
 
-impl<'a, 'tcx> IndexBinding<'a, 'tcx> {
+impl<'tcx> IndexBinding<'_, 'tcx> {
     fn snippet_index_bindings(&mut self, exprs: &[&'tcx Expr<'tcx>]) -> String {
         let mut bindings = FxHashSet::default();
         for expr in exprs {
diff --git a/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs
index 20e9608a15d..8c5cf93ab6e 100644
--- a/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/swap_ptr_to_ref.rs
@@ -5,7 +5,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span, SyntaxContext};
+use rustc_span::{Span, SyntaxContext, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs b/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs
index 25d0a16e2ab..3cd4fefffad 100644
--- a/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs
+++ b/src/tools/clippy/clippy_lints/src/tests_outside_test_module.rs
@@ -4,8 +4,8 @@ use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs
index dafe9e38818..4f96a566b63 100644
--- a/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs
+++ b/src/tools/clippy/clippy_lints/src/to_digit_is_some.rs
@@ -56,11 +56,13 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
                         && let hir::ExprKind::Path(to_digits_path) = &to_digits_call.kind
                         && let to_digits_call_res = cx.qpath_res(to_digits_path, to_digits_call.hir_id)
                         && let Some(to_digits_def_id) = to_digits_call_res.opt_def_id()
-                        && match_def_path(
-                            cx,
-                            to_digits_def_id,
-                            &["core", "char", "methods", "<impl char>", "to_digit"],
-                        )
+                        && match_def_path(cx, to_digits_def_id, &[
+                            "core",
+                            "char",
+                            "methods",
+                            "<impl char>",
+                            "to_digit",
+                        ])
                     {
                         Some((false, char_arg, radix_arg))
                     } else {
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 2e87d36df31..00277593622 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -1,8 +1,8 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
-use clippy_utils::source::{snippet, snippet_with_applicability, SpanRangeExt};
-use clippy_utils::{is_from_proc_macro, SpanlessEq, SpanlessHash};
+use clippy_utils::source::{SpanRangeExt, snippet, snippet_with_applicability};
+use clippy_utils::{SpanlessEq, SpanlessHash, is_from_proc_macro};
 use core::hash::{Hash, Hasher};
 use itertools::Itertools;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index da7906b1183..25fec9f688c 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -19,8 +19,8 @@ mod useless_transmute;
 mod utils;
 mod wrong_transmute;
 
-use clippy_config::msrvs::Msrv;
 use clippy_config::Conf;
+use clippy_config::msrvs::Msrv;
 use clippy_utils::is_in_const_context;
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
@@ -527,24 +527,44 @@ declare_clippy_lint! {
     /// Checks if transmute calls have all generics specified.
     ///
     /// ### Why is this bad?
-    /// If not set, some unexpected output type could be retrieved instead of the expected one,
-    /// potentially leading to invalid code.
+    /// If not, one or more unexpected types could be used during `transmute()`, potentially leading
+    /// to Undefined Behavior or other problems.
+    ///
+    /// This is particularly dangerous in case a seemingly innocent/unrelated change causes type
+    /// inference to result in a different type. For example, if `transmute()` is the tail
+    /// expression of an `if`-branch, and the `else`-branch type changes, the compiler may silently
+    /// infer a different type to be returned by `transmute()`. That is because the compiler is
+    /// free to change the inference of a type as long as that inference is technically correct,
+    /// regardless of the programmer's unknown expectation.
     ///
-    /// This is particularly dangerous in case a seemingly innocent/unrelated change can cause type
-    /// inference to start inferring a different type. E.g. the transmute is the tail expression of
-    /// an `if` branch, and a different branches type changes, causing the transmute to silently
-    /// have a different type, instead of a proper error.
+    /// Both type-parameters, the input- and the output-type, to any `transmute()` should
+    /// be given explicitly: Setting the input-type explicitly avoids confusion about what the
+    /// argument's type actually is. Setting the output-type explicitly avoids type-inference
+    /// to infer a technically correct yet unexpected type.
     ///
     /// ### Example
     /// ```no_run
     /// # unsafe {
+    /// // Avoid "naked" calls to `transmute()`!
     /// let x: i32 = std::mem::transmute([1u16, 2u16]);
+    ///
+    /// // `first_answers` is intended to transmute a slice of bool to a slice of u8.
+    /// // But the programmer forgot to index the first element of the outer slice,
+    /// // so we are actually transmuting from "pointers to slices" instead of
+    /// // transmuting from "a slice of bool", causing a nonsensical result.
+    /// let the_answers: &[&[bool]] = &[&[true, false, true]];
+    /// let first_answers: &[u8] = std::mem::transmute(the_answers);
     /// # }
     /// ```
     /// Use instead:
     /// ```no_run
     /// # unsafe {
     /// let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+    ///
+    /// // The explicit type parameters on `transmute()` makes the intention clear,
+    /// // and cause a type-error if the actual types don't match our expectation.
+    /// let the_answers: &[&[bool]] = &[&[true, false, true]];
+    /// let first_answers: &[u8] = std::mem::transmute::<&[bool], &[u8]>(the_answers[0]);
     /// # }
     /// ```
     #[clippy::version = "1.79.0"]
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index ba8c7d6bfcb..fca332dba40 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -6,8 +6,8 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, Node};
 use rustc_hir_typeck::cast::check_cast;
 use rustc_lint::LateContext;
-use rustc_middle::ty::cast::CastKind;
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::cast::CastKind;
 
 /// Checks for `transmutes_expressible_as_ptr_casts` lint.
 /// Returns `true` if it's triggered, otherwise returns `false`.
diff --git a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
index 35e93830766..f46e95b0b83 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
@@ -1,5 +1,5 @@
-use super::utils::is_layout_incompatible;
 use super::UNSOUND_COLLECTION_TRANSMUTE;
+use super::utils::is_layout_incompatible;
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
index 1d0de932754..3da8a449a7c 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::visitors::for_each_local_use_after_expr;
 use clippy_utils::{is_from_proc_macro, path_to_local};
diff --git a/src/tools/clippy/clippy_lints/src/types/box_collection.rs b/src/tools/clippy/clippy_lints/src/types/box_collection.rs
index 9ac73394548..24fe4e08a5b 100644
--- a/src/tools/clippy/clippy_lints/src/types/box_collection.rs
+++ b/src/tools/clippy/clippy_lints/src/types/box_collection.rs
@@ -3,7 +3,7 @@ use clippy_utils::{path_def_id, qpath_generic_tys};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, QPath};
 use rustc_lint::LateContext;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 
 use super::BOX_COLLECTION;
 
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 3a14927802b..363aea8be72 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -18,8 +18,8 @@ use rustc_hir::{
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -261,8 +261,59 @@ declare_clippy_lint! {
     /// ### Example
     /// ```no_run
     /// # use std::rc::Rc;
-    /// struct Foo {
-    ///     inner: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>>,
+    /// struct PointMatrixContainer {
+    ///     matrix: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>>,
+    /// }
+    ///
+    /// fn main() {
+    ///     let point_matrix: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![
+    ///         vec![
+    ///             Box::new((1, 2, 3, 4)),
+    ///             Box::new((5, 6, 7, 8)),
+    ///         ],
+    ///         vec![
+    ///             Box::new((9, 10, 11, 12)),
+    ///         ],
+    ///     ];
+    ///
+    ///     let shared_point_matrix: Rc<Vec<Vec<Box<(u32, u32, u32, u32)>>>> = Rc::new(point_matrix);
+    ///
+    ///     let container = PointMatrixContainer {
+    ///         matrix: shared_point_matrix,
+    ///     };
+    ///
+    ///     // ...
+    /// }
+    /// ```
+    /// Use instead:
+    /// ### Example
+    /// ```no_run
+    /// # use std::rc::Rc;
+    /// type PointMatrix = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
+    /// type SharedPointMatrix = Rc<PointMatrix>;
+    ///
+    /// struct PointMatrixContainer {
+    ///     matrix: SharedPointMatrix,
+    /// }
+    ///
+    /// fn main() {
+    ///     let point_matrix: PointMatrix = vec![
+    ///         vec![
+    ///             Box::new((1, 2, 3, 4)),
+    ///             Box::new((5, 6, 7, 8)),
+    ///         ],
+    ///         vec![
+    ///             Box::new((9, 10, 11, 12)),
+    ///         ],
+    ///     ];
+    ///
+    ///     let shared_point_matrix: SharedPointMatrix = Rc::new(point_matrix);
+    ///
+    ///     let container = PointMatrixContainer {
+    ///         matrix: shared_point_matrix,
+    ///     };
+    ///
+    ///     // ...
     /// }
     /// ```
     #[clippy::version = "pre 1.29.0"]
@@ -335,30 +386,22 @@ impl<'tcx> LateLintPass<'tcx> for Types {
 
         let is_exported = cx.effective_visibilities.is_exported(def_id);
 
-        self.check_fn_decl(
-            cx,
-            decl,
-            CheckTyContext {
-                is_in_trait_impl,
-                is_exported,
-                in_body: matches!(fn_kind, FnKind::Closure),
-                ..CheckTyContext::default()
-            },
-        );
+        self.check_fn_decl(cx, decl, CheckTyContext {
+            is_in_trait_impl,
+            is_exported,
+            in_body: matches!(fn_kind, FnKind::Closure),
+            ..CheckTyContext::default()
+        });
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         let is_exported = cx.effective_visibilities.is_exported(item.owner_id.def_id);
 
         match item.kind {
-            ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty(
-                cx,
-                ty,
-                CheckTyContext {
-                    is_exported,
-                    ..CheckTyContext::default()
-                },
-            ),
+            ItemKind::Static(ty, _, _) | ItemKind::Const(ty, _, _) => self.check_ty(cx, ty, CheckTyContext {
+                is_exported,
+                ..CheckTyContext::default()
+            }),
             // functions, enums, structs, impls and traits are covered
             _ => (),
         }
@@ -376,14 +419,10 @@ impl<'tcx> LateLintPass<'tcx> for Types {
                     false
                 };
 
-                self.check_ty(
-                    cx,
-                    ty,
-                    CheckTyContext {
-                        is_in_trait_impl,
-                        ..CheckTyContext::default()
-                    },
-                );
+                self.check_ty(cx, ty, CheckTyContext {
+                    is_in_trait_impl,
+                    ..CheckTyContext::default()
+                });
             },
             // Methods are covered by check_fn.
             // Type aliases are ignored because oftentimes it's impossible to
@@ -399,14 +438,10 @@ impl<'tcx> LateLintPass<'tcx> for Types {
 
         let is_exported = cx.effective_visibilities.is_exported(field.def_id);
 
-        self.check_ty(
-            cx,
-            field.ty,
-            CheckTyContext {
-                is_exported,
-                ..CheckTyContext::default()
-            },
-        );
+        self.check_ty(cx, field.ty, CheckTyContext {
+            is_exported,
+            ..CheckTyContext::default()
+        });
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &TraitItem<'tcx>) {
@@ -434,14 +469,10 @@ impl<'tcx> LateLintPass<'tcx> for Types {
 
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {
         if let Some(ty) = local.ty {
-            self.check_ty(
-                cx,
-                ty,
-                CheckTyContext {
-                    in_body: true,
-                    ..CheckTyContext::default()
-                },
-            );
+            self.check_ty(cx, ty, CheckTyContext {
+                in_body: true,
+                ..CheckTyContext::default()
+            });
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
index 0801eace4fc..1a656088b17 100644
--- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
+++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
@@ -9,7 +9,7 @@ use rustc_lint::LateContext;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_span::symbol::sym;
 
-use super::{utils, REDUNDANT_ALLOCATION};
+use super::{REDUNDANT_ALLOCATION, utils};
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath: &QPath<'tcx>, def_id: DefId) -> bool {
     let mut applicability = Applicability::MaybeIncorrect;
diff --git a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
index 7fcfd5c8f35..0b64fddb447 100644
--- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir as hir;
-use rustc_hir::intravisit::{walk_inf, walk_ty, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_inf, walk_ty};
 use rustc_hir::{GenericParamKind, TyKind};
 use rustc_lint::LateContext;
 use rustc_target::spec::abi::Abi;
diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
index 29996a6f783..230239335c6 100644
--- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
@@ -6,8 +6,8 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::LateContext;
-use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::TypeVisitableExt;
+use rustc_middle::ty::layout::LayoutOf;
 use rustc_span::symbol::sym;
 
 use super::VEC_BOX;
diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
index 42100e1d755..3fc08e8192d 100644
--- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::intravisit::{walk_body, walk_expr, FnKind, Visitor};
+use rustc_hir::intravisit::{FnKind, Visitor, walk_body, walk_expr};
 use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind};
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
@@ -13,8 +13,8 @@ use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::{kw, Ident};
-use rustc_span::{sym, Span};
+use rustc_span::symbol::{Ident, kw};
+use rustc_span::{Span, sym};
 use rustc_trait_selection::error_reporting::traits::suggestions::ReturnsVisitor;
 use std::ops::ControlFlow;
 
@@ -257,13 +257,10 @@ fn is_default_method_on_current_ty<'tcx>(tcx: TyCtxt<'tcx>, qpath: QPath<'tcx>,
             }
             if matches!(
                 ty.kind,
-                TyKind::Path(QPath::Resolved(
-                    _,
-                    hir::Path {
-                        res: Res::SelfTyAlias { .. },
-                        ..
-                    },
-                ))
+                TyKind::Path(QPath::Resolved(_, hir::Path {
+                    res: Res::SelfTyAlias { .. },
+                    ..
+                },))
             ) {
                 return true;
             }
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 f51c5f74d99..44eb0a6c593 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -4,12 +4,12 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_lint_allowed;
 use clippy_utils::source::walk_span_to_context;
-use clippy_utils::visitors::{for_each_expr, Descend};
+use clippy_utils::visitors::{Descend, for_each_expr};
 use hir::HirId;
 use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource};
-use rustc_lexer::{tokenize, TokenKind};
+use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
index 88039372ebd..cfa565cf803 100644
--- a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
+++ b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
@@ -5,8 +5,8 @@ use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
+use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/uninit_vec.rs b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
index 9ffcfcc0f50..93ed15777e0 100644
--- a/src/tools/clippy/clippy_lints/src/uninit_vec.rs
+++ b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
-use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
+use clippy_utils::higher::{VecInitKind, get_vec_init_kind};
 use clippy_utils::ty::{is_type_diagnostic_item, is_uninit_value_valid_for_ty};
-use clippy_utils::{is_integer_literal, is_lint_allowed, path_to_local_id, peel_hir_expr_while, SpanlessEq};
+use clippy_utils::{SpanlessEq, is_integer_literal, is_lint_allowed, path_to_local_id, peel_hir_expr_while};
 use rustc_hir::{Block, Expr, ExprKind, HirId, PatKind, PathSegment, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 // TODO: add `ReadBuf` (RFC 2930) in "How to fix" once it is available in std
 declare_clippy_lint! {
diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
index a8cc2f97963..87478a120dd 100644
--- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
@@ -5,7 +5,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_middle::ty::{ClauseKind, GenericPredicates, ProjectionPredicate, TraitPredicate};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{BytePos, Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
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 80b661a757c..bf2d75ea1a9 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
@@ -4,7 +4,7 @@ use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source, i
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::{walk_body, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_body};
 use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, LetStmt, MatchSource, Node, PatKind, QPath, TyKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::{in_external_macro, is_from_async_await};
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 978d49f09c3..41b2ca5d268 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
@@ -1,11 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
-use clippy_utils::source::{indent_of, reindent_multiline, SourceText, SpanRangeExt};
+use clippy_utils::source::{SourceText, SpanRangeExt, indent_of, reindent_multiline};
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Expr, ExprKind, MatchSource, Node, StmtKind};
 use rustc_lint::LateContext;
 
-use super::{utils, UNIT_ARG};
+use super::{UNIT_ARG, utils};
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
     if expr.span.from_expansion() {
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index 080efe983c2..937e35dea96 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -4,15 +4,15 @@ use clippy_utils::source::snippet;
 use clippy_utils::visitors::find_all_ret_expressions;
 use clippy_utils::{contains_return, is_res_lang_ctor, path_res, return_ty};
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::FnKind;
 use rustc_hir::LangItem::{OptionSome, ResultOk};
+use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, ExprKind, FnDecl, Impl, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
+use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::sym;
-use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 98f0be3135d..c7c837de505 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -1,14 +1,14 @@
 #![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_maybe_qself, eq_pat, eq_path};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::over;
+use rustc_ast::PatKind::*;
 use rustc_ast::mut_visit::*;
 use rustc_ast::ptr::P;
-use rustc_ast::PatKind::*;
-use rustc_ast::{self as ast, Mutability, Pat, PatKind, DUMMY_NODE_ID};
+use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind};
 use rustc_ast_pretty::pprust;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
@@ -16,7 +16,7 @@ use rustc_session::impl_lint_pass;
 use rustc_span::DUMMY_SP;
 use std::cell::Cell;
 use std::mem;
-use thin_vec::{thin_vec, ThinVec};
+use thin_vec::{ThinVec, thin_vec};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -275,12 +275,15 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
             |k, ps1, idx| matches!(
                 k,
                 TupleStruct(qself2, path2, ps2)
-                    if eq_maybe_qself(qself1, qself2) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
+                    if eq_maybe_qself(qself1.as_ref(), qself2.as_ref())
+                       && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
             ),
             |k| always_pat!(k, TupleStruct(_, _, ps) => ps),
         ),
         // Transform a record pattern `S { fp_0, ..., fp_n }`.
-        Struct(qself1, path1, fps1, rest1) => extend_with_struct_pat(qself1, path1, fps1, *rest1, start, alternatives),
+        Struct(qself1, path1, fps1, rest1) => {
+            extend_with_struct_pat(qself1.as_ref(), path1, fps1, *rest1, start, alternatives)
+        },
     };
 
     alternatives[focus_idx].kind = focus_kind;
@@ -292,7 +295,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
 /// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
 /// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
 fn extend_with_struct_pat(
-    qself1: &Option<P<ast::QSelf>>,
+    qself1: Option<&P<ast::QSelf>>,
     path1: &ast::Path,
     fps1: &mut [ast::PatField],
     rest1: ast::PatFieldsRest,
@@ -307,7 +310,7 @@ fn extend_with_struct_pat(
             |k| {
                 matches!(k, Struct(qself2, path2, fps2, rest2)
                 if rest1 == *rest2 // If one struct pattern has `..` so must the other.
-                && eq_maybe_qself(qself1, qself2)
+                && eq_maybe_qself(qself1, qself2.as_ref())
                 && eq_path(path1, path2)
                 && fps1.len() == fps2.len()
                 && fps1.iter().enumerate().all(|(idx_1, fp1)| {
diff --git a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
index 309eaedac8d..e70d2a2dafe 100644
--- a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
@@ -2,8 +2,8 @@ use clippy_utils::diagnostics::span_lint;
 use rustc_ast::ast::{Item, ItemKind, UseTree, UseTreeKind};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::Ident;
 use rustc_span::Span;
+use rustc_span::symbol::Ident;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index 738fba54fa8..c899b1868a6 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -1,13 +1,13 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::is_def_id_trait_method;
 use rustc_hir::def::DefKind;
-use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
-use rustc_hir::{Body, Expr, ExprKind, FnDecl, Node, YieldSource};
+use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Node, YieldSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::{LocalDefId, LocalDefIdSet};
 use rustc_span::Span;
+use rustc_span::def_id::{LocalDefId, LocalDefIdSet};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -67,7 +67,7 @@ struct AsyncFnVisitor<'a, 'tcx> {
     async_depth: usize,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for AsyncFnVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
@@ -137,17 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         }
     }
 
-    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &rustc_hir::Path<'tcx>, hir_id: rustc_hir::HirId) {
-        fn is_node_func_call(node: Node<'_>, expected_receiver: Span) -> bool {
-            matches!(
-                node,
-                Node::Expr(Expr {
-                    kind: ExprKind::Call(Expr { span, .. }, _) | ExprKind::MethodCall(_, Expr { span, .. }, ..),
-                    ..
-                }) if *span == expected_receiver
-            )
-        }
-
+    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &rustc_hir::Path<'tcx>, hir_id: HirId) {
         // Find paths to local async functions that aren't immediately called.
         // E.g. `async fn f() {}; let x = f;`
         // Depending on how `x` is used, f's asyncness might be required despite not having any `await`
@@ -156,7 +146,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
             && let Some(local_def_id) = def_id.as_local()
             && cx.tcx.def_kind(def_id) == DefKind::Fn
             && cx.tcx.asyncness(def_id).is_async()
-            && !is_node_func_call(cx.tcx.parent_hir_node(hir_id), path.span)
+            && let parent = cx.tcx.parent_hir_node(hir_id)
+            && !matches!(
+                parent,
+                Node::Expr(Expr {
+                    kind: ExprKind::Call(Expr { span, .. }, _),
+                    ..
+                }) if *span == path.span
+            )
         {
             self.async_fns_as_value.insert(local_def_id);
         }
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 af7abd009d2..d2a21b11ef4 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -5,7 +5,7 @@ use hir::{ExprKind, HirId, PatKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/unused_peekable.rs b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
index 86a811e17ca..71aa57e0a14 100644
--- a/src/tools/clippy/clippy_lints/src/unused_peekable.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_peekable.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
 use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators};
 use rustc_ast::Mutability;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{Block, Expr, ExprKind, HirId, LetStmt, Node, PatKind, PathSegment, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter::OnlyBodies;
diff --git a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
new file mode 100644
index 00000000000..9fd6ebccd02
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
@@ -0,0 +1,94 @@
+use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_from_proc_macro;
+use clippy_utils::source::snippet_opt;
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{Item, ItemKind, UseKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext as _};
+use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::Visibility;
+use rustc_session::impl_lint_pass;
+use rustc_span::symbol::kw;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `use Trait` where the Trait is only used for its methods and not referenced by a path directly.
+    ///
+    /// ### Why is this bad?
+    /// Traits imported that aren't used directly can be imported anonymously with `use Trait as _`.
+    /// It is more explicit, avoids polluting the current scope with unused names and can be useful to show which imports are required for traits.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// use std::fmt::Write;
+    ///
+    /// fn main() {
+    ///     let mut s = String::new();
+    ///     let _ = write!(s, "hello, world!");
+    ///     println!("{s}");
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// use std::fmt::Write as _;
+    ///
+    /// fn main() {
+    ///     let mut s = String::new();
+    ///     let _ = write!(s, "hello, world!");
+    ///     println!("{s}");
+    /// }
+    /// ```
+    #[clippy::version = "1.83.0"]
+    pub UNUSED_TRAIT_NAMES,
+    restriction,
+    "use items that import a trait but only use it anonymously"
+}
+
+pub struct UnusedTraitNames {
+    msrv: Msrv,
+}
+
+impl UnusedTraitNames {
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+        }
+    }
+}
+
+impl_lint_pass!(UnusedTraitNames => [UNUSED_TRAIT_NAMES]);
+
+impl<'tcx> LateLintPass<'tcx> for UnusedTraitNames {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        if self.msrv.meets(msrvs::UNDERSCORE_IMPORTS)
+            && !in_external_macro(cx.sess(), item.span)
+            && let ItemKind::Use(path, UseKind::Single) = item.kind
+            // Ignore imports that already use Underscore
+            && item.ident.name != kw::Underscore
+            // Only check traits
+            && let Some(Res::Def(DefKind::Trait, _)) = path.res.first()
+            && cx.tcx.maybe_unused_trait_imports(()).contains(&item.owner_id.def_id)
+            // Only check this import if it is visible to its module only (no pub, pub(crate), ...)
+            && let module = cx.tcx.parent_module_from_def_id(item.owner_id.def_id)
+            && cx.tcx.visibility(item.owner_id.def_id) == Visibility::Restricted(module.to_def_id())
+            && let Some(last_segment) = path.segments.last()
+            && let Some(snip) = snippet_opt(cx, last_segment.ident.span)
+            && !is_from_proc_macro(cx, &last_segment.ident)
+        {
+            let complete_span = last_segment.ident.span.to(item.ident.span);
+            span_lint_and_sugg(
+                cx,
+                UNUSED_TRAIT_NAMES,
+                complete_span,
+                "importing trait that is only used anonymously",
+                "use",
+                format!("{snip} as _"),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
diff --git a/src/tools/clippy/clippy_lints/src/unused_unit.rs b/src/tools/clippy/clippy_lints/src/unused_unit.rs
index 65f431d338b..d5309aade7a 100644
--- a/src/tools/clippy/clippy_lints/src/unused_unit.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_unit.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{position_before_rarrow, SpanRangeExt};
+use clippy_utils::source::{SpanRangeExt, position_before_rarrow};
 use rustc_ast::visit::FnKind;
-use rustc_ast::{ast, ClosureBinder};
+use rustc_ast::{ClosureBinder, ast};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index 0b4ea0752b6..6fe660b6a47 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -3,7 +3,7 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::usage::is_potentially_local_place;
 use clippy_utils::{higher, path_to_local};
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
+use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegment, UnOp};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId};
 use rustc_lint::{LateContext, LateLintPass};
@@ -13,7 +13,7 @@ use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -235,7 +235,7 @@ impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx> {
     fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
-impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> {
+impl<'tcx> UnwrappableVariablesVisitor<'_, 'tcx> {
     fn visit_branch(
         &mut self,
         if_expr: &'tcx Expr<'_>,
@@ -288,7 +288,7 @@ fn consume_option_as_ref<'tcx>(expr: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, Opt
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
index f77badd97b7..9b9a2ffbbc8 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
@@ -7,7 +7,7 @@ use rustc_hir as hir;
 use rustc_hir::ImplItemKind;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 5da48f4f7fb..f5cf4a586fd 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -1,5 +1,5 @@
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::ty::same_type_and_consts;
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::intravisit::{walk_inf, walk_ty, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_inf, walk_ty};
 use rustc_hir::{
     self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl,
     ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind,
@@ -85,10 +85,6 @@ const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element";
 
 impl<'tcx> LateLintPass<'tcx> for UseSelf {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &Item<'tcx>) {
-        if matches!(item.kind, ItemKind::OpaqueTy(_)) {
-            // skip over `ItemKind::OpaqueTy` in order to lint `foo() -> impl <..>`
-            return;
-        }
         // We push the self types of `impl`s on a stack here. Only the top type on the stack is
         // relevant for linting, since this is the self type of the `impl` we're currently in. To
         // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that
@@ -130,10 +126,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         self.stack.push(stack_item);
     }
 
-    fn check_item_post(&mut self, _: &LateContext<'_>, item: &Item<'_>) {
-        if !matches!(item.kind, ItemKind::OpaqueTy(_)) {
-            self.stack.pop();
-        }
+    fn check_item_post(&mut self, _: &LateContext<'_>, _: &Item<'_>) {
+        self.stack.pop();
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
@@ -280,7 +274,7 @@ struct SkipTyCollector {
     types_to_skip: Vec<HirId>,
 }
 
-impl<'tcx> Visitor<'tcx> for SkipTyCollector {
+impl Visitor<'_> for SkipTyCollector {
     fn visit_infer(&mut self, inf: &hir::InferArg) {
         self.types_to_skip.push(inf.hir_id);
 
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 2f7d54e73ed..29a7949b343 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -12,7 +12,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 
 declare_clippy_lint! {
@@ -217,12 +217,12 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                             },
                             ExprKind::MethodCall(.., args, _) => {
                                 cx.typeck_results().type_dependent_def_id(parent.hir_id).map(|did| {
-                                    return (
+                                    (
                                         did,
                                         args,
                                         cx.typeck_results().node_args(parent.hir_id),
                                         MethodOrFunction::Method,
-                                    );
+                                    )
                                 })
                             },
                             _ => None,
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 0cce45290cf..31f9d84f5e4 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -1,6 +1,6 @@
 use clippy_utils::{get_attr, higher};
-use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_ast::LitIntType;
+use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{
     self as hir, ArrayLen, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
index f50ce6c99de..8f314ce7a60 100644
--- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
@@ -3,10 +3,10 @@ use clippy_utils::source::SpanRangeExt;
 use itertools::Itertools;
 use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_lexer::{tokenize, TokenKind};
+use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::{hygiene, Span};
+use rustc_span::{Span, hygiene};
 use std::iter::once;
 use std::mem;
 
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 f7529682675..d8f101a8614 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
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::{is_expr_path_def_path, is_lint_allowed, peel_blocks_with_stmt, SpanlessEq};
+use clippy_utils::{SpanlessEq, is_expr_path_def_path, is_lint_allowed, peel_blocks_with_stmt};
 use rustc_errors::Applicability;
 use rustc_hir::{Closure, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
index 7c2e23995c1..9e400d2391f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
@@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
                         && let ty = cx.tcx.type_of(item_def_id).instantiate_identity()
                         && match_type(cx, ty, &paths::SYMBOL)
                         && let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id)
-                        && let Ok(value) = value.to_u32()
+                        && let Some(value) = value.to_u32().discard_err()
                     {
                         self.symbol_map.insert(value, item_def_id);
                     }
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 0ffcb433481..96397375d5e 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -2,11 +2,11 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::def_path_res;
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
 use rustc_hir::Item;
+use rustc_hir::def::DefKind;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::FloatTy;
+use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::Symbol;
 
@@ -72,8 +72,7 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
         SimplifiedType::Bool,
     ]
     .iter()
-    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).into_iter())
-    .flatten()
+    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter())
     .copied();
     for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
         let lang_item_path = cx.get_def_path(item_def_id);
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 20526113d69..dd456022212 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
@@ -12,7 +12,7 @@ use rustc_middle::hir::nested_filter;
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use {rustc_ast as ast, rustc_hir as hir};
 
 declare_clippy_lint! {
@@ -270,7 +270,7 @@ struct LintCollector<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for LintCollector<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for LintCollector<'_, 'tcx> {
     type NestedFilter = nested_filter::All;
 
     fn visit_path(&mut self, path: &Path<'_>, _: HirId) {
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 41183700f09..76b0a52621b 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -8,12 +8,12 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, LetStmt, Mutability, Node};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::interpret::{Allocation, GlobalAlloc};
 use rustc_middle::mir::ConstValue;
+use rustc_middle::mir::interpret::{Allocation, GlobalAlloc};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::Symbol;
 use rustc_span::Span;
+use rustc_span::symbol::Symbol;
 
 use std::str;
 
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index d3e49bff422..ce4f41e854d 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -1,8 +1,8 @@
 use std::collections::BTreeMap;
 use std::ops::ControlFlow;
 
-use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::SpanRangeExt;
@@ -15,7 +15,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, DesugaringKind, Span};
+use rustc_span::{DesugaringKind, Span, sym};
 
 #[expect(clippy::module_name_repetitions)]
 pub struct UselessVec {
diff --git a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
index a599415a2dd..91dff5a9523 100644
--- a/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/vec_init_then_push.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
+use clippy_utils::higher::{VecInitKind, get_vec_init_kind};
 use clippy_utils::source::snippet;
 use clippy_utils::visitors::for_each_local_use_after_expr;
 use clippy_utils::{get_parent_expr, path_to_local_id};
diff --git a/src/tools/clippy/clippy_lints/src/visibility.rs b/src/tools/clippy/clippy_lints/src/visibility.rs
index 7a85196ceca..2e5fc5834e2 100644
--- a/src/tools/clippy/clippy_lints/src/visibility.rs
+++ b/src/tools/clippy/clippy_lints/src/visibility.rs
@@ -5,8 +5,8 @@ use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
-use rustc_span::symbol::kw;
 use rustc_span::Span;
+use rustc_span::symbol::kw;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index 7d9e58ad2f8..405310512df 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -10,7 +10,7 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
-use rustc_span::{sym, BytePos};
+use rustc_span::{BytePos, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index ec5a5896fb2..1dd46ed5a89 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -1,8 +1,8 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::is_in_test;
-use clippy_utils::macros::{format_arg_removal_span, root_macro_call_first_node, FormatArgsStorage, MacroCall};
-use clippy_utils::source::{expand_past_previous_comma, SpanRangeExt};
+use clippy_utils::macros::{FormatArgsStorage, MacroCall, format_arg_removal_span, root_macro_call_first_node};
+use clippy_utils::source::{SpanRangeExt, expand_past_previous_comma};
 use rustc_ast::token::LitKind;
 use rustc_ast::{
     FormatArgPosition, FormatArgPositionKind, FormatArgs, FormatArgsPiece, FormatOptions, FormatPlaceholder,
@@ -12,7 +12,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, Impl, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, BytePos, Span};
+use rustc_span::{BytePos, Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/zombie_processes.rs b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
new file mode 100644
index 00000000000..8d9241cc7d9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
@@ -0,0 +1,341 @@
+use ControlFlow::{Break, Continue};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::{fn_def_id, get_enclosing_block, match_any_def_paths, match_def_path, path_to_local_id, paths};
+use rustc_ast::Mutability;
+use rustc_errors::Applicability;
+use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_local};
+use rustc_hir::{Expr, ExprKind, HirId, LetStmt, Node, PatKind, Stmt, StmtKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::hir::nested_filter;
+use rustc_session::declare_lint_pass;
+use rustc_span::sym;
+use std::ops::ControlFlow;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Looks for code that spawns a process but never calls `wait()` on the child.
+    ///
+    /// ### Why is this bad?
+    /// As explained in the [standard library documentation](https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning),
+    /// calling `wait()` is necessary on Unix platforms to properly release all OS resources associated with the process.
+    /// Not doing so will effectively leak process IDs and/or other limited global resources,
+    /// which can eventually lead to resource exhaustion, so it's recommended to call `wait()` in long-running applications.
+    /// Such processes are called "zombie processes".
+    ///
+    /// ### Example
+    /// ```rust
+    /// use std::process::Command;
+    ///
+    /// let _child = Command::new("ls").spawn().expect("failed to execute child");
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// use std::process::Command;
+    ///
+    /// let mut child = Command::new("ls").spawn().expect("failed to execute child");
+    /// child.wait().expect("failed to wait on child");
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub ZOMBIE_PROCESSES,
+    suspicious,
+    "not waiting on a spawned child process"
+}
+declare_lint_pass!(ZombieProcesses => [ZOMBIE_PROCESSES]);
+
+impl<'tcx> LateLintPass<'tcx> for ZombieProcesses {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if let ExprKind::Call(..) | ExprKind::MethodCall(..) = expr.kind
+            && let Some(child_adt) = cx.typeck_results().expr_ty(expr).ty_adt_def()
+            && match_def_path(cx, child_adt.did(), &paths::CHILD)
+        {
+            match cx.tcx.parent_hir_node(expr.hir_id) {
+                Node::LetStmt(local)
+                    if let PatKind::Binding(_, local_id, ..) = local.pat.kind
+                        && let Some(enclosing_block) = get_enclosing_block(cx, expr.hir_id) =>
+                {
+                    let mut vis = WaitFinder::WalkUpTo(cx, local_id);
+
+                    // If it does have a `wait()` call, we're done. Don't lint.
+                    if let Break(BreakReason::WaitFound) = walk_block(&mut vis, enclosing_block) {
+                        return;
+                    }
+
+                    // Don't emit a suggestion since the binding is used later
+                    check(cx, expr, false);
+                },
+                Node::LetStmt(&LetStmt { pat, .. }) if let PatKind::Wild = pat.kind => {
+                    // `let _ = child;`, also dropped immediately without `wait()`ing
+                    check(cx, expr, true);
+                },
+                Node::Stmt(&Stmt {
+                    kind: StmtKind::Semi(_),
+                    ..
+                }) => {
+                    // Immediately dropped. E.g. `std::process::Command::new("echo").spawn().unwrap();`
+                    check(cx, expr, true);
+                },
+                _ => {},
+            }
+        }
+    }
+}
+
+enum BreakReason {
+    WaitFound,
+    EarlyReturn,
+}
+
+/// A visitor responsible for finding a `wait()` call on a local variable.
+///
+/// Conditional `wait()` calls are assumed to not call wait:
+/// ```ignore
+/// let mut c = Command::new("").spawn().unwrap();
+/// if true {
+///     c.wait();
+/// }
+/// ```
+///
+/// Note that this visitor does NOT explicitly look for `wait()` calls directly, but rather does the
+/// inverse -- checking if all uses of the local are either:
+/// - a field access (`child.{stderr,stdin,stdout}`)
+/// - calling `id` or `kill`
+/// - no use at all (e.g. `let _x = child;`)
+/// - taking a shared reference (`&`), `wait()` can't go through that
+///
+/// None of these are sufficient to prevent zombie processes.
+/// Doing it like this means more FNs, but FNs are better than FPs.
+///
+/// `return` expressions, conditional or not, short-circuit the visitor because
+/// if a `wait()` call hadn't been found at that point, it might never reach one at a later point:
+/// ```ignore
+/// let mut c = Command::new("").spawn().unwrap();
+/// if true {
+///     return; // Break(BreakReason::EarlyReturn)
+/// }
+/// c.wait(); // this might not be reachable
+/// ```
+enum WaitFinder<'a, 'tcx> {
+    WalkUpTo(&'a LateContext<'tcx>, HirId),
+    Found(&'a LateContext<'tcx>, HirId),
+}
+
+impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
+    type NestedFilter = nested_filter::OnlyBodies;
+    type Result = ControlFlow<BreakReason>;
+
+    fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) -> Self::Result {
+        if let Self::WalkUpTo(cx, local_id) = *self
+            && let PatKind::Binding(_, pat_id, ..) = l.pat.kind
+            && local_id == pat_id
+        {
+            *self = Self::Found(cx, local_id);
+        }
+
+        walk_local(self, l)
+    }
+
+    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {
+        let Self::Found(cx, local_id) = *self else {
+            return walk_expr(self, ex);
+        };
+
+        if path_to_local_id(ex, local_id) {
+            match cx.tcx.parent_hir_node(ex.hir_id) {
+                Node::Stmt(Stmt {
+                    kind: StmtKind::Semi(_),
+                    ..
+                }) => {},
+                Node::Expr(expr) if let ExprKind::Field(..) = expr.kind => {},
+                Node::Expr(expr) if let ExprKind::AddrOf(_, Mutability::Not, _) = expr.kind => {},
+                Node::Expr(expr)
+                    if let Some(fn_did) = fn_def_id(cx, expr)
+                        && match_any_def_paths(cx, fn_did, &[&paths::CHILD_ID, &paths::CHILD_KILL]).is_some() => {},
+
+                // Conservatively assume that all other kinds of nodes call `.wait()` somehow.
+                _ => return Break(BreakReason::WaitFound),
+            }
+        } else {
+            match ex.kind {
+                ExprKind::Ret(..) => return Break(BreakReason::EarlyReturn),
+                ExprKind::If(cond, then, None) => {
+                    walk_expr(self, cond)?;
+
+                    // A `wait()` call in an if expression with no else is not enough:
+                    //
+                    // let c = spawn();
+                    // if true {
+                    //   c.wait();
+                    // }
+                    //
+                    // This might not call wait(). However, early returns are propagated,
+                    // because they might lead to a later wait() not being called.
+                    if let Break(BreakReason::EarlyReturn) = walk_expr(self, then) {
+                        return Break(BreakReason::EarlyReturn);
+                    }
+
+                    return Continue(());
+                },
+
+                ExprKind::If(cond, then, Some(else_)) => {
+                    walk_expr(self, cond)?;
+
+                    #[expect(clippy::unnested_or_patterns)]
+                    match (walk_expr(self, then), walk_expr(self, else_)) {
+                        (Continue(()), Continue(()))
+
+                        // `wait()` in one branch but nothing in the other does not count
+                        | (Continue(()), Break(BreakReason::WaitFound))
+                        | (Break(BreakReason::WaitFound), Continue(())) => {},
+
+                        // `wait()` in both branches is ok
+                        (Break(BreakReason::WaitFound), Break(BreakReason::WaitFound)) => {
+                            return Break(BreakReason::WaitFound);
+                        },
+
+                        // Propagate early returns in either branch
+                        (Break(BreakReason::EarlyReturn), _) | (_, Break(BreakReason::EarlyReturn)) => {
+                            return Break(BreakReason::EarlyReturn);
+                        },
+                    }
+
+                    return Continue(());
+                },
+                _ => {},
+            }
+        }
+
+        walk_expr(self, ex)
+    }
+
+    fn nested_visit_map(&mut self) -> Self::Map {
+        let (Self::Found(cx, _) | Self::WalkUpTo(cx, _)) = self;
+        cx.tcx.hir()
+    }
+}
+
+/// This function has shared logic between the different kinds of nodes that can trigger the lint.
+///
+/// In particular, `let <binding> = <expr that spawns child>;` requires some custom additional logic
+/// such as checking that the binding is not used in certain ways, which isn't necessary for
+/// `let _ = <expr that spawns child>;`.
+///
+/// This checks if the program doesn't unconditionally exit after the spawn expression.
+fn check<'tcx>(cx: &LateContext<'tcx>, spawn_expr: &'tcx Expr<'tcx>, emit_suggestion: bool) {
+    let Some(block) = get_enclosing_block(cx, spawn_expr.hir_id) else {
+        return;
+    };
+
+    let mut vis = ExitPointFinder {
+        cx,
+        state: ExitPointState::WalkUpTo(spawn_expr.hir_id),
+    };
+    if let Break(ExitCallFound) = vis.visit_block(block) {
+        // Visitor found an unconditional `exit()` call, so don't lint.
+        return;
+    }
+
+    span_lint_and_then(
+        cx,
+        ZOMBIE_PROCESSES,
+        spawn_expr.span,
+        "spawned process is never `wait()`ed on",
+        |diag| {
+            if emit_suggestion {
+                diag.span_suggestion(
+                    spawn_expr.span.shrink_to_hi(),
+                    "try",
+                    ".wait()",
+                    Applicability::MaybeIncorrect,
+                );
+            } else {
+                diag.note("consider calling `.wait()`");
+            }
+
+            diag.note("not doing so might leave behind zombie processes")
+                .note("see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning");
+        },
+    );
+}
+
+/// Checks if the given expression exits the process.
+fn is_exit_expression(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    fn_def_id(cx, expr).is_some_and(|fn_did| {
+        cx.tcx.is_diagnostic_item(sym::process_exit, fn_did) || match_def_path(cx, fn_did, &paths::ABORT)
+    })
+}
+
+#[derive(Debug)]
+enum ExitPointState {
+    /// Still walking up to the expression that initiated the visitor.
+    WalkUpTo(HirId),
+    /// We're inside of a control flow construct (e.g. `if`, `match`, `loop`)
+    /// Within this, we shouldn't accept any `exit()` calls in here, but we can leave all of these
+    /// constructs later and still continue looking for an `exit()` call afterwards. Example:
+    /// ```ignore
+    /// Command::new("").spawn().unwrap();
+    ///
+    /// if true {                // depth=1
+    ///     if true {            // depth=2
+    ///         match () {       // depth=3
+    ///             () => loop { // depth=4
+    ///
+    ///                 std::process::exit();
+    ///                 ^^^^^^^^^^^^^^^^^^^^^ conditional exit call, ignored
+    ///
+    ///             }           // depth=3
+    ///         }               // depth=2
+    ///     }                   // depth=1
+    /// }                       // depth=0
+    ///
+    /// std::process::exit();
+    /// ^^^^^^^^^^^^^^^^^^^^^ this exit call is accepted because we're now unconditionally calling it
+    /// ```
+    /// We can only get into this state from `NoExit`.
+    InControlFlow { depth: u32 },
+    /// No exit call found yet, but looking for one.
+    NoExit,
+}
+
+fn expr_enters_control_flow(expr: &Expr<'_>) -> bool {
+    matches!(expr.kind, ExprKind::If(..) | ExprKind::Match(..) | ExprKind::Loop(..))
+}
+
+struct ExitPointFinder<'a, 'tcx> {
+    state: ExitPointState,
+    cx: &'a LateContext<'tcx>,
+}
+
+struct ExitCallFound;
+
+impl<'tcx> Visitor<'tcx> for ExitPointFinder<'_, 'tcx> {
+    type Result = ControlFlow<ExitCallFound>;
+
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {
+        match self.state {
+            ExitPointState::WalkUpTo(id) if expr.hir_id == id => {
+                self.state = ExitPointState::NoExit;
+                walk_expr(self, expr)
+            },
+            ExitPointState::NoExit if expr_enters_control_flow(expr) => {
+                self.state = ExitPointState::InControlFlow { depth: 1 };
+                walk_expr(self, expr)?;
+                if let ExitPointState::InControlFlow { .. } = self.state {
+                    self.state = ExitPointState::NoExit;
+                }
+                Continue(())
+            },
+            ExitPointState::NoExit if is_exit_expression(self.cx, expr) => Break(ExitCallFound),
+            ExitPointState::InControlFlow { ref mut depth } if expr_enters_control_flow(expr) => {
+                *depth += 1;
+                walk_expr(self, expr)?;
+                match self.state {
+                    ExitPointState::InControlFlow { depth: 1 } => self.state = ExitPointState::NoExit,
+                    ExitPointState::InControlFlow { ref mut depth } => *depth -= 1,
+                    _ => {},
+                }
+                Continue(())
+            },
+            _ => Continue(()),
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 629ce9d04d4..fe30b10c435 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_utils"
-version = "0.1.82"
+version = "0.1.83"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index de8bbb619f8..68f74e52ed7 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -37,20 +37,27 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool {
         (_, Paren(r)) => eq_pat(l, r),
         (Wild, Wild) | (Rest, Rest) => true,
         (Lit(l), Lit(r)) => eq_expr(l, r),
-        (Ident(b1, i1, s1), Ident(b2, i2, s2)) => b1 == b2 && eq_id(*i1, *i2) && both(s1, s2, |l, r| eq_pat(l, r)),
+        (Ident(b1, i1, s1), Ident(b2, i2, s2)) => {
+            b1 == b2 && eq_id(*i1, *i2) && both(s1.as_deref(), s2.as_deref(), eq_pat)
+        },
         (Range(lf, lt, le), Range(rf, rt, re)) => {
-            eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt) && eq_range_end(&le.node, &re.node)
+            eq_expr_opt(lf.as_ref(), rf.as_ref())
+                && eq_expr_opt(lt.as_ref(), rt.as_ref())
+                && eq_range_end(&le.node, &re.node)
         },
         (Box(l), Box(r))
         | (Ref(l, Mutability::Not), Ref(r, Mutability::Not))
         | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r),
         (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)),
-        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
+        (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp),
         (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => {
-            eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r))
+            eq_maybe_qself(lqself.as_ref(), rqself.as_ref()) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r))
         },
         (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => {
-            lr == rr && eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && unordered_over(lfs, rfs, eq_field_pat)
+            lr == rr
+                && eq_maybe_qself(lqself.as_ref(), rqself.as_ref())
+                && eq_path(lp, rp)
+                && unordered_over(lfs, rfs, eq_field_pat)
         },
         (Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)),
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
@@ -79,7 +86,7 @@ pub fn eq_qself(l: &P<QSelf>, r: &P<QSelf>) -> bool {
     l.position == r.position && eq_ty(&l.ty, &r.ty)
 }
 
-pub fn eq_maybe_qself(l: &Option<P<QSelf>>, r: &Option<P<QSelf>>) -> bool {
+pub fn eq_maybe_qself(l: Option<&P<QSelf>>, r: Option<&P<QSelf>>) -> bool {
     match (l, r) {
         (Some(l), Some(r)) => eq_qself(l, r),
         (None, None) => true,
@@ -92,7 +99,7 @@ pub fn eq_path(l: &Path, r: &Path) -> bool {
 }
 
 pub fn eq_path_seg(l: &PathSegment, r: &PathSegment) -> bool {
-    eq_id(l.ident, r.ident) && both(&l.args, &r.args, |l, r| eq_generic_args(l, r))
+    eq_id(l.ident, r.ident) && both(l.args.as_ref(), r.args.as_ref(), |l, r| eq_generic_args(l, r))
 }
 
 pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {
@@ -122,7 +129,7 @@ pub fn eq_generic_arg(l: &GenericArg, r: &GenericArg) -> bool {
     }
 }
 
-pub fn eq_expr_opt(l: &Option<P<Expr>>, r: &Option<P<Expr>>) -> bool {
+pub fn eq_expr_opt(l: Option<&P<Expr>>, r: Option<&P<Expr>>) -> bool {
     both(l, r, |l, r| eq_expr(l, r))
 }
 
@@ -169,8 +176,12 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         (Lit(l), Lit(r)) => l == r,
         (Cast(l, lt), Cast(r, rt)) | (Type(l, lt), Type(r, rt)) => eq_expr(l, r) && eq_ty(lt, rt),
         (Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re),
-        (If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re),
-        (While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt),
+        (If(lc, lt, le), If(rc, rt, re)) => {
+            eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref())
+        },
+        (While(lc, lt, ll), While(rc, rt, rl)) => {
+            eq_label(ll.as_ref(), rl.as_ref()) && eq_expr(lc, rc) && eq_block(lt, rt)
+        },
         (
             ForLoop {
                 pat: lp,
@@ -186,13 +197,13 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
                 label: rl,
                 kind: rk,
             },
-        ) => eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
-        (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt),
-        (Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
+        ) => eq_label(ll.as_ref(), rl.as_ref()) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
+        (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt),
+        (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb),
         (TryBlock(l), TryBlock(r)) => eq_block(l, r),
-        (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r),
-        (Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re),
-        (Continue(ll), Continue(rl)) => eq_label(ll, rl),
+        (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l.as_ref(), r.as_ref()),
+        (Break(ll, le), Break(rl, re)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_expr_opt(le.as_ref(), re.as_ref()),
+        (Continue(ll), Continue(rl)) => eq_label(ll.as_ref(), rl.as_ref()),
         (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => {
             eq_expr(l1, r1) && eq_expr(l2, r2)
         },
@@ -227,12 +238,14 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
                 && eq_expr(le, re)
         },
         (Gen(lc, lb, lk, _), Gen(rc, rb, rk, _)) => lc == rc && eq_block(lb, rb) && lk == rk,
-        (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt),
+        (Range(lf, lt, ll), Range(rf, rt, rl)) => {
+            ll == rl && eq_expr_opt(lf.as_ref(), rf.as_ref()) && eq_expr_opt(lt.as_ref(), rt.as_ref())
+        },
         (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),
-        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
+        (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp),
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
         (Struct(lse), Struct(rse)) => {
-            eq_maybe_qself(&lse.qself, &rse.qself)
+            eq_maybe_qself(lse.qself.as_ref(), rse.qself.as_ref())
                 && eq_path(&lse.path, &rse.path)
                 && eq_struct_rest(&lse.rest, &rse.rest)
                 && unordered_over(&lse.fields, &rse.fields, eq_field)
@@ -242,13 +255,16 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
 }
 
 fn eq_coroutine_kind(a: Option<CoroutineKind>, b: Option<CoroutineKind>) -> bool {
-    match (a, b) {
+    matches!(
+        (a, b),
         (Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
-        | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
-        | (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. }))
-        | (None, None) => true,
-        _ => false,
-    }
+            | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
+            | (
+                Some(CoroutineKind::AsyncGen { .. }),
+                Some(CoroutineKind::AsyncGen { .. })
+            )
+            | (None, None)
+    )
 }
 
 pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
@@ -261,12 +277,12 @@ pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
 pub fn eq_arm(l: &Arm, r: &Arm) -> bool {
     l.is_placeholder == r.is_placeholder
         && eq_pat(&l.pat, &r.pat)
-        && eq_expr_opt(&l.body, &r.body)
-        && eq_expr_opt(&l.guard, &r.guard)
+        && eq_expr_opt(l.body.as_ref(), r.body.as_ref())
+        && eq_expr_opt(l.guard.as_ref(), r.guard.as_ref())
         && over(&l.attrs, &r.attrs, eq_attr)
 }
 
-pub fn eq_label(l: &Option<Label>, r: &Option<Label>) -> bool {
+pub fn eq_label(l: Option<&Label>, r: Option<&Label>) -> bool {
     both(l, r, |l, r| eq_id(l.ident, r.ident))
 }
 
@@ -279,7 +295,7 @@ pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool {
     match (&l.kind, &r.kind) {
         (Let(l), Let(r)) => {
             eq_pat(&l.pat, &r.pat)
-                && both(&l.ty, &r.ty, |l, r| eq_ty(l, r))
+                && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| eq_ty(l, r))
                 && eq_local_kind(&l.kind, &r.kind)
                 && over(&l.attrs, &r.attrs, eq_attr)
         },
@@ -326,7 +342,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 expr: re,
                 safety: rs,
             }),
-        ) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Const(box ConstItem {
                 defaultness: ld,
@@ -340,7 +356,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 ty: rt,
                 expr: re,
             }),
-        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Fn(box ast::Fn {
                 defaultness: ld,
@@ -355,7 +371,10 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 body: rb,
             }),
         ) => {
-            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
+            eq_defaultness(*ld, *rd)
+                && eq_fn_sig(lf, rf)
+                && eq_generics(lg, rg)
+                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (Mod(lu, lmk), Mod(ru, rmk)) => {
             lu == ru
@@ -368,7 +387,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 }
         },
         (ForeignMod(l), ForeignMod(r)) => {
-            both(&l.abi, &r.abi, eq_str_lit) && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
+            both(l.abi.as_ref(), r.abi.as_ref(), eq_str_lit)
+                && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
         },
         (
             TyAlias(box ast::TyAlias {
@@ -389,7 +409,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
-                && both(lt, rt, |l, r| eq_ty(l, r))
+                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
         },
         (Enum(le, lg), Enum(re, rg)) => over(&le.variants, &re.variants, eq_variant) && eq_generics(lg, rg),
         (Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
@@ -445,7 +465,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 && eq_defaultness(*ld, *rd)
                 && matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)
                 && eq_generics(lg, rg)
-                && both(lot, rot, |l, r| eq_path(&l.path, &r.path))
+                && both(lot.as_ref(), rot.as_ref(), |l, r| eq_path(&l.path, &r.path))
                 && eq_ty(lst, rst)
                 && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
         },
@@ -471,7 +491,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 expr: re,
                 safety: rs,
             }),
-        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re) && ls == rs,
+        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()) && ls == rs,
         (
             Fn(box ast::Fn {
                 defaultness: ld,
@@ -486,7 +506,10 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 body: rb,
             }),
         ) => {
-            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
+            eq_defaultness(*ld, *rd)
+                && eq_fn_sig(lf, rf)
+                && eq_generics(lg, rg)
+                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
             TyAlias(box ast::TyAlias {
@@ -507,7 +530,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
-                && both(lt, rt, |l, r| eq_ty(l, r))
+                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
         },
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
         _ => false,
@@ -530,7 +553,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 ty: rt,
                 expr: re,
             }),
-        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Fn(box ast::Fn {
                 defaultness: ld,
@@ -545,7 +568,10 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 body: rb,
             }),
         ) => {
-            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
+            eq_defaultness(*ld, *rd)
+                && eq_fn_sig(lf, rf)
+                && eq_generics(lg, rg)
+                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
             Type(box TyAlias {
@@ -566,7 +592,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
-                && both(lt, rt, |l, r| eq_ty(l, r))
+                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
         },
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
         _ => false,
@@ -579,7 +605,9 @@ pub fn eq_variant(l: &Variant, r: &Variant) -> bool {
         && eq_vis(&l.vis, &r.vis)
         && eq_id(l.ident, r.ident)
         && eq_variant_data(&l.data, &r.data)
-        && both(&l.disr_expr, &r.disr_expr, |l, r| eq_expr(&l.value, &r.value))
+        && both(l.disr_expr.as_ref(), r.disr_expr.as_ref(), |l, r| {
+            eq_expr(&l.value, &r.value)
+        })
 }
 
 pub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {
@@ -597,7 +625,7 @@ pub fn eq_struct_field(l: &FieldDef, r: &FieldDef) -> bool {
     l.is_placeholder == r.is_placeholder
         && over(&l.attrs, &r.attrs, eq_attr)
         && eq_vis(&l.vis, &r.vis)
-        && both(&l.ident, &r.ident, |l, r| eq_id(*l, *r))
+        && both(l.ident.as_ref(), r.ident.as_ref(), |l, r| eq_id(*l, *r))
         && eq_ty(&l.ty, &r.ty)
 }
 
@@ -661,7 +689,7 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
     use UseTreeKind::*;
     match (l, r) {
         (Glob, Glob) => true,
-        (Simple(l), Simple(r)) => both(l, r, |l, r| eq_id(*l, *r)),
+        (Simple(l), Simple(r)) => both(l.as_ref(), r.as_ref(), |l, r| eq_id(*l, *r)),
         (Nested { items: l, .. }, Nested { items: r, .. }) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)),
         _ => false,
     }
@@ -723,7 +751,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
         (Array(le, ls), Array(re, rs)) => eq_ty(le, re) && eq_expr(&ls.value, &rs.value),
         (Ptr(l), Ptr(r)) => l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty),
         (Ref(ll, l), Ref(rl, r)) => {
-            both(ll, rl, |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
+            both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
         },
         (BareFn(l), BareFn(r)) => {
             l.safety == r.safety
@@ -732,7 +760,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
                 && eq_fn_decl(&l.decl, &r.decl)
         },
         (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)),
-        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
+        (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp),
         (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound),
         (ImplTrait(_, lg), ImplTrait(_, rg)) => over(lg, rg, eq_generic_bound),
         (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value),
@@ -768,7 +796,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
         && over(&l.bounds, &r.bounds, eq_generic_bound)
         && match (&l.kind, &r.kind) {
             (Lifetime, Lifetime) => true,
-            (Type { default: l }, Type { default: r }) => both(l, r, |l, r| eq_ty(l, r)),
+            (Type { default: l }, Type { default: r }) => both(l.as_ref(), r.as_ref(), |l, r| eq_ty(l, r)),
             (
                 Const {
                     ty: lt,
@@ -780,7 +808,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
                     kw_span: _,
                     default: rd,
                 },
-            ) => eq_ty(lt, rt) && both(ld, rd, eq_anon_const),
+            ) => eq_ty(lt, rt) && both(ld.as_ref(), rd.as_ref(), eq_anon_const),
             _ => false,
         }
         && over(&l.attrs, &r.attrs, eq_attr)
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs b/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs
index eefcbabd835..032cd3ed739 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/ident_iter.rs
@@ -1,5 +1,5 @@
 use core::iter::FusedIterator;
-use rustc_ast::visit::{walk_attribute, walk_expr, Visitor};
+use rustc_ast::visit::{Visitor, walk_attribute, walk_expr};
 use rustc_ast::{Attribute, Expr};
 use rustc_span::symbol::Ident;
 
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 42c8b218d14..edc9c6ccdff 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -4,7 +4,7 @@ use rustc_lexer::TokenKind;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use std::str::FromStr;
 
 use crate::source::SpanRangeExt;
@@ -183,15 +183,15 @@ pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
         let mut iter = tokenize_with_text(src);
 
         // Search for the token sequence [`#`, `[`, `cfg`]
-        while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
-            let mut iter = iter.by_ref().skip_while(|(t, _)| {
+        while iter.any(|(t, ..)| matches!(t, TokenKind::Pound)) {
+            let mut iter = iter.by_ref().skip_while(|(t, ..)| {
                 matches!(
                     t,
                     TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
                 )
             });
-            if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
-                && matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
+            if matches!(iter.next(), Some((TokenKind::OpenBracket, ..)))
+                && matches!(iter.next(), Some((TokenKind::Ident, "cfg", _)))
             {
                 return true;
             }
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 2bd6837d973..b18997e6ee4 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -12,9 +12,9 @@
 //! code was written, and check if the span contains that text. Note this will only work correctly
 //! if the span is not from a `macro_rules` based macro.
 
+use rustc_ast::AttrStyle;
 use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy};
 use rustc_ast::token::CommentKind;
-use rustc_ast::AttrStyle;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl,
@@ -24,7 +24,7 @@ use rustc_hir::{
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
-use rustc_span::symbol::{kw, Ident};
+use rustc_span::symbol::{Ident, kw};
 use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi::Abi;
 
@@ -220,7 +220,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
         ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
         ItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
         ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
-        ItemKind::TyAlias(..) | ItemKind::OpaqueTy(_) => (Pat::Str("type"), Pat::Str(";")),
+        ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
         ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
         ItemKind::Struct(VariantData::Struct { .. }, _) => (Pat::Str("struct"), Pat::Str("}")),
         ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 760d5bc95f7..510034876e0 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -1,24 +1,24 @@
 #![allow(clippy::float_cmp)]
 
 use crate::macros::HirNode;
-use crate::source::{walk_span_to_context, SpanRangeExt};
+use crate::source::{SpanRangeExt, walk_span_to_context};
 use crate::{clip, is_direct_expn_of, sext, unsext};
 
-use rustc_apfloat::ieee::{Half, Quad};
 use rustc_apfloat::Float;
+use rustc_apfloat::ieee::{Half, Quad};
 use rustc_ast::ast::{self, LitFloatType, LitKind};
 use rustc_data_structures::sync::Lrc;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
 use rustc_lexer::tokenize;
 use rustc_lint::LateContext;
-use rustc_middle::mir::interpret::{alloc_range, Scalar};
 use rustc_middle::mir::ConstValue;
+use rustc_middle::mir::interpret::{Scalar, alloc_range};
 use rustc_middle::ty::{self, FloatTy, IntTy, ParamEnv, ScalarInt, Ty, TyCtxt, TypeckResults, UintTy};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, SyntaxContext};
+use rustc_span::{SyntaxContext, sym};
 use rustc_target::abi::Size;
 use std::cell::Cell;
 use std::cmp::Ordering;
@@ -118,7 +118,7 @@ impl IntTypeBounds for IntTy {
     }
 }
 
-impl<'tcx> PartialEq for Constant<'tcx> {
+impl PartialEq for Constant<'_> {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
             (Self::Str(ls), Self::Str(rs)) => ls == rs,
@@ -147,7 +147,7 @@ impl<'tcx> PartialEq for Constant<'tcx> {
     }
 }
 
-impl<'tcx> Hash for Constant<'tcx> {
+impl Hash for Constant<'_> {
     fn hash<H>(&self, state: &mut H)
     where
         H: Hasher,
@@ -203,7 +203,7 @@ impl<'tcx> Hash for Constant<'tcx> {
     }
 }
 
-impl<'tcx> Constant<'tcx> {
+impl Constant<'_> {
     pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option<Ordering> {
         match (left, right) {
             (Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)),
@@ -581,7 +581,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
     }
 
     fn constant_negate(&self, o: &Constant<'tcx>, ty: Ty<'_>) -> Option<Constant<'tcx>> {
-        use self::Constant::{Int, F32, F64};
+        use self::Constant::{F32, F64, Int};
         match *o {
             Int(value) => {
                 let ty::Int(ity) = *ty.kind() else { return None };
@@ -870,10 +870,10 @@ pub fn mir_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::Const<'tcx>) -> Option
                 let range = alloc_range(offset + size * idx, size);
                 let val = alloc.read_scalar(&tcx, range, /* read_provenance */ false).ok()?;
                 res.push(match flt {
-                    FloatTy::F16 => Constant::F16(f16::from_bits(val.to_u16().ok()?)),
-                    FloatTy::F32 => Constant::F32(f32::from_bits(val.to_u32().ok()?)),
-                    FloatTy::F64 => Constant::F64(f64::from_bits(val.to_u64().ok()?)),
-                    FloatTy::F128 => Constant::F128(f128::from_bits(val.to_u128().ok()?)),
+                    FloatTy::F16 => Constant::F16(f16::from_bits(val.to_u16().discard_err()?)),
+                    FloatTy::F32 => Constant::F32(f32::from_bits(val.to_u32().discard_err()?)),
+                    FloatTy::F64 => Constant::F64(f64::from_bits(val.to_u64().discard_err()?)),
+                    FloatTy::F128 => Constant::F128(f128::from_bits(val.to_u128().discard_err()?)),
                 });
             }
             Some(Constant::Vec(res))
@@ -903,7 +903,7 @@ fn mir_is_empty<'tcx>(tcx: TyCtxt<'tcx>, result: mir::Const<'tcx>) -> Option<boo
                         .read_scalar(&tcx, alloc_range(offset + ptr_size, ptr_size), false)
                         .ok()?
                         .to_target_usize(&tcx)
-                        .ok()?;
+                        .discard_err()?;
                     Some(len == 0)
                 } else {
                     None
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index a6dd12a28c5..a2e97919d04 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -14,12 +14,12 @@ use crate::ty::{all_predicates_of, is_copy};
 use crate::visitors::is_const_evaluatable;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::intravisit::{walk_expr, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_hir::{BinOpKind, Block, Expr, ExprKind, QPath, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_middle::ty::adjustment::Adjust;
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 use std::{cmp, ops};
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
@@ -118,7 +118,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
         eagerness: EagernessSuggestion,
     }
 
-    impl<'cx, 'tcx> Visitor<'tcx> for V<'cx, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
         fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
             use EagernessSuggestion::{ForceNoChange, Lazy, NoChange};
             if self.eagerness == ForceNoChange {
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index e09cc9edf3a..3175a9a1dd3 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -3,14 +3,14 @@
 #![deny(clippy::missing_docs_in_private_items)]
 
 use crate::consts::{ConstEvalCtxt, Constant};
-use crate::ty::is_type_diagnostic_item;
 use crate::is_expn_of;
+use crate::ty::is_type_diagnostic_item;
 
 use rustc_ast::ast;
 use rustc_hir as hir;
 use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath};
 use rustc_lint::LateContext;
-use rustc_span::{sym, symbol, Span};
+use rustc_span::{Span, sym, symbol};
 
 /// The essential nodes of a desugared for loop as well as the entire span:
 /// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`.
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index f61ef9ac1b0..a19c1555d16 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -1,20 +1,20 @@
 use crate::consts::ConstEvalCtxt;
 use crate::macros::macro_backtrace;
-use crate::source::{walk_span_to_context, SpanRange, SpanRangeExt};
+use crate::source::{SpanRange, SpanRangeExt, walk_span_to_context};
 use crate::tokenize_with_text;
 use rustc_ast::ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxHasher;
-use rustc_hir::def::Res;
 use rustc_hir::MatchSource::TryDesugar;
+use rustc_hir::def::Res;
 use rustc_hir::{
     ArrayLen, AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr,
     ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime,
     LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind,
 };
-use rustc_lexer::{tokenize, TokenKind};
+use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::LateContext;
 use rustc_middle::ty::TypeckResults;
-use rustc_span::{sym, BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext};
+use rustc_span::{BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext, sym};
 use std::hash::{Hash, Hasher};
 use std::ops::Range;
 
@@ -121,9 +121,9 @@ impl HirEqInterExpr<'_, '_, '_> {
 
                 // eq_pat adds the HirIds to the locals map. We therefore call it last to make sure that
                 // these only get added if the init and type is equal.
-                both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
-                    && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r))
-                    && both(&l.els, &r.els, |l, r| self.eq_block(l, r))
+                both(l.init.as_ref(), r.init.as_ref(), |l, r| self.eq_expr(l, r))
+                    && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| self.eq_ty(l, r))
+                    && both(l.els.as_ref(), r.els.as_ref(), |l, r| self.eq_block(l, r))
                     && self.eq_pat(l.pat, r.pat)
             },
             (&StmtKind::Expr(l), &StmtKind::Expr(r)) | (&StmtKind::Semi(l), &StmtKind::Semi(r)) => self.eq_expr(l, r),
@@ -142,7 +142,9 @@ impl HirEqInterExpr<'_, '_, '_> {
         if lspan.ctxt != SyntaxContext::root() && rspan.ctxt != SyntaxContext::root() {
             // Don't try to check in between statements inside macros.
             return over(left.stmts, right.stmts, |left, right| self.eq_stmt(left, right))
-                && both(&left.expr, &right.expr, |left, right| self.eq_expr(left, right));
+                && both(left.expr.as_ref(), right.expr.as_ref(), |left, right| {
+                    self.eq_expr(left, right)
+                });
         }
         if lspan.ctxt != rspan.ctxt {
             return false;
@@ -285,8 +287,8 @@ impl HirEqInterExpr<'_, '_, '_> {
                     })
             },
             (&ExprKind::Break(li, ref le), &ExprKind::Break(ri, ref re)) => {
-                both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
-                    && both(le, re, |l, r| self.eq_expr(l, r))
+                both(li.label.as_ref(), ri.label.as_ref(), |l, r| l.ident.name == r.ident.name)
+                    && both(le.as_ref(), re.as_ref(), |l, r| self.eq_expr(l, r))
             },
             (&ExprKind::Call(l_fun, l_args), &ExprKind::Call(r_fun, r_args)) => {
                 self.inner.allow_side_effects && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args)
@@ -297,7 +299,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Closure(_l), &ExprKind::Closure(_r)) => false,
             (&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_body(lb.body, rb.body),
             (&ExprKind::Continue(li), &ExprKind::Continue(ri)) => {
-                both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
+                both(li.label.as_ref(), ri.label.as_ref(), |l, r| l.ident.name == r.ident.name)
             },
             (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re),
             (&ExprKind::Field(l_f_exp, ref l_f_ident), &ExprKind::Field(r_f_exp, ref r_f_ident)) => {
@@ -305,21 +307,25 @@ impl HirEqInterExpr<'_, '_, '_> {
             },
             (&ExprKind::Index(la, li, _), &ExprKind::Index(ra, ri, _)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
             (&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
-                self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
+                self.eq_expr(lc, rc) && self.eq_expr(lt, rt)
+                    && both(le.as_ref(), re.as_ref(), |l, r| self.eq_expr(l, r))
             },
             (&ExprKind::Let(l), &ExprKind::Let(r)) => {
-                self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
+                self.eq_pat(l.pat, r.pat)
+                    && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| self.eq_ty(l, r))
+                    && self.eq_expr(l.init, r.init)
             },
             (ExprKind::Lit(l), ExprKind::Lit(r)) => l.node == r.node,
             (&ExprKind::Loop(lb, ref ll, ref lls, _), &ExprKind::Loop(rb, ref rl, ref rls, _)) => {
-                lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
+                lls == rls && self.eq_block(lb, rb)
+                    && both(ll.as_ref(), rl.as_ref(), |l, r| l.ident.name == r.ident.name)
             },
             (&ExprKind::Match(le, la, ref ls), &ExprKind::Match(re, ra, ref rs)) => {
                 (ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_)))))
                     && self.eq_expr(le, re)
                     && over(la, ra, |l, r| {
                         self.eq_pat(l.pat, r.pat)
-                            && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r))
+                            && both(l.guard.as_ref(), r.guard.as_ref(), |l, r| self.eq_expr(l, r))
                             && self.eq_expr(l.body, r.body)
                     })
             },
@@ -339,10 +345,10 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
                 self.eq_expr(le, re) && self.eq_array_length(ll, rl)
             },
-            (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l, r, |l, r| self.eq_expr(l, r)),
+            (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l.as_ref(), r.as_ref(), |l, r| self.eq_expr(l, r)),
             (&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => {
                 self.eq_qpath(l_path, r_path)
-                    && both(lo, ro, |l, r| self.eq_expr(l, r))
+                    && both(lo.as_ref(), ro.as_ref(), |l, r| self.eq_expr(l, r))
                     && over(lf, rf, |l, r| self.eq_expr_field(l, r))
             },
             (&ExprKind::Tup(l_tup), &ExprKind::Tup(r_tup)) => self.eq_exprs(l_tup, r_tup),
@@ -450,7 +456,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs
             },
             (&PatKind::Binding(lb, li, _, ref lp), &PatKind::Binding(rb, ri, _, ref rp)) => {
-                let eq = lb == rb && both(lp, rp, |l, r| self.eq_pat(l, r));
+                let eq = lb == rb && both(lp.as_ref(), rp.as_ref(), |l, r| self.eq_pat(l, r));
                 if eq {
                     self.locals.insert(li, ri);
                 }
@@ -460,13 +466,15 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&PatKind::Lit(l), &PatKind::Lit(r)) => self.eq_expr(l, r),
             (&PatKind::Tuple(l, ls), &PatKind::Tuple(r, rs)) => ls == rs && over(l, r, |l, r| self.eq_pat(l, r)),
             (&PatKind::Range(ref ls, ref le, li), &PatKind::Range(ref rs, ref re, ri)) => {
-                both(ls, rs, |a, b| self.eq_expr(a, b)) && both(le, re, |a, b| self.eq_expr(a, b)) && (li == ri)
+                both(ls.as_ref(), rs.as_ref(), |a, b| self.eq_expr(a, b))
+                    && both(le.as_ref(), re.as_ref(), |a, b| self.eq_expr(a, b))
+                    && (li == ri)
             },
             (&PatKind::Ref(le, ref lm), &PatKind::Ref(re, ref rm)) => lm == rm && self.eq_pat(le, re),
             (&PatKind::Slice(ls, ref li, le), &PatKind::Slice(rs, ref ri, re)) => {
                 over(ls, rs, |l, r| self.eq_pat(l, r))
                     && over(le, re, |l, r| self.eq_pat(l, r))
-                    && both(li, ri, |l, r| self.eq_pat(l, r))
+                    && both(li.as_ref(), ri.as_ref(), |l, r| self.eq_pat(l, r))
             },
             (&PatKind::Wild, &PatKind::Wild) => true,
             _ => false,
@@ -476,7 +484,7 @@ impl HirEqInterExpr<'_, '_, '_> {
     fn eq_qpath(&mut self, left: &QPath<'_>, right: &QPath<'_>) -> bool {
         match (left, right) {
             (&QPath::Resolved(ref lty, lpath), &QPath::Resolved(ref rty, rpath)) => {
-                both(lty, rty, |l, r| self.eq_ty(l, r)) && self.eq_path(lpath, rpath)
+                both(lty.as_ref(), rty.as_ref(), |l, r| self.eq_ty(l, r)) && self.eq_path(lpath, rpath)
             },
             (&QPath::TypeRelative(lty, lseg), &QPath::TypeRelative(rty, rseg)) => {
                 self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg)
@@ -510,7 +518,10 @@ impl HirEqInterExpr<'_, '_, '_> {
     pub fn eq_path_segment(&mut self, left: &PathSegment<'_>, right: &PathSegment<'_>) -> bool {
         // The == of idents doesn't work with different contexts,
         // we have to be explicit about hygiene
-        left.ident.name == right.ident.name && both(&left.args, &right.args, |l, r| self.eq_path_parameters(l, r))
+        left.ident.name == right.ident.name
+            && both(left.args.as_ref(), right.args.as_ref(), |l, r| {
+                self.eq_path_parameters(l, r)
+            })
     }
 
     pub fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {
@@ -649,7 +660,7 @@ fn swap_binop<'a>(
 
 /// Checks if the two `Option`s are both `None` or some equal values as per
 /// `eq_fn`.
-pub fn both<X>(l: &Option<X>, r: &Option<X>, mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
+pub fn both<X>(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
     l.as_ref()
         .map_or_else(|| r.is_none(), |x| r.as_ref().map_or(false, |y| eq_fn(x, y)))
 }
@@ -1115,9 +1126,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 }
             },
             TyKind::Path(ref qpath) => self.hash_qpath(qpath),
-            TyKind::OpaqueDef(_, arg_list, in_trait) => {
+            TyKind::OpaqueDef(_, arg_list) => {
                 self.hash_generic_args(arg_list);
-                in_trait.hash(&mut self.s);
             },
             TyKind::TraitObject(_, lifetime, _) => {
                 self.hash_lifetime(lifetime);
@@ -1194,8 +1204,8 @@ fn eq_span_tokens(
             && let Some(rsrc) = right.get_source_range(cx)
             && let Some(rsrc) = rsrc.as_str()
         {
-            let pred = |t: &(_, _)| pred(t.0);
-            let map = |(_, x)| x;
+            let pred = |&(token, ..): &(TokenKind, _, _)| pred(token);
+            let map = |(_, source, _)| source;
 
             let ltok = tokenize_with_text(lsrc).filter(pred).map(map);
             let rtok = tokenize_with_text(rsrc).filter(pred).map(map);
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index aed0bc565d8..10e258444a6 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1,6 +1,5 @@
 #![feature(array_chunks)]
 #![feature(box_patterns)]
-#![feature(control_flow_enum)]
 #![feature(f128)]
 #![feature(f16)]
 #![feature(if_let_guard)]
@@ -78,7 +77,7 @@ pub mod visitors;
 pub use self::attrs::*;
 pub use self::check_proc_macro::{is_from_proc_macro, is_span_if, is_span_match};
 pub use self::hir_utils::{
-    both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over, HirEqInterExpr, SpanlessEq, SpanlessHash,
+    HirEqInterExpr, SpanlessEq, SpanlessHash, both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over,
 };
 
 use core::mem;
@@ -94,20 +93,20 @@ use rustc_ast::ast::{self, LitKind, RangeLimits};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::unhash::UnhashMap;
+use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalModDefId, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE, LocalDefId, LocalModDefId};
 use rustc_hir::definitions::{DefPath, DefPathData};
 use rustc_hir::hir_id::{HirIdMap, HirIdSet};
-use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
-use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
+use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
 use rustc_hir::{
-    self as hir, def, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind,
-    ConstContext, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem,
-    ImplItemKind, ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
-    Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef,
-    TraitRef, TyKind, UnOp,
+    self as hir, Arm, ArrayLen, BindingMode, Block, BlockCheckMode, Body, ByRef, Closure, ConstArgKind, ConstContext,
+    Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind,
+    ImplItemRef, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode, Param, Pat,
+    PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef,
+    TyKind, UnOp, def,
 };
-use rustc_lexer::{tokenize, TokenKind};
+use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::place::PlaceBase;
 use rustc_middle::mir::Const;
@@ -120,12 +119,12 @@ use rustc_middle::ty::{
 };
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
-use rustc_span::symbol::{kw, Ident, Symbol};
-use rustc_span::{sym, Span};
+use rustc_span::symbol::{Ident, Symbol, kw};
+use rustc_span::{InnerSpan, Span, sym};
 use rustc_target::abi::Integer;
 use visitors::Visitable;
 
-use crate::consts::{mir_to_const, ConstEvalCtxt, Constant};
+use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
 use crate::higher::Range;
 use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};
 use crate::visitors::for_each_expr_without_closures;
@@ -263,9 +262,13 @@ pub fn is_res_lang_ctor(cx: &LateContext<'_>, res: Res, lang_item: LangItem) ->
     }
 }
 
-
 /// Checks if `{ctor_call_id}(...)` is `{enum_item}::{variant_name}(...)`.
-pub fn is_enum_variant_ctor(cx: &LateContext<'_>, enum_item: Symbol, variant_name: Symbol, ctor_call_id: DefId) -> bool {
+pub fn is_enum_variant_ctor(
+    cx: &LateContext<'_>,
+    enum_item: Symbol,
+    variant_name: Symbol,
+    ctor_call_id: DefId,
+) -> bool {
     let Some(enum_def_id) = cx.tcx.get_diagnostic_item(enum_item) else {
         return false;
     };
@@ -593,7 +596,7 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<It
         },
     };
 
-    tcx.incoherent_impls(ty).into_iter().copied()
+    tcx.incoherent_impls(ty).iter().copied()
 }
 
 fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
@@ -664,6 +667,17 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
     }
 }
 
+/// Finds the crates called `name`, may be multiple due to multiple major versions.
+pub fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> Vec<Res> {
+    tcx.crates(())
+        .iter()
+        .copied()
+        .filter(move |&num| tcx.crate_name(num) == name)
+        .map(CrateNum::as_def_id)
+        .map(|id| Res::Def(tcx.def_kind(id), id))
+        .collect()
+}
+
 /// Resolves a def path like `std::vec::Vec`.
 ///
 /// Can return multiple resolutions when there are multiple versions of the same crate, e.g.
@@ -674,15 +688,7 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Re
 ///
 /// This function is expensive and should be used sparingly.
 pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
-    fn find_crates(tcx: TyCtxt<'_>, name: Symbol) -> impl Iterator<Item = DefId> + '_ {
-        tcx.crates(())
-            .iter()
-            .copied()
-            .filter(move |&num| tcx.crate_name(num) == name)
-            .map(CrateNum::as_def_id)
-    }
-
-    let (base, mut path) = match *path {
+    let (base, path) = match *path {
         [primitive] => {
             return vec![PrimTy::from_name(Symbol::intern(primitive)).map_or(Res::Err, Res::PrimTy)];
         },
@@ -698,18 +704,25 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
         None
     };
 
-    let starts = find_primitive_impls(tcx, base)
-        .chain(find_crates(tcx, base_sym))
+    let crates = find_primitive_impls(tcx, base)
         .chain(local_crate)
-        .map(|id| Res::Def(tcx.def_kind(id), id));
+        .map(|id| Res::Def(tcx.def_kind(id), id))
+        .chain(find_crates(tcx, base_sym))
+        .collect();
 
-    let mut resolutions: Vec<Res> = starts.collect();
+    def_path_res_with_base(tcx, crates, path)
+}
 
+/// Resolves a def path like `vec::Vec` with the base `std`.
+///
+/// This is lighter than [`def_path_res`], and should be called with [`find_crates`] looking up
+/// items from the same crate repeatedly, although should still be used sparingly.
+pub fn def_path_res_with_base(tcx: TyCtxt<'_>, mut base: Vec<Res>, mut path: &[&str]) -> Vec<Res> {
     while let [segment, rest @ ..] = path {
         path = rest;
         let segment = Symbol::intern(segment);
 
-        resolutions = resolutions
+        base = base
             .into_iter()
             .filter_map(|res| res.opt_def_id())
             .flat_map(|def_id| {
@@ -717,7 +730,7 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
                 // `impl S { ... }`
                 let inherent_impl_children = tcx
                     .inherent_impls(def_id)
-                    .into_iter()
+                    .iter()
                     .flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
 
                 let direct_children = item_children_by_name(tcx, def_id, segment);
@@ -727,7 +740,7 @@ pub fn def_path_res(tcx: TyCtxt<'_>, path: &[&str]) -> Vec<Res> {
             .collect();
     }
 
-    resolutions
+    base
 }
 
 /// Resolves a def path like `std::vec::Vec` to its [`DefId`]s, see [`def_path_res`].
@@ -1327,7 +1340,7 @@ pub struct ContainsName<'a, 'tcx> {
     pub result: bool,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ContainsName<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_name(&mut self, name: Symbol) {
@@ -2940,13 +2953,14 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> ExprU
 }
 
 /// Tokenizes the input while keeping the text associated with each token.
-pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str)> {
+pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str, InnerSpan)> {
     let mut pos = 0;
     tokenize(s).map(move |t| {
         let end = pos + t.len;
         let range = pos as usize..end as usize;
+        let inner = InnerSpan::new(range.start, range.end);
         pos = end;
-        (t.kind, s.get(range).unwrap_or_default())
+        (t.kind, s.get(range).unwrap_or_default(), inner)
     })
 }
 
@@ -2970,8 +2984,8 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool {
 pub fn span_extract_comment(sm: &SourceMap, span: Span) -> String {
     let snippet = sm.span_to_snippet(span).unwrap_or_default();
     let res = tokenize_with_text(&snippet)
-        .filter(|(t, _)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))
-        .map(|(_, s)| s)
+        .filter(|(t, ..)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))
+        .map(|(_, s, _)| s)
         .join("\n");
     res
 }
@@ -2991,7 +3005,7 @@ pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
 /// pat: Some(a)
 /// else_body: return None
 /// ```
-
+///
 /// And for this example:
 /// ```ignore
 /// let Some(FooBar { a, b }) = ex else { return None };
@@ -3001,7 +3015,7 @@ pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
 /// pat: Some(FooBar { a, b })
 /// else_body: return None
 /// ```
-
+///
 /// We output `Some(a)` in the first instance, and `Some(FooBar { a, b })` in the second, because
 /// the question mark operator is applicable here. Callers have to check whether we are in a
 /// constant or not.
@@ -3096,7 +3110,7 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
         is_never: bool,
     }
 
-    impl<'tcx> V<'_, 'tcx> {
+    impl V<'_, '_> {
         fn push_break_target(&mut self, id: HirId) {
             self.break_targets.push(BreakTarget { id, unused: true });
             self.break_targets_for_result_ty += u32::from(self.in_final_expr);
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 1d7479bff82..9c4d19ac1f1 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::similar_names)] // `expr` and `expn`
 
-use crate::visitors::{for_each_expr_without_closures, Descend};
+use crate::visitors::{Descend, for_each_expr_without_closures};
 
 use arrayvec::ArrayVec;
 use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder};
@@ -10,7 +10,7 @@ use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
 use rustc_lint::LateContext;
 use rustc_span::def_id::DefId;
 use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
-use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol};
+use rustc_span::{BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol, sym};
 use std::ops::ControlFlow;
 
 const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 654fb564848..3924e384c37 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -2,7 +2,7 @@ use rustc_hir::{Expr, HirId};
 use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{
-    traversal, BasicBlock, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
+    BasicBlock, Body, InlineAsmOperand, Local, Location, Place, START_BLOCK, StatementKind, TerminatorKind, traversal,
 };
 use rustc_middle::ty::TyCtxt;
 
@@ -58,7 +58,7 @@ struct V<'a> {
     results: Vec<LocalUsage>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for V<'a> {
+impl<'tcx> Visitor<'tcx> for V<'_> {
     fn visit_place(&mut self, place: &Place<'tcx>, ctx: PlaceContext, loc: Location) {
         if loc.block == self.location.block && loc.statement_index <= self.location.statement_index {
             return;
@@ -112,14 +112,10 @@ pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {
 
 /// Convenience wrapper around `visit_local_usage`.
 pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option<bool> {
-    visit_local_usage(
-        &[local],
-        mir,
-        Location {
-            block: START_BLOCK,
-            statement_index: 0,
-        },
-    )
+    visit_local_usage(&[local], mir, Location {
+        block: START_BLOCK,
+        statement_index: 0,
+    })
     .map(|mut vec| {
         let LocalUsage { local_use_locs, .. } = vec.remove(0);
         let mut locations = local_use_locs
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
index 07e6705cd3d..6bb434a466f 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
@@ -65,7 +65,7 @@ impl<'a, 'b, 'tcx> PossibleBorrowerVisitor<'a, 'b, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b, 'tcx> {
+impl<'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'_, '_, 'tcx> {
     fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
         let lhs = place.local;
         match rvalue {
@@ -177,8 +177,8 @@ pub struct PossibleBorrowerMap<'b, 'tcx> {
     pub bitset: (BitSet<mir::Local>, BitSet<mir::Local>),
 }
 
-impl<'a, 'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
-    pub fn new(cx: &'a LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {
+impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
+    pub fn new(cx: &LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {
         let possible_origin = {
             let mut vis = PossibleOriginVisitor::new(mir);
             vis.visit_body(mir);
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs b/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs
index da04266863f..4157b3f4930 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs
@@ -39,7 +39,7 @@ impl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'a, 'tcx> {
+impl<'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'_, 'tcx> {
     fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
         let lhs = place.local;
         match rvalue {
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index a30edc48fff..11a98b02f33 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -29,7 +29,11 @@ pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
 pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
 
 // Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items.
-// ... none currently!
+pub const ABORT: [&str; 3] = ["std", "process", "abort"];
+pub const CHILD: [&str; 3] = ["std", "process", "Child"];
+pub const CHILD_ID: [&str; 4] = ["std", "process", "Child", "id"];
+pub const CHILD_KILL: [&str; 4] = ["std", "process", "Child", "kill"];
+pub const PANIC_ANY: [&str; 3] = ["std", "panic", "panic_any"];
 
 // Paths in clippy itself
 pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
diff --git a/src/tools/clippy/clippy_utils/src/ptr.rs b/src/tools/clippy/clippy_utils/src/ptr.rs
index 991ea428dc3..273c1b0defa 100644
--- a/src/tools/clippy/clippy_utils/src/ptr.rs
+++ b/src/tools/clippy/clippy_utils/src/ptr.rs
@@ -1,5 +1,5 @@
 use crate::source::snippet;
-use crate::visitors::{for_each_expr_without_closures, Descend};
+use crate::visitors::{Descend, for_each_expr_without_closures};
 use crate::{path_to_local_id, strip_pat_refs};
 use core::ops::ControlFlow;
 use rustc_hir::{Body, BodyId, ExprKind, HirId, PatKind};
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index ce1895b7fb1..5f12b6bf99e 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -18,8 +18,8 @@ use rustc_middle::mir::{
 use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause};
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt};
-use rustc_span::symbol::sym;
 use rustc_span::Span;
+use rustc_span::symbol::sym;
 use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext};
 use std::borrow::Cow;
 
@@ -131,7 +131,8 @@ fn check_rvalue<'tcx>(
             CastKind::PointerCoercion(
                 PointerCoercion::UnsafeFnPointer
                 | PointerCoercion::ClosureFnPointer(_)
-                | PointerCoercion::ReifyFnPointer, _
+                | PointerCoercion::ReifyFnPointer,
+                _,
             ),
             _,
             _,
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index 482e1e0147b..eecbfb3936a 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -9,10 +9,10 @@ use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
 use rustc_lint::{EarlyContext, LateContext};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
-use rustc_span::source_map::{original_sp, SourceMap};
+use rustc_span::source_map::{SourceMap, original_sp};
 use rustc_span::{
-    hygiene, BytePos, FileNameDisplayPreference, Pos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext,
-    DUMMY_SP,
+    BytePos, DUMMY_SP, FileNameDisplayPreference, Pos, SourceFile, SourceFileAndLine, Span, SpanData, SyntaxContext,
+    hygiene,
 };
 use std::borrow::Cow;
 use std::fmt;
@@ -287,6 +287,7 @@ impl SourceFileRange {
         self.sf
             .src
             .as_ref()
+            .map(|src| src.as_str())
             .or_else(|| self.sf.external_src.get().and_then(|src| src.get_source()))
             .and_then(|x| x.get(self.range.clone()))
     }
@@ -666,39 +667,6 @@ pub fn walk_span_to_context(span: Span, outer: SyntaxContext) -> Option<Span> {
     (outer_span.ctxt() == outer).then_some(outer_span)
 }
 
-/// Removes block comments from the given `Vec` of lines.
-///
-/// # Examples
-///
-/// ```rust,ignore
-/// without_block_comments(vec!["/*", "foo", "*/"]);
-/// // => vec![]
-///
-/// without_block_comments(vec!["bar", "/*", "foo", "*/"]);
-/// // => vec!["bar"]
-/// ```
-pub fn without_block_comments(lines: Vec<&str>) -> Vec<&str> {
-    let mut without = vec![];
-
-    let mut nest_level = 0;
-
-    for line in lines {
-        if line.contains("/*") {
-            nest_level += 1;
-            continue;
-        } else if line.contains("*/") {
-            nest_level -= 1;
-            continue;
-        }
-
-        if nest_level == 0 {
-            without.push(line);
-        }
-    }
-
-    without
-}
-
 /// Trims the whitespace from the start and the end of the span.
 pub fn trim_span(sm: &SourceMap, span: Span) -> Span {
     let data = span.data();
@@ -758,15 +726,12 @@ pub fn str_literal_to_char_literal(
             &snip[1..(snip.len() - 1)]
         };
 
-        let hint = format!(
-            "'{}'",
-            match ch {
-                "'" => "\\'",
-                r"\" => "\\\\",
-                "\\\"" => "\"", // no need to escape `"` in `'"'`
-                _ => ch,
-            }
-        );
+        let hint = format!("'{}'", match ch {
+            "'" => "\\'",
+            r"\" => "\\\\",
+            "\\\"" => "\"", // no need to escape `"` in `'"'`
+            _ => ch,
+        });
 
         Some(hint)
     } else {
@@ -776,7 +741,7 @@ pub fn str_literal_to_char_literal(
 
 #[cfg(test)]
 mod test {
-    use super::{reindent_multiline, without_block_comments};
+    use super::reindent_multiline;
 
     #[test]
     fn test_reindent_multiline_single_line() {
@@ -844,29 +809,4 @@ mod test {
         z
     }".into(), true, Some(8)));
     }
-
-    #[test]
-    fn test_without_block_comments_lines_without_block_comments() {
-        let result = without_block_comments(vec!["/*", "", "*/"]);
-        println!("result: {result:?}");
-        assert!(result.is_empty());
-
-        let result = without_block_comments(vec!["", "/*", "", "*/", "#[crate_type = \"lib\"]", "/*", "", "*/", ""]);
-        assert_eq!(result, vec!["", "#[crate_type = \"lib\"]", ""]);
-
-        let result = without_block_comments(vec!["/* rust", "", "*/"]);
-        assert!(result.is_empty());
-
-        let result = without_block_comments(vec!["/* one-line comment */"]);
-        assert!(result.is_empty());
-
-        let result = without_block_comments(vec!["/* nested", "/* multi-line", "comment", "*/", "test", "*/"]);
-        assert!(result.is_empty());
-
-        let result = without_block_comments(vec!["/* nested /* inline /* comment */ test */ */"]);
-        assert!(result.is_empty());
-
-        let result = without_block_comments(vec!["foo", "bar", "baz"]);
-        assert_eq!(result, vec!["foo", "bar", "baz"]);
-    }
 }
diff --git a/src/tools/clippy/clippy_utils/src/str_utils.rs b/src/tools/clippy/clippy_utils/src/str_utils.rs
index 421b25a77fe..1588ee452da 100644
--- a/src/tools/clippy/clippy_utils/src/str_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/str_utils.rs
@@ -370,9 +370,11 @@ mod test {
         assert_eq!(camel_case_split("AbcDef"), vec!["Abc", "Def"]);
         assert_eq!(camel_case_split("Abc"), vec!["Abc"]);
         assert_eq!(camel_case_split("abcDef"), vec!["abc", "Def"]);
-        assert_eq!(
-            camel_case_split("\u{f6}\u{f6}AabABcd"),
-            vec!["\u{f6}\u{f6}", "Aab", "A", "Bcd"]
-        );
+        assert_eq!(camel_case_split("\u{f6}\u{f6}AabABcd"), vec![
+            "\u{f6}\u{f6}",
+            "Aab",
+            "A",
+            "Bcd"
+        ]);
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 0f86d89c980..3255c51d009 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -180,8 +180,10 @@ impl<'a> Sugg<'a> {
     ) -> Self {
         use rustc_ast::ast::RangeLimits;
 
+        let mut snippet = |span: Span| snippet_with_context(cx, span, ctxt, default, app).0;
+
         match expr.kind {
-            _ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
+            _ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet(expr.span)),
             ast::ExprKind::AddrOf(..)
             | ast::ExprKind::Closure { .. }
             | ast::ExprKind::If(..)
@@ -224,46 +226,38 @@ impl<'a> Sugg<'a> {
             | ast::ExprKind::While(..)
             | ast::ExprKind::Await(..)
             | ast::ExprKind::Err(_)
-            | ast::ExprKind::Dummy => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
+            | ast::ExprKind::Dummy => Sugg::NonParen(snippet(expr.span)),
             ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp(
                 AssocOp::DotDot,
-                lhs.as_ref().map_or("".into(), |lhs| {
-                    snippet_with_context(cx, lhs.span, ctxt, default, app).0
-                }),
-                rhs.as_ref().map_or("".into(), |rhs| {
-                    snippet_with_context(cx, rhs.span, ctxt, default, app).0
-                }),
+                lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)),
+                rhs.as_ref().map_or("".into(), |rhs| snippet(rhs.span)),
             ),
             ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::Closed) => Sugg::BinOp(
                 AssocOp::DotDotEq,
-                lhs.as_ref().map_or("".into(), |lhs| {
-                    snippet_with_context(cx, lhs.span, ctxt, default, app).0
-                }),
-                rhs.as_ref().map_or("".into(), |rhs| {
-                    snippet_with_context(cx, rhs.span, ctxt, default, app).0
-                }),
+                lhs.as_ref().map_or("".into(), |lhs| snippet(lhs.span)),
+                rhs.as_ref().map_or("".into(), |rhs| snippet(rhs.span)),
             ),
             ast::ExprKind::Assign(ref lhs, ref rhs, _) => Sugg::BinOp(
                 AssocOp::Assign,
-                snippet_with_context(cx, lhs.span, ctxt, default, app).0,
-                snippet_with_context(cx, rhs.span, ctxt, default, app).0,
+                snippet(lhs.span),
+                snippet(rhs.span),
             ),
             ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => Sugg::BinOp(
                 astbinop2assignop(op),
-                snippet_with_context(cx, lhs.span, ctxt, default, app).0,
-                snippet_with_context(cx, rhs.span, ctxt, default, app).0,
+                snippet(lhs.span),
+                snippet(rhs.span),
             ),
             ast::ExprKind::Binary(op, ref lhs, ref rhs) => Sugg::BinOp(
                 AssocOp::from_ast_binop(op.node),
-                snippet_with_context(cx, lhs.span, ctxt, default, app).0,
-                snippet_with_context(cx, rhs.span, ctxt, default, app).0,
+                snippet(lhs.span),
+                snippet(rhs.span),
             ),
             ast::ExprKind::Cast(ref lhs, ref ty) |
             //FIXME(chenyukang), remove this after type ascription is removed from AST
             ast::ExprKind::Type(ref lhs, ref ty) => Sugg::BinOp(
                 AssocOp::As,
-                snippet_with_context(cx, lhs.span, ctxt, default, app).0,
-                snippet_with_context(cx, ty.span, ctxt, default, app).0,
+                snippet(lhs.span),
+                snippet(ty.span),
             ),
         }
     }
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 22aaaa1b734..21c2b19f4bd 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -12,8 +12,8 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, FnDecl, LangItem, Safety, TyKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
-use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::ConstValue;
+use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::traits::EvaluationResult;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{
@@ -22,7 +22,7 @@ use rustc_middle::ty::{
     TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, Upcast, VariantDef, VariantDiscr,
 };
 use rustc_span::symbol::Ident;
-use rustc_span::{sym, Span, Symbol, DUMMY_SP};
+use rustc_span::{DUMMY_SP, Span, Symbol, sym};
 use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
@@ -606,10 +606,13 @@ fn is_uninit_value_valid_for_ty_fallback<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
         ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)),
         // Unions are always fine right now.
         // This includes MaybeUninit, the main way people use uninitialized memory.
-        // For ADTs, we could look at all fields just like for tuples, but that's potentially
-        // exponential, so let's avoid doing that for now. Code doing that is sketchy enough to
-        // just use an `#[allow()]`.
-        ty::Adt(adt, _) => adt.is_union(),
+        ty::Adt(adt, _) if adt.is_union() => true,
+        // Types (e.g. `UnsafeCell<MaybeUninit<T>>`) that recursively contain only types that can be uninit
+        // can themselves be uninit too.
+        // This purposefully ignores enums as they may have a discriminant that can't be uninit.
+        ty::Adt(adt, args) if adt.is_struct() => adt
+            .all_fields()
+            .all(|field| is_uninit_value_valid_for_ty(cx, field.ty(cx.tcx, args))),
         // For the rest, conservatively assume that they cannot be uninit.
         _ => false,
     }
@@ -1316,7 +1319,7 @@ pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl
 /// If you need this, you should wrap this call in `clippy_utils::ty::deref_chain().any(...)`.
 pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<&'a AssocItem> {
     if let Some(ty_did) = ty.ty_adt_def().map(AdtDef::did) {
-        cx.tcx.inherent_impls(ty_did).into_iter().find_map(|&did| {
+        cx.tcx.inherent_impls(ty_did).iter().find_map(|&did| {
             cx.tcx
                 .associated_items(did)
                 .filter_by_name_unhygienic(method_name)
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 875ddec259e..91ec120adbf 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
@@ -14,14 +14,14 @@
 use crate::def_path_res;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::intravisit::{walk_qpath, walk_ty, Visitor};
+use rustc_hir::intravisit::{Visitor, walk_qpath, walk_ty};
 use rustc_hir::{self as hir, Expr, ExprKind, GenericArgs, HirId, Node, PathSegment, QPath, TyKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, AdtDef, GenericArgKind, Ty};
 use rustc_span::{Span, Symbol};
 
 mod certainty;
-use certainty::{join, meet, Certainty, Meet};
+use certainty::{Certainty, Meet, join, meet};
 
 pub fn expr_type_is_certain(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     expr_type_certainty(cx, expr).is_certain()
@@ -108,7 +108,7 @@ impl<'cx, 'tcx> CertaintyVisitor<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx> Visitor<'cx> for CertaintyVisitor<'cx, 'tcx> {
+impl<'cx> Visitor<'cx> for CertaintyVisitor<'cx, '_> {
     fn visit_qpath(&mut self, qpath: &'cx QPath<'_>, hir_id: HirId, _: Span) {
         self.certainty = self.certainty.meet(qpath_certainty(self.cx, qpath, true));
         if self.certainty != Certainty::Uncertain {
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index fbf3d95365a..8af3bdccaa1 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -1,4 +1,4 @@
-use crate::visitors::{for_each_expr, for_each_expr_without_closures, Descend, Visitable};
+use crate::visitors::{Descend, Visitable, for_each_expr, for_each_expr_without_closures};
 use crate::{self as utils, get_enclosing_loop_or_multi_call_closure};
 use core::ops::ControlFlow;
 use hir::def::Res;
@@ -46,8 +46,8 @@ struct MutVarsDelegate {
     skip: bool,
 }
 
-impl<'tcx> MutVarsDelegate {
-    fn update(&mut self, cat: &PlaceWithHirId<'tcx>) {
+impl MutVarsDelegate {
+    fn update(&mut self, cat: &PlaceWithHirId<'_>) {
         match cat.place.base {
             PlaceBase::Local(id) => {
                 self.used_mutably.insert(id);
@@ -122,7 +122,7 @@ impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
         finder.usage_found
     }
 }
-impl<'a, 'tcx> Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index e5b6d3965e9..02931306f16 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -1,10 +1,10 @@
 use crate::ty::needs_ordered_drop;
 use crate::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
-use rustc_ast::visit::{try_visit, VisitorResult};
+use rustc_ast::visit::{VisitorResult, try_visit};
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::intravisit::{self, walk_block, walk_expr, Visitor};
+use rustc_hir::intravisit::{self, Visitor, walk_block, walk_expr};
 use rustc_hir::{
     AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath,
     Safety, Stmt, UnOp, UnsafeSource,
@@ -552,7 +552,7 @@ pub fn for_each_local_use_after_expr<'tcx, B>(
         res: ControlFlow<B>,
         f: F,
     }
-    impl<'cx, 'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'cx, 'tcx, F, B> {
+    impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {
         type NestedFilter = nested_filter::OnlyBodies;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
@@ -734,7 +734,7 @@ pub fn for_each_local_assignment<'tcx, B>(
         res: ControlFlow<B>,
         f: F,
     }
-    impl<'cx, 'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'cx, 'tcx, F, B> {
+    impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {
         type NestedFilter = nested_filter::OnlyBodies;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml
index 31270241b0b..67a1f7cc72c 100644
--- a/src/tools/clippy/declare_clippy_lint/Cargo.toml
+++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "declare_clippy_lint"
-version = "0.1.82"
+version = "0.1.83"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/declare_clippy_lint/src/lib.rs b/src/tools/clippy/declare_clippy_lint/src/lib.rs
index 6aa24329b06..fefc1a0a6c4 100644
--- a/src/tools/clippy/declare_clippy_lint/src/lib.rs
+++ b/src/tools/clippy/declare_clippy_lint/src/lib.rs
@@ -5,7 +5,7 @@
 use proc_macro::TokenStream;
 use quote::{format_ident, quote};
 use syn::parse::{Parse, ParseStream};
-use syn::{parse_macro_input, Attribute, Error, Expr, ExprLit, Ident, Lit, LitStr, Meta, Result, Token};
+use syn::{Attribute, Error, Expr, ExprLit, Ident, Lit, LitStr, Meta, Result, Token, parse_macro_input};
 
 fn parse_attr<const LEN: usize>(path: [&'static str; LEN], attr: &Attribute) -> Option<LitStr> {
     if let Meta::NameValue(name_value) = &attr.meta {
@@ -140,15 +140,12 @@ pub fn declare_clippy_lint(input: TokenStream) -> TokenStream {
 
     let mut category = category.to_string();
 
-    let level = format_ident!(
-        "{}",
-        match category.as_str() {
-            "correctness" => "Deny",
-            "style" | "suspicious" | "complexity" | "perf" => "Warn",
-            "pedantic" | "restriction" | "cargo" | "nursery" | "internal" => "Allow",
-            _ => panic!("unknown category {category}"),
-        },
-    );
+    let level = format_ident!("{}", match category.as_str() {
+        "correctness" => "Deny",
+        "style" | "suspicious" | "complexity" | "perf" => "Warn",
+        "pedantic" | "restriction" | "cargo" | "nursery" | "internal" => "Allow",
+        _ => panic!("unknown category {category}"),
+    },);
 
     let info_name = format_ident!("{name}_INFO");
 
diff --git a/src/tools/clippy/lintcheck/src/driver.rs b/src/tools/clippy/lintcheck/src/driver.rs
index 2fda2b00f87..87ab14ba0cf 100644
--- a/src/tools/clippy/lintcheck/src/driver.rs
+++ b/src/tools/clippy/lintcheck/src/driver.rs
@@ -1,4 +1,4 @@
-use crate::recursive::{deserialize_line, serialize_line, DriverInfo};
+use crate::recursive::{DriverInfo, deserialize_line, serialize_line};
 
 use std::io::{self, BufReader, Write};
 use std::net::TcpStream;
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index acb6eaa5278..8c62dd3ed38 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -68,7 +68,7 @@ impl Crate {
         total_crates_to_lint: usize,
         config: &LintcheckConfig,
         lint_levels_args: &[String],
-        server: &Option<LintcheckServer>,
+        server: Option<&LintcheckServer>,
     ) -> Vec<ClippyCheckOutput> {
         // advance the atomic index by one
         let index = target_dir_index.fetch_add(1, Ordering::SeqCst);
@@ -359,7 +359,7 @@ fn lintcheck(config: LintcheckConfig) {
                 crates.len(),
                 &config,
                 &lint_level_args,
-                &server,
+                server.as_ref(),
             )
         })
         .collect();
diff --git a/src/tools/clippy/lintcheck/src/recursive.rs b/src/tools/clippy/lintcheck/src/recursive.rs
index 6a662970ae8..57073f52364 100644
--- a/src/tools/clippy/lintcheck/src/recursive.rs
+++ b/src/tools/clippy/lintcheck/src/recursive.rs
@@ -3,8 +3,8 @@
 //! [`LintcheckServer`] to ask if it should be skipped, and if not sends the stderr of running
 //! clippy on the crate to the server
 
-use crate::input::RecursiveOptions;
 use crate::ClippyWarning;
+use crate::input::RecursiveOptions;
 
 use std::collections::HashSet;
 use std::io::{BufRead, BufReader, Read, Write};
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 0be2e81810e..f0c8651efce 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2024-08-23"
+channel = "nightly-2024-10-03"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 0ac3f35b446..c66837dc998 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -15,14 +15,13 @@ extern crate rustc_session;
 extern crate rustc_span;
 
 use rustc_interface::interface;
+use rustc_session::EarlyDiagCtxt;
 use rustc_session::config::ErrorOutputType;
 use rustc_session::parse::ParseSess;
-use rustc_session::EarlyDiagCtxt;
 use rustc_span::symbol::Symbol;
 
 use std::env;
 use std::fs::read_to_string;
-use std::ops::Deref;
 use std::path::Path;
 use std::process::exit;
 
@@ -30,12 +29,8 @@ use anstream::println;
 
 /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
 /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
-fn arg_value<'a, T: Deref<Target = str>>(
-    args: &'a [T],
-    find_arg: &str,
-    pred: impl Fn(&str) -> bool,
-) -> Option<&'a str> {
-    let mut args = args.iter().map(Deref::deref);
+fn arg_value<'a>(args: &'a [String], find_arg: &str, pred: impl Fn(&str) -> bool) -> Option<&'a str> {
+    let mut args = args.iter().map(String::as_str);
     while let Some(arg) = args.next() {
         let mut arg = arg.splitn(2, '=');
         if arg.next() != Some(find_arg) {
@@ -50,11 +45,15 @@ fn arg_value<'a, T: Deref<Target = str>>(
     None
 }
 
+fn has_arg(args: &[String], find_arg: &str) -> bool {
+    args.iter().any(|arg| find_arg == arg.split('=').next().unwrap())
+}
+
 #[test]
 fn test_arg_value() {
-    let args = &["--bar=bar", "--foobar", "123", "--foo"];
+    let args = &["--bar=bar", "--foobar", "123", "--foo"].map(String::from);
 
-    assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None);
+    assert_eq!(arg_value(&[], "--foobar", |_| true), None);
     assert_eq!(arg_value(args, "--bar", |_| false), None);
     assert_eq!(arg_value(args, "--bar", |_| true), Some("bar"));
     assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar"));
@@ -65,11 +64,21 @@ fn test_arg_value() {
     assert_eq!(arg_value(args, "--foo", |_| true), None);
 }
 
-fn track_clippy_args(psess: &mut ParseSess, args_env_var: &Option<String>) {
-    psess.env_depinfo.get_mut().insert((
-        Symbol::intern("CLIPPY_ARGS"),
-        args_env_var.as_deref().map(Symbol::intern),
-    ));
+#[test]
+fn test_has_arg() {
+    let args = &["--foo=bar", "-vV", "--baz"].map(String::from);
+    assert!(has_arg(args, "--foo"));
+    assert!(has_arg(args, "--baz"));
+    assert!(has_arg(args, "-vV"));
+
+    assert!(!has_arg(args, "--bar"));
+}
+
+fn track_clippy_args(psess: &mut ParseSess, args_env_var: Option<&str>) {
+    psess
+        .env_depinfo
+        .get_mut()
+        .insert((Symbol::intern("CLIPPY_ARGS"), args_env_var.map(Symbol::intern)));
 }
 
 /// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy
@@ -113,7 +122,7 @@ impl rustc_driver::Callbacks for RustcCallbacks {
     fn config(&mut self, config: &mut interface::Config) {
         let clippy_args_var = self.clippy_args_var.take();
         config.psess_created = Some(Box::new(move |psess| {
-            track_clippy_args(psess, &clippy_args_var);
+            track_clippy_args(psess, clippy_args_var.as_deref());
         }));
     }
 }
@@ -130,7 +139,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
         let previous = config.register_lints.take();
         let clippy_args_var = self.clippy_args_var.take();
         config.psess_created = Some(Box::new(move |psess| {
-            track_clippy_args(psess, &clippy_args_var);
+            track_clippy_args(psess, clippy_args_var.as_deref());
             track_files(psess);
 
             // Trigger a rebuild if CLIPPY_CONF_DIR changes. The value must be a valid string so
@@ -189,7 +198,7 @@ pub fn main() {
         let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?;
 
         let has_sysroot_arg = |args: &mut [String]| -> bool {
-            if arg_value(args, "--sysroot", |_| true).is_some() {
+            if has_arg(args, "--sysroot") {
                 return true;
             }
             // https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path
@@ -199,7 +208,7 @@ pub fn main() {
                 if let Some(arg_file_path) = arg.strip_prefix('@') {
                     if let Ok(arg_file) = read_to_string(arg_file_path) {
                         let split_arg_file: Vec<String> = arg_file.lines().map(ToString::to_string).collect();
-                        if arg_value(&split_arg_file, "--sysroot", |_| true).is_some() {
+                        if has_arg(&split_arg_file, "--sysroot") {
                             return true;
                         }
                     }
@@ -268,21 +277,21 @@ pub fn main() {
                 },
                 _ => Some(s.to_string()),
             })
-            // FIXME: remove this line in 1.79 to only keep `--cfg clippy`.
-            .chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()])
             .chain(vec!["--cfg".into(), "clippy".into()])
             .collect::<Vec<String>>();
 
-        // We enable Clippy if one of the following conditions is met
-        // - IF Clippy is run on its test suite OR
-        // - IF Clippy is run on the main crate, not on deps (`!cap_lints_allow`) THEN
-        //    - IF `--no-deps` is not set (`!no_deps`) OR
-        //    - IF `--no-deps` is set and Clippy is run on the specified primary package
+        // If no Clippy lints will be run we do not need to run Clippy
         let cap_lints_allow = arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some()
             && arg_value(&orig_args, "--force-warn", |val| val.contains("clippy::")).is_none();
-        let in_primary_package = env::var("CARGO_PRIMARY_PACKAGE").is_ok();
 
-        let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package);
+        // If `--no-deps` is enabled only lint the primary pacakge
+        let relevant_package = !no_deps || env::var("CARGO_PRIMARY_PACKAGE").is_ok();
+
+        // Do not run Clippy for Cargo's info queries so that invalid CLIPPY_ARGS are not cached
+        // https://github.com/rust-lang/cargo/issues/14385
+        let info_query = has_arg(&orig_args, "-vV") || has_arg(&orig_args, "--print");
+
+        let clippy_enabled = !cap_lints_allow && relevant_package && !info_query;
         if clippy_enabled {
             args.extend(clippy_args);
             rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var })
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 9754254cdd0..af2aa519257 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -2,26 +2,25 @@
 #![warn(rust_2018_idioms, unused_lifetimes)]
 #![allow(unused_extern_crates)]
 
-use cargo_metadata::diagnostic::{Applicability, Diagnostic};
 use cargo_metadata::Message;
+use cargo_metadata::diagnostic::{Applicability, Diagnostic};
 use clippy_config::ClippyConfiguration;
+use clippy_lints::LintInfo;
 use clippy_lints::declared_lints::LINTS;
 use clippy_lints::deprecated_lints::{DEPRECATED, DEPRECATED_VERSION, RENAMED};
-use clippy_lints::LintInfo;
 use serde::{Deserialize, Serialize};
 use test_utils::IS_RUSTC_TEST_SUITE;
-use ui_test::custom_flags::rustfix::RustfixMode;
 use ui_test::custom_flags::Flag;
+use ui_test::custom_flags::rustfix::RustfixMode;
 use ui_test::spanned::Spanned;
-use ui_test::test_result::TestRun;
-use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, OutputConflictHandling};
+use ui_test::{Args, CommandBuilder, Config, Match, OutputConflictHandling, status_emitter};
 
 use std::collections::{BTreeMap, HashMap};
 use std::env::{self, set_var, var_os};
 use std::ffi::{OsStr, OsString};
 use std::fmt::Write;
 use std::path::{Path, PathBuf};
-use std::sync::mpsc::{channel, Sender};
+use std::sync::mpsc::{Sender, channel};
 use std::{fs, iter, thread};
 
 // Test dependencies may need an `extern crate` here to ensure that they show up
@@ -469,15 +468,14 @@ fn applicability_ord(applicability: &Applicability) -> u8 {
 impl Flag for DiagnosticCollector {
     fn post_test_action(
         &self,
-        _config: &ui_test::per_test_config::TestConfig<'_>,
-        _cmd: &mut std::process::Command,
+        _config: &ui_test::per_test_config::TestConfig,
         output: &std::process::Output,
-        _build_manager: &ui_test::build_manager::BuildManager<'_>,
-    ) -> Result<Vec<TestRun>, ui_test::Errored> {
+        _build_manager: &ui_test::build_manager::BuildManager,
+    ) -> Result<(), ui_test::Errored> {
         if !output.stderr.is_empty() {
             self.sender.send(output.stderr.clone()).unwrap();
         }
-        Ok(Vec::new())
+        Ok(())
     }
 
     fn clone_inner(&self) -> Box<dyn Flag> {
diff --git a/src/tools/clippy/tests/config-metadata.rs b/src/tools/clippy/tests/config-metadata.rs
index 3e3711873ba..628dfc8f758 100644
--- a/src/tools/clippy/tests/config-metadata.rs
+++ b/src/tools/clippy/tests/config-metadata.rs
@@ -1,6 +1,6 @@
 #![feature(rustc_private)]
 
-use clippy_config::{get_configuration_metadata, ClippyConfiguration};
+use clippy_config::{ClippyConfiguration, get_configuration_metadata};
 use itertools::Itertools;
 use regex::Regex;
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs
index 8d10d5e7161..858be389a9e 100644
--- a/src/tools/clippy/tests/dogfood.rs
+++ b/src/tools/clippy/tests/dogfood.rs
@@ -6,11 +6,9 @@
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
 use itertools::Itertools;
-use std::fs::File;
 use std::io::{self, IsTerminal};
 use std::path::PathBuf;
 use std::process::Command;
-use std::time::SystemTime;
 use test_utils::IS_RUSTC_TEST_SUITE;
 use ui_test::Args;
 
@@ -28,11 +26,7 @@ fn main() {
             println!("dogfood: test");
         }
     } else if !args.skip.iter().any(|arg| arg == "dogfood") {
-        if args.filters.iter().any(|arg| arg == "collect_metadata") {
-            collect_metadata();
-        } else {
-            dogfood();
-        }
+        dogfood();
     }
 }
 
@@ -61,47 +55,6 @@ fn dogfood() {
     );
 }
 
-fn collect_metadata() {
-    assert!(cfg!(feature = "internal"));
-
-    // Setup for validation
-    let metadata_output_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("util/gh-pages/lints.json");
-    let start_time = SystemTime::now();
-
-    // Run collection as is
-    std::env::set_var("ENABLE_METADATA_COLLECTION", "1");
-    assert!(run_clippy_for_package(
-        "clippy_lints",
-        &["-A", "unfulfilled_lint_expectations"]
-    ));
-
-    // Check if cargo caching got in the way
-    if let Ok(file) = File::open(metadata_output_path) {
-        if let Ok(metadata) = file.metadata() {
-            if let Ok(last_modification) = metadata.modified() {
-                if last_modification > start_time {
-                    // The output file has been modified. Most likely by a hungry
-                    // metadata collection monster. So We'll return.
-                    return;
-                }
-            }
-        }
-    }
-
-    // Force cargo to invalidate the caches
-    filetime::set_file_mtime(
-        PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("clippy_lints/src/lib.rs"),
-        filetime::FileTime::now(),
-    )
-    .unwrap();
-
-    // Running the collection again
-    assert!(run_clippy_for_package(
-        "clippy_lints",
-        &["-A", "unfulfilled_lint_expectations"]
-    ));
-}
-
 #[must_use]
 fn run_clippy_for_package(project: &str, args: &[&str]) -> bool {
     let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
index 3908411da82..0a994842834 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.fixed
@@ -13,7 +13,7 @@ extern crate rustc_span;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item, match_type};
 #[allow(unused)]
 use clippy_utils::{
-    is_expr_path_def_path, is_path_diagnostic_item, is_res_diagnostic_ctor, is_res_lang_ctor, is_trait_method,
+    is_enum_variant_ctor, is_expr_path_def_path, is_path_diagnostic_item, is_res_lang_ctor, is_trait_method,
     match_def_path, match_trait_method, path_res,
 };
 
@@ -22,8 +22,8 @@ use rustc_hir::LangItem;
 #[allow(unused)]
 use rustc_span::sym;
 
-use rustc_hir::def_id::DefId;
 use rustc_hir::Expr;
+use rustc_hir::def_id::DefId;
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
 
diff --git a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
index 632e26215a4..ba68de6c6d0 100644
--- a/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
+++ b/src/tools/clippy/tests/ui-internal/unnecessary_def_path.rs
@@ -13,7 +13,7 @@ extern crate rustc_span;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item, match_type};
 #[allow(unused)]
 use clippy_utils::{
-    is_expr_path_def_path, is_path_diagnostic_item, is_res_diagnostic_ctor, is_res_lang_ctor, is_trait_method,
+    is_enum_variant_ctor, is_expr_path_def_path, is_path_diagnostic_item, is_res_lang_ctor, is_trait_method,
     match_def_path, match_trait_method, path_res,
 };
 
@@ -22,8 +22,8 @@ use rustc_hir::LangItem;
 #[allow(unused)]
 use rustc_span::sym;
 
-use rustc_hir::def_id::DefId;
 use rustc_hir::Expr;
+use rustc_hir::def_id::DefId;
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
 
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs
index a2e2b46c426..61ae8de8e33 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_append/disallowed_names.rs
@@ -1,4 +1,4 @@
-#[warn(clippy::disallowed_names)]
+#![warn(clippy::disallowed_names)]
 
 fn main() {
     // `foo` is part of the default configuration
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs
index a2e2b46c426..61ae8de8e33 100644
--- a/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs
+++ b/src/tools/clippy/tests/ui-toml/disallowed_names_replace/disallowed_names.rs
@@ -1,4 +1,4 @@
-#[warn(clippy::disallowed_names)]
+#![warn(clippy::disallowed_names)]
 
 fn main() {
     // `foo` is part of the default configuration
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed
index 5f4f007cf5c..a6072111dc0 100644
--- a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.fixed
@@ -2,7 +2,7 @@
 
 use std::alloc as colla;
 use std::option::Option as Maybe;
-use std::process::{exit as goodbye, Child as Kid};
+use std::process::{Child as Kid, exit as goodbye};
 use std::thread::sleep as thread_sleep;
 #[rustfmt::skip]
 use std::{
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs
index f60058c8628..c2b61aab5b3 100644
--- a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs
@@ -2,7 +2,7 @@
 
 use std::alloc as colla;
 use std::option::Option as Maybe;
-use std::process::{exit as wrong_exit, Child as Kid};
+use std::process::{Child as Kid, exit as wrong_exit};
 use std::thread::sleep;
 #[rustfmt::skip]
 use std::{
diff --git a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
index f66938c83fb..d3bb07ec47f 100644
--- a/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
+++ b/src/tools/clippy/tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.stderr
@@ -1,8 +1,8 @@
 error: this import should be renamed
-  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:5:20
+  --> tests/ui-toml/missing_enforced_import_rename/conf_missing_enforced_import_rename.rs:5:34
    |
-LL | use std::process::{exit as wrong_exit, Child as Kid};
-   |                    ^^^^^^^^^^^^^^^^^^ help: try: `exit as goodbye`
+LL | use std::process::{Child as Kid, exit as wrong_exit};
+   |                                  ^^^^^^^^^^^^^^^^^^ help: try: `exit as goodbye`
    |
    = note: `-D clippy::missing-enforced-import-renames` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::missing_enforced_import_renames)]`
diff --git a/src/tools/clippy/tests/ui-toml/panic/panic.rs b/src/tools/clippy/tests/ui-toml/panic/panic.rs
index 618a37ddfc5..b6264c950e4 100644
--- a/src/tools/clippy/tests/ui-toml/panic/panic.rs
+++ b/src/tools/clippy/tests/ui-toml/panic/panic.rs
@@ -1,5 +1,6 @@
 //@compile-flags: --test
 #![warn(clippy::panic)]
+use std::panic::panic_any;
 
 fn main() {
     enum Enam {
@@ -12,6 +13,10 @@ fn main() {
     }
 }
 
+fn issue_13292() {
+    panic_any("should lint")
+}
+
 #[test]
 fn lonely_test() {
     enum Enam {
diff --git a/src/tools/clippy/tests/ui-toml/panic/panic.stderr b/src/tools/clippy/tests/ui-toml/panic/panic.stderr
index bf7503e086c..a034207d919 100644
--- a/src/tools/clippy/tests/ui-toml/panic/panic.stderr
+++ b/src/tools/clippy/tests/ui-toml/panic/panic.stderr
@@ -1,5 +1,5 @@
 error: `panic` should not be present in production code
-  --> tests/ui-toml/panic/panic.rs:11:14
+  --> tests/ui-toml/panic/panic.rs:12:14
    |
 LL |         _ => panic!(""),
    |              ^^^^^^^^^^
@@ -7,5 +7,11 @@ LL |         _ => panic!(""),
    = note: `-D clippy::panic` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::panic)]`
 
-error: aborting due to 1 previous error
+error: `panic_any` should not be present in production code
+  --> tests/ui-toml/panic/panic.rs:17:5
+   |
+LL |     panic_any("should lint")
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs
index 232bccf6a15..4613a74b85d 100644
--- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs
+++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs
@@ -7,7 +7,8 @@
     clippy::no_effect,
     clippy::unnecessary_operation,
     clippy::useless_vec,
-    clippy::out_of_bounds_indexing
+    clippy::out_of_bounds_indexing,
+    clippy::needless_lifetimes
 )]
 
 const ARR: [i32; 2] = [1, 2];
diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
index 5ce2ed2ffae..120f5c35cb0 100644
--- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
@@ -1,5 +1,5 @@
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:26:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:27:5
    |
 LL |     x[index];
    |     ^^^^^^^^
@@ -9,7 +9,7 @@ LL |     x[index];
    = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:41:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
    |
 LL |     v[0];
    |     ^^^^
@@ -17,7 +17,7 @@ LL |     v[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
    |
 LL |     v[10];
    |     ^^^^^
@@ -25,7 +25,7 @@ LL |     v[10];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:44:5
    |
 LL |     v[1 << 3];
    |     ^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     v[1 << 3];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:49:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
    |
 LL |     v[N];
    |     ^^^^
@@ -41,7 +41,7 @@ LL |     v[N];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:51:5
    |
 LL |     v[M];
    |     ^^^^
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
index baf939af24e..cdb8fa0454c 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.fixed
@@ -86,6 +86,7 @@ mod issue9612 {
         util();
     }
 
+    #[allow(unconditional_panic)]
     fn util() {
         let _a: u8 = 4.try_into().unwrap();
         let _a: u8 = 5.try_into().expect("");
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
index e300ba18c33..e53d53db5f7 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.rs
@@ -86,6 +86,7 @@ mod issue9612 {
         util();
     }
 
+    #[allow(unconditional_panic)]
     fn util() {
         let _a: u8 = 4.try_into().unwrap();
         let _a: u8 = 5.try_into().expect("");
diff --git a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
index 320578bfabc..b58ce9b8af3 100644
--- a/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
+++ b/src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr
@@ -274,7 +274,7 @@ LL |     let _ = &boxed_slice[1];
    |             ~~~~~~~~~~~~~~~
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui-toml/unwrap_used/unwrap_used.rs:93:17
+  --> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17
    |
 LL |         let _ = Box::new([0]).get(1).unwrap();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/allow_attributes.fixed b/src/tools/clippy/tests/ui/allow_attributes.fixed
index 49ee3ee17c7..058dbb77a32 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.fixed
+++ b/src/tools/clippy/tests/ui/allow_attributes.fixed
@@ -58,3 +58,10 @@ fn msrv_1_80() {
     #[allow(unused)]
     let x = 1;
 }
+
+#[deny(clippy::allow_attributes)]
+fn deny_allow_attributes() -> Option<u8> {
+    let allow = None;
+    allow?;
+    Some(42)
+}
diff --git a/src/tools/clippy/tests/ui/allow_attributes.rs b/src/tools/clippy/tests/ui/allow_attributes.rs
index 854acf8348d..6d94ce50e4c 100644
--- a/src/tools/clippy/tests/ui/allow_attributes.rs
+++ b/src/tools/clippy/tests/ui/allow_attributes.rs
@@ -58,3 +58,10 @@ fn msrv_1_80() {
     #[allow(unused)]
     let x = 1;
 }
+
+#[deny(clippy::allow_attributes)]
+fn deny_allow_attributes() -> Option<u8> {
+    let allow = None;
+    allow?;
+    Some(42)
+}
diff --git a/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs b/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs
index 86f6b2c5742..334e7ddd9d2 100644
--- a/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs
+++ b/src/tools/clippy/tests/ui/allow_attributes_without_reason.rs
@@ -15,7 +15,6 @@ use proc_macros::{external, with_span};
 #[warn(deref_nullptr)]
 #[deny(deref_nullptr)]
 #[forbid(deref_nullptr)]
-
 fn main() {
     external! {
         #[allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr b/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr
index 9bc3ca0f2af..86d7845df04 100644
--- a/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr
+++ b/src/tools/clippy/tests/ui/allow_attributes_without_reason.stderr
@@ -36,7 +36,7 @@ LL | #[expect(dead_code)]
    = help: try adding a reason at the end with `, reason = ".."`
 
 error: `allow` attribute without specifying a reason
-  --> tests/ui/allow_attributes_without_reason.rs:47:5
+  --> tests/ui/allow_attributes_without_reason.rs:46:5
    |
 LL |     #[allow(unused)]
    |     ^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL |     #[allow(unused)]
    = help: try adding a reason at the end with `, reason = ".."`
 
 error: `allow` attribute without specifying a reason
-  --> tests/ui/allow_attributes_without_reason.rs:47:5
+  --> tests/ui/allow_attributes_without_reason.rs:46:5
    |
 LL |     #[allow(unused)]
    |     ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
index 0838d064a5f..3f204073085 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -2,7 +2,6 @@
 
 #![feature(f128)]
 #![feature(f16)]
-
 #![allow(
     clippy::assign_op_pattern,
     clippy::erasing_op,
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index 78914667bf3..78b1aca4b8a 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -1,5 +1,5 @@
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:167:13
+  --> tests/ui/arithmetic_side_effects.rs:166:13
    |
 LL |     let _ = 1f16 + 1f16;
    |             ^^^^^^^^^^^
@@ -8,733 +8,733 @@ LL |     let _ = 1f16 + 1f16;
    = help: to override `-D warnings` add `#[allow(clippy::arithmetic_side_effects)]`
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:170:13
+  --> tests/ui/arithmetic_side_effects.rs:169:13
    |
 LL |     let _ = 1f128 + 1f128;
    |             ^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:308:5
+  --> tests/ui/arithmetic_side_effects.rs:307:5
    |
 LL |     _n += 1;
    |     ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:309:5
+  --> tests/ui/arithmetic_side_effects.rs:308:5
    |
 LL |     _n += &1;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:310:5
+  --> tests/ui/arithmetic_side_effects.rs:309:5
    |
 LL |     _n -= 1;
    |     ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:311:5
+  --> tests/ui/arithmetic_side_effects.rs:310:5
    |
 LL |     _n -= &1;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:312:5
+  --> tests/ui/arithmetic_side_effects.rs:311:5
    |
 LL |     _n /= 0;
    |     ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:313:5
+  --> tests/ui/arithmetic_side_effects.rs:312:5
    |
 LL |     _n /= &0;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:314:5
+  --> tests/ui/arithmetic_side_effects.rs:313:5
    |
 LL |     _n %= 0;
    |     ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:315:5
+  --> tests/ui/arithmetic_side_effects.rs:314:5
    |
 LL |     _n %= &0;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:316:5
+  --> tests/ui/arithmetic_side_effects.rs:315:5
    |
 LL |     _n *= 2;
    |     ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:317:5
+  --> tests/ui/arithmetic_side_effects.rs:316:5
    |
 LL |     _n *= &2;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:318:5
+  --> tests/ui/arithmetic_side_effects.rs:317:5
    |
 LL |     _n += -1;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:319:5
+  --> tests/ui/arithmetic_side_effects.rs:318:5
    |
 LL |     _n += &-1;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:320:5
+  --> tests/ui/arithmetic_side_effects.rs:319:5
    |
 LL |     _n -= -1;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:321:5
+  --> tests/ui/arithmetic_side_effects.rs:320:5
    |
 LL |     _n -= &-1;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:322:5
+  --> tests/ui/arithmetic_side_effects.rs:321:5
    |
 LL |     _n /= -0;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:323:5
+  --> tests/ui/arithmetic_side_effects.rs:322:5
    |
 LL |     _n /= &-0;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:324:5
+  --> tests/ui/arithmetic_side_effects.rs:323:5
    |
 LL |     _n %= -0;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:325:5
+  --> tests/ui/arithmetic_side_effects.rs:324:5
    |
 LL |     _n %= &-0;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:326:5
+  --> tests/ui/arithmetic_side_effects.rs:325:5
    |
 LL |     _n *= -2;
    |     ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:327:5
+  --> tests/ui/arithmetic_side_effects.rs:326:5
    |
 LL |     _n *= &-2;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:328:5
+  --> tests/ui/arithmetic_side_effects.rs:327:5
    |
 LL |     _custom += Custom;
    |     ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:329:5
+  --> tests/ui/arithmetic_side_effects.rs:328:5
    |
 LL |     _custom += &Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:330:5
+  --> tests/ui/arithmetic_side_effects.rs:329:5
    |
 LL |     _custom -= Custom;
    |     ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:331:5
+  --> tests/ui/arithmetic_side_effects.rs:330:5
    |
 LL |     _custom -= &Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:332:5
+  --> tests/ui/arithmetic_side_effects.rs:331:5
    |
 LL |     _custom /= Custom;
    |     ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:333:5
+  --> tests/ui/arithmetic_side_effects.rs:332:5
    |
 LL |     _custom /= &Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:334:5
+  --> tests/ui/arithmetic_side_effects.rs:333:5
    |
 LL |     _custom %= Custom;
    |     ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:335:5
+  --> tests/ui/arithmetic_side_effects.rs:334:5
    |
 LL |     _custom %= &Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:336:5
+  --> tests/ui/arithmetic_side_effects.rs:335:5
    |
 LL |     _custom *= Custom;
    |     ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:337:5
+  --> tests/ui/arithmetic_side_effects.rs:336:5
    |
 LL |     _custom *= &Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:338:5
+  --> tests/ui/arithmetic_side_effects.rs:337:5
    |
 LL |     _custom >>= Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:339:5
+  --> tests/ui/arithmetic_side_effects.rs:338:5
    |
 LL |     _custom >>= &Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:340:5
+  --> tests/ui/arithmetic_side_effects.rs:339:5
    |
 LL |     _custom <<= Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:341:5
+  --> tests/ui/arithmetic_side_effects.rs:340:5
    |
 LL |     _custom <<= &Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:342:5
+  --> tests/ui/arithmetic_side_effects.rs:341:5
    |
 LL |     _custom += -Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:343:5
+  --> tests/ui/arithmetic_side_effects.rs:342:5
    |
 LL |     _custom += &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:344:5
+  --> tests/ui/arithmetic_side_effects.rs:343:5
    |
 LL |     _custom -= -Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:345:5
+  --> tests/ui/arithmetic_side_effects.rs:344:5
    |
 LL |     _custom -= &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:346:5
+  --> tests/ui/arithmetic_side_effects.rs:345:5
    |
 LL |     _custom /= -Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:347:5
+  --> tests/ui/arithmetic_side_effects.rs:346:5
    |
 LL |     _custom /= &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:348:5
+  --> tests/ui/arithmetic_side_effects.rs:347:5
    |
 LL |     _custom %= -Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:349:5
+  --> tests/ui/arithmetic_side_effects.rs:348:5
    |
 LL |     _custom %= &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:350:5
+  --> tests/ui/arithmetic_side_effects.rs:349:5
    |
 LL |     _custom *= -Custom;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:351:5
+  --> tests/ui/arithmetic_side_effects.rs:350:5
    |
 LL |     _custom *= &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:352:5
+  --> tests/ui/arithmetic_side_effects.rs:351:5
    |
 LL |     _custom >>= -Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:353:5
+  --> tests/ui/arithmetic_side_effects.rs:352:5
    |
 LL |     _custom >>= &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:354:5
+  --> tests/ui/arithmetic_side_effects.rs:353:5
    |
 LL |     _custom <<= -Custom;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:355:5
+  --> tests/ui/arithmetic_side_effects.rs:354:5
    |
 LL |     _custom <<= &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:358:10
+  --> tests/ui/arithmetic_side_effects.rs:357:10
    |
 LL |     _n = _n + 1;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:359:10
+  --> tests/ui/arithmetic_side_effects.rs:358:10
    |
 LL |     _n = _n + &1;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:360:10
+  --> tests/ui/arithmetic_side_effects.rs:359:10
    |
 LL |     _n = 1 + _n;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:361:10
+  --> tests/ui/arithmetic_side_effects.rs:360:10
    |
 LL |     _n = &1 + _n;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:362:10
+  --> tests/ui/arithmetic_side_effects.rs:361:10
    |
 LL |     _n = _n - 1;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:363:10
+  --> tests/ui/arithmetic_side_effects.rs:362:10
    |
 LL |     _n = _n - &1;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:364:10
+  --> tests/ui/arithmetic_side_effects.rs:363:10
    |
 LL |     _n = 1 - _n;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:365:10
+  --> tests/ui/arithmetic_side_effects.rs:364:10
    |
 LL |     _n = &1 - _n;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:366:10
+  --> tests/ui/arithmetic_side_effects.rs:365:10
    |
 LL |     _n = _n / 0;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:367:10
+  --> tests/ui/arithmetic_side_effects.rs:366:10
    |
 LL |     _n = _n / &0;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:368:10
+  --> tests/ui/arithmetic_side_effects.rs:367:10
    |
 LL |     _n = _n % 0;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:369:10
+  --> tests/ui/arithmetic_side_effects.rs:368:10
    |
 LL |     _n = _n % &0;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:370:10
+  --> tests/ui/arithmetic_side_effects.rs:369:10
    |
 LL |     _n = _n * 2;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:371:10
+  --> tests/ui/arithmetic_side_effects.rs:370:10
    |
 LL |     _n = _n * &2;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:372:10
+  --> tests/ui/arithmetic_side_effects.rs:371:10
    |
 LL |     _n = 2 * _n;
    |          ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:373:10
+  --> tests/ui/arithmetic_side_effects.rs:372:10
    |
 LL |     _n = &2 * _n;
    |          ^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:374:10
+  --> tests/ui/arithmetic_side_effects.rs:373:10
    |
 LL |     _n = 23 + &85;
    |          ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:375:10
+  --> tests/ui/arithmetic_side_effects.rs:374:10
    |
 LL |     _n = &23 + 85;
    |          ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:376:10
+  --> tests/ui/arithmetic_side_effects.rs:375:10
    |
 LL |     _n = &23 + &85;
    |          ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:377:15
+  --> tests/ui/arithmetic_side_effects.rs:376:15
    |
 LL |     _custom = _custom + _custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:378:15
+  --> tests/ui/arithmetic_side_effects.rs:377:15
    |
 LL |     _custom = _custom + &_custom;
    |               ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:379:15
+  --> tests/ui/arithmetic_side_effects.rs:378:15
    |
 LL |     _custom = Custom + _custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:380:15
+  --> tests/ui/arithmetic_side_effects.rs:379:15
    |
 LL |     _custom = &Custom + _custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:381:15
+  --> tests/ui/arithmetic_side_effects.rs:380:15
    |
 LL |     _custom = _custom - Custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:382:15
+  --> tests/ui/arithmetic_side_effects.rs:381:15
    |
 LL |     _custom = _custom - &Custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:383:15
+  --> tests/ui/arithmetic_side_effects.rs:382:15
    |
 LL |     _custom = Custom - _custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:384:15
+  --> tests/ui/arithmetic_side_effects.rs:383:15
    |
 LL |     _custom = &Custom - _custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:385:15
+  --> tests/ui/arithmetic_side_effects.rs:384:15
    |
 LL |     _custom = _custom / Custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:386:15
+  --> tests/ui/arithmetic_side_effects.rs:385:15
    |
 LL |     _custom = _custom / &Custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:387:15
+  --> tests/ui/arithmetic_side_effects.rs:386:15
    |
 LL |     _custom = _custom % Custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:388:15
+  --> tests/ui/arithmetic_side_effects.rs:387:15
    |
 LL |     _custom = _custom % &Custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:389:15
+  --> tests/ui/arithmetic_side_effects.rs:388:15
    |
 LL |     _custom = _custom * Custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:390:15
+  --> tests/ui/arithmetic_side_effects.rs:389:15
    |
 LL |     _custom = _custom * &Custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:391:15
+  --> tests/ui/arithmetic_side_effects.rs:390:15
    |
 LL |     _custom = Custom * _custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:392:15
+  --> tests/ui/arithmetic_side_effects.rs:391:15
    |
 LL |     _custom = &Custom * _custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:393:15
+  --> tests/ui/arithmetic_side_effects.rs:392:15
    |
 LL |     _custom = Custom + &Custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:394:15
+  --> tests/ui/arithmetic_side_effects.rs:393:15
    |
 LL |     _custom = &Custom + Custom;
    |               ^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:395:15
+  --> tests/ui/arithmetic_side_effects.rs:394:15
    |
 LL |     _custom = &Custom + &Custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:396:15
+  --> tests/ui/arithmetic_side_effects.rs:395:15
    |
 LL |     _custom = _custom >> _custom;
    |               ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:397:15
+  --> tests/ui/arithmetic_side_effects.rs:396:15
    |
 LL |     _custom = _custom >> &_custom;
    |               ^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:398:15
+  --> tests/ui/arithmetic_side_effects.rs:397:15
    |
 LL |     _custom = Custom << _custom;
    |               ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:399:15
+  --> tests/ui/arithmetic_side_effects.rs:398:15
    |
 LL |     _custom = &Custom << _custom;
    |               ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:402:23
+  --> tests/ui/arithmetic_side_effects.rs:401:23
    |
 LL |     _n.saturating_div(0);
    |                       ^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:403:21
+  --> tests/ui/arithmetic_side_effects.rs:402:21
    |
 LL |     _n.wrapping_div(0);
    |                     ^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:404:21
+  --> tests/ui/arithmetic_side_effects.rs:403:21
    |
 LL |     _n.wrapping_rem(0);
    |                     ^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:405:28
+  --> tests/ui/arithmetic_side_effects.rs:404:28
    |
 LL |     _n.wrapping_rem_euclid(0);
    |                            ^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:407:23
+  --> tests/ui/arithmetic_side_effects.rs:406:23
    |
 LL |     _n.saturating_div(_n);
    |                       ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:408:21
+  --> tests/ui/arithmetic_side_effects.rs:407:21
    |
 LL |     _n.wrapping_div(_n);
    |                     ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:409:21
+  --> tests/ui/arithmetic_side_effects.rs:408:21
    |
 LL |     _n.wrapping_rem(_n);
    |                     ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:410:28
+  --> tests/ui/arithmetic_side_effects.rs:409:28
    |
 LL |     _n.wrapping_rem_euclid(_n);
    |                            ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:413:10
+  --> tests/ui/arithmetic_side_effects.rs:412:10
    |
 LL |     _n = -_n;
    |          ^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:414:10
+  --> tests/ui/arithmetic_side_effects.rs:413:10
    |
 LL |     _n = -&_n;
    |          ^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:415:15
+  --> tests/ui/arithmetic_side_effects.rs:414:15
    |
 LL |     _custom = -_custom;
    |               ^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:416:15
+  --> tests/ui/arithmetic_side_effects.rs:415:15
    |
 LL |     _custom = -&_custom;
    |               ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:425:5
+  --> tests/ui/arithmetic_side_effects.rs:424:5
    |
 LL |     1 + i;
    |     ^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:426:5
+  --> tests/ui/arithmetic_side_effects.rs:425:5
    |
 LL |     i * 2;
    |     ^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:427:5
+  --> tests/ui/arithmetic_side_effects.rs:426:5
    |
 LL |     1 % i / 2;
    |     ^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:428:5
+  --> tests/ui/arithmetic_side_effects.rs:427:5
    |
 LL |     i - 2 + 2 - i;
    |     ^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:429:5
+  --> tests/ui/arithmetic_side_effects.rs:428:5
    |
 LL |     -i;
    |     ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:440:5
+  --> tests/ui/arithmetic_side_effects.rs:439:5
    |
 LL |     i += 1;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:441:5
+  --> tests/ui/arithmetic_side_effects.rs:440:5
    |
 LL |     i -= 1;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:442:5
+  --> tests/ui/arithmetic_side_effects.rs:441:5
    |
 LL |     i *= 2;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:444:5
+  --> tests/ui/arithmetic_side_effects.rs:443:5
    |
 LL |     i /= 0;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:446:5
+  --> tests/ui/arithmetic_side_effects.rs:445:5
    |
 LL |     i /= var1;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:447:5
+  --> tests/ui/arithmetic_side_effects.rs:446:5
    |
 LL |     i /= var2;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:449:5
+  --> tests/ui/arithmetic_side_effects.rs:448:5
    |
 LL |     i %= 0;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:451:5
+  --> tests/ui/arithmetic_side_effects.rs:450:5
    |
 LL |     i %= var1;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:452:5
+  --> tests/ui/arithmetic_side_effects.rs:451:5
    |
 LL |     i %= var2;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:462:5
+  --> tests/ui/arithmetic_side_effects.rs:461:5
    |
 LL |     10 / a
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:516:9
+  --> tests/ui/arithmetic_side_effects.rs:515:9
    |
 LL |         x / maybe_zero
    |         ^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:520:9
+  --> tests/ui/arithmetic_side_effects.rs:519:9
    |
 LL |         x % maybe_zero
    |         ^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:531:5
+  --> tests/ui/arithmetic_side_effects.rs:530:5
    |
 LL |     one.add_assign(1);
    |     ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:535:5
+  --> tests/ui/arithmetic_side_effects.rs:534:5
    |
 LL |     one.sub_assign(1);
    |     ^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs b/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
index 297a53b1bbf..9e862320f4e 100644
--- a/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
+++ b/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
@@ -1,7 +1,7 @@
 #![allow(unused)]
 #![warn(clippy::as_ptr_cast_mut)]
 #![allow(clippy::wrong_self_convention, clippy::unnecessary_cast)]
-//@no-rustfix
+//@no-rustfix: incorrect suggestion
 
 struct MutPtrWrapper(Vec<u8>);
 impl MutPtrWrapper {
diff --git a/src/tools/clippy/tests/ui/asm_syntax_not_x86.rs b/src/tools/clippy/tests/ui/asm_syntax_not_x86.rs
index 33cea480681..a7d29cc239e 100644
--- a/src/tools/clippy/tests/ui/asm_syntax_not_x86.rs
+++ b/src/tools/clippy/tests/ui/asm_syntax_not_x86.rs
@@ -1,5 +1,4 @@
-//@ignore-target-i686
-//@ignore-target-x86
+//@ignore-target: i686 x86
 //@needs-asm-support
 
 #[warn(clippy::inline_asm_x86_intel_syntax)]
diff --git a/src/tools/clippy/tests/ui/asm_syntax_x86.rs b/src/tools/clippy/tests/ui/asm_syntax_x86.rs
index 835943b4389..5ceaceb7527 100644
--- a/src/tools/clippy/tests/ui/asm_syntax_x86.rs
+++ b/src/tools/clippy/tests/ui/asm_syntax_x86.rs
@@ -1,6 +1,4 @@
-//@revisions: i686 x86_64
-//@[i686] only-target-i686
-//@[x86_64] only-target-x86_64
+//@only-target: i686 x86_64
 
 #[warn(clippy::inline_asm_x86_intel_syntax)]
 mod warn_intel {
diff --git a/src/tools/clippy/tests/ui/asm_syntax_x86.stderr b/src/tools/clippy/tests/ui/asm_syntax_x86.stderr
new file mode 100644
index 00000000000..1911ef66e23
--- /dev/null
+++ b/src/tools/clippy/tests/ui/asm_syntax_x86.stderr
@@ -0,0 +1,70 @@
+error: Intel x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:8:9
+   |
+LL |         asm!("");
+   |         ^^^^^^^^
+   |
+   = help: use AT&T x86 assembly syntax
+   = note: `-D clippy::inline-asm-x86-intel-syntax` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_intel_syntax)]`
+
+error: Intel x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:10:9
+   |
+LL |         asm!("", options());
+   |         ^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use AT&T x86 assembly syntax
+
+error: Intel x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:12:9
+   |
+LL |         asm!("", options(nostack));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use AT&T x86 assembly syntax
+
+error: Intel x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:18:5
+   |
+LL |     global_asm!("");
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: use AT&T x86 assembly syntax
+
+error: Intel x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:20:5
+   |
+LL |     global_asm!("", options());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use AT&T x86 assembly syntax
+
+error: AT&T x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:33:9
+   |
+LL |         asm!("", options(att_syntax));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use Intel x86 assembly syntax
+   = note: `-D clippy::inline-asm-x86-att-syntax` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::inline_asm_x86_att_syntax)]`
+
+error: AT&T x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:35:9
+   |
+LL |         asm!("", options(nostack, att_syntax));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use Intel x86 assembly syntax
+
+error: AT&T x86 assembly syntax used
+  --> tests/ui/asm_syntax_x86.rs:41:5
+   |
+LL |     global_asm!("", options(att_syntax));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use Intel x86 assembly syntax
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/auxiliary/external_item.rs b/src/tools/clippy/tests/ui/auxiliary/external_item.rs
new file mode 100644
index 00000000000..ca4bc369e44
--- /dev/null
+++ b/src/tools/clippy/tests/ui/auxiliary/external_item.rs
@@ -0,0 +1,7 @@
+pub struct _ExternalStruct {}
+
+impl _ExternalStruct {
+    pub fn _foo(self) {}
+}
+
+pub fn _exernal_foo() {}
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs
index f6fdebaf252..e72d6b6cead 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_attr.rs
@@ -11,8 +11,8 @@ use quote::{quote, quote_spanned};
 use syn::spanned::Spanned;
 use syn::token::Star;
 use syn::{
-    parse_macro_input, parse_quote, FnArg, ImplItem, ItemFn, ItemImpl, ItemStruct, ItemTrait, Lifetime, Pat, PatIdent,
-    PatType, Signature, TraitItem, Type, Visibility,
+    FnArg, ImplItem, ItemFn, ItemImpl, ItemStruct, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature, TraitItem,
+    Type, Visibility, parse_macro_input, parse_quote,
 };
 
 #[proc_macro_attribute]
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 4c3df472269..bd90042c1da 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
@@ -5,7 +5,7 @@
 
 extern crate proc_macro;
 
-use proc_macro::{quote, Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
+use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree, quote};
 
 #[proc_macro_derive(DeriveSomething)]
 pub fn derive(_: TokenStream) -> TokenStream {
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs
index 79e8eff3aa1..3d6f164d358 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_suspicious_else_formatting.rs
@@ -1,5 +1,5 @@
 extern crate proc_macro;
-use proc_macro::{token_stream, Delimiter, Group, Ident, Span, TokenStream, TokenTree};
+use proc_macro::{Delimiter, Group, Ident, Span, TokenStream, TokenTree, token_stream};
 
 fn read_ident(iter: &mut token_stream::IntoIter) -> Ident {
     match iter.next() {
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs
index ed7412f7c40..1a2a4ec2311 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macros.rs
@@ -5,9 +5,9 @@
 extern crate proc_macro;
 
 use core::mem;
-use proc_macro::token_stream::IntoIter;
 use proc_macro::Delimiter::{self, Brace, Parenthesis};
 use proc_macro::Spacing::{self, Alone, Joint};
+use proc_macro::token_stream::IntoIter;
 use proc_macro::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree as TT};
 use syn::spanned::Spanned;
 
diff --git a/src/tools/clippy/tests/ui/borrow_box.fixed b/src/tools/clippy/tests/ui/borrow_box.fixed
new file mode 100644
index 00000000000..08ea60583ea
--- /dev/null
+++ b/src/tools/clippy/tests/ui/borrow_box.fixed
@@ -0,0 +1,133 @@
+#![deny(clippy::borrowed_box)]
+#![allow(dead_code, unused_variables)]
+#![allow(
+    clippy::uninlined_format_args,
+    clippy::disallowed_names,
+    clippy::needless_pass_by_ref_mut,
+    clippy::needless_lifetimes
+)]
+
+use std::fmt::Display;
+
+pub fn test1(foo: &mut Box<bool>) {
+    // Although this function could be changed to "&mut bool",
+    // avoiding the Box, mutable references to boxes are not
+    // flagged by this lint.
+    //
+    // This omission is intentional: By passing a mutable Box,
+    // the memory location of the pointed-to object could be
+    // modified. By passing a mutable reference, the contents
+    // could change, but not the location.
+    println!("{:?}", foo)
+}
+
+pub fn test2() {
+    let foo: &bool;
+    //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+}
+
+struct Test3<'a> {
+    foo: &'a bool,
+    //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+}
+
+trait Test4 {
+    fn test4(a: &bool);
+    //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+}
+
+use std::any::Any;
+
+pub fn test5(foo: &mut Box<dyn Any>) {
+    println!("{:?}", foo)
+}
+
+pub fn test6() {
+    let foo: &Box<dyn Any>;
+}
+
+struct Test7<'a> {
+    foo: &'a Box<dyn Any>,
+}
+
+trait Test8 {
+    fn test8(a: &Box<dyn Any>);
+}
+
+impl<'a> Test8 for Test7<'a> {
+    fn test8(a: &Box<dyn Any>) {
+        unimplemented!();
+    }
+}
+
+pub fn test9(foo: &mut Box<dyn Any + Send + Sync>) {
+    let _ = foo;
+}
+
+pub fn test10() {
+    let foo: &Box<dyn Any + Send + 'static>;
+}
+
+struct Test11<'a> {
+    foo: &'a Box<dyn Any + Send>,
+}
+
+trait Test12 {
+    fn test4(a: &Box<dyn Any + 'static>);
+}
+
+impl<'a> Test12 for Test11<'a> {
+    fn test4(a: &Box<dyn Any + 'static>) {
+        unimplemented!();
+    }
+}
+
+pub fn test13(boxed_slice: &mut Box<[i32]>) {
+    // Unconditionally replaces the box pointer.
+    //
+    // This cannot be accomplished if "&mut [i32]" is passed,
+    // and provides a test case where passing a reference to
+    // a Box is valid.
+    let mut data = vec![12];
+    *boxed_slice = data.into_boxed_slice();
+}
+
+// The suggestion should include proper parentheses to avoid a syntax error.
+pub fn test14(_display: &dyn Display) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test15(_display: &(dyn Display + Send)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test16<'a>(_display: &'a (dyn Display + 'a)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+
+pub fn test17(_display: &impl Display) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test18(_display: &(impl Display + Send)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test19<'a>(_display: &'a (impl Display + 'a)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+
+// This exists only to check what happens when parentheses are already present.
+// Even though the current implementation doesn't put extra parentheses,
+// it's fine that unnecessary parentheses appear in the future for some reason.
+pub fn test20(_display: &(dyn Display + Send)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+
+#[allow(clippy::borrowed_box)]
+trait Trait {
+    fn f(b: &Box<bool>);
+}
+
+// Trait impls are not linted
+impl Trait for () {
+    fn f(_: &Box<bool>) {}
+}
+
+fn main() {
+    test1(&mut Box::new(false));
+    test2();
+    test5(&mut (Box::new(false) as Box<dyn Any>));
+    test6();
+    test9(&mut (Box::new(false) as Box<dyn Any + Send + Sync>));
+    test10();
+}
diff --git a/src/tools/clippy/tests/ui/borrow_box.rs b/src/tools/clippy/tests/ui/borrow_box.rs
index e9994aac845..b55de1701da 100644
--- a/src/tools/clippy/tests/ui/borrow_box.rs
+++ b/src/tools/clippy/tests/ui/borrow_box.rs
@@ -3,9 +3,9 @@
 #![allow(
     clippy::uninlined_format_args,
     clippy::disallowed_names,
-    clippy::needless_pass_by_ref_mut
+    clippy::needless_pass_by_ref_mut,
+    clippy::needless_lifetimes
 )]
-//@no-rustfix
 
 use std::fmt::Display;
 
@@ -36,12 +36,6 @@ trait Test4 {
     //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
 }
 
-impl<'a> Test4 for Test3<'a> {
-    fn test4(a: &Box<bool>) {
-        unimplemented!();
-    }
-}
-
 use std::any::Any;
 
 pub fn test5(foo: &mut Box<dyn Any>) {
@@ -119,6 +113,16 @@ pub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}
 pub fn test20(_display: &Box<(dyn Display + Send)>) {}
 //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
 
+#[allow(clippy::borrowed_box)]
+trait Trait {
+    fn f(b: &Box<bool>);
+}
+
+// Trait impls are not linted
+impl Trait for () {
+    fn f(_: &Box<bool>) {}
+}
+
 fn main() {
     test1(&mut Box::new(false));
     test2();
diff --git a/src/tools/clippy/tests/ui/borrow_box.stderr b/src/tools/clippy/tests/ui/borrow_box.stderr
index 34e8f11dfd7..6f80f86c3b3 100644
--- a/src/tools/clippy/tests/ui/borrow_box.stderr
+++ b/src/tools/clippy/tests/ui/borrow_box.stderr
@@ -23,43 +23,43 @@ LL |     fn test4(a: &Box<bool>);
    |                 ^^^^^^^^^^ help: try: `&bool`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:102:25
+  --> tests/ui/borrow_box.rs:96:25
    |
 LL | pub fn test14(_display: &Box<dyn Display>) {}
    |                         ^^^^^^^^^^^^^^^^^ help: try: `&dyn Display`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:104:25
+  --> tests/ui/borrow_box.rs:98:25
    |
 LL | pub fn test15(_display: &Box<dyn Display + Send>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:106:29
+  --> tests/ui/borrow_box.rs:100:29
    |
 LL | pub fn test16<'a>(_display: &'a Box<dyn Display + 'a>) {}
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (dyn Display + 'a)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:109:25
+  --> tests/ui/borrow_box.rs:103:25
    |
 LL | pub fn test17(_display: &Box<impl Display>) {}
    |                         ^^^^^^^^^^^^^^^^^^ help: try: `&impl Display`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:111:25
+  --> tests/ui/borrow_box.rs:105:25
    |
 LL | pub fn test18(_display: &Box<impl Display + Send>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(impl Display + Send)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:113:29
+  --> tests/ui/borrow_box.rs:107:29
    |
 LL | pub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (impl Display + 'a)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:119:25
+  --> tests/ui/borrow_box.rs:113:25
    |
 LL | pub fn test20(_display: &Box<(dyn Display + Send)>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`
diff --git a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs
index 452d1b19813..de220505c3e 100644
--- a/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs
+++ b/src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs
@@ -5,8 +5,8 @@
 use std::borrow::Cow;
 use std::cell::{Cell, UnsafeCell};
 use std::fmt::Display;
-use std::sync::atomic::{AtomicUsize, Ordering};
 use std::sync::Once;
+use std::sync::atomic::{AtomicUsize, Ordering};
 
 const ATOMIC: AtomicUsize = AtomicUsize::new(5);
 const CELL: Cell<usize> = Cell::new(6);
diff --git a/src/tools/clippy/tests/ui/boxed_local.rs b/src/tools/clippy/tests/ui/boxed_local.rs
index fbd9e12fc18..e2c27e585fc 100644
--- a/src/tools/clippy/tests/ui/boxed_local.rs
+++ b/src/tools/clippy/tests/ui/boxed_local.rs
@@ -3,7 +3,8 @@
     clippy::needless_pass_by_value,
     clippy::unused_unit,
     clippy::redundant_clone,
-    clippy::match_single_binding
+    clippy::match_single_binding,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::boxed_local)]
 
diff --git a/src/tools/clippy/tests/ui/boxed_local.stderr b/src/tools/clippy/tests/ui/boxed_local.stderr
index 7710233fa4d..d3156c820b2 100644
--- a/src/tools/clippy/tests/ui/boxed_local.stderr
+++ b/src/tools/clippy/tests/ui/boxed_local.stderr
@@ -1,5 +1,5 @@
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:39:13
+  --> tests/ui/boxed_local.rs:40:13
    |
 LL | fn warn_arg(x: Box<A>) {
    |             ^
@@ -8,19 +8,19 @@ LL | fn warn_arg(x: Box<A>) {
    = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:122:12
+  --> tests/ui/boxed_local.rs:123:12
    |
 LL | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
    |            ^^^^^^^^^^^
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:187:44
+  --> tests/ui/boxed_local.rs:188:44
    |
 LL |         fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {
    |                                            ^
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:195:16
+  --> tests/ui/boxed_local.rs:196:16
    |
 LL |         fn foo(x: Box<u32>) {}
    |                ^
diff --git a/src/tools/clippy/tests/ui/bytecount.rs b/src/tools/clippy/tests/ui/bytecount.rs
index 3794fc5d441..f3b02fda8a8 100644
--- a/src/tools/clippy/tests/ui/bytecount.rs
+++ b/src/tools/clippy/tests/ui/bytecount.rs
@@ -1,4 +1,4 @@
-//@no-rustfix
+//@no-rustfix: suggests external crate
 
 #![allow(clippy::needless_borrow, clippy::useless_vec)]
 
diff --git a/src/tools/clippy/tests/ui/cast_alignment.rs b/src/tools/clippy/tests/ui/cast_alignment.rs
index 98ef5e36f94..72f5d4268cc 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.rs
+++ b/src/tools/clippy/tests/ui/cast_alignment.rs
@@ -2,16 +2,16 @@
 
 #![feature(rustc_private)]
 #![feature(core_intrinsics)]
-extern crate libc;
-
-#[warn(clippy::cast_ptr_alignment)]
-#[allow(
+#![warn(clippy::cast_ptr_alignment)]
+#![allow(
     clippy::no_effect,
     clippy::unnecessary_operation,
     clippy::cast_lossless,
     clippy::borrow_as_ptr
 )]
 
+extern crate libc;
+
 fn main() {
     /* These should be warned against */
 
diff --git a/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs b/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs
index ec45d635c17..913aab72747 100644
--- a/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs
+++ b/src/tools/clippy/tests/ui/cmp_owned/without_suggestion.rs
@@ -1,5 +1,5 @@
-#[allow(clippy::unnecessary_operation)]
-#[allow(clippy::implicit_clone)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::implicit_clone)]
 
 fn main() {
     let x = &Baz;
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.fixed b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
index 3b410b2f17b..c2d76146c64 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
@@ -1,9 +1,7 @@
 #![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)]
+#![warn(clippy::collapsible_if, clippy::collapsible_else_if)]
 
 #[rustfmt::skip]
-#[warn(clippy::collapsible_if)]
-#[warn(clippy::collapsible_else_if)]
-
 fn main() {
     let x = "hello";
     let y = "world";
@@ -76,7 +74,6 @@ fn main() {
 }
 
 #[rustfmt::skip]
-#[allow(dead_code)]
 fn issue_7318() {
     if true { println!("I've been resolved!")
     }else if false {}
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.rs b/src/tools/clippy/tests/ui/collapsible_else_if.rs
index 772ef6f9fc6..3579e46cd44 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.rs
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.rs
@@ -1,9 +1,7 @@
 #![allow(clippy::assertions_on_constants, clippy::equatable_if_let, clippy::needless_if)]
+#![warn(clippy::collapsible_if, clippy::collapsible_else_if)]
 
 #[rustfmt::skip]
-#[warn(clippy::collapsible_if)]
-#[warn(clippy::collapsible_else_if)]
-
 fn main() {
     let x = "hello";
     let y = "world";
@@ -90,7 +88,6 @@ fn main() {
 }
 
 #[rustfmt::skip]
-#[allow(dead_code)]
 fn issue_7318() {
     if true { println!("I've been resolved!")
     }else{
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.stderr b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
index dc19d90b4d1..395c2dcf68d 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
@@ -1,5 +1,5 @@
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:13:12
+  --> tests/ui/collapsible_else_if.rs:11:12
    |
 LL |       } else {
    |  ____________^
@@ -19,7 +19,7 @@ LL +     }
    |
 
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:21:12
+  --> tests/ui/collapsible_else_if.rs:19:12
    |
 LL |       } else {
    |  ____________^
@@ -37,7 +37,7 @@ LL +     }
    |
 
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:29:12
+  --> tests/ui/collapsible_else_if.rs:27:12
    |
 LL |       } else {
    |  ____________^
@@ -60,7 +60,7 @@ LL +     }
    |
 
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:40:12
+  --> tests/ui/collapsible_else_if.rs:38:12
    |
 LL |       } else {
    |  ____________^
@@ -83,7 +83,7 @@ LL +     }
    |
 
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:51:12
+  --> tests/ui/collapsible_else_if.rs:49:12
    |
 LL |       } else {
    |  ____________^
@@ -106,7 +106,7 @@ LL +     }
    |
 
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:62:12
+  --> tests/ui/collapsible_else_if.rs:60:12
    |
 LL |       } else {
    |  ____________^
@@ -129,7 +129,7 @@ LL +     }
    |
 
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:73:12
+  --> tests/ui/collapsible_else_if.rs:71:12
    |
 LL |       } else {
    |  ____________^
@@ -152,7 +152,7 @@ LL +     }
    |
 
 error: this `else { if .. }` block can be collapsed
-  --> tests/ui/collapsible_else_if.rs:96:10
+  --> tests/ui/collapsible_else_if.rs:93:10
    |
 LL |       }else{
    |  __________^
diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.fixed b/src/tools/clippy/tests/ui/comparison_to_empty.fixed
index e102b13a761..a2a3dd9086d 100644
--- a/src/tools/clippy/tests/ui/comparison_to_empty.fixed
+++ b/src/tools/clippy/tests/ui/comparison_to_empty.fixed
@@ -33,4 +33,12 @@ fn main() {
     if let [0] = &*s
         && s == [0]
     {}
+
+    // Also lint the `PartialEq` methods
+    let s = String::new();
+    let _ = s.is_empty();
+    let _ = !s.is_empty();
+    let v = vec![0];
+    let _ = v.is_empty();
+    let _ = !v.is_empty();
 }
diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.rs b/src/tools/clippy/tests/ui/comparison_to_empty.rs
index 69a6c967d38..7c5689a4bbe 100644
--- a/src/tools/clippy/tests/ui/comparison_to_empty.rs
+++ b/src/tools/clippy/tests/ui/comparison_to_empty.rs
@@ -33,4 +33,12 @@ fn main() {
     if let [0] = &*s
         && s == [0]
     {}
+
+    // Also lint the `PartialEq` methods
+    let s = String::new();
+    let _ = s.eq("");
+    let _ = s.ne("");
+    let v = vec![0];
+    let _ = v.eq(&[]);
+    let _ = v.ne(&[]);
 }
diff --git a/src/tools/clippy/tests/ui/comparison_to_empty.stderr b/src/tools/clippy/tests/ui/comparison_to_empty.stderr
index 6b027459ed3..2ee0efc7dbb 100644
--- a/src/tools/clippy/tests/ui/comparison_to_empty.stderr
+++ b/src/tools/clippy/tests/ui/comparison_to_empty.stderr
@@ -55,5 +55,29 @@ error: comparison to empty slice
 LL |         && s == []
    |            ^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
 
-error: aborting due to 9 previous errors
+error: comparison to empty slice
+  --> tests/ui/comparison_to_empty.rs:39:13
+   |
+LL |     let _ = s.eq("");
+   |             ^^^^^^^^ help: using `is_empty` is clearer and more explicit: `s.is_empty()`
+
+error: comparison to empty slice
+  --> tests/ui/comparison_to_empty.rs:40:13
+   |
+LL |     let _ = s.ne("");
+   |             ^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!s.is_empty()`
+
+error: comparison to empty slice
+  --> tests/ui/comparison_to_empty.rs:42:13
+   |
+LL |     let _ = v.eq(&[]);
+   |             ^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `v.is_empty()`
+
+error: comparison to empty slice
+  --> tests/ui/comparison_to_empty.rs:43:13
+   |
+LL |     let _ = v.ne(&[]);
+   |             ^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!v.is_empty()`
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/associated-constant-ice.rs b/src/tools/clippy/tests/ui/crashes/associated-constant-ice.rs
index 948deba3ea6..fec16671eeb 100644
--- a/src/tools/clippy/tests/ui/crashes/associated-constant-ice.rs
+++ b/src/tools/clippy/tests/ui/crashes/associated-constant-ice.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/1698
+// Test for https://github.com/rust-lang/rust-clippy/issues/1698
 
 pub trait Trait {
     const CONSTANT: u8;
diff --git a/src/tools/clippy/tests/ui/crashes/cc_seme.rs b/src/tools/clippy/tests/ui/crashes/cc_seme.rs
index 98588be9cf8..98897d6d7aa 100644
--- a/src/tools/clippy/tests/ui/crashes/cc_seme.rs
+++ b/src/tools/clippy/tests/ui/crashes/cc_seme.rs
@@ -1,6 +1,4 @@
-#[allow(dead_code)]
-
-/// Test for https://github.com/rust-lang/rust-clippy/issues/478
+// Test for https://github.com/rust-lang/rust-clippy/issues/478
 
 enum Baz {
     One,
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11230.rs b/src/tools/clippy/tests/ui/crashes/ice-11230.rs
index 5761882273e..94044e9435e 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-11230.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-11230.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/11230
+// Test for https://github.com/rust-lang/rust-clippy/issues/11230
 
 fn main() {
     const A: &[for<'a> fn(&'a ())] = &[];
diff --git a/src/tools/clippy/tests/ui/crashes/ice-1588.rs b/src/tools/clippy/tests/ui/crashes/ice-1588.rs
index b0a3d11bce4..9ec093721c1 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-1588.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-1588.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::all)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/1588
+// Test for https://github.com/rust-lang/rust-clippy/issues/1588
 
 fn main() {
     match 1 {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-1969.rs b/src/tools/clippy/tests/ui/crashes/ice-1969.rs
index 96a8fe6c24d..eb901c76729 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-1969.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-1969.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::all)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/1969
+// Test for https://github.com/rust-lang/rust-clippy/issues/1969
 
 fn main() {}
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2499.rs b/src/tools/clippy/tests/ui/crashes/ice-2499.rs
index 45b3b1869dd..732f331ad14 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2499.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2499.rs
@@ -1,8 +1,8 @@
 #![allow(dead_code, clippy::char_lit_as_u8, clippy::needless_bool)]
 
-/// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
-///
-/// Issue: https://github.com/rust-lang/rust-clippy/issues/2499
+// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
+//
+// Issue: https://github.com/rust-lang/rust-clippy/issues/2499
 
 fn f(s: &[u8]) -> bool {
     let t = s[0] as char;
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2594.rs b/src/tools/clippy/tests/ui/crashes/ice-2594.rs
index 3f3986b6fc6..dddf860bd17 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2594.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2594.rs
@@ -3,7 +3,6 @@
 /// Should not trigger an ICE in `SpanlessHash` / `consts::constant`
 ///
 /// Issue: https://github.com/rust-lang/rust-clippy/issues/2594
-
 fn spanless_hash_ice() {
     let txt = "something";
     let empty_header: [u8; 1] = [1; 1];
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2727.rs b/src/tools/clippy/tests/ui/crashes/ice-2727.rs
index 56024abc8f5..59fb9b04b86 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2727.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2727.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/2727
+// Test for https://github.com/rust-lang/rust-clippy/issues/2727
 
 pub fn f(new: fn()) {
     new();
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2760.rs b/src/tools/clippy/tests/ui/crashes/ice-2760.rs
index 61ef2480498..5f7d91abf99 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2760.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2760.rs
@@ -5,10 +5,10 @@
     dead_code
 )]
 
-/// This should not compile-fail with:
-///
-///      error[E0277]: the trait bound `T: Foo` is not satisfied
-// See rust-lang/rust-clippy#2760.
+// This should not compile-fail with:
+//
+//      error[E0277]: the trait bound `T: Foo` is not satisfied
+// See https://github.com/rust-lang/rust-clippy/issues/2760
 
 trait Foo {
     type Bar;
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2862.rs b/src/tools/clippy/tests/ui/crashes/ice-2862.rs
index 8326e3663b0..2573b571f55 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2862.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2862.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/2862
+// Test for https://github.com/rust-lang/rust-clippy/issues/2862
 
 pub trait FooMap {
     fn map<B, F: Fn() -> B>(&self, f: F) -> B;
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2865.rs b/src/tools/clippy/tests/ui/crashes/ice-2865.rs
index c6298139601..28363707acc 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2865.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2865.rs
@@ -1,6 +1,6 @@
 #![allow(dead_code, clippy::extra_unused_lifetimes)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/2865
+// Test for https://github.com/rust-lang/rust-clippy/issues/2865
 
 struct Ice {
     size: String,
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3151.rs b/src/tools/clippy/tests/ui/crashes/ice-3151.rs
index 268ba86fc7a..f88a26cb485 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3151.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3151.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/3151
+// Test for https://github.com/rust-lang/rust-clippy/issues/3151
 
 #[derive(Clone)]
 pub struct HashMap<V, S> {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3462.rs b/src/tools/clippy/tests/ui/crashes/ice-3462.rs
index 21cd9d337cd..ccd617e305d 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3462.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3462.rs
@@ -2,7 +2,7 @@
 #![allow(clippy::disallowed_names, clippy::equatable_if_let, clippy::needless_if)]
 #![allow(unused)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/3462
+// Test for https://github.com/rust-lang/rust-clippy/issues/3462
 
 enum Foo {
     Bar,
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3747.rs b/src/tools/clippy/tests/ui/crashes/ice-3747.rs
index cdf018cbc88..44b1d7ed1b2 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3747.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3747.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/3747
+// Test for https://github.com/rust-lang/rust-clippy/issues/3747
 
 macro_rules! a {
     ( $pub:tt $($attr:tt)* ) => {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3969.rs b/src/tools/clippy/tests/ui/crashes/ice-3969.rs
index d5676cbd91d..ac09ce08753 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3969.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3969.rs
@@ -1,7 +1,7 @@
 // https://github.com/rust-lang/rust-clippy/issues/3969
 // used to crash: error: internal compiler error:
 // src/librustc_traits/normalize_erasing_regions.rs:43: could not fully normalize `<i32 as
-// std::iter::Iterator>::Item test from rustc ./ui/trivial-bounds/trivial-bounds-inconsistent.rs
+// std::iter::Iterator>::Item` test from rustc ./ui/trivial-bounds/trivial-bounds-inconsistent.rs
 
 // Check that tautalogically false bounds are accepted, and are used
 // in type inference.
@@ -18,7 +18,7 @@ struct Dst<X: ?Sized> {
 struct TwoStrs(str, str)
 where
     str: Sized;
-//~^ ERROR: trait bound str: std::marker::Sized does not depend on any type or lifetim
+//~^ ERROR: trait bound str: std::marker::Sized does not depend on any type or lifetime
 //~| NOTE: `-D trivial-bounds` implied by `-D warnings`
 
 fn unsized_local()
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6251.rs b/src/tools/clippy/tests/ui/crashes/ice-6251.rs
index a81137a6465..73e919b6dd2 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6251.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6251.rs
@@ -1,5 +1,5 @@
 // originally from glacier/fixed/77329.rs
-// assertion failed: `(left == right) ; different DefIds
+// assertion failed: `(left == right)` ; different DefIds
 //@no-rustfix
 fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {
     std::iter::empty()
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6251.stderr b/src/tools/clippy/tests/ui/crashes/ice-6251.stderr
index 82e7d723586..77c3e6288ce 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6251.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6251.stderr
@@ -1,8 +1,8 @@
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> tests/ui/crashes/ice-6251.rs:4:45
+  --> tests/ui/crashes/ice-6251.rs:4:48
    |
 LL | fn bug<T>() -> impl Iterator<Item = [(); { |x: [u8]| x }]> {
-   |                                             ^ doesn't have a size known at compile-time
+   |                                                ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `std::marker::Sized` is not implemented for `[u8]`
    = help: unsized fn params are gated as an unstable feature
diff --git a/src/tools/clippy/tests/ui/crashes/ice-700.rs b/src/tools/clippy/tests/ui/crashes/ice-700.rs
index 0cbceedbd6b..5e004b94330 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-700.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-700.rs
@@ -1,6 +1,6 @@
 #![deny(clippy::all)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/700
+// Test for https://github.com/rust-lang/rust-clippy/issues/700
 
 fn core() {}
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7410.rs b/src/tools/clippy/tests/ui/crashes/ice-7410.rs
index a2683b3ce34..ccf6d7ff94f 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7410.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-7410.rs
@@ -1,6 +1,5 @@
 //@compile-flags: -Clink-arg=-nostartfiles
-//@ignore-target-apple
-//@ignore-target-windows
+//@ignore-target: apple windows
 
 #![feature(lang_items, start, libc)]
 #![no_std]
diff --git a/src/tools/clippy/tests/ui/crashes/ice_exact_size.rs b/src/tools/clippy/tests/ui/crashes/ice_exact_size.rs
index 30e4b11ec0b..c0671eaff14 100644
--- a/src/tools/clippy/tests/ui/crashes/ice_exact_size.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice_exact_size.rs
@@ -1,6 +1,6 @@
 #![deny(clippy::all)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/1336
+// Test for https://github.com/rust-lang/rust-clippy/issues/1336
 
 #[allow(dead_code)]
 struct Foo;
diff --git a/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs b/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
index 2f913292995..a900fe5e6bc 100644
--- a/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
+++ b/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
@@ -1,7 +1,7 @@
 #![allow(clippy::comparison_chain)]
 #![deny(clippy::if_same_then_else)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/2426
+// Test for https://github.com/rust-lang/rust-clippy/issues/2426
 
 fn main() {}
 
diff --git a/src/tools/clippy/tests/ui/crashes/inherent_impl.rs b/src/tools/clippy/tests/ui/crashes/inherent_impl.rs
index aeb27b5ba8c..800a5a383f6 100644
--- a/src/tools/clippy/tests/ui/crashes/inherent_impl.rs
+++ b/src/tools/clippy/tests/ui/crashes/inherent_impl.rs
@@ -1,6 +1,6 @@
 #![deny(clippy::multiple_inherent_impl)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/4578
+// Test for https://github.com/rust-lang/rust-clippy/issues/4578
 
 macro_rules! impl_foo {
     ($struct:ident) => {
diff --git a/src/tools/clippy/tests/ui/crashes/issue-825.rs b/src/tools/clippy/tests/ui/crashes/issue-825.rs
index 05696e3d7d5..e8b455a0ec6 100644
--- a/src/tools/clippy/tests/ui/crashes/issue-825.rs
+++ b/src/tools/clippy/tests/ui/crashes/issue-825.rs
@@ -1,6 +1,6 @@
 #![allow(warnings)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/825
+// Test for https://github.com/rust-lang/rust-clippy/issues/825
 
 // this should compile in a reasonable amount of time
 fn rust_type_id(name: &str) {
diff --git a/src/tools/clippy/tests/ui/crashes/match_same_arms_const.rs b/src/tools/clippy/tests/ui/crashes/match_same_arms_const.rs
index 94c939665e6..626179c0015 100644
--- a/src/tools/clippy/tests/ui/crashes/match_same_arms_const.rs
+++ b/src/tools/clippy/tests/ui/crashes/match_same_arms_const.rs
@@ -1,6 +1,6 @@
 #![deny(clippy::match_same_arms)]
 
-/// Test for https://github.com/rust-lang/rust-clippy/issues/2427
+// Test for https://github.com/rust-lang/rust-clippy/issues/2427
 
 const PRICE_OF_SWEETS: u32 = 5;
 const PRICE_OF_KINDNESS: u32 = 0;
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
index 8bd9eea75bb..837069cae6d 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
@@ -9,7 +9,7 @@ struct Baz<'a> {
     bar: &'a Bar,
 }
 
-impl<'a> Foo for Baz<'a> {}
+impl Foo for Baz<'_> {}
 
 impl Bar {
     fn baz(&self) -> impl Foo + '_ {
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
index 3a2d1f4410e..bed6aab25c4 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
@@ -1,8 +1,8 @@
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:15:12
+  --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:12:6
    |
-LL |     fn baz<'a>(&'a self) -> impl Foo + 'a {
-   |            ^^   ^^                     ^^
+LL | impl<'a> Foo for Baz<'a> {}
+   |      ^^              ^^
    |
 note: the lint level is defined here
   --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:1:9
@@ -11,9 +11,21 @@ LL | #![deny(clippy::needless_lifetimes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: elide the lifetimes
    |
+LL - impl<'a> Foo for Baz<'a> {}
+LL + impl Foo for Baz<'_> {}
+   |
+
+error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:15:12
+   |
+LL |     fn baz<'a>(&'a self) -> impl Foo + 'a {
+   |            ^^   ^^                     ^^
+   |
+help: elide the lifetimes
+   |
 LL -     fn baz<'a>(&'a self) -> impl Foo + 'a {
 LL +     fn baz(&self) -> impl Foo + '_ {
    |
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
index 90076d4338a..28479570006 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
+++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
@@ -4,7 +4,7 @@ error: this argument is passed by value, but not consumed in the function body
 LL | fn test(x: Foo<'_>) {}
    |            ^^^^^^^ help: consider taking a reference instead: `&Foo<'_>`
    |
-help: consider marking this type as `Copy`
+help: or consider marking this type as `Copy`
   --> tests/ui/crashes/needless_pass_by_value-w-late-bound.rs:5:1
    |
 LL | struct Foo<'a>(&'a [(); 100]);
diff --git a/src/tools/clippy/tests/ui/crashes/returns.rs b/src/tools/clippy/tests/ui/crashes/returns.rs
index 8021ed4607d..91cdb5306c8 100644
--- a/src/tools/clippy/tests/ui/crashes/returns.rs
+++ b/src/tools/clippy/tests/ui/crashes/returns.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/1346
+// Test for https://github.com/rust-lang/rust-clippy/issues/1346
 
 #[deny(warnings)]
 fn cfg_return() -> i32 {
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs
index aa76688d801..5d853d97bc3 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs
+++ b/src/tools/clippy/tests/ui/crate_level_checks/entrypoint_recursion.rs
@@ -1,4 +1,4 @@
-//@ignore-target-apple
+//@ignore-target: apple
 
 #![feature(rustc_attrs)]
 
diff --git a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs
index 32eba969592..9e5b2a48903 100644
--- a/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs
+++ b/src/tools/clippy/tests/ui/crate_level_checks/no_std_main_recursion.rs
@@ -1,5 +1,5 @@
 //@compile-flags: -Clink-arg=-nostartfiles
-//@ignore-target-apple
+//@ignore-target: apple
 
 #![feature(lang_items, start, libc)]
 #![no_std]
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
index 9dafad8b784..0dccf18c493 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
@@ -4,8 +4,8 @@ use std::borrow::Cow;
 use std::cell::Cell;
 use std::fmt::Display;
 use std::ptr;
-use std::sync::atomic::AtomicUsize;
 use std::sync::Once;
+use std::sync::atomic::AtomicUsize;
 
 const ATOMIC: AtomicUsize = AtomicUsize::new(5); //~ ERROR: interior mutable
 const CELL: Cell<usize> = Cell::new(6); //~ ERROR: interior mutable
diff --git a/src/tools/clippy/tests/ui/def_id_nocore.rs b/src/tools/clippy/tests/ui/def_id_nocore.rs
index 190d636ebf3..c9650312db8 100644
--- a/src/tools/clippy/tests/ui/def_id_nocore.rs
+++ b/src/tools/clippy/tests/ui/def_id_nocore.rs
@@ -1,4 +1,4 @@
-//@ignore-target-apple
+//@ignore-target: apple
 
 #![feature(no_core, lang_items, start)]
 #![no_core]
diff --git a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
index 32582a3a8bf..6f997875777 100644
--- a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
+++ b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
@@ -1,5 +1,5 @@
-// This test can't work with run-rustfix because it needs two passes of test+fix
-//@no-rustfix
+//@no-rustfix: this test can't work with run-rustfix because it needs two passes of test+fix
+
 #[warn(clippy::deref_addrof)]
 #[allow(unused_variables, unused_mut)]
 fn main() {
diff --git a/src/tools/clippy/tests/ui/derive.rs b/src/tools/clippy/tests/ui/derive.rs
index 20ac8a6e6be..b06dd78608f 100644
--- a/src/tools/clippy/tests/ui/derive.rs
+++ b/src/tools/clippy/tests/ui/derive.rs
@@ -1,4 +1,9 @@
-#![allow(clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, dead_code)]
+#![allow(
+    clippy::non_canonical_clone_impl,
+    clippy::non_canonical_partial_ord_impl,
+    clippy::needless_lifetimes,
+    dead_code
+)]
 #![warn(clippy::expl_impl_clone_on_copy)]
 
 
diff --git a/src/tools/clippy/tests/ui/derive.stderr b/src/tools/clippy/tests/ui/derive.stderr
index d5f9d7cf2a2..0eb4b3c1ada 100644
--- a/src/tools/clippy/tests/ui/derive.stderr
+++ b/src/tools/clippy/tests/ui/derive.stderr
@@ -1,5 +1,5 @@
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:8:1
+  --> tests/ui/derive.rs:13:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -10,7 +10,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:8:1
+  --> tests/ui/derive.rs:13:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -23,7 +23,7 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:33:1
+  --> tests/ui/derive.rs:38:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -34,7 +34,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:33:1
+  --> tests/ui/derive.rs:38:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -45,7 +45,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:45:1
+  --> tests/ui/derive.rs:50:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -56,7 +56,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:45:1
+  --> tests/ui/derive.rs:50:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -67,7 +67,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:57:1
+  --> tests/ui/derive.rs:62:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -78,7 +78,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:57:1
+  --> tests/ui/derive.rs:62:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -89,7 +89,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:78:1
+  --> tests/ui/derive.rs:83:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |
@@ -100,7 +100,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:78:1
+  --> tests/ui/derive.rs:83:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |
diff --git a/src/tools/clippy/tests/ui/diverging_sub_expression.rs b/src/tools/clippy/tests/ui/diverging_sub_expression.rs
index e0acf050949..1abba60fd34 100644
--- a/src/tools/clippy/tests/ui/diverging_sub_expression.rs
+++ b/src/tools/clippy/tests/ui/diverging_sub_expression.rs
@@ -67,3 +67,9 @@ fn foobar() {
         };
     }
 }
+
+#[allow(unused)]
+fn ignore_todo() {
+    let x: u32 = todo!();
+    println!("{x}");
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.fixed b/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.fixed
deleted file mode 100644
index 1aaa26afe7f..00000000000
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.fixed
+++ /dev/null
@@ -1,47 +0,0 @@
-// https://github.com/rust-lang/rust-clippy/issues/12917
-#![warn(clippy::doc_lazy_continuation)]
-
-/// This is a constant.
-///
-/// The meaning of which should not be explained.
-pub const A: i32 = 42;
-
-/// This is another constant, no longer used.
-///
-/// This block of documentation has a long
-/// explanation and derivation to explain
-/// why it is what it is, and how it's used.
-///
-/// It is left here for historical reasons, and
-/// for reference.
-///
-/// Reasons it's great:
-///  - First reason
-///  - Second reason
-///
-//pub const B: i32 = 1337;
-
-/// This is yet another constant.
-///
-/// This has a similar fate as `B`.
-///
-/// Reasons it's useful:
-///  1. First reason
-///  2. Second reason
-///
-//pub const C: i32 = 8008;
-
-/// This is still in use.
-pub const D: i32 = 20;
-
-/// > blockquote code path
-///
-
-/// bottom text
-pub const E: i32 = 20;
-
-/// > blockquote code path
-///
-#[repr(C)]
-/// bottom text
-pub struct Foo(i32);
diff --git a/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.rs b/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.rs
deleted file mode 100644
index e1ab8fc8389..00000000000
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-// https://github.com/rust-lang/rust-clippy/issues/12917
-#![warn(clippy::doc_lazy_continuation)]
-
-/// This is a constant.
-///
-/// The meaning of which should not be explained.
-pub const A: i32 = 42;
-
-/// This is another constant, no longer used.
-///
-/// This block of documentation has a long
-/// explanation and derivation to explain
-/// why it is what it is, and how it's used.
-///
-/// It is left here for historical reasons, and
-/// for reference.
-///
-/// Reasons it's great:
-///  - First reason
-///  - Second reason
-//pub const B: i32 = 1337;
-
-/// This is yet another constant.
-///
-/// This has a similar fate as `B`.
-///
-/// Reasons it's useful:
-///  1. First reason
-///  2. Second reason
-//pub const C: i32 = 8008;
-
-/// This is still in use.
-pub const D: i32 = 20;
-
-/// > blockquote code path
-
-/// bottom text
-pub const E: i32 = 20;
-
-/// > blockquote code path
-#[repr(C)]
-/// bottom text
-pub struct Foo(i32);
diff --git a/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.stderr b/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.stderr
deleted file mode 100644
index 854906a7474..00000000000
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_blank_line.stderr
+++ /dev/null
@@ -1,56 +0,0 @@
-error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_blank_line.rs:23:5
-   |
-LL | /// This is yet another constant.
-   |     ^
-   |
-   = help: if this is intended to be part of the list, indent 3 spaces
-   = note: `-D clippy::doc-lazy-continuation` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::doc_lazy_continuation)]`
-help: if this should be its own paragraph, add a blank doc comment line
-   |
-LL ~ ///  - Second reason
-LL + ///
-   |
-
-error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_blank_line.rs:32:5
-   |
-LL | /// This is still in use.
-   |     ^
-   |
-   = help: if this is intended to be part of the list, indent 4 spaces
-help: if this should be its own paragraph, add a blank doc comment line
-   |
-LL ~ ///  2. Second reason
-LL + ///
-   |
-
-error: doc quote line without `>` marker
-  --> tests/ui/doc/doc_lazy_blank_line.rs:37:5
-   |
-LL | /// bottom text
-   |     ^
-   |
-   = help: if this not intended to be a quote at all, escape it with `\>`
-help: if this should be its own paragraph, add a blank doc comment line
-   |
-LL ~ /// > blockquote code path
-LL + ///
-   |
-
-error: doc quote line without `>` marker
-  --> tests/ui/doc/doc_lazy_blank_line.rs:42:5
-   |
-LL | /// bottom text
-   |     ^
-   |
-   = help: if this not intended to be a quote at all, escape it with `\>`
-help: if this should be its own paragraph, add a blank doc comment line
-   |
-LL ~ /// > blockquote code path
-LL + ///
-   |
-
-error: aborting due to 4 previous errors
-
diff --git a/src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed b/src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed
index ea59ae4c01c..da537518a2b 100644
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed
@@ -7,9 +7,8 @@ fn one() {}
 
 /// 1. first line
 ///    lazy list continuations don't make warnings with this lint
-///
 //~^ ERROR: doc list item without indentation
-/// because they don't have the
+///    because they don't have the
 //~^ ERROR: doc list item without indentation
 fn two() {}
 
@@ -20,9 +19,8 @@ fn three() {}
 
 ///   - first line
 ///     lazy list continuations don't make warnings with this lint
-///
 //~^ ERROR: doc list item without indentation
-/// because they don't have the
+///     because they don't have the
 //~^ ERROR: doc list item without indentation
 fn four() {}
 
@@ -33,9 +31,8 @@ fn five() {}
 
 ///   - - first line
 ///       this will warn on the lazy continuation
-///
 //~^ ERROR: doc list item without indentation
-///     and so should this
+///       and so should this
 //~^ ERROR: doc list item without indentation
 fn six() {}
 
diff --git a/src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr b/src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr
index 52aa74df894..b38f43b7555 100644
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr
@@ -30,12 +30,11 @@ error: doc list item without indentation
 LL | /// because they don't have the
    |     ^
    |
-   = help: if this is intended to be part of the list, indent 3 spaces
-help: if this should be its own paragraph, add a blank doc comment line
-   |
-LL ~ /// lazy list continuations don't make warnings with this lint
-LL + ///
+   = help: if this is supposed to be its own paragraph, add a blank line
+help: indent this line
    |
+LL | ///    because they don't have the
+   |     +++
 
 error: doc list item without indentation
   --> tests/ui/doc/doc_lazy_list.rs:16:5
@@ -67,12 +66,11 @@ error: doc list item without indentation
 LL | /// because they don't have the
    |     ^
    |
-   = help: if this is intended to be part of the list, indent 4 spaces
-help: if this should be its own paragraph, add a blank doc comment line
-   |
-LL ~ /// lazy list continuations don't make warnings with this lint
-LL + ///
+   = help: if this is supposed to be its own paragraph, add a blank line
+help: indent this line
    |
+LL | ///     because they don't have the
+   |     ++++
 
 error: doc list item without indentation
   --> tests/ui/doc/doc_lazy_list.rs:28:5
@@ -104,12 +102,11 @@ error: doc list item without indentation
 LL | ///     and so should this
    |     ^^^^
    |
-   = help: if this is intended to be part of the list, indent 2 spaces
-help: if this should be its own paragraph, add a blank doc comment line
-   |
-LL ~ /// this will warn on the lazy continuation
-LL + ///
+   = help: if this is supposed to be its own paragraph, add a blank line
+help: indent this line
    |
+LL | ///       and so should this
+   |         ++
 
 error: doc list item without indentation
   --> tests/ui/doc/doc_lazy_list.rs:56:5
diff --git a/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs b/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs
index 118f6e4a34c..a725538436c 100644
--- a/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs
+++ b/src/tools/clippy/tests/ui/duplicate_underscore_argument.rs
@@ -1,5 +1,4 @@
 #![warn(clippy::duplicate_underscore_argument)]
-#[allow(dead_code, unused)]
 
 fn join_the_dark_side(darth: i32, _darth: i32) {}
 //~^ ERROR: `darth` already exists, having another argument having almost the same name ma
diff --git a/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr b/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr
index 40a24b823d1..74979b15788 100644
--- a/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr
+++ b/src/tools/clippy/tests/ui/duplicate_underscore_argument.stderr
@@ -1,5 +1,5 @@
 error: `darth` already exists, having another argument having almost the same name makes code comprehension and documentation more difficult
-  --> tests/ui/duplicate_underscore_argument.rs:4:23
+  --> tests/ui/duplicate_underscore_argument.rs:3:23
    |
 LL | fn join_the_dark_side(darth: i32, _darth: i32) {}
    |                       ^^^^^
diff --git a/src/tools/clippy/tests/ui/duplicated_attributes.rs b/src/tools/clippy/tests/ui/duplicated_attributes.rs
index 97cf4a69682..874f5d22075 100644
--- a/src/tools/clippy/tests/ui/duplicated_attributes.rs
+++ b/src/tools/clippy/tests/ui/duplicated_attributes.rs
@@ -27,4 +27,8 @@ trait Abc {}
 #[proc_macro_attr::duplicated_attr()] // Should not warn!
 fn babar() {}
 
+#[allow(missing_docs, reason = "library for internal use only")]
+#[allow(exported_private_dependencies, reason = "library for internal use only")]
+fn duplicate_reason() {}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed
new file mode 100644
index 00000000000..fd6a94b6a80
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed
@@ -0,0 +1,135 @@
+#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
+
+//~vvv empty_line_after_doc_comments
+/// Meant to be an
+/// inner doc comment
+/// for the crate
+fn first_in_crate() {}
+
+mod m {
+    //~vvv empty_line_after_doc_comments
+    /// Meant to be an
+    /// inner doc comment
+    /// for the module
+    fn first_in_module() {}
+}
+
+mod some_mod {
+    //! This doc comment should *NOT* produce a warning
+
+    mod some_inner_mod {
+        fn some_noop() {}
+    }
+
+    //~v empty_line_after_doc_comments
+    /// # Indented
+    /// Blank line
+    fn indented() {}
+}
+
+//~v empty_line_after_doc_comments
+/// This should produce a warning
+fn with_doc_and_newline() {}
+
+// This should *NOT* produce a warning
+#[crate_type = "lib"]
+/// some comment
+fn with_no_newline_and_comment() {}
+
+//~v empty_line_after_doc_comments
+/// This doc comment should produce a warning
+/** This is also a doc comment and is part of the warning
+ */
+#[allow(non_camel_case_types)]
+#[allow(missing_docs)]
+#[allow(dead_code)]
+fn three_attributes() {}
+
+mod misattributed {
+    //~v empty_line_after_doc_comments
+    /// docs for `old_code`
+    // fn old_code() {}
+    fn new_code() {}
+
+    //~vv empty_line_after_doc_comments
+    /// Docs
+    /// for OldA
+    // struct OldA;
+    /// Docs
+    /// for OldB
+    // struct OldB;
+    /// Docs
+    /// for Multiple
+    #[allow(dead_code)]
+    struct Multiple;
+}
+
+mod block_comments {
+    //~v empty_line_after_doc_comments
+    /**
+     * Meant to be inner doc comment
+     */
+    fn first_in_module() {}
+
+    //~v empty_line_after_doc_comments
+    /**
+     * Docs for `old_code`
+     */
+    /* fn old_code() {} */
+    /**
+     * Docs for `new_code`
+     */
+    fn new_code() {}
+
+    //~v empty_line_after_doc_comments
+    /// Docs for `old_code2`
+    /* fn old_code2() {} */
+    /// Docs for `new_code2`
+    fn new_code2() {}
+}
+
+// This should *NOT* produce a warning
+#[doc = "
+Returns the escaped value of the textual representation of
+
+"]
+pub fn function() -> bool {
+    true
+}
+
+// This should *NOT* produce a warning
+#[derive(Clone, Copy)]
+pub enum FooFighter {
+    Bar1,
+
+    Bar2,
+
+    Bar3,
+
+    Bar4,
+}
+
+/// Should not lint
+// some line comment
+/// gaps without an empty line
+struct LineComment;
+
+/// This should *NOT* produce a warning because the empty line is inside a block comment
+/*
+
+*/
+pub struct EmptyInBlockComment;
+
+/// This should *NOT* produce a warning
+/* test */
+pub struct BlockComment;
+
+/// Ignore the empty line inside a cfg_attr'd out attribute
+#[cfg_attr(any(), multiline(
+    foo = 1
+
+    bar = 2
+))]
+fn empty_line_in_cfg_attr() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed
new file mode 100644
index 00000000000..7a57dcd9233
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed
@@ -0,0 +1,144 @@
+#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
+
+//~vvv empty_line_after_doc_comments
+//! Meant to be an
+//! inner doc comment
+//! for the crate
+
+fn first_in_crate() {}
+
+mod m {
+    //~vvv empty_line_after_doc_comments
+    //! Meant to be an
+    //! inner doc comment
+    //! for the module
+
+    fn first_in_module() {}
+}
+
+mod some_mod {
+    //! This doc comment should *NOT* produce a warning
+
+    mod some_inner_mod {
+        fn some_noop() {}
+    }
+
+    //~v empty_line_after_doc_comments
+    /// # Indented
+    ///
+    /// Blank line
+    fn indented() {}
+}
+
+//~v empty_line_after_doc_comments
+/// This should produce a warning
+fn with_doc_and_newline() {}
+
+// This should *NOT* produce a warning
+#[crate_type = "lib"]
+/// some comment
+fn with_no_newline_and_comment() {}
+
+//~v empty_line_after_doc_comments
+/// This doc comment should produce a warning
+/** This is also a doc comment and is part of the warning
+ */
+#[allow(non_camel_case_types)]
+#[allow(missing_docs)]
+#[allow(dead_code)]
+fn three_attributes() {}
+
+mod misattributed {
+    //~v empty_line_after_doc_comments
+    // /// docs for `old_code`
+    // fn old_code() {}
+
+    fn new_code() {}
+
+    //~vv empty_line_after_doc_comments
+    // /// Docs
+    // /// for OldA
+    // struct OldA;
+
+    // /// Docs
+    // /// for OldB
+    // struct OldB;
+
+    /// Docs
+    /// for Multiple
+    #[allow(dead_code)]
+    struct Multiple;
+}
+
+mod block_comments {
+    //~v empty_line_after_doc_comments
+    /*!
+     * Meant to be inner doc comment
+     */
+
+    fn first_in_module() {}
+
+    //~v empty_line_after_doc_comments
+    /*
+     * Docs for `old_code`
+     */
+    /* fn old_code() {} */
+
+    /**
+     * Docs for `new_code`
+     */
+    fn new_code() {}
+
+    //~v empty_line_after_doc_comments
+    // /// Docs for `old_code2`
+    /* fn old_code2() {} */
+
+    /// Docs for `new_code2`
+    fn new_code2() {}
+}
+
+// This should *NOT* produce a warning
+#[doc = "
+Returns the escaped value of the textual representation of
+
+"]
+pub fn function() -> bool {
+    true
+}
+
+// This should *NOT* produce a warning
+#[derive(Clone, Copy)]
+pub enum FooFighter {
+    Bar1,
+
+    Bar2,
+
+    Bar3,
+
+    Bar4,
+}
+
+/// Should not lint
+// some line comment
+/// gaps without an empty line
+struct LineComment;
+
+/// This should *NOT* produce a warning because the empty line is inside a block comment
+/*
+
+*/
+pub struct EmptyInBlockComment;
+
+/// This should *NOT* produce a warning
+/* test */
+pub struct BlockComment;
+
+/// Ignore the empty line inside a cfg_attr'd out attribute
+#[cfg_attr(any(), multiline(
+    foo = 1
+
+    bar = 2
+))]
+fn empty_line_in_cfg_attr() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs
new file mode 100644
index 00000000000..1da761a5c3d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs
@@ -0,0 +1,147 @@
+#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
+
+//~vvv empty_line_after_doc_comments
+/// Meant to be an
+/// inner doc comment
+/// for the crate
+
+fn first_in_crate() {}
+
+mod m {
+    //~vvv empty_line_after_doc_comments
+    /// Meant to be an
+    /// inner doc comment
+    /// for the module
+
+    fn first_in_module() {}
+}
+
+mod some_mod {
+    //! This doc comment should *NOT* produce a warning
+
+    mod some_inner_mod {
+        fn some_noop() {}
+    }
+
+    //~v empty_line_after_doc_comments
+    /// # Indented
+
+    /// Blank line
+    fn indented() {}
+}
+
+//~v empty_line_after_doc_comments
+/// This should produce a warning
+
+fn with_doc_and_newline() {}
+
+// This should *NOT* produce a warning
+#[crate_type = "lib"]
+/// some comment
+fn with_no_newline_and_comment() {}
+
+//~v empty_line_after_doc_comments
+/// This doc comment should produce a warning
+
+/** This is also a doc comment and is part of the warning
+ */
+
+#[allow(non_camel_case_types)]
+#[allow(missing_docs)]
+#[allow(dead_code)]
+fn three_attributes() {}
+
+mod misattributed {
+    //~v empty_line_after_doc_comments
+    /// docs for `old_code`
+    // fn old_code() {}
+
+    fn new_code() {}
+
+    //~vv empty_line_after_doc_comments
+    /// Docs
+    /// for OldA
+    // struct OldA;
+
+    /// Docs
+    /// for OldB
+    // struct OldB;
+
+    /// Docs
+    /// for Multiple
+    #[allow(dead_code)]
+    struct Multiple;
+}
+
+mod block_comments {
+    //~v empty_line_after_doc_comments
+    /**
+     * Meant to be inner doc comment
+     */
+
+    fn first_in_module() {}
+
+    //~v empty_line_after_doc_comments
+    /**
+     * Docs for `old_code`
+     */
+    /* fn old_code() {} */
+
+    /**
+     * Docs for `new_code`
+     */
+    fn new_code() {}
+
+    //~v empty_line_after_doc_comments
+    /// Docs for `old_code2`
+    /* fn old_code2() {} */
+
+    /// Docs for `new_code2`
+    fn new_code2() {}
+}
+
+// This should *NOT* produce a warning
+#[doc = "
+Returns the escaped value of the textual representation of
+
+"]
+pub fn function() -> bool {
+    true
+}
+
+// This should *NOT* produce a warning
+#[derive(Clone, Copy)]
+pub enum FooFighter {
+    Bar1,
+
+    Bar2,
+
+    Bar3,
+
+    Bar4,
+}
+
+/// Should not lint
+// some line comment
+/// gaps without an empty line
+struct LineComment;
+
+/// This should *NOT* produce a warning because the empty line is inside a block comment
+/*
+
+*/
+pub struct EmptyInBlockComment;
+
+/// This should *NOT* produce a warning
+/* test */
+pub struct BlockComment;
+
+/// Ignore the empty line inside a cfg_attr'd out attribute
+#[cfg_attr(any(), multiline(
+    foo = 1
+
+    bar = 2
+))]
+fn empty_line_in_cfg_attr() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
new file mode 100644
index 00000000000..c238b4c9a17
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
@@ -0,0 +1,176 @@
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:6:1
+   |
+LL | / /// for the crate
+LL | |
+   | |_
+LL |   fn first_in_crate() {}
+   |   ------------------- the comment documents this function
+   |
+   = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`
+   = help: if the empty line is unintentional remove it
+help: if the comment should document the crate use an inner doc comment
+   |
+LL ~ //! Meant to be an
+LL ~ //! inner doc comment
+LL ~ //! for the crate
+   |
+
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:14:5
+   |
+LL | /     /// for the module
+LL | |
+   | |_
+LL |       fn first_in_module() {}
+   |       -------------------- the comment documents this function
+   |
+   = help: if the empty line is unintentional remove it
+help: if the comment should document the parent module use an inner doc comment
+   |
+LL ~     //! Meant to be an
+LL ~     //! inner doc comment
+LL ~     //! for the module
+   |
+
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:27:5
+   |
+LL | /     /// # Indented
+LL | |
+   | |_
+LL |       /// Blank line
+LL |       fn indented() {}
+   |       ------------- the comment documents this function
+   |
+   = help: if the empty line is unintentional remove it
+help: if the documentation should include the empty line include it in the comment
+   |
+LL |     ///
+   |
+
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:34:1
+   |
+LL | / /// This should produce a warning
+LL | |
+   | |_
+LL |   fn with_doc_and_newline() {}
+   |   ------------------------- the comment documents this function
+   |
+   = help: if the empty line is unintentional remove it
+
+error: empty lines after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:44:1
+   |
+LL | / /// This doc comment should produce a warning
+LL | |
+LL | | /** This is also a doc comment and is part of the warning
+LL | |  */
+LL | |
+   | |_
+...
+LL |   fn three_attributes() {}
+   |   --------------------- the comment documents this function
+   |
+   = help: if the empty lines are unintentional remove them
+
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:56:5
+   |
+LL | /     /// docs for `old_code`
+LL | |     // fn old_code() {}
+LL | |
+   | |_
+LL |       fn new_code() {}
+   |       ------------- the comment documents this function
+   |
+   = help: if the empty line is unintentional remove it
+help: if the doc comment should not document `new_code` comment it out
+   |
+LL |     // /// docs for `old_code`
+   |     ++
+
+error: empty lines after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:63:5
+   |
+LL | /     /// for OldA
+LL | |     // struct OldA;
+LL | |
+LL | |     /// Docs
+LL | |     /// for OldB
+LL | |     // struct OldB;
+LL | |
+   | |_
+...
+LL |       struct Multiple;
+   |       --------------- the comment documents this struct
+   |
+   = help: if the empty lines are unintentional remove them
+help: if the doc comment should not document `Multiple` comment it out
+   |
+LL ~     // /// Docs
+LL ~     // /// for OldA
+LL |     // struct OldA;
+LL |
+LL ~     // /// Docs
+LL ~     // /// for OldB
+   |
+
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:78:5
+   |
+LL | /     /**
+LL | |      * Meant to be inner doc comment
+LL | |      */
+LL | |
+   | |_
+LL |       fn first_in_module() {}
+   |       -------------------- the comment documents this function
+   |
+   = help: if the empty line is unintentional remove it
+help: if the comment should document the parent module use an inner doc comment
+   |
+LL |     /*!
+   |       ~
+
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:85:5
+   |
+LL | /     /**
+LL | |      * Docs for `old_code`
+LL | |      */
+LL | |     /* fn old_code() {} */
+LL | |
+   | |_
+...
+LL |       fn new_code() {}
+   |       ------------- the comment documents this function
+   |
+   = help: if the empty line is unintentional remove it
+help: if the doc comment should not document `new_code` comment it out
+   |
+LL -     /**
+LL +     /*
+   |
+
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:96:5
+   |
+LL | /     /// Docs for `old_code2`
+LL | |     /* fn old_code2() {} */
+LL | |
+   | |_
+LL |       /// Docs for `new_code2`
+LL |       fn new_code2() {}
+   |       -------------- the comment documents this function
+   |
+   = help: if the empty line is unintentional remove it
+help: if the doc comment should not document `new_code2` comment it out
+   |
+LL |     // /// Docs for `old_code2`
+   |     ++
+
+error: aborting due to 10 previous errors
+
diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed
new file mode 100644
index 00000000000..36d80a2c95b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.1.fixed
@@ -0,0 +1,108 @@
+//@aux-build:../auxiliary/proc_macro_attr.rs
+#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
+
+//~v empty_line_after_outer_attr
+#[crate_type = "lib"]
+fn first_in_crate() {}
+
+#[macro_use]
+extern crate proc_macro_attr;
+
+//~v empty_line_after_outer_attr
+#[inline]
+/// some comment
+fn with_one_newline_and_comment() {}
+
+#[inline]
+/// some comment
+fn with_no_newline_and_comment() {}
+
+//~v empty_line_after_outer_attr
+#[inline]
+fn with_one_newline() {}
+
+#[rustfmt::skip]
+mod two_lines {
+    //~v empty_line_after_outer_attr
+    #[crate_type = "lib"]
+    fn with_two_newlines() {}
+}
+
+//~v empty_line_after_outer_attr
+#[doc = "doc attributes should be considered attributes"]
+enum Baz {
+    One,
+    Two,
+}
+
+//~v empty_line_after_outer_attr
+#[repr(C)]
+struct Foo {
+    one: isize,
+    two: isize,
+}
+
+//~v empty_line_after_outer_attr
+#[allow(dead_code)]
+mod foo {}
+
+//~v empty_line_after_outer_attr
+#[inline]
+// Still lint cases where the empty line does not immediately follow the attribute
+fn comment_before_empty_line() {}
+
+//~v empty_line_after_outer_attr
+#[allow(unused)]
+// This comment is isolated
+pub fn isolated_comment() {}
+
+#[doc = "
+Returns the escaped value of the textual representation of
+
+"]
+pub fn function() -> bool {
+    true
+}
+
+#[derive(Clone, Copy)]
+pub enum FooFighter {
+    Bar1,
+
+    Bar2,
+
+    Bar3,
+
+    Bar4,
+}
+
+#[crate_type = "lib"]
+/*
+
+*/
+pub struct EmptyLineInBlockComment;
+
+#[crate_type = "lib"]
+/* test */
+pub struct BlockComment;
+
+// See https://github.com/rust-lang/rust-clippy/issues/5567
+#[rustfmt::skip]
+#[fake_async_trait]
+pub trait Bazz {
+    fn foo() -> Vec<u8> {
+        let _i = "";
+
+
+
+        vec![]
+    }
+}
+
+#[derive(Clone, Copy)]
+#[dummy(string = "first line
+
+second line
+")]
+pub struct Args;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed
new file mode 100644
index 00000000000..0e8e4129e85
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.2.fixed
@@ -0,0 +1,111 @@
+//@aux-build:../auxiliary/proc_macro_attr.rs
+#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
+
+//~v empty_line_after_outer_attr
+#![crate_type = "lib"]
+
+fn first_in_crate() {}
+
+#[macro_use]
+extern crate proc_macro_attr;
+
+//~v empty_line_after_outer_attr
+#[inline]
+/// some comment
+fn with_one_newline_and_comment() {}
+
+#[inline]
+/// some comment
+fn with_no_newline_and_comment() {}
+
+//~v empty_line_after_outer_attr
+#[inline]
+fn with_one_newline() {}
+
+#[rustfmt::skip]
+mod two_lines {
+    //~v empty_line_after_outer_attr
+    #![crate_type = "lib"]
+
+
+    fn with_two_newlines() {}
+}
+
+//~v empty_line_after_outer_attr
+#[doc = "doc attributes should be considered attributes"]
+enum Baz {
+    One,
+    Two,
+}
+
+//~v empty_line_after_outer_attr
+#[repr(C)]
+struct Foo {
+    one: isize,
+    two: isize,
+}
+
+//~v empty_line_after_outer_attr
+#[allow(dead_code)]
+mod foo {}
+
+//~v empty_line_after_outer_attr
+#[inline]
+// Still lint cases where the empty line does not immediately follow the attribute
+fn comment_before_empty_line() {}
+
+//~v empty_line_after_outer_attr
+#[allow(unused)]
+// This comment is isolated
+pub fn isolated_comment() {}
+
+#[doc = "
+Returns the escaped value of the textual representation of
+
+"]
+pub fn function() -> bool {
+    true
+}
+
+#[derive(Clone, Copy)]
+pub enum FooFighter {
+    Bar1,
+
+    Bar2,
+
+    Bar3,
+
+    Bar4,
+}
+
+#[crate_type = "lib"]
+/*
+
+*/
+pub struct EmptyLineInBlockComment;
+
+#[crate_type = "lib"]
+/* test */
+pub struct BlockComment;
+
+// See https://github.com/rust-lang/rust-clippy/issues/5567
+#[rustfmt::skip]
+#[fake_async_trait]
+pub trait Bazz {
+    fn foo() -> Vec<u8> {
+        let _i = "";
+
+
+
+        vec![]
+    }
+}
+
+#[derive(Clone, Copy)]
+#[dummy(string = "first line
+
+second line
+")]
+pub struct Args;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs
new file mode 100644
index 00000000000..1295088ac00
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.rs
@@ -0,0 +1,119 @@
+//@aux-build:../auxiliary/proc_macro_attr.rs
+#![warn(clippy::empty_line_after_outer_attr, clippy::empty_line_after_doc_comments)]
+
+//~v empty_line_after_outer_attr
+#[crate_type = "lib"]
+
+fn first_in_crate() {}
+
+#[macro_use]
+extern crate proc_macro_attr;
+
+//~v empty_line_after_outer_attr
+#[inline]
+
+/// some comment
+fn with_one_newline_and_comment() {}
+
+#[inline]
+/// some comment
+fn with_no_newline_and_comment() {}
+
+//~v empty_line_after_outer_attr
+#[inline]
+
+fn with_one_newline() {}
+
+#[rustfmt::skip]
+mod two_lines {
+    //~v empty_line_after_outer_attr
+    #[crate_type = "lib"]
+
+
+    fn with_two_newlines() {}
+}
+
+//~v empty_line_after_outer_attr
+#[doc = "doc attributes should be considered attributes"]
+
+enum Baz {
+    One,
+    Two,
+}
+
+//~v empty_line_after_outer_attr
+#[repr(C)]
+
+struct Foo {
+    one: isize,
+    two: isize,
+}
+
+//~v empty_line_after_outer_attr
+#[allow(dead_code)]
+
+mod foo {}
+
+//~v empty_line_after_outer_attr
+#[inline]
+// Still lint cases where the empty line does not immediately follow the attribute
+
+fn comment_before_empty_line() {}
+
+//~v empty_line_after_outer_attr
+#[allow(unused)]
+
+// This comment is isolated
+
+pub fn isolated_comment() {}
+
+#[doc = "
+Returns the escaped value of the textual representation of
+
+"]
+pub fn function() -> bool {
+    true
+}
+
+#[derive(Clone, Copy)]
+pub enum FooFighter {
+    Bar1,
+
+    Bar2,
+
+    Bar3,
+
+    Bar4,
+}
+
+#[crate_type = "lib"]
+/*
+
+*/
+pub struct EmptyLineInBlockComment;
+
+#[crate_type = "lib"]
+/* test */
+pub struct BlockComment;
+
+// See https://github.com/rust-lang/rust-clippy/issues/5567
+#[rustfmt::skip]
+#[fake_async_trait]
+pub trait Bazz {
+    fn foo() -> Vec<u8> {
+        let _i = "";
+
+
+
+        vec![]
+    }
+}
+
+#[derive(Clone, Copy)]
+#[dummy(string = "first line
+
+second line
+")]
+pub struct Args;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
new file mode 100644
index 00000000000..958b40424a9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
@@ -0,0 +1,116 @@
+error: empty line after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:5:1
+   |
+LL | / #[crate_type = "lib"]
+LL | |
+   | |_
+LL |   fn first_in_crate() {}
+   |   ------------------- the attribute applies to this function
+   |
+   = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`
+   = help: if the empty line is unintentional remove it
+help: if the attribute should apply to the crate use an inner attribute
+   |
+LL | #![crate_type = "lib"]
+   |  +
+
+error: empty line after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:13:1
+   |
+LL | / #[inline]
+LL | |
+   | |_
+LL |   /// some comment
+LL |   fn with_one_newline_and_comment() {}
+   |   --------------------------------- the attribute applies to this function
+   |
+   = help: if the empty line is unintentional remove it
+
+error: empty line after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:23:1
+   |
+LL | / #[inline]
+LL | |
+   | |_
+LL |   fn with_one_newline() {}
+   |   --------------------- the attribute applies to this function
+   |
+   = help: if the empty line is unintentional remove it
+
+error: empty lines after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:30:5
+   |
+LL | /     #[crate_type = "lib"]
+LL | |
+LL | |
+   | |_
+LL |       fn with_two_newlines() {}
+   |       ---------------------- the attribute applies to this function
+   |
+   = help: if the empty lines are unintentional remove them
+help: if the attribute should apply to the parent module use an inner attribute
+   |
+LL |     #![crate_type = "lib"]
+   |      +
+
+error: empty line after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:37:1
+   |
+LL | / #[doc = "doc attributes should be considered attributes"]
+LL | |
+   | |_
+LL |   enum Baz {
+   |   -------- the attribute applies to this enum
+   |
+   = help: if the empty line is unintentional remove it
+
+error: empty line after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:45:1
+   |
+LL | / #[repr(C)]
+LL | |
+   | |_
+LL |   struct Foo {
+   |   ---------- the attribute applies to this struct
+   |
+   = help: if the empty line is unintentional remove it
+
+error: empty line after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:53:1
+   |
+LL | / #[allow(dead_code)]
+LL | |
+   | |_
+LL |   mod foo {}
+   |   ------- the attribute applies to this module
+   |
+   = help: if the empty line is unintentional remove it
+
+error: empty line after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:58:1
+   |
+LL | / #[inline]
+LL | | // Still lint cases where the empty line does not immediately follow the attribute
+LL | |
+   | |_
+LL |   fn comment_before_empty_line() {}
+   |   ------------------------------ the attribute applies to this function
+   |
+   = help: if the empty line is unintentional remove it
+
+error: empty lines after outer attribute
+  --> tests/ui/empty_line_after/outer_attribute.rs:64:1
+   |
+LL | / #[allow(unused)]
+LL | |
+LL | | // This comment is isolated
+LL | |
+   | |_
+LL |   pub fn isolated_comment() {}
+   |   ------------------------- the attribute applies to this function
+   |
+   = help: if the empty lines are unintentional remove them
+
+error: aborting due to 9 previous errors
+
diff --git a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs b/src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs
deleted file mode 100644
index dd78491749c..00000000000
--- a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.rs
+++ /dev/null
@@ -1,132 +0,0 @@
-//@aux-build:proc_macro_attr.rs
-#![warn(clippy::empty_line_after_doc_comments)]
-#![allow(clippy::assertions_on_constants, clippy::duplicated_attributes)]
-#![feature(custom_inner_attributes)]
-#![rustfmt::skip]
-
-#[macro_use]
-extern crate proc_macro_attr;
-
-mod some_mod {
-    //! This doc comment should *NOT* produce a warning
-
-    mod some_inner_mod {
-        fn some_noop() {}
-    }
-}
-
-/// This should produce a warning
-
-fn with_doc_and_newline() { assert!(true)}
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-
-/// some comment
-fn with_one_newline_and_comment() { assert!(true) }
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-/// some comment
-fn with_no_newline_and_comment() { assert!(true) }
-
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-
-fn with_one_newline() { assert!(true) }
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-
-
-fn with_two_newlines() { assert!(true) }
-
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-
-enum Baz {
-    One,
-    Two
-}
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-
-struct Foo {
-    one: isize,
-    two: isize
-}
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-
-mod foo {
-}
-
-/// This doc comment should produce a warning
-
-/** This is also a doc comment and should produce a warning
- */
-
-// This should *NOT* produce a warning
-#[allow(non_camel_case_types)]
-#[allow(missing_docs)]
-#[allow(missing_docs)]
-fn three_attributes() { assert!(true) }
-
-// This should *NOT* produce a warning
-#[doc = "
-Returns the escaped value of the textual representation of
-
-"]
-pub fn function() -> bool {
-    true
-}
-
-// This should *NOT* produce a warning
-#[derive(Clone, Copy)]
-pub enum FooFighter {
-    Bar1,
-
-    Bar2,
-
-    Bar3,
-
-    Bar4
-}
-
-// This should *NOT* produce a warning because the empty line is inside a block comment
-#[crate_type = "lib"]
-/*
-
-*/
-pub struct S;
-
-// This should *NOT* produce a warning
-#[crate_type = "lib"]
-/* test */
-pub struct T;
-
-// This should *NOT* produce a warning
-// See https://github.com/rust-lang/rust-clippy/issues/5567
-#[fake_async_trait]
-pub trait Bazz {
-    fn foo() -> Vec<u8> {
-        let _i = "";
-
-
-
-        vec![]
-    }
-}
-
-#[derive(Clone, Copy)]
-#[dummy(string = "first line
-
-second line
-")]
-pub struct Args;
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr
deleted file mode 100644
index 889ccf6ba19..00000000000
--- a/src/tools/clippy/tests/ui/empty_line_after_doc_comments.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?
-  --> tests/ui/empty_line_after_doc_comments.rs:18:1
-   |
-LL | / /// This should produce a warning
-LL | |
-LL | | fn with_doc_and_newline() { assert!(true)}
-   | |_
-   |
-   = note: `-D clippy::empty-line-after-doc-comments` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_doc_comments)]`
-
-error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?
-  --> tests/ui/empty_line_after_doc_comments.rs:68:1
-   |
-LL | / /// This doc comment should produce a warning
-LL | |
-LL | | /** This is also a doc comment and should produce a warning
-LL | |  */
-...  |
-LL | | #[allow(missing_docs)]
-LL | | fn three_attributes() { assert!(true) }
-   | |_
-
-error: found an empty line after a doc comment. Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?
-  --> tests/ui/empty_line_after_doc_comments.rs:70:1
-   |
-LL | / /** This is also a doc comment and should produce a warning
-LL | |  */
-LL | |
-LL | | // This should *NOT* produce a warning
-...  |
-LL | | #[allow(missing_docs)]
-LL | | fn three_attributes() { assert!(true) }
-   | |_
-
-error: aborting due to 3 previous errors
-
diff --git a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs
deleted file mode 100644
index f147cf2cd5d..00000000000
--- a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-//@aux-build:proc_macro_attr.rs
-#![warn(clippy::empty_line_after_outer_attr)]
-#![allow(clippy::assertions_on_constants, clippy::duplicated_attributes)]
-#![feature(custom_inner_attributes)]
-#![rustfmt::skip]
-
-#[macro_use]
-extern crate proc_macro_attr;
-
-// This should produce a warning
-#[crate_type = "lib"]
-
-/// some comment
-fn with_one_newline_and_comment() { assert!(true) }
-
-// This should not produce a warning
-#[crate_type = "lib"]
-/// some comment
-fn with_no_newline_and_comment() { assert!(true) }
-
-
-// This should produce a warning
-#[crate_type = "lib"]
-
-fn with_one_newline() { assert!(true) }
-
-// This should produce a warning, too
-#[crate_type = "lib"]
-
-
-fn with_two_newlines() { assert!(true) }
-
-
-// This should produce a warning
-#[crate_type = "lib"]
-
-enum Baz {
-    One,
-    Two
-}
-
-// This should produce a warning
-#[crate_type = "lib"]
-
-struct Foo {
-    one: isize,
-    two: isize
-}
-
-// This should produce a warning
-#[crate_type = "lib"]
-
-mod foo {
-}
-
-/// This doc comment should not produce a warning
-
-/** This is also a doc comment and should not produce a warning
- */
-
-// This should not produce a warning
-#[allow(non_camel_case_types)]
-#[allow(missing_docs)]
-#[allow(missing_docs)]
-fn three_attributes() { assert!(true) }
-
-// This should not produce a warning
-#[doc = "
-Returns the escaped value of the textual representation of
-
-"]
-pub fn function() -> bool {
-    true
-}
-
-// This should not produce a warning
-#[derive(Clone, Copy)]
-pub enum FooFighter {
-    Bar1,
-
-    Bar2,
-
-    Bar3,
-
-    Bar4
-}
-
-// This should not produce a warning because the empty line is inside a block comment
-#[crate_type = "lib"]
-/*
-
-*/
-pub struct S;
-
-// This should not produce a warning
-#[crate_type = "lib"]
-/* test */
-pub struct T;
-
-// This should not produce a warning
-// See https://github.com/rust-lang/rust-clippy/issues/5567
-#[fake_async_trait]
-pub trait Bazz {
-    fn foo() -> Vec<u8> {
-        let _i = "";
-
-
-
-        vec![]
-    }
-}
-
-#[derive(Clone, Copy)]
-#[dummy(string = "first line
-
-second line
-")]
-pub struct Args;
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr b/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr
deleted file mode 100644
index b43e6e30da2..00000000000
--- a/src/tools/clippy/tests/ui/empty_line_after_outer_attribute.stderr
+++ /dev/null
@@ -1,54 +0,0 @@
-error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
-  --> tests/ui/empty_line_after_outer_attribute.rs:11:1
-   |
-LL | / #[crate_type = "lib"]
-LL | |
-LL | | /// some comment
-LL | | fn with_one_newline_and_comment() { assert!(true) }
-   | |_
-   |
-   = note: `-D clippy::empty-line-after-outer-attr` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::empty_line_after_outer_attr)]`
-
-error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
-  --> tests/ui/empty_line_after_outer_attribute.rs:23:1
-   |
-LL | / #[crate_type = "lib"]
-LL | |
-LL | | fn with_one_newline() { assert!(true) }
-   | |_
-
-error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
-  --> tests/ui/empty_line_after_outer_attribute.rs:28:1
-   |
-LL | / #[crate_type = "lib"]
-...  |
-LL | | fn with_two_newlines() { assert!(true) }
-   | |_
-
-error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
-  --> tests/ui/empty_line_after_outer_attribute.rs:35:1
-   |
-LL | / #[crate_type = "lib"]
-LL | |
-LL | | enum Baz {
-   | |_
-
-error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
-  --> tests/ui/empty_line_after_outer_attribute.rs:43:1
-   |
-LL | / #[crate_type = "lib"]
-LL | |
-LL | | struct Foo {
-   | |_
-
-error: found an empty line after an outer attribute. Perhaps you forgot to add a `!` to make it an inner attribute?
-  --> tests/ui/empty_line_after_outer_attribute.rs:51:1
-   |
-LL | / #[crate_type = "lib"]
-LL | |
-LL | | mod foo {
-   | |_
-
-error: aborting due to 6 previous errors
-
diff --git a/src/tools/clippy/tests/ui/empty_loop_no_std.rs b/src/tools/clippy/tests/ui/empty_loop_no_std.rs
index 5fe32351ed4..1bb895bda75 100644
--- a/src/tools/clippy/tests/ui/empty_loop_no_std.rs
+++ b/src/tools/clippy/tests/ui/empty_loop_no_std.rs
@@ -1,5 +1,5 @@
 //@compile-flags: -Clink-arg=-nostartfiles
-//@ignore-target-apple
+//@ignore-target: apple
 
 #![warn(clippy::empty_loop)]
 #![feature(lang_items, start, libc)]
diff --git a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs
index c50404c5047..37849179d6a 100644
--- a/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs
+++ b/src/tools/clippy/tests/ui/enum_clike_unportable_variant.rs
@@ -1,4 +1,4 @@
-//@ignore-32bit
+//@ignore-bitwidth: 32
 
 #![warn(clippy::enum_clike_unportable_variant)]
 #![allow(unused, non_upper_case_globals)]
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index ca422ee29c1..f1baf28200e 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -9,7 +9,8 @@
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
     clippy::useless_vec,
-    clippy::unnecessary_map_on_constructor
+    clippy::unnecessary_map_on_constructor,
+    clippy::needless_lifetimes
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index c0db91c03ef..c52a51880bf 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -9,7 +9,8 @@
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
     clippy::useless_vec,
-    clippy::unnecessary_map_on_constructor
+    clippy::unnecessary_map_on_constructor,
+    clippy::needless_lifetimes
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index 5540261fc57..1731a4377f5 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -1,5 +1,5 @@
 error: redundant closure
-  --> tests/ui/eta.rs:30:27
+  --> tests/ui/eta.rs:31:27
    |
 LL |     let a = Some(1u8).map(|a| foo(a));
    |                           ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
@@ -8,31 +8,31 @@ LL |     let a = Some(1u8).map(|a| foo(a));
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
 
 error: redundant closure
-  --> tests/ui/eta.rs:34:40
+  --> tests/ui/eta.rs:35:40
    |
 LL |     let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
    |                                        ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
 
 error: redundant closure
-  --> tests/ui/eta.rs:35:35
+  --> tests/ui/eta.rs:36:35
    |
 LL |     let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
    |                                   ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
 
 error: redundant closure
-  --> tests/ui/eta.rs:36:26
+  --> tests/ui/eta.rs:37:26
    |
 LL |     all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
    |                          ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
 
 error: redundant closure
-  --> tests/ui/eta.rs:43:27
+  --> tests/ui/eta.rs:44:27
    |
 LL |     let e = Some(1u8).map(|a| generic(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
 
 error: redundant closure
-  --> tests/ui/eta.rs:95:51
+  --> tests/ui/eta.rs:96:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    |                                                   ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
@@ -41,169 +41,169 @@ LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]`
 
 error: redundant closure
-  --> tests/ui/eta.rs:96:51
+  --> tests/ui/eta.rs:97:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
    |                                                   ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
 
 error: redundant closure
-  --> tests/ui/eta.rs:98:42
+  --> tests/ui/eta.rs:99:42
    |
 LL |     let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
    |                                          ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
 
 error: redundant closure
-  --> tests/ui/eta.rs:102:29
+  --> tests/ui/eta.rs:103:29
    |
 LL |     let e = Some("str").map(|s| s.to_string());
    |                             ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
 
 error: redundant closure
-  --> tests/ui/eta.rs:103:27
+  --> tests/ui/eta.rs:104:27
    |
 LL |     let e = Some('a').map(|s| s.to_uppercase());
    |                           ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
 
 error: redundant closure
-  --> tests/ui/eta.rs:105:65
+  --> tests/ui/eta.rs:106:65
    |
 LL |     let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
    |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
 
 error: redundant closure
-  --> tests/ui/eta.rs:168:22
+  --> tests/ui/eta.rs:169:22
    |
 LL |     requires_fn_once(|| x());
    |                      ^^^^^^ help: replace the closure with the function itself: `x`
 
 error: redundant closure
-  --> tests/ui/eta.rs:175:27
+  --> tests/ui/eta.rs:176:27
    |
 LL |     let a = Some(1u8).map(|a| foo_ptr(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
 
 error: redundant closure
-  --> tests/ui/eta.rs:180:27
+  --> tests/ui/eta.rs:181:27
    |
 LL |     let a = Some(1u8).map(|a| closure(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
 
 error: redundant closure
-  --> tests/ui/eta.rs:212:28
+  --> tests/ui/eta.rs:213:28
    |
 LL |     x.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> tests/ui/eta.rs:213:28
+  --> tests/ui/eta.rs:214:28
    |
 LL |     y.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> tests/ui/eta.rs:214:28
+  --> tests/ui/eta.rs:215:28
    |
 LL |     z.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
 
 error: redundant closure
-  --> tests/ui/eta.rs:221:21
+  --> tests/ui/eta.rs:222:21
    |
 LL |         Some(1).map(|n| closure(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
 
 error: redundant closure
-  --> tests/ui/eta.rs:225:21
+  --> tests/ui/eta.rs:226:21
    |
 LL |         Some(1).map(|n| in_loop(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
 
 error: redundant closure
-  --> tests/ui/eta.rs:318:18
+  --> tests/ui/eta.rs:319:18
    |
 LL |     takes_fn_mut(|| f());
    |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:321:19
+  --> tests/ui/eta.rs:322:19
    |
 LL |     takes_fn_once(|| f());
    |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:325:26
+  --> tests/ui/eta.rs:326:26
    |
 LL |     move || takes_fn_mut(|| f_used_once())
    |                          ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
 
 error: redundant closure
-  --> tests/ui/eta.rs:337:19
+  --> tests/ui/eta.rs:338:19
    |
 LL |     array_opt.map(|a| a.as_slice());
    |                   ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
 
 error: redundant closure
-  --> tests/ui/eta.rs:340:19
+  --> tests/ui/eta.rs:341:19
    |
 LL |     slice_opt.map(|s| s.len());
    |                   ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
 
 error: redundant closure
-  --> tests/ui/eta.rs:343:17
+  --> tests/ui/eta.rs:344:17
    |
 LL |     ptr_opt.map(|p| p.is_null());
    |                 ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
 
 error: redundant closure
-  --> tests/ui/eta.rs:347:17
+  --> tests/ui/eta.rs:348:17
    |
 LL |     dyn_opt.map(|d| d.method_on_dyn());
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
 
 error: redundant closure
-  --> tests/ui/eta.rs:407:19
+  --> tests/ui/eta.rs:408:19
    |
 LL |     let _ = f(&0, |x, y| f2(x, y));
    |                   ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
 
 error: redundant closure
-  --> tests/ui/eta.rs:435:22
+  --> tests/ui/eta.rs:436:22
    |
 LL |             test.map(|t| t.method())
    |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:439:22
+  --> tests/ui/eta.rs:440:22
    |
 LL |             test.map(|t| t.method())
    |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:452:18
+  --> tests/ui/eta.rs:453:18
    |
 LL |         test.map(|t| t.method())
    |                  ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:459:30
+  --> tests/ui/eta.rs:460:30
    |
 LL |                     test.map(|t| t.method())
    |                              ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:478:38
+  --> tests/ui/eta.rs:479:38
    |
 LL |         let x = Box::new(|| None.map(|x| f(x)));
    |                                      ^^^^^^^^ help: replace the closure with the function itself: `&f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:482:38
+  --> tests/ui/eta.rs:483:38
    |
 LL |         let x = Box::new(|| None.map(|x| f(x)));
    |                                      ^^^^^^^^ help: replace the closure with the function itself: `f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:499:35
+  --> tests/ui/eta.rs:500:35
    |
 LL |         let _field = bind.or_else(|| get_default()).unwrap();
    |                                   ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default`
diff --git a/src/tools/clippy/tests/ui/exit1.rs b/src/tools/clippy/tests/ui/exit1.rs
index a89f6dd4ca0..36b3c42fd99 100644
--- a/src/tools/clippy/tests/ui/exit1.rs
+++ b/src/tools/clippy/tests/ui/exit1.rs
@@ -1,4 +1,4 @@
-#[warn(clippy::exit)]
+#![warn(clippy::exit)]
 
 fn not_main() {
     if true {
diff --git a/src/tools/clippy/tests/ui/exit2.rs b/src/tools/clippy/tests/ui/exit2.rs
index d5ff93fb9cc..9bbb7b073a4 100644
--- a/src/tools/clippy/tests/ui/exit2.rs
+++ b/src/tools/clippy/tests/ui/exit2.rs
@@ -1,4 +1,4 @@
-#[warn(clippy::exit)]
+#![warn(clippy::exit)]
 
 fn also_not_main() {
     std::process::exit(3);
diff --git a/src/tools/clippy/tests/ui/exit3.rs b/src/tools/clippy/tests/ui/exit3.rs
index 9dc0e1015a4..cab908aafd3 100644
--- a/src/tools/clippy/tests/ui/exit3.rs
+++ b/src/tools/clippy/tests/ui/exit3.rs
@@ -1,4 +1,4 @@
-#[warn(clippy::exit)]
+#![warn(clippy::exit)]
 
 fn main() {
     if true {
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.fixed b/src/tools/clippy/tests/ui/expect_fun_call.fixed
index 6ac3c43ad29..8f800c71941 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/expect_fun_call.fixed
@@ -5,8 +5,6 @@
     clippy::unnecessary_literal_unwrap
 )]
 
-/// Checks implementation of the `EXPECT_FUN_CALL` lint
-
 macro_rules! one {
     () => {
         1
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.rs b/src/tools/clippy/tests/ui/expect_fun_call.rs
index 22ea2db504f..b5cfafb2993 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.rs
+++ b/src/tools/clippy/tests/ui/expect_fun_call.rs
@@ -5,8 +5,6 @@
     clippy::unnecessary_literal_unwrap
 )]
 
-/// Checks implementation of the `EXPECT_FUN_CALL` lint
-
 macro_rules! one {
     () => {
         1
diff --git a/src/tools/clippy/tests/ui/expect_fun_call.stderr b/src/tools/clippy/tests/ui/expect_fun_call.stderr
index b41904d04fa..bae853ac5c1 100644
--- a/src/tools/clippy/tests/ui/expect_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/expect_fun_call.stderr
@@ -1,5 +1,5 @@
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:37:26
+  --> tests/ui/expect_fun_call.rs:35:26
    |
 LL |     with_none_and_format.expect(&format!("Error {}: fake error", error_code));
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))`
@@ -8,85 +8,85 @@ LL |     with_none_and_format.expect(&format!("Error {}: fake error", error_code
    = help: to override `-D warnings` add `#[allow(clippy::expect_fun_call)]`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:40:26
+  --> tests/ui/expect_fun_call.rs:38:26
    |
 LL |     with_none_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", error_code))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:43:37
+  --> tests/ui/expect_fun_call.rs:41:37
    |
 LL |     with_none_and_format_with_macro.expect(format!("Error {}: fake error", one!()).as_str());
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("Error {}: fake error", one!()))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:53:25
+  --> tests/ui/expect_fun_call.rs:51:25
    |
 LL |     with_err_and_format.expect(&format!("Error {}: fake error", error_code));
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:56:25
+  --> tests/ui/expect_fun_call.rs:54:25
    |
 LL |     with_err_and_as_str.expect(format!("Error {}: fake error", error_code).as_str());
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|_| panic!("Error {}: fake error", error_code))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:68:17
+  --> tests/ui/expect_fun_call.rs:66:17
    |
 LL |     Some("foo").expect(format!("{} {}", 1, 2).as_ref());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{} {}", 1, 2))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:89:21
+  --> tests/ui/expect_fun_call.rs:87:21
    |
 LL |         Some("foo").expect(&get_string());
    |                     ^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:90:21
+  --> tests/ui/expect_fun_call.rs:88:21
    |
 LL |         Some("foo").expect(get_string().as_ref());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:91:21
+  --> tests/ui/expect_fun_call.rs:89:21
    |
 LL |         Some("foo").expect(get_string().as_str());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_string()) })`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:93:21
+  --> tests/ui/expect_fun_call.rs:91:21
    |
 LL |         Some("foo").expect(get_static_str());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_static_str()) })`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:94:21
+  --> tests/ui/expect_fun_call.rs:92:21
    |
 LL |         Some("foo").expect(get_non_static_str(&0));
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| { panic!("{}", get_non_static_str(&0).to_string()) })`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:98:16
+  --> tests/ui/expect_fun_call.rs:96:16
    |
 LL |     Some(true).expect(&format!("key {}, {}", 1, 2));
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("key {}, {}", 1, 2))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:104:17
+  --> tests/ui/expect_fun_call.rs:102:17
    |
 LL |         opt_ref.expect(&format!("{:?}", opt_ref));
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{:?}", opt_ref))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:108:20
+  --> tests/ui/expect_fun_call.rs:106:20
    |
 LL |     format_capture.expect(&format!("{error_code}"));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}"))`
 
 error: use of `expect` followed by a function call
-  --> tests/ui/expect_fun_call.rs:111:30
+  --> tests/ui/expect_fun_call.rs:109:30
    |
 LL |     format_capture_and_value.expect(&format!("{error_code}, {}", 1));
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unwrap_or_else(|| panic!("{error_code}, {}", 1))`
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
index 255b2c5a220..9d476259b87 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
@@ -10,7 +10,8 @@
     clippy::redundant_field_names,
     clippy::too_many_arguments,
     clippy::borrow_deref_ref,
-    clippy::let_unit_value
+    clippy::let_unit_value,
+    clippy::needless_lifetimes
 )]
 
 trait CallableStr {
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
index 99906999f01..23307c837f0 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
@@ -10,7 +10,8 @@
     clippy::redundant_field_names,
     clippy::too_many_arguments,
     clippy::borrow_deref_ref,
-    clippy::let_unit_value
+    clippy::let_unit_value,
+    clippy::needless_lifetimes
 )]
 
 trait CallableStr {
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
index 53784934f63..0b05a554eb1 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
@@ -1,5 +1,5 @@
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:68:19
+  --> tests/ui/explicit_auto_deref.rs:69:19
    |
 LL |     let _: &str = &*s;
    |                   ^^^ help: try: `&s`
@@ -8,271 +8,271 @@ LL |     let _: &str = &*s;
    = help: to override `-D warnings` add `#[allow(clippy::explicit_auto_deref)]`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:69:19
+  --> tests/ui/explicit_auto_deref.rs:70:19
    |
 LL |     let _: &str = &*{ String::new() };
    |                   ^^^^^^^^^^^^^^^^^^^ help: try: `&{ String::new() }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:70:19
+  --> tests/ui/explicit_auto_deref.rs:71:19
    |
 LL |     let _: &str = &mut *{ String::new() };
    |                   ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut { String::new() }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:74:11
+  --> tests/ui/explicit_auto_deref.rs:75:11
    |
 LL |     f_str(&*s);
    |           ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:78:13
+  --> tests/ui/explicit_auto_deref.rs:79:13
    |
 LL |     f_str_t(&*s, &*s); // Don't lint second param.
    |             ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:81:24
+  --> tests/ui/explicit_auto_deref.rs:82:24
    |
 LL |     let _: &Box<i32> = &**b;
    |                        ^^^^ help: try: `&b`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:87:7
+  --> tests/ui/explicit_auto_deref.rs:88:7
    |
 LL |     c(&*s);
    |       ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:93:9
+  --> tests/ui/explicit_auto_deref.rs:94:9
    |
 LL |         &**x
    |         ^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:97:11
+  --> tests/ui/explicit_auto_deref.rs:98:11
    |
 LL |         { &**x }
    |           ^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:101:9
+  --> tests/ui/explicit_auto_deref.rs:102:9
    |
 LL |         &**{ x }
    |         ^^^^^^^^ help: try: `{ x }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:105:9
+  --> tests/ui/explicit_auto_deref.rs:106:9
    |
 LL |         &***x
    |         ^^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:122:12
+  --> tests/ui/explicit_auto_deref.rs:123:12
    |
 LL |         f1(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:123:12
+  --> tests/ui/explicit_auto_deref.rs:124:12
    |
 LL |         f2(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:124:12
+  --> tests/ui/explicit_auto_deref.rs:125:12
    |
 LL |         f3(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:125:27
+  --> tests/ui/explicit_auto_deref.rs:126:27
    |
 LL |         f4.callable_str()(&*x);
    |                           ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:126:12
+  --> tests/ui/explicit_auto_deref.rs:127:12
    |
 LL |         f5(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:127:12
+  --> tests/ui/explicit_auto_deref.rs:128:12
    |
 LL |         f6(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:128:27
+  --> tests/ui/explicit_auto_deref.rs:129:27
    |
 LL |         f7.callable_str()(&*x);
    |                           ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:129:25
+  --> tests/ui/explicit_auto_deref.rs:130:25
    |
 LL |         f8.callable_t()(&*x);
    |                         ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:130:12
+  --> tests/ui/explicit_auto_deref.rs:131:12
    |
 LL |         f9(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:131:13
+  --> tests/ui/explicit_auto_deref.rs:132:13
    |
 LL |         f10(&*x);
    |             ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:132:26
+  --> tests/ui/explicit_auto_deref.rs:133:26
    |
 LL |         f11.callable_t()(&*x);
    |                          ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:136:16
+  --> tests/ui/explicit_auto_deref.rs:137:16
    |
 LL |     let _ = S1(&*s);
    |                ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:141:21
+  --> tests/ui/explicit_auto_deref.rs:142:21
    |
 LL |     let _ = S2 { s: &*s };
    |                     ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:157:30
+  --> tests/ui/explicit_auto_deref.rs:158:30
    |
 LL |             let _ = Self::S1(&**s);
    |                              ^^^^ help: try: `s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:158:35
+  --> tests/ui/explicit_auto_deref.rs:159:35
    |
 LL |             let _ = Self::S2 { s: &**s };
    |                                   ^^^^ help: try: `s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:161:20
+  --> tests/ui/explicit_auto_deref.rs:162:20
    |
 LL |     let _ = E1::S1(&*s);
    |                    ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:162:25
+  --> tests/ui/explicit_auto_deref.rs:163:25
    |
 LL |     let _ = E1::S2 { s: &*s };
    |                         ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:180:13
+  --> tests/ui/explicit_auto_deref.rs:181:13
    |
 LL |     let _ = (*b).foo;
    |             ^^^^ help: try: `b`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:181:13
+  --> tests/ui/explicit_auto_deref.rs:182:13
    |
 LL |     let _ = (**b).foo;
    |             ^^^^^ help: try: `b`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:196:19
+  --> tests/ui/explicit_auto_deref.rs:197:19
    |
 LL |     let _ = f_str(*ref_str);
    |                   ^^^^^^^^ help: try: `ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:198:19
+  --> tests/ui/explicit_auto_deref.rs:199:19
    |
 LL |     let _ = f_str(**ref_ref_str);
    |                   ^^^^^^^^^^^^^ help: try: `ref_ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:208:12
+  --> tests/ui/explicit_auto_deref.rs:209:12
    |
 LL |     f_str(&&*ref_str); // `needless_borrow` will suggest removing both references
    |            ^^^^^^^^^ help: try: `ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:209:12
+  --> tests/ui/explicit_auto_deref.rs:210:12
    |
 LL |     f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference
    |            ^^^^^^^^^^ help: try: `ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:218:41
+  --> tests/ui/explicit_auto_deref.rs:219:41
    |
 LL |     let _ = || -> &'static str { return *s };
    |                                         ^^ help: try: `s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:237:9
+  --> tests/ui/explicit_auto_deref.rs:238:9
    |
 LL |         &**x
    |         ^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:260:8
+  --> tests/ui/explicit_auto_deref.rs:261:8
    |
 LL |     c1(*x);
    |        ^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:263:20
+  --> tests/ui/explicit_auto_deref.rs:264:20
    |
 LL |             return *x;
    |                    ^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:265:9
+  --> tests/ui/explicit_auto_deref.rs:266:9
    |
 LL |         *x
    |         ^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:299:20
+  --> tests/ui/explicit_auto_deref.rs:300:20
    |
 LL |         Some(x) => &mut *x,
    |                    ^^^^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:332:22
+  --> tests/ui/explicit_auto_deref.rs:333:22
    |
 LL |         let _ = &mut (*{ x.u }).x;
    |                      ^^^^^^^^^^ help: try: `{ x.u }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:338:22
+  --> tests/ui/explicit_auto_deref.rs:339:22
    |
 LL |         let _ = &mut (**x.u).x;
    |                      ^^^^^^^ help: try: `(*x.u)`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:339:22
+  --> tests/ui/explicit_auto_deref.rs:340:22
    |
 LL |         let _ = &mut (**{ x.u }).x;
    |                      ^^^^^^^^^^^ help: try: `{ x.u }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:343:22
+  --> tests/ui/explicit_auto_deref.rs:344:22
    |
 LL |         let _ = &mut (*x.u).x;
    |                      ^^^^^^ help: try: `x.u`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:344:22
+  --> tests/ui/explicit_auto_deref.rs:345:22
    |
 LL |         let _ = &mut (*{ x.u }).x;
    |                      ^^^^^^^^^^ help: try: `{ x.u }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:367:13
+  --> tests/ui/explicit_auto_deref.rs:368:13
    |
 LL |         foo(&*wrapped_bar);
    |             ^^^^^^^^^^^^^ help: try: `&wrapped_bar`
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
index cdfaf8d3afe..17d2ed9f50c 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
@@ -114,9 +114,17 @@ mod second_case {
         fn hey();
     }
 
+    // Should lint. The response to the above comment incorrectly called this a false positive. The
+    // lifetime `'a` can be removed, as demonstrated below.
     impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
         fn hey() {}
     }
+
+    struct OtherBox<T: ?Sized>(Box<T>);
+
+    impl<T: Source + ?Sized> Source for OtherBox<T> {
+        fn hey() {}
+    }
 }
 
 // Should not lint
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
index 56292cb5d1a..85fbb7568ff 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
@@ -37,5 +37,11 @@ error: this lifetime isn't used in the function definition
 LL |         pub fn something<'c>() -> Self {
    |                          ^^
 
-error: aborting due to 6 previous errors
+error: this lifetime isn't used in the impl
+  --> tests/ui/extra_unused_lifetimes.rs:119:10
+   |
+LL |     impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
+   |          ^^
+
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.rs b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
index 620cffb4f04..2a432751952 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.rs
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
@@ -192,8 +192,8 @@ struct WrapperMulti<T, U> {
 }
 
 mod issue6312 {
-    use std::sync::atomic::AtomicBool;
     use std::sync::Arc;
+    use std::sync::atomic::AtomicBool;
 
     // do not lint: type implements `Drop` but not all fields are `Copy`
     #[derive(Clone, Default)]
diff --git a/src/tools/clippy/tests/ui/float_cmp.rs b/src/tools/clippy/tests/ui/float_cmp.rs
index 78dd2c6c01c..a1dfd1954fc 100644
--- a/src/tools/clippy/tests/ui/float_cmp.rs
+++ b/src/tools/clippy/tests/ui/float_cmp.rs
@@ -8,7 +8,7 @@
     clippy::unnecessary_operation,
     clippy::cast_lossless
 )]
-//@no-rustfix
+//@no-rustfix: suggestions have an error margin placeholder
 use std::ops::Add;
 
 const ZERO: f32 = 0.0;
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.rs b/src/tools/clippy/tests/ui/float_cmp_const.rs
index 08180556437..ba760a18f28 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.rs
+++ b/src/tools/clippy/tests/ui/float_cmp_const.rs
@@ -1,5 +1,4 @@
-// does not test any rustfixable lints
-//@no-rustfix
+//@no-rustfix: suggestions have an error margin placeholder
 #![warn(clippy::float_cmp_const)]
 #![allow(clippy::float_cmp)]
 #![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.stderr b/src/tools/clippy/tests/ui/float_cmp_const.stderr
index 4f88746e958..e0cd6faf4b3 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp_const.stderr
@@ -1,5 +1,5 @@
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:16:5
+  --> tests/ui/float_cmp_const.rs:15:5
    |
 LL |     1f32 == ONE;
    |     ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin`
@@ -8,43 +8,43 @@ LL |     1f32 == ONE;
    = help: to override `-D warnings` add `#[allow(clippy::float_cmp_const)]`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:18:5
+  --> tests/ui/float_cmp_const.rs:17:5
    |
 LL |     TWO == ONE;
    |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:20:5
+  --> tests/ui/float_cmp_const.rs:19:5
    |
 LL |     TWO != ONE;
    |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:22:5
+  --> tests/ui/float_cmp_const.rs:21:5
    |
 LL |     ONE + ONE == TWO;
    |     ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:25:5
+  --> tests/ui/float_cmp_const.rs:24:5
    |
 LL |     x as f32 == ONE;
    |     ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:29:5
+  --> tests/ui/float_cmp_const.rs:28:5
    |
 LL |     v == ONE;
    |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:31:5
+  --> tests/ui/float_cmp_const.rs:30:5
    |
 LL |     v != ONE;
    |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin`
 
 error: strict comparison of `f32` or `f64` constant arrays
-  --> tests/ui/float_cmp_const.rs:64:5
+  --> tests/ui/float_cmp_const.rs:63:5
    |
 LL |     NON_ZERO_ARRAY == NON_ZERO_ARRAY2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/float_equality_without_abs.rs b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
index 2b67c8bec10..500b3035390 100644
--- a/src/tools/clippy/tests/ui/float_equality_without_abs.rs
+++ b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::float_equality_without_abs)]
-//@no-rustfix
+//@no-rustfix: suggestions cause type ambiguity
 
 // FIXME(f16_f128): add tests for these types when abs is available
 
diff --git a/src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs b/src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs
index 47c113d61c0..8ea75fae89b 100644
--- a/src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs
+++ b/src/tools/clippy/tests/ui/floating_point_arithmetic_nostd.rs
@@ -4,7 +4,7 @@
 #![no_std]
 
 // The following should not lint, as the suggested methods `{f16,f32,f64,f128}.mul_add()`
-// and ``{f16,f32,f64,f128}::abs()` are not available in no_std
+// and `{f16,f32,f64,f128}::abs()` are not available in no_std
 
 pub fn mul_add() {
     let a: f64 = 1234.567;
diff --git a/src/tools/clippy/tests/ui/format_args.fixed b/src/tools/clippy/tests/ui/format_args.fixed
index 4d812f6bf1d..20d1e3d9050 100644
--- a/src/tools/clippy/tests/ui/format_args.fixed
+++ b/src/tools/clippy/tests/ui/format_args.fixed
@@ -8,7 +8,7 @@
     clippy::uninlined_format_args
 )]
 
-use std::io::{stdout, Write};
+use std::io::{Write, stdout};
 use std::ops::Deref;
 use std::panic::Location;
 
diff --git a/src/tools/clippy/tests/ui/format_args.rs b/src/tools/clippy/tests/ui/format_args.rs
index d242623feb6..18ab223db78 100644
--- a/src/tools/clippy/tests/ui/format_args.rs
+++ b/src/tools/clippy/tests/ui/format_args.rs
@@ -8,7 +8,7 @@
     clippy::uninlined_format_args
 )]
 
-use std::io::{stdout, Write};
+use std::io::{Write, stdout};
 use std::ops::Deref;
 use std::panic::Location;
 
diff --git a/src/tools/clippy/tests/ui/format_args_unfixable.rs b/src/tools/clippy/tests/ui/format_args_unfixable.rs
index b7492e38b25..f04715f4f01 100644
--- a/src/tools/clippy/tests/ui/format_args_unfixable.rs
+++ b/src/tools/clippy/tests/ui/format_args_unfixable.rs
@@ -2,7 +2,7 @@
 #![allow(unused)]
 #![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::uninlined_format_args)]
 
-use std::io::{stdout, Error, ErrorKind, Write};
+use std::io::{Error, ErrorKind, Write, stdout};
 use std::ops::Deref;
 use std::panic::Location;
 
diff --git a/src/tools/clippy/tests/ui/get_unwrap.fixed b/src/tools/clippy/tests/ui/get_unwrap.fixed
index 62beb195939..2dd3c30a4e2 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/get_unwrap.fixed
@@ -70,6 +70,7 @@ fn main() {
 mod issue9909 {
     #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
 
+    #[allow(unconditional_panic)]
     fn reduced() {
         let f = &[1, 2, 3];
 
diff --git a/src/tools/clippy/tests/ui/get_unwrap.rs b/src/tools/clippy/tests/ui/get_unwrap.rs
index 1e09ff5c67e..94226564cac 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.rs
+++ b/src/tools/clippy/tests/ui/get_unwrap.rs
@@ -70,6 +70,7 @@ fn main() {
 mod issue9909 {
     #![allow(clippy::identity_op, clippy::unwrap_used, dead_code)]
 
+    #[allow(unconditional_panic)]
     fn reduced() {
         let f = &[1, 2, 3];
 
diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr
index 0f8b279da1e..8eacb249c60 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/get_unwrap.stderr
@@ -266,7 +266,7 @@ LL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();
    = help: consider using `expect()` to provide a better panic message
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:77:24
+  --> tests/ui/get_unwrap.rs:78:24
    |
 LL |         let _x: &i32 = f.get(1 + 2).unwrap();
    |                        ^^^^^^^^^^^^^^^^^^^^^
@@ -277,7 +277,7 @@ LL |         let _x: &i32 = &f[1 + 2];
    |                        ~~~~~~~~~
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:80:18
+  --> tests/ui/get_unwrap.rs:81:18
    |
 LL |         let _x = f.get(1 + 2).unwrap().to_string();
    |                  ^^^^^^^^^^^^^^^^^^^^^
@@ -288,7 +288,7 @@ LL |         let _x = f[1 + 2].to_string();
    |                  ~~~~~~~~
 
 error: called `.get().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:83:18
+  --> tests/ui/get_unwrap.rs:84:18
    |
 LL |         let _x = f.get(1 + 2).unwrap().abs();
    |                  ^^^^^^^^^^^^^^^^^^^^^
@@ -299,7 +299,7 @@ LL |         let _x = f[1 + 2].abs();
    |                  ~~~~~~~~
 
 error: called `.get_mut().unwrap()` on a slice
-  --> tests/ui/get_unwrap.rs:100:33
+  --> tests/ui/get_unwrap.rs:101:33
    |
 LL |                         let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.fixed b/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
index ad13372a68b..1f47dddcbc4 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.fixed
@@ -113,6 +113,10 @@ fn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> {
     Ok(())
 }
 
+fn issue13407(s: &str) -> Option<bool> {
+    (s == "1").then(|| true)
+}
+
 const fn issue12103(x: u32) -> Option<u32> {
     // Should not issue an error in `const` context
     if x > 42 { Some(150) } else { None }
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.rs b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
index 73edbb7da2a..499f008fb87 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.rs
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.rs
@@ -131,6 +131,10 @@ fn issue11394(b: bool, v: Result<(), ()>) -> Result<(), ()> {
     Ok(())
 }
 
+fn issue13407(s: &str) -> Option<bool> {
+    if s == "1" { Some(true) } else { None }
+}
+
 const fn issue12103(x: u32) -> Option<u32> {
     // Should not issue an error in `const` context
     if x > 42 { Some(150) } else { None }
diff --git a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
index aed01e026cb..e7bc66b3ee8 100644
--- a/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
+++ b/src/tools/clippy/tests/ui/if_then_some_else_none.stderr
@@ -52,5 +52,11 @@ LL | |         None
 LL | |     };
    | |_____^ help: try: `foo().then(||  { println!("true!"); 150 })`
 
-error: aborting due to 5 previous errors
+error: this could be simplified with `bool::then`
+  --> tests/ui/if_then_some_else_none.rs:135:5
+   |
+LL |     if s == "1" { Some(true) } else { None }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(s == "1").then(|| true)`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
index 118f0b48895..fde40437309 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
@@ -21,15 +21,12 @@ fn main() {
     let _ = foo().map_err(|()| todo!());
     //~^ ERROR: matching over `()` is more explicit
 
-    println!(
-        "{:?}",
-        match foo() {
-            Ok(()) => {},
-            //~^ ERROR: matching over `()` is more explicit
-            Err(()) => {},
-            //~^ ERROR: matching over `()` is more explicit
-        }
-    );
+    println!("{:?}", match foo() {
+        Ok(()) => {},
+        //~^ ERROR: matching over `()` is more explicit
+        Err(()) => {},
+        //~^ ERROR: matching over `()` is more explicit
+    });
 }
 
 // ignored_unit_patterns in derive macro should be ok
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
index 92feb9e6c28..528844d76e0 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
@@ -21,15 +21,12 @@ fn main() {
     let _ = foo().map_err(|_| todo!());
     //~^ ERROR: matching over `()` is more explicit
 
-    println!(
-        "{:?}",
-        match foo() {
-            Ok(_) => {},
-            //~^ ERROR: matching over `()` is more explicit
-            Err(_) => {},
-            //~^ ERROR: matching over `()` is more explicit
-        }
-    );
+    println!("{:?}", match foo() {
+        Ok(_) => {},
+        //~^ ERROR: matching over `()` is more explicit
+        Err(_) => {},
+        //~^ ERROR: matching over `()` is more explicit
+    });
 }
 
 // ignored_unit_patterns in derive macro should be ok
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
index 00a254e3919..54ff4454d6b 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
@@ -26,31 +26,31 @@ LL |     let _ = foo().map_err(|_| todo!());
    |                            ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:27:16
+  --> tests/ui/ignored_unit_patterns.rs:25:12
    |
-LL |             Ok(_) => {},
-   |                ^ help: use `()` instead of `_`: `()`
+LL |         Ok(_) => {},
+   |            ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:29:17
+  --> tests/ui/ignored_unit_patterns.rs:27:13
    |
-LL |             Err(_) => {},
-   |                 ^ help: use `()` instead of `_`: `()`
+LL |         Err(_) => {},
+   |             ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:41:9
+  --> tests/ui/ignored_unit_patterns.rs:38:9
    |
 LL |     let _ = foo().unwrap();
    |         ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:50:13
+  --> tests/ui/ignored_unit_patterns.rs:47:13
    |
 LL |         (1, _) => unimplemented!(),
    |             ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:57:13
+  --> tests/ui/ignored_unit_patterns.rs:54:13
    |
 LL |     for (x, _) in v {
    |             ^ help: use `()` instead of `_`: `()`
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
index 27f679797dd..81cc1494914 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
@@ -184,18 +184,18 @@ fn main() {
     let mut m = Mock;
     let mut u_32 = 3000;
     let a = 200;
-    let mut _b = 8;
+    let mut b = 8;
 
     if m != 0 {
         m -= 1;
     }
 
     if a > 0 {
-        _b -= 1;
+        b -= 1;
     }
 
     if 0 > a {
-        _b -= 1;
+        b -= 1;
     }
 
     if u_32 > 0 {
@@ -214,4 +214,11 @@ fn main() {
     } else if u_32 > 0 {
         u_32 -= 1;
     }
+
+    let result = if a < b {
+        println!("we shouldn't remove this");
+        0
+    } else {
+        a - b
+    };
 }
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
index 5d7b95d2c65..f73396ebd27 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
@@ -230,18 +230,18 @@ fn main() {
     let mut m = Mock;
     let mut u_32 = 3000;
     let a = 200;
-    let mut _b = 8;
+    let mut b = 8;
 
     if m != 0 {
         m -= 1;
     }
 
     if a > 0 {
-        _b -= 1;
+        b -= 1;
     }
 
     if 0 > a {
-        _b -= 1;
+        b -= 1;
     }
 
     if u_32 > 0 {
@@ -260,4 +260,11 @@ fn main() {
     } else if u_32 > 0 {
         u_32 -= 1;
     }
+
+    let result = if a < b {
+        println!("we shouldn't remove this");
+        0
+    } else {
+        a - b
+    };
 }
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.rs b/src/tools/clippy/tests/ui/incompatible_msrv.rs
index 8ef1f554bc3..c23df223d50 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.rs
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.rs
@@ -2,8 +2,8 @@
 #![feature(custom_inner_attributes)]
 #![clippy::msrv = "1.3.0"]
 
-use std::collections::hash_map::Entry;
 use std::collections::HashMap;
+use std::collections::hash_map::Entry;
 use std::future::Future;
 use std::thread::sleep;
 use std::time::Duration;
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
index 5bbdabcaad1..a4cb50bd682 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
@@ -1,5 +1,5 @@
 #![deny(clippy::index_refutable_slice)]
-#![allow(clippy::uninlined_format_args)]
+#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes)]
 
 //@no-rustfix: need to change the suggestion to a multipart suggestion
 
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
index eeddc2349a1..092e875a255 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
@@ -24,11 +24,8 @@ fn main() {
         let _a: A = std::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr());
 
         let _a: A = std::ptr::replace(core::ptr::NonNull::dangling().as_ptr(), A);
-
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(core::ptr::NonNull::dangling().as_ptr(), 0);
+        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
+        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
 
         std::ptr::swap::<A>(core::ptr::NonNull::dangling().as_ptr(), &mut A);
         std::ptr::swap::<A>(&mut A, core::ptr::NonNull::dangling().as_ptr());
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
index 8569b774084..480b6642a3e 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
@@ -24,10 +24,7 @@ fn main() {
         let _a: A = std::ptr::read_volatile(std::ptr::null_mut());
 
         let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
-
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null(), 0);
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0);
-
+        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
         let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
 
         std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
index 54d79ba1aeb..a0be2c0ad75 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
@@ -85,70 +85,52 @@ LL |         let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
    |                                       ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:28:69
-   |
-LL |         let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null(), 0);
-   |                                                                     ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:29:69
-   |
-LL |         let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0);
-   |                                                                     ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:31:73
-   |
-LL |         let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
-   |                                                                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:33:29
+  --> tests/ui/invalid_null_ptr_usage.rs:30:29
    |
 LL |         std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
    |                             ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:34:37
+  --> tests/ui/invalid_null_ptr_usage.rs:31:37
    |
 LL |         std::ptr::swap::<A>(&mut A, std::ptr::null_mut());
    |                                     ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:36:44
+  --> tests/ui/invalid_null_ptr_usage.rs:33:44
    |
 LL |         std::ptr::swap_nonoverlapping::<A>(std::ptr::null_mut(), &mut A, 0);
    |                                            ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:37:52
+  --> tests/ui/invalid_null_ptr_usage.rs:34:52
    |
 LL |         std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::null_mut(), 0);
    |                                                    ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:39:25
+  --> tests/ui/invalid_null_ptr_usage.rs:36:25
    |
 LL |         std::ptr::write(std::ptr::null_mut(), A);
    |                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:41:35
+  --> tests/ui/invalid_null_ptr_usage.rs:38:35
    |
 LL |         std::ptr::write_unaligned(std::ptr::null_mut(), A);
    |                                   ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:43:34
+  --> tests/ui/invalid_null_ptr_usage.rs:40:34
    |
 LL |         std::ptr::write_volatile(std::ptr::null_mut(), A);
    |                                  ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:45:40
+  --> tests/ui/invalid_null_ptr_usage.rs:42:40
    |
 LL |         std::ptr::write_bytes::<usize>(std::ptr::null_mut(), 42, 0);
    |                                        ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
-error: aborting due to 25 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.rs b/src/tools/clippy/tests/ui/iter_without_into_iter.rs
index 3054d848efb..d5b28e45453 100644
--- a/src/tools/clippy/tests/ui/iter_without_into_iter.rs
+++ b/src/tools/clippy/tests/ui/iter_without_into_iter.rs
@@ -1,6 +1,7 @@
 //@no-rustfix
 //@aux-build:proc_macros.rs
 #![warn(clippy::iter_without_into_iter)]
+#![allow(clippy::needless_lifetimes)]
 extern crate proc_macros;
 
 pub struct S1;
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 382a7606f48..7c42fa1dd89 100644
--- a/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
+++ b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
@@ -1,5 +1,5 @@
 error: `iter` method without an `IntoIterator` impl for `&S1`
-  --> tests/ui/iter_without_into_iter.rs:8:5
+  --> tests/ui/iter_without_into_iter.rs:9:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'_, u8> {
 LL | |
@@ -22,7 +22,7 @@ LL + }
    |
 
 error: `iter_mut` method without an `IntoIterator` impl for `&mut S1`
-  --> tests/ui/iter_without_into_iter.rs:12:5
+  --> tests/ui/iter_without_into_iter.rs:13:5
    |
 LL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
 LL | |
@@ -43,7 +43,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&S3<'a>`
-  --> tests/ui/iter_without_into_iter.rs:28:5
+  --> tests/ui/iter_without_into_iter.rs:29:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'_, u8> {
 LL | |
@@ -64,7 +64,7 @@ LL + }
    |
 
 error: `iter_mut` method without an `IntoIterator` impl for `&mut S3<'a>`
-  --> tests/ui/iter_without_into_iter.rs:32:5
+  --> tests/ui/iter_without_into_iter.rs:33:5
    |
 LL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
 LL | |
@@ -85,7 +85,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&S8<T>`
-  --> tests/ui/iter_without_into_iter.rs:69:5
+  --> tests/ui/iter_without_into_iter.rs:70:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'static, T> {
 LL | |         todo!()
@@ -105,7 +105,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&S9<T>`
-  --> tests/ui/iter_without_into_iter.rs:77:5
+  --> tests/ui/iter_without_into_iter.rs:78:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'_, T> {
 LL | |
@@ -126,7 +126,7 @@ LL + }
    |
 
 error: `iter_mut` method without an `IntoIterator` impl for `&mut S9<T>`
-  --> tests/ui/iter_without_into_iter.rs:81:5
+  --> tests/ui/iter_without_into_iter.rs:82:5
    |
 LL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
 LL | |
@@ -147,7 +147,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&Issue12037`
-  --> tests/ui/iter_without_into_iter.rs:130:13
+  --> tests/ui/iter_without_into_iter.rs:131:13
    |
 LL | /             fn iter(&self) -> std::slice::Iter<'_, u8> {
 LL | |                 todo!()
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed b/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
index a6ef8f8c119..3a2294ef4c5 100644
--- a/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
@@ -22,8 +22,8 @@ macro_rules! b {
     };
 }
 
-use std::u32::MAX;
 use std::u8::MIN;
+use std::u32::MAX;
 use std::{f64, u32};
 
 #[warn(clippy::legacy_numeric_constants)]
@@ -99,8 +99,8 @@ fn allow() {
     ::std::primitive::u8::MIN;
     ::std::u8::MIN;
     ::std::primitive::u8::min_value();
-    use std::u64;
     use std::u8::MIN;
+    use std::u64;
 }
 
 #[warn(clippy::legacy_numeric_constants)]
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.rs b/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
index cd633545372..6cb3e694ea1 100644
--- a/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
@@ -22,8 +22,8 @@ macro_rules! b {
     };
 }
 
-use std::u32::MAX;
 use std::u8::MIN;
+use std::u32::MAX;
 use std::{f64, u32};
 
 #[warn(clippy::legacy_numeric_constants)]
@@ -99,8 +99,8 @@ fn allow() {
     ::std::primitive::u8::MIN;
     ::std::u8::MIN;
     ::std::primitive::u8::min_value();
-    use std::u64;
     use std::u8::MIN;
+    use std::u64;
 }
 
 #[warn(clippy::legacy_numeric_constants)]
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.fixed b/src/tools/clippy/tests/ui/macro_use_imports.fixed
index 38ed5a957e7..28844fab747 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.fixed
+++ b/src/tools/clippy/tests/ui/macro_use_imports.fixed
@@ -2,7 +2,7 @@
 //@aux-build:macro_use_helper.rs
 //@aux-build:proc_macro_derive.rs
 
-//@ignore-32bit
+//@ignore-bitwidth: 32
 
 #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]
 #![allow(clippy::single_component_path_imports)]
diff --git a/src/tools/clippy/tests/ui/macro_use_imports.rs b/src/tools/clippy/tests/ui/macro_use_imports.rs
index ae6cc16ed27..5381f295989 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports.rs
+++ b/src/tools/clippy/tests/ui/macro_use_imports.rs
@@ -2,7 +2,7 @@
 //@aux-build:macro_use_helper.rs
 //@aux-build:proc_macro_derive.rs
 
-//@ignore-32bit
+//@ignore-bitwidth: 32
 
 #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]
 #![allow(clippy::single_component_path_imports)]
diff --git a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs
index df6d5b9fbab..60cce1d24a2 100644
--- a/src/tools/clippy/tests/ui/macro_use_imports_expect.rs
+++ b/src/tools/clippy/tests/ui/macro_use_imports_expect.rs
@@ -1,7 +1,7 @@
 //@aux-build:macro_rules.rs
 //@aux-build:macro_use_helper.rs
 //@aux-build:proc_macro_derive.rs
-//@ignore-32bit
+//@ignore-bitwidth: 32
 
 #![allow(unused_imports, unreachable_code, unused_variables, dead_code, unused_attributes)]
 #![allow(clippy::single_component_path_imports)]
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
new file mode 100644
index 00000000000..e97e3bdfef7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
@@ -0,0 +1,35 @@
+//@no-rustfix
+#![warn(clippy::implicit_saturating_sub)]
+#![allow(arithmetic_overflow)]
+
+fn main() {
+    let a = 12u32;
+    let b = 13u32;
+
+    let result = if a > b { b - a } else { 0 };
+    //~^ ERROR: inverted arithmetic check before subtraction
+    let result = if b < a { b - a } else { 0 };
+    //~^ ERROR: inverted arithmetic check before subtraction
+
+    let result = if a > b { 0 } else { a - b };
+    //~^ ERROR: inverted arithmetic check before subtraction
+    let result = if a >= b { 0 } else { a - b };
+    //~^ ERROR: inverted arithmetic check before subtraction
+    let result = if b < a { 0 } else { a - b };
+    //~^ ERROR: inverted arithmetic check before subtraction
+    let result = if b <= a { 0 } else { a - b };
+    //~^ ERROR: inverted arithmetic check before subtraction
+
+    let af = 12f32;
+    let bf = 13f32;
+    // Should not lint!
+    let result = if bf < af { 0. } else { af - bf };
+
+    // Should not lint!
+    let result = if a < b {
+        println!("we shouldn't remove this");
+        0
+    } else {
+        a - b
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
new file mode 100644
index 00000000000..4121aa7464f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
@@ -0,0 +1,75 @@
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:9:23
+   |
+LL |     let result = if a > b { b - a } else { 0 };
+   |                       ^     ----- help: try replacing it with: `a - b`
+   |
+note: this subtraction underflows when `b < a`
+  --> tests/ui/manual_arithmetic_check-2.rs:9:29
+   |
+LL |     let result = if a > b { b - a } else { 0 };
+   |                             ^^^^^
+   = note: `#[deny(clippy::inverted_saturating_sub)]` on by default
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:11:23
+   |
+LL |     let result = if b < a { b - a } else { 0 };
+   |                       ^     ----- help: try replacing it with: `a - b`
+   |
+note: this subtraction underflows when `b < a`
+  --> tests/ui/manual_arithmetic_check-2.rs:11:29
+   |
+LL |     let result = if b < a { b - a } else { 0 };
+   |                             ^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:14:23
+   |
+LL |     let result = if a > b { 0 } else { a - b };
+   |                       ^                ----- help: try replacing it with: `b - a`
+   |
+note: this subtraction underflows when `a < b`
+  --> tests/ui/manual_arithmetic_check-2.rs:14:40
+   |
+LL |     let result = if a > b { 0 } else { a - b };
+   |                                        ^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:16:23
+   |
+LL |     let result = if a >= b { 0 } else { a - b };
+   |                       ^^                ----- help: try replacing it with: `b - a`
+   |
+note: this subtraction underflows when `a < b`
+  --> tests/ui/manual_arithmetic_check-2.rs:16:41
+   |
+LL |     let result = if a >= b { 0 } else { a - b };
+   |                                         ^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:18:23
+   |
+LL |     let result = if b < a { 0 } else { a - b };
+   |                       ^                ----- help: try replacing it with: `b - a`
+   |
+note: this subtraction underflows when `a < b`
+  --> tests/ui/manual_arithmetic_check-2.rs:18:40
+   |
+LL |     let result = if b < a { 0 } else { a - b };
+   |                                        ^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:20:23
+   |
+LL |     let result = if b <= a { 0 } else { a - b };
+   |                       ^^                ----- help: try replacing it with: `b - a`
+   |
+note: this subtraction underflows when `a < b`
+  --> tests/ui/manual_arithmetic_check-2.rs:20:41
+   |
+LL |     let result = if b <= a { 0 } else { a - b };
+   |                                         ^^^^^
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check.fixed b/src/tools/clippy/tests/ui/manual_arithmetic_check.fixed
new file mode 100644
index 00000000000..29ecbb9ad2a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check.fixed
@@ -0,0 +1,24 @@
+#![warn(clippy::implicit_saturating_sub, clippy::inverted_saturating_sub)]
+#![allow(clippy::if_same_then_else)]
+
+fn main() {
+    let a = 12u32;
+    let b = 13u32;
+    let c = 8u32;
+
+    let result = a.saturating_sub(b);
+    //~^ ERROR: manual arithmetic check found
+    let result = a.saturating_sub(b);
+    //~^ ERROR: manual arithmetic check found
+
+    let result = a.saturating_sub(b);
+    //~^ ERROR: manual arithmetic check found
+    let result = a.saturating_sub(b);
+    //~^ ERROR: manual arithmetic check found
+
+    // Should not warn!
+    let result = if a > b { a - b } else { a - c };
+
+    // Just to check it won't break clippy.
+    let result = if b > a { 0 } else { 0 };
+}
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check.rs b/src/tools/clippy/tests/ui/manual_arithmetic_check.rs
new file mode 100644
index 00000000000..69554c6b61c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check.rs
@@ -0,0 +1,24 @@
+#![warn(clippy::implicit_saturating_sub, clippy::inverted_saturating_sub)]
+#![allow(clippy::if_same_then_else)]
+
+fn main() {
+    let a = 12u32;
+    let b = 13u32;
+    let c = 8u32;
+
+    let result = if a > b { a - b } else { 0 };
+    //~^ ERROR: manual arithmetic check found
+    let result = if b < a { a - b } else { 0 };
+    //~^ ERROR: manual arithmetic check found
+
+    let result = if a < b { 0 } else { a - b };
+    //~^ ERROR: manual arithmetic check found
+    let result = if b > a { 0 } else { a - b };
+    //~^ ERROR: manual arithmetic check found
+
+    // Should not warn!
+    let result = if a > b { a - b } else { a - c };
+
+    // Just to check it won't break clippy.
+    let result = if b > a { 0 } else { 0 };
+}
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check.stderr b/src/tools/clippy/tests/ui/manual_arithmetic_check.stderr
new file mode 100644
index 00000000000..b0cf73cd915
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check.stderr
@@ -0,0 +1,29 @@
+error: manual arithmetic check found
+  --> tests/ui/manual_arithmetic_check.rs:9:18
+   |
+LL |     let result = if a > b { a - b } else { 0 };
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`
+   |
+   = note: `-D clippy::implicit-saturating-sub` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::implicit_saturating_sub)]`
+
+error: manual arithmetic check found
+  --> tests/ui/manual_arithmetic_check.rs:11:18
+   |
+LL |     let result = if b < a { a - b } else { 0 };
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`
+
+error: manual arithmetic check found
+  --> tests/ui/manual_arithmetic_check.rs:14:18
+   |
+LL |     let result = if a < b { 0 } else { a - b };
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`
+
+error: manual arithmetic check found
+  --> tests/ui/manual_arithmetic_check.rs:16:18
+   |
+LL |     let result = if b > a { 0 } else { a - b };
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b)`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil.fixed b/src/tools/clippy/tests/ui/manual_div_ceil.fixed
new file mode 100644
index 00000000000..e7801f7376a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_div_ceil.fixed
@@ -0,0 +1,30 @@
+#![warn(clippy::manual_div_ceil)]
+
+fn main() {
+    let x = 7_u32;
+    let y = 4_u32;
+    let z = 11_u32;
+
+    // Lint
+    let _ = x.div_ceil(y); //~ ERROR: manually reimplementing `div_ceil`
+    let _ = x.div_ceil(y); //~ ERROR: manually reimplementing `div_ceil`
+    let _ = x.div_ceil(y); //~ ERROR: manually reimplementing `div_ceil`
+
+    let _ = 7_u32.div_ceil(4); //~ ERROR: manually reimplementing `div_ceil`
+    let _ = (7_i32 as u32).div_ceil(4); //~ ERROR: manually reimplementing `div_ceil`
+
+    // No lint
+    let _ = (x + (y - 2)) / y;
+    let _ = (x + (y + 1)) / y;
+
+    let _ = (x + (y - 1)) / z;
+
+    let x_i = 7_i32;
+    let y_i = 4_i32;
+    let z_i = 11_i32;
+
+    // No lint because `int_roundings` feature is not enabled.
+    let _ = (z as i32 + (y_i - 1)) / y_i;
+    let _ = (7_u32 as i32 + (y_i - 1)) / y_i;
+    let _ = (7_u32 as i32 + (4 - 1)) / 4;
+}
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil.rs b/src/tools/clippy/tests/ui/manual_div_ceil.rs
new file mode 100644
index 00000000000..2de74c7eaa8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_div_ceil.rs
@@ -0,0 +1,30 @@
+#![warn(clippy::manual_div_ceil)]
+
+fn main() {
+    let x = 7_u32;
+    let y = 4_u32;
+    let z = 11_u32;
+
+    // Lint
+    let _ = (x + (y - 1)) / y; //~ ERROR: manually reimplementing `div_ceil`
+    let _ = ((y - 1) + x) / y; //~ ERROR: manually reimplementing `div_ceil`
+    let _ = (x + y - 1) / y; //~ ERROR: manually reimplementing `div_ceil`
+
+    let _ = (7_u32 + (4 - 1)) / 4; //~ ERROR: manually reimplementing `div_ceil`
+    let _ = (7_i32 as u32 + (4 - 1)) / 4; //~ ERROR: manually reimplementing `div_ceil`
+
+    // No lint
+    let _ = (x + (y - 2)) / y;
+    let _ = (x + (y + 1)) / y;
+
+    let _ = (x + (y - 1)) / z;
+
+    let x_i = 7_i32;
+    let y_i = 4_i32;
+    let z_i = 11_i32;
+
+    // No lint because `int_roundings` feature is not enabled.
+    let _ = (z as i32 + (y_i - 1)) / y_i;
+    let _ = (7_u32 as i32 + (y_i - 1)) / y_i;
+    let _ = (7_u32 as i32 + (4 - 1)) / 4;
+}
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil.stderr b/src/tools/clippy/tests/ui/manual_div_ceil.stderr
new file mode 100644
index 00000000000..dc652dff405
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_div_ceil.stderr
@@ -0,0 +1,35 @@
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil.rs:9:13
+   |
+LL |     let _ = (x + (y - 1)) / y;
+   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`
+   |
+   = note: `-D clippy::manual-div-ceil` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_div_ceil)]`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil.rs:10:13
+   |
+LL |     let _ = ((y - 1) + x) / y;
+   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil.rs:11:13
+   |
+LL |     let _ = (x + y - 1) / y;
+   |             ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil.rs:13:13
+   |
+LL |     let _ = (7_u32 + (4 - 1)) / 4;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_u32.div_ceil(4)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil.rs:14:13
+   |
+LL |     let _ = (7_i32 as u32 + (4 - 1)) / 4;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.fixed b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.fixed
new file mode 100644
index 00000000000..a1d678c6689
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.fixed
@@ -0,0 +1,25 @@
+#![warn(clippy::manual_div_ceil)]
+#![feature(int_roundings)]
+
+fn main() {
+    let x = 7_i32;
+    let y = 4_i32;
+    let z = 3_i32;
+    let z_u: u32 = 11;
+
+    // Lint.
+    let _ = x.div_ceil(y);
+    let _ = x.div_ceil(y);
+    let _ = x.div_ceil(y);
+
+    let _ = 7_i32.div_ceil(4);
+    let _ = (7_i32 as u32).div_ceil(4);
+    let _ = (7_u32 as i32).div_ceil(4);
+    let _ = z_u.div_ceil(4);
+
+    // No lint.
+    let _ = (x + (y - 2)) / y;
+    let _ = (x + (y + 1)) / y;
+
+    let _ = (x + (y - 1)) / z;
+}
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.rs b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.rs
new file mode 100644
index 00000000000..58cb1dbe34d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.rs
@@ -0,0 +1,25 @@
+#![warn(clippy::manual_div_ceil)]
+#![feature(int_roundings)]
+
+fn main() {
+    let x = 7_i32;
+    let y = 4_i32;
+    let z = 3_i32;
+    let z_u: u32 = 11;
+
+    // Lint.
+    let _ = (x + (y - 1)) / y;
+    let _ = ((y - 1) + x) / y;
+    let _ = (x + y - 1) / y;
+
+    let _ = (7_i32 + (4 - 1)) / 4;
+    let _ = (7_i32 as u32 + (4 - 1)) / 4;
+    let _ = (7_u32 as i32 + (4 - 1)) / 4;
+    let _ = (z_u + (4 - 1)) / 4;
+
+    // No lint.
+    let _ = (x + (y - 2)) / y;
+    let _ = (x + (y + 1)) / y;
+
+    let _ = (x + (y - 1)) / z;
+}
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.stderr b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.stderr
new file mode 100644
index 00000000000..361ef9bd9f4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.stderr
@@ -0,0 +1,47 @@
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:11:13
+   |
+LL |     let _ = (x + (y - 1)) / y;
+   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`
+   |
+   = note: `-D clippy::manual-div-ceil` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_div_ceil)]`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:12:13
+   |
+LL |     let _ = ((y - 1) + x) / y;
+   |             ^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:13:13
+   |
+LL |     let _ = (x + y - 1) / y;
+   |             ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(y)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:15:13
+   |
+LL |     let _ = (7_i32 + (4 - 1)) / 4;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `7_i32.div_ceil(4)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:16:13
+   |
+LL |     let _ = (7_i32 as u32 + (4 - 1)) / 4;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:17:13
+   |
+LL |     let _ = (7_u32 as i32 + (4 - 1)) / 4;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_u32 as i32).div_ceil(4)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:18:13
+   |
+LL |     let _ = (z_u + (4 - 1)) / 4;
+   |             ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `z_u.div_ceil(4)`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_is_power_of_two.fixed b/src/tools/clippy/tests/ui/manual_is_power_of_two.fixed
new file mode 100644
index 00000000000..dda5fe0ec3e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_is_power_of_two.fixed
@@ -0,0 +1,20 @@
+#![warn(clippy::manual_is_power_of_two)]
+
+fn main() {
+    let a = 16_u64;
+
+    let _ = a.is_power_of_two();
+    let _ = a.is_power_of_two();
+
+    // Test different orders of expression
+    let _ = a.is_power_of_two();
+    let _ = a.is_power_of_two();
+    let _ = a.is_power_of_two();
+    let _ = a.is_power_of_two();
+
+    let b = 4_i64;
+
+    // is_power_of_two only works for unsigned integers
+    let _ = b.count_ones() == 1;
+    let _ = b & (b - 1) == 0;
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_power_of_two.rs b/src/tools/clippy/tests/ui/manual_is_power_of_two.rs
new file mode 100644
index 00000000000..a1d3a95c410
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_is_power_of_two.rs
@@ -0,0 +1,20 @@
+#![warn(clippy::manual_is_power_of_two)]
+
+fn main() {
+    let a = 16_u64;
+
+    let _ = a.count_ones() == 1;
+    let _ = a & (a - 1) == 0;
+
+    // Test different orders of expression
+    let _ = 1 == a.count_ones();
+    let _ = (a - 1) & a == 0;
+    let _ = 0 == a & (a - 1);
+    let _ = 0 == (a - 1) & a;
+
+    let b = 4_i64;
+
+    // is_power_of_two only works for unsigned integers
+    let _ = b.count_ones() == 1;
+    let _ = b & (b - 1) == 0;
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_power_of_two.stderr b/src/tools/clippy/tests/ui/manual_is_power_of_two.stderr
new file mode 100644
index 00000000000..3cfc6297abf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_is_power_of_two.stderr
@@ -0,0 +1,41 @@
+error: manually reimplementing `is_power_of_two`
+  --> tests/ui/manual_is_power_of_two.rs:6:13
+   |
+LL |     let _ = a.count_ones() == 1;
+   |             ^^^^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`
+   |
+   = note: `-D clippy::manual-is-power-of-two` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_is_power_of_two)]`
+
+error: manually reimplementing `is_power_of_two`
+  --> tests/ui/manual_is_power_of_two.rs:7:13
+   |
+LL |     let _ = a & (a - 1) == 0;
+   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`
+
+error: manually reimplementing `is_power_of_two`
+  --> tests/ui/manual_is_power_of_two.rs:10:13
+   |
+LL |     let _ = 1 == a.count_ones();
+   |             ^^^^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`
+
+error: manually reimplementing `is_power_of_two`
+  --> tests/ui/manual_is_power_of_two.rs:11:13
+   |
+LL |     let _ = (a - 1) & a == 0;
+   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`
+
+error: manually reimplementing `is_power_of_two`
+  --> tests/ui/manual_is_power_of_two.rs:12:13
+   |
+LL |     let _ = 0 == a & (a - 1);
+   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`
+
+error: manually reimplementing `is_power_of_two`
+  --> tests/ui/manual_is_power_of_two.rs:13:13
+   |
+LL |     let _ = 0 == (a - 1) & a;
+   |             ^^^^^^^^^^^^^^^^ help: consider using `.is_power_of_two()`: `a.is_power_of_two()`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
index 31c3cc80137..ffe2bb92467 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
@@ -1,8 +1,8 @@
 #![warn(clippy::manual_non_exhaustive)]
 #![allow(unused)]
 //@no-rustfix
-enum E {
-    //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
+pub enum E {
+    //~^ manual_non_exhaustive
     A,
     B,
     #[doc(hidden)]
@@ -11,7 +11,7 @@ enum E {
 
 // if the user explicitly marks as nonexhaustive we shouldn't warn them
 #[non_exhaustive]
-enum Ep {
+pub enum Ep {
     A,
     B,
     #[doc(hidden)]
@@ -19,14 +19,14 @@ enum Ep {
 }
 
 // marker variant does not have doc hidden attribute, should be ignored
-enum NoDocHidden {
+pub enum NoDocHidden {
     A,
     B,
     _C,
 }
 
 // name of variant with doc hidden does not start with underscore
-enum NoUnderscore {
+pub enum NoUnderscore {
     A,
     B,
     #[doc(hidden)]
@@ -34,7 +34,7 @@ enum NoUnderscore {
 }
 
 // variant with doc hidden is not unit, should be ignored
-enum NotUnit {
+pub enum NotUnit {
     A,
     B,
     #[doc(hidden)]
@@ -42,13 +42,13 @@ enum NotUnit {
 }
 
 // variant with doc hidden is the only one, should be ignored
-enum OnlyMarker {
+pub enum OnlyMarker {
     #[doc(hidden)]
     _A,
 }
 
 // variant with multiple markers, should be ignored
-enum MultipleMarkers {
+pub enum MultipleMarkers {
     A,
     #[doc(hidden)]
     _B,
@@ -58,13 +58,13 @@ enum MultipleMarkers {
 
 // already non_exhaustive and no markers, should be ignored
 #[non_exhaustive]
-enum NonExhaustive {
+pub enum NonExhaustive {
     A,
     B,
 }
 
 // marked is used, don't lint
-enum UsedHidden {
+pub enum UsedHidden {
     #[doc(hidden)]
     _A,
     B,
@@ -77,11 +77,9 @@ fn foo(x: &mut UsedHidden) {
 }
 
 #[expect(clippy::manual_non_exhaustive)]
-enum ExpectLint {
+pub enum ExpectLint {
     A,
     B,
     #[doc(hidden)]
     _C,
 }
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
index dc669568dd2..0a9ac157f85 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
@@ -1,11 +1,7 @@
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> tests/ui/manual_non_exhaustive_enum.rs:4:1
    |
-LL |   enum E {
-   |   ^-----
-   |   |
-   |  _help: add the attribute: `#[non_exhaustive] enum E`
-   | |
+LL | / pub enum E {
 LL | |
 LL | |     A,
 LL | |     B,
@@ -21,15 +17,16 @@ LL |     _C,
    |     ^^
    = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`
+help: use the `#[non_exhaustive]` attribute instead
+   |
+LL + #[non_exhaustive]
+LL | pub enum E {
+   |
 
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> tests/ui/manual_non_exhaustive_enum.rs:29:1
    |
-LL |   enum NoUnderscore {
-   |   ^----------------
-   |   |
-   |  _help: add the attribute: `#[non_exhaustive] enum NoUnderscore`
-   | |
+LL | / pub enum NoUnderscore {
 LL | |     A,
 LL | |     B,
 LL | |     #[doc(hidden)]
@@ -42,6 +39,11 @@ help: remove this variant
    |
 LL |     C,
    |     ^
+help: use the `#[non_exhaustive]` attribute instead
+   |
+LL + #[non_exhaustive]
+LL | pub enum NoUnderscore {
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
index 4b2803ccc4a..31dd50281fa 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
@@ -1,9 +1,9 @@
 #![warn(clippy::manual_non_exhaustive)]
 #![allow(unused)]
 //@no-rustfix
-mod structs {
-    struct S {
-        //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
+pub mod structs {
+    pub struct S {
+        //~^ manual_non_exhaustive
         pub a: i32,
         pub b: i32,
         _c: (),
@@ -11,68 +11,76 @@ mod structs {
 
     // user forgot to remove the private field
     #[non_exhaustive]
-    struct Sp {
-        //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
+    pub struct Sp {
+        //~^ manual_non_exhaustive
         pub a: i32,
         pub b: i32,
         _c: (),
     }
 
     // some other fields are private, should be ignored
-    struct PrivateFields {
+    pub struct PrivateFields {
         a: i32,
         pub b: i32,
         _c: (),
     }
 
-    // private field name does not start with underscore, should be ignored
-    struct NoUnderscore {
+    pub struct NoUnderscore {
+        //~^ manual_non_exhaustive
         pub a: i32,
         pub b: i32,
         c: (),
     }
 
     // private field is not unit type, should be ignored
-    struct NotUnit {
+    pub struct NotUnit {
         pub a: i32,
         pub b: i32,
         _c: i32,
     }
 
     // private field is the only field, should be ignored
-    struct OnlyMarker {
+    pub struct OnlyMarker {
         _a: (),
     }
 
     // already non exhaustive and no private fields, should be ignored
     #[non_exhaustive]
-    struct NonExhaustive {
+    pub struct NonExhaustive {
         pub a: i32,
         pub b: i32,
     }
 }
 
-mod tuple_structs {
-    struct T(pub i32, pub i32, ());
-    //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
+pub mod tuple_structs {
+    pub struct T(pub i32, pub i32, ());
+    //~^ manual_non_exhaustive
 
     // user forgot to remove the private field
     #[non_exhaustive]
-    struct Tp(pub i32, pub i32, ());
-    //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
+    pub struct Tp(pub i32, pub i32, ());
+    //~^ manual_non_exhaustive
 
     // some other fields are private, should be ignored
-    struct PrivateFields(pub i32, i32, ());
+    pub struct PrivateFields(pub i32, i32, ());
 
     // private field is not unit type, should be ignored
-    struct NotUnit(pub i32, pub i32, i32);
+    pub struct NotUnit(pub i32, pub i32, i32);
 
     // private field is the only field, should be ignored
-    struct OnlyMarker(());
+    pub struct OnlyMarker(());
 
     // already non exhaustive and no private fields, should be ignored
     #[non_exhaustive]
-    struct NonExhaustive(pub i32, pub i32);
+    pub struct NonExhaustive(pub i32, pub i32);
 }
 
-fn main() {}
+mod private {
+    // Don't lint structs that are not actually public as `#[non_exhaustive]` only applies to
+    // external crates. The manual pattern can still be used to get module local non exhaustiveness
+    pub struct NotPublic {
+        pub a: i32,
+        pub b: i32,
+        _c: (),
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
index 1cab812988a..81de1e4f271 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
@@ -1,11 +1,7 @@
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> tests/ui/manual_non_exhaustive_struct.rs:5:5
    |
-LL |       struct S {
-   |       ^-------
-   |       |
-   |  _____help: add the attribute: `#[non_exhaustive] struct S`
-   | |
+LL | /     pub struct S {
 LL | |
 LL | |         pub a: i32,
 LL | |         pub b: i32,
@@ -20,11 +16,16 @@ LL |         _c: (),
    |         ^^^^^^
    = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`
+help: use the `#[non_exhaustive]` attribute instead
+   |
+LL ~     #[non_exhaustive]
+LL ~     pub struct S {
+   |
 
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> tests/ui/manual_non_exhaustive_struct.rs:14:5
    |
-LL | /     struct Sp {
+LL | /     pub struct Sp {
 LL | |
 LL | |         pub a: i32,
 LL | |         pub b: i32,
@@ -32,6 +33,11 @@ LL | |         _c: (),
 LL | |     }
    | |_____^
    |
+note: the struct is already non-exhaustive
+  --> tests/ui/manual_non_exhaustive_struct.rs:13:5
+   |
+LL |     #[non_exhaustive]
+   |     ^^^^^^^^^^^^^^^^^
 help: remove this field
   --> tests/ui/manual_non_exhaustive_struct.rs:18:9
    |
@@ -39,13 +45,10 @@ LL |         _c: (),
    |         ^^^^^^
 
 error: this seems like a manual implementation of the non-exhaustive pattern
-  --> tests/ui/manual_non_exhaustive_struct.rs:29:5
+  --> tests/ui/manual_non_exhaustive_struct.rs:28:5
    |
-LL |       struct NoUnderscore {
-   |       ^------------------
-   |       |
-   |  _____help: add the attribute: `#[non_exhaustive] struct NoUnderscore`
-   | |
+LL | /     pub struct NoUnderscore {
+LL | |
 LL | |         pub a: i32,
 LL | |         pub b: i32,
 LL | |         c: (),
@@ -57,32 +60,45 @@ help: remove this field
    |
 LL |         c: (),
    |         ^^^^^
+help: use the `#[non_exhaustive]` attribute instead
+   |
+LL ~     #[non_exhaustive]
+LL ~     pub struct NoUnderscore {
+   |
 
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> tests/ui/manual_non_exhaustive_struct.rs:56:5
    |
-LL |     struct T(pub i32, pub i32, ());
-   |     --------^^^^^^^^^^^^^^^^^^^^^^^
-   |     |
-   |     help: add the attribute: `#[non_exhaustive] struct T`
+LL |     pub struct T(pub i32, pub i32, ());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: remove this field
-  --> tests/ui/manual_non_exhaustive_struct.rs:56:32
+  --> tests/ui/manual_non_exhaustive_struct.rs:56:36
+   |
+LL |     pub struct T(pub i32, pub i32, ());
+   |                                    ^^
+help: use the `#[non_exhaustive]` attribute instead
+   |
+LL ~     #[non_exhaustive]
+LL ~     pub struct T(pub i32, pub i32, ());
    |
-LL |     struct T(pub i32, pub i32, ());
-   |                                ^^
 
 error: this seems like a manual implementation of the non-exhaustive pattern
   --> tests/ui/manual_non_exhaustive_struct.rs:61:5
    |
-LL |     struct Tp(pub i32, pub i32, ());
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     pub struct Tp(pub i32, pub i32, ());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the struct is already non-exhaustive
+  --> tests/ui/manual_non_exhaustive_struct.rs:60:5
    |
+LL |     #[non_exhaustive]
+   |     ^^^^^^^^^^^^^^^^^
 help: remove this field
-  --> tests/ui/manual_non_exhaustive_struct.rs:61:33
+  --> tests/ui/manual_non_exhaustive_struct.rs:61:37
    |
-LL |     struct Tp(pub i32, pub i32, ());
-   |                                 ^^
+LL |     pub struct Tp(pub i32, pub i32, ());
+   |                                     ^^
 
 error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.fixed b/src/tools/clippy/tests/ui/manual_range_patterns.fixed
index f1b99637afd..60467bf9e88 100644
--- a/src/tools/clippy/tests/ui/manual_range_patterns.fixed
+++ b/src/tools/clippy/tests/ui/manual_range_patterns.fixed
@@ -45,4 +45,12 @@ fn main() {
         };
     }
     mac!(f);
+
+    #[rustfmt::skip]
+    let _ = match f {
+        | 2..=15 => 4,
+        | 241..=254 => 5,
+        | 255 => 6,
+        | _ => 7,
+    };
 }
diff --git a/src/tools/clippy/tests/ui/manual_range_patterns.rs b/src/tools/clippy/tests/ui/manual_range_patterns.rs
index 869ffbe80b9..9cd80333449 100644
--- a/src/tools/clippy/tests/ui/manual_range_patterns.rs
+++ b/src/tools/clippy/tests/ui/manual_range_patterns.rs
@@ -45,4 +45,12 @@ fn main() {
         };
     }
     mac!(f);
+
+    #[rustfmt::skip]
+    let _ = match f {
+        | 2..=15 => 4,
+        | 241..=254 => 5,
+        | 255 => 6,
+        | _ => 7,
+    };
 }
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
index 41a32df32ee..528a65790c4 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
@@ -1,6 +1,6 @@
 #![allow(clippy::legacy_numeric_constants, unused_imports)]
 
-use std::{i128, i32, u128, u32};
+use std::{i32, i128, u32, u128};
 
 fn main() {
     let _ = 1u32.saturating_add(1);
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
index 3a6b32d8069..55f3720dfcc 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::legacy_numeric_constants, unused_imports)]
 
-use std::{i128, i32, u128, u32};
+use std::{i32, i128, u32, u128};
 
 fn main() {
     let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());
diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.rs b/src/tools/clippy/tests/ui/match_overlapping_arm.rs
index 4457ae73da2..a056fdeaa5d 100644
--- a/src/tools/clippy/tests/ui/match_overlapping_arm.rs
+++ b/src/tools/clippy/tests/ui/match_overlapping_arm.rs
@@ -2,8 +2,6 @@
 #![allow(clippy::redundant_pattern_matching)]
 #![allow(clippy::if_same_then_else, clippy::equatable_if_let, clippy::needless_if)]
 
-/// Tests for match_overlapping_arm
-
 fn overlapping() {
     const FOO: u64 = 2;
 
diff --git a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
index 65092ffbb55..a60a09a0799 100644
--- a/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
+++ b/src/tools/clippy/tests/ui/match_overlapping_arm.stderr
@@ -1,11 +1,11 @@
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:11:9
+  --> tests/ui/match_overlapping_arm.rs:9:9
    |
 LL |         0..=10 => println!("0..=10"),
    |         ^^^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:13:9
+  --> tests/ui/match_overlapping_arm.rs:11:9
    |
 LL |         0..=11 => println!("0..=11"),
    |         ^^^^^^
@@ -13,85 +13,85 @@ LL |         0..=11 => println!("0..=11"),
    = help: to override `-D warnings` add `#[allow(clippy::match_overlapping_arm)]`
 
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:18:9
+  --> tests/ui/match_overlapping_arm.rs:16:9
    |
 LL |         0..=5 => println!("0..=5"),
    |         ^^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:21:9
+  --> tests/ui/match_overlapping_arm.rs:19:9
    |
 LL |         FOO..=11 => println!("FOO..=11"),
    |         ^^^^^^^^
 
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:56:9
+  --> tests/ui/match_overlapping_arm.rs:54:9
    |
 LL |         0..11 => println!("0..11"),
    |         ^^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:58:9
+  --> tests/ui/match_overlapping_arm.rs:56:9
    |
 LL |         0..=11 => println!("0..=11"),
    |         ^^^^^^
 
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:82:9
+  --> tests/ui/match_overlapping_arm.rs:80:9
    |
 LL |         0..=10 => println!("0..=10"),
    |         ^^^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:81:9
+  --> tests/ui/match_overlapping_arm.rs:79:9
    |
 LL |         5..14 => println!("5..14"),
    |         ^^^^^
 
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:88:9
+  --> tests/ui/match_overlapping_arm.rs:86:9
    |
 LL |         0..7 => println!("0..7"),
    |         ^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:90:9
+  --> tests/ui/match_overlapping_arm.rs:88:9
    |
 LL |         0..=10 => println!("0..=10"),
    |         ^^^^^^
 
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:101:9
+  --> tests/ui/match_overlapping_arm.rs:99:9
    |
 LL |         ..=23 => println!("..=23"),
    |         ^^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:103:9
+  --> tests/ui/match_overlapping_arm.rs:101:9
    |
 LL |         ..26 => println!("..26"),
    |         ^^^^
 
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:111:9
+  --> tests/ui/match_overlapping_arm.rs:109:9
    |
 LL |         21..=30 => (),
    |         ^^^^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:113:9
+  --> tests/ui/match_overlapping_arm.rs:111:9
    |
 LL |         21..=40 => (),
    |         ^^^^^^^
 
 error: some ranges overlap
-  --> tests/ui/match_overlapping_arm.rs:126:9
+  --> tests/ui/match_overlapping_arm.rs:124:9
    |
 LL |         0..=0x0000_0000_0000_00ff => (),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: overlaps with this
-  --> tests/ui/match_overlapping_arm.rs:128:9
+  --> tests/ui/match_overlapping_arm.rs:126:9
    |
 LL |         0..=0x0000_0000_0000_ffff => (),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mem_replace.fixed b/src/tools/clippy/tests/ui/mem_replace.fixed
index 78d8b3e9bce..4210dbbe82d 100644
--- a/src/tools/clippy/tests/ui/mem_replace.fixed
+++ b/src/tools/clippy/tests/ui/mem_replace.fixed
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace.rs b/src/tools/clippy/tests/ui/mem_replace.rs
index 28915bf6dae..bd7ad78b2af 100644
--- a/src/tools/clippy/tests/ui/mem_replace.rs
+++ b/src/tools/clippy/tests/ui/mem_replace.rs
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace.stderr b/src/tools/clippy/tests/ui/mem_replace.stderr
index 44be2c9b63d..c33f80b01b8 100644
--- a/src/tools/clippy/tests/ui/mem_replace.stderr
+++ b/src/tools/clippy/tests/ui/mem_replace.stderr
@@ -1,5 +1,5 @@
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:14:13
+  --> tests/ui/mem_replace.rs:13:13
    |
 LL |     let _ = mem::replace(&mut an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
@@ -8,13 +8,13 @@ LL |     let _ = mem::replace(&mut an_option, None);
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:16:13
+  --> tests/ui/mem_replace.rs:15:13
    |
 LL |     let _ = mem::replace(an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:21:13
+  --> tests/ui/mem_replace.rs:20:13
    |
 LL |     let _ = std::mem::replace(&mut s, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
@@ -23,127 +23,127 @@ LL |     let _ = std::mem::replace(&mut s, String::default());
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:24:13
+  --> tests/ui/mem_replace.rs:23:13
    |
 LL |     let _ = std::mem::replace(s, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:25:13
+  --> tests/ui/mem_replace.rs:24:13
    |
 LL |     let _ = std::mem::replace(s, Default::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:28:13
+  --> tests/ui/mem_replace.rs:27:13
    |
 LL |     let _ = std::mem::replace(&mut v, Vec::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:29:13
+  --> tests/ui/mem_replace.rs:28:13
    |
 LL |     let _ = std::mem::replace(&mut v, Default::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:30:13
+  --> tests/ui/mem_replace.rs:29:13
    |
 LL |     let _ = std::mem::replace(&mut v, Vec::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:31:13
+  --> tests/ui/mem_replace.rs:30:13
    |
 LL |     let _ = std::mem::replace(&mut v, vec![]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:34:13
+  --> tests/ui/mem_replace.rs:33:13
    |
 LL |     let _ = std::mem::replace(&mut hash_map, HashMap::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_map)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:37:13
+  --> tests/ui/mem_replace.rs:36:13
    |
 LL |     let _ = std::mem::replace(&mut btree_map, BTreeMap::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_map)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:40:13
+  --> tests/ui/mem_replace.rs:39:13
    |
 LL |     let _ = std::mem::replace(&mut vd, VecDeque::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut vd)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:43:13
+  --> tests/ui/mem_replace.rs:42:13
    |
 LL |     let _ = std::mem::replace(&mut hash_set, HashSet::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_set)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:46:13
+  --> tests/ui/mem_replace.rs:45:13
    |
 LL |     let _ = std::mem::replace(&mut btree_set, BTreeSet::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_set)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:49:13
+  --> tests/ui/mem_replace.rs:48:13
    |
 LL |     let _ = std::mem::replace(&mut list, LinkedList::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut list)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:52:13
+  --> tests/ui/mem_replace.rs:51:13
    |
 LL |     let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut binary_heap)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:55:13
+  --> tests/ui/mem_replace.rs:54:13
    |
 LL |     let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new()));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut tuple)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:58:13
+  --> tests/ui/mem_replace.rs:57:13
    |
 LL |     let _ = std::mem::replace(&mut refstr, "");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut refstr)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:61:13
+  --> tests/ui/mem_replace.rs:60:13
    |
 LL |     let _ = std::mem::replace(&mut slice, &[]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut slice)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:97:13
+  --> tests/ui/mem_replace.rs:96:13
    |
 LL |     let _ = std::mem::replace(&mut s, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:127:13
+  --> tests/ui/mem_replace.rs:126:13
    |
 LL |     let _ = std::mem::replace(&mut f.0, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:128:13
+  --> tests/ui/mem_replace.rs:127:13
    |
 LL |     let _ = std::mem::replace(&mut *f, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:129:13
+  --> tests/ui/mem_replace.rs:128:13
    |
 LL |     let _ = std::mem::replace(&mut b.opt, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:131:13
+  --> tests/ui/mem_replace.rs:130:13
    |
 LL |     let _ = std::mem::replace(&mut b.val, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)`
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.fixed b/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
index c970f2ba281..60f523c8ef1 100644
--- a/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.rs b/src/tools/clippy/tests/ui/mem_replace_no_std.rs
index 673d5c7b4f4..d1cb9a5817b 100644
--- a/src/tools/clippy/tests/ui/mem_replace_no_std.rs
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.rs
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.stderr b/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
index eea538da427..6ba6d2162a7 100644
--- a/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
@@ -1,5 +1,5 @@
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:24:13
+  --> tests/ui/mem_replace_no_std.rs:23:13
    |
 LL |     let _ = mem::replace(&mut an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
@@ -8,13 +8,13 @@ LL |     let _ = mem::replace(&mut an_option, None);
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:26:13
+  --> tests/ui/mem_replace_no_std.rs:25:13
    |
 LL |     let _ = mem::replace(an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
-  --> tests/ui/mem_replace_no_std.rs:31:13
+  --> tests/ui/mem_replace_no_std.rs:30:13
    |
 LL |     let _ = mem::replace(&mut refstr, "");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)`
@@ -23,25 +23,25 @@ LL |     let _ = mem::replace(&mut refstr, "");
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
-  --> tests/ui/mem_replace_no_std.rs:34:13
+  --> tests/ui/mem_replace_no_std.rs:33:13
    |
 LL |     let _ = mem::replace(&mut slice, &[]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:77:13
+  --> tests/ui/mem_replace_no_std.rs:76:13
    |
 LL |     let _ = mem::replace(&mut f.0, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:78:13
+  --> tests/ui/mem_replace_no_std.rs:77:13
    |
 LL |     let _ = mem::replace(&mut *f, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:79:13
+  --> tests/ui/mem_replace_no_std.rs:78:13
    |
 LL |     let _ = mem::replace(&mut b.opt, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
index af2882e41fb..a4560f9e9a9 100644
--- a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
+++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::mismatching_type_param_order)]
-#![allow(clippy::disallowed_names)]
+#![allow(clippy::disallowed_names, clippy::needless_lifetimes)]
 
 fn main() {
     struct Foo<A, B> {
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.rs b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
index 1a646c26522..93ab9392cf8 100644
--- a/src/tools/clippy/tests/ui/mixed_attributes_style.rs
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
@@ -82,7 +82,8 @@ mod issue_12530 {
             #![allow(dead_code)]
         }
     }
-    /// Nested mod //~ ERROR: item has both inner and outer attributes
+    /// Nested mod
+    //~^ ERROR: item has both inner and outer attributes
     #[allow(unused)]
     mod nest_mod_2 {
         #![allow(unused)]
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.stderr b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
index a1d3fc430f6..abdc2df23cf 100644
--- a/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
@@ -46,13 +46,14 @@ error: item has both inner and outer attributes
   --> tests/ui/mixed_attributes_style.rs:85:5
    |
 LL | /     /// Nested mod
+LL | |
 LL | |     #[allow(unused)]
 LL | |     mod nest_mod_2 {
 LL | |         #![allow(unused)]
    | |_________________________^
 
 error: item has both inner and outer attributes
-  --> tests/ui/mixed_attributes_style.rs:90:9
+  --> tests/ui/mixed_attributes_style.rs:91:9
    |
 LL | /         #[allow(dead_code)]
 LL | |         mod inner_mod {
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed
index adb266ffbc8..2459af60688 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.fixed
+++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed
@@ -7,8 +7,8 @@
 )]
 #![warn(clippy::must_use_candidate)]
 use std::rc::Rc;
-use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Arc;
+use std::sync::atomic::{AtomicBool, Ordering};
 
 pub struct MyAtomic(AtomicBool);
 pub struct MyPure;
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.rs b/src/tools/clippy/tests/ui/must_use_candidates.rs
index 49bb16af788..5f9b2449552 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.rs
+++ b/src/tools/clippy/tests/ui/must_use_candidates.rs
@@ -7,8 +7,8 @@
 )]
 #![warn(clippy::must_use_candidate)]
 use std::rc::Rc;
-use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Arc;
+use std::sync::atomic::{AtomicBool, Ordering};
 
 pub struct MyAtomic(AtomicBool);
 pub struct MyPure;
diff --git a/src/tools/clippy/tests/ui/mut_key.rs b/src/tools/clippy/tests/ui/mut_key.rs
index 81d8732b3b2..43ff705c477 100644
--- a/src/tools/clippy/tests/ui/mut_key.rs
+++ b/src/tools/clippy/tests/ui/mut_key.rs
@@ -2,9 +2,9 @@ use std::cell::Cell;
 use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
 use std::hash::{Hash, Hasher};
 use std::rc::Rc;
+use std::sync::Arc;
 use std::sync::atomic::AtomicUsize;
 use std::sync::atomic::Ordering::Relaxed;
-use std::sync::Arc;
 
 struct Key(AtomicUsize);
 
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
index bbedbb2bed2..29c5a27cb62 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
@@ -9,6 +9,11 @@ fn mut_mutex_lock() {
 
     let mut value = value_mutex.get_mut().unwrap();
     *value += 1;
+
+    let mut value_mutex = Mutex::new(42_u8);
+    let mut_ref_mut_ref_mutex = &mut &mut value_mutex;
+    let mut value = mut_ref_mut_ref_mutex.get_mut().unwrap();
+    *value += 1;
 }
 
 fn no_owned_mutex_lock() {
@@ -24,4 +29,11 @@ fn issue9415() {
     *guard += 1;
 }
 
+fn mut_ref_ref_mutex_lock() {
+    let mutex = Mutex::new(42_u8);
+    let mut_ref_ref_mutex = &mut &mutex;
+    let mut guard = mut_ref_ref_mutex.lock().unwrap();
+    *guard += 1;
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.rs b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
index 74116100e82..fcdb3ff97db 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.rs
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
@@ -9,6 +9,11 @@ fn mut_mutex_lock() {
 
     let mut value = value_mutex.lock().unwrap();
     *value += 1;
+
+    let mut value_mutex = Mutex::new(42_u8);
+    let mut_ref_mut_ref_mutex = &mut &mut value_mutex;
+    let mut value = mut_ref_mut_ref_mutex.lock().unwrap();
+    *value += 1;
 }
 
 fn no_owned_mutex_lock() {
@@ -24,4 +29,11 @@ fn issue9415() {
     *guard += 1;
 }
 
+fn mut_ref_ref_mutex_lock() {
+    let mutex = Mutex::new(42_u8);
+    let mut_ref_ref_mutex = &mut &mutex;
+    let mut guard = mut_ref_ref_mutex.lock().unwrap();
+    *guard += 1;
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
index a3d4905c04c..92601c4c612 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
@@ -7,5 +7,11 @@ LL |     let mut value = value_mutex.lock().unwrap();
    = note: `-D clippy::mut-mutex-lock` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::mut_mutex_lock)]`
 
-error: aborting due to 1 previous error
+error: calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference
+  --> tests/ui/mut_mutex_lock.rs:15:43
+   |
+LL |     let mut value = mut_ref_mut_ref_mutex.lock().unwrap();
+   |                                           ^^^^ help: change this to: `get_mut`
+
+error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index cabdc22bda8..2763830e09c 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -4,7 +4,8 @@
     clippy::uninlined_format_args,
     clippy::unnecessary_mut_passed,
     clippy::unnecessary_to_owned,
-    clippy::unnecessary_literal_unwrap
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::needless_borrow)]
 
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 50062589645..b46f82b18c6 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -4,7 +4,8 @@
     clippy::uninlined_format_args,
     clippy::unnecessary_mut_passed,
     clippy::unnecessary_to_owned,
-    clippy::unnecessary_literal_unwrap
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::needless_borrow)]
 
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index bf0e265c250..4b2b17e7e57 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -1,5 +1,5 @@
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:15:15
+  --> tests/ui/needless_borrow.rs:16:15
    |
 LL |     let _ = x(&&a); // warn
    |               ^^^ help: change this to: `&a`
@@ -8,163 +8,163 @@ LL |     let _ = x(&&a); // warn
    = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:19:13
+  --> tests/ui/needless_borrow.rs:20:13
    |
 LL |     mut_ref(&mut &mut b); // warn
    |             ^^^^^^^^^^^ help: change this to: `&mut b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:31:13
+  --> tests/ui/needless_borrow.rs:32:13
    |
 LL |             &&a
    |             ^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:33:15
+  --> tests/ui/needless_borrow.rs:34:15
    |
 LL |         46 => &&a,
    |               ^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:39:27
+  --> tests/ui/needless_borrow.rs:40:27
    |
 LL |                     break &ref_a;
    |                           ^^^^^^ help: change this to: `ref_a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:46:15
+  --> tests/ui/needless_borrow.rs:47:15
    |
 LL |     let _ = x(&&&a);
    |               ^^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:47:15
+  --> tests/ui/needless_borrow.rs:48:15
    |
 LL |     let _ = x(&mut &&a);
    |               ^^^^^^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:48:15
+  --> tests/ui/needless_borrow.rs:49:15
    |
 LL |     let _ = x(&&&mut b);
    |               ^^^^^^^^ help: change this to: `&mut b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:49:15
+  --> tests/ui/needless_borrow.rs:50:15
    |
 LL |     let _ = x(&&ref_a);
    |               ^^^^^^^ help: change this to: `ref_a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:52:11
+  --> tests/ui/needless_borrow.rs:53:11
    |
 LL |         x(&b);
    |           ^^ help: change this to: `b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:59:13
+  --> tests/ui/needless_borrow.rs:60:13
    |
 LL |     mut_ref(&mut x);
    |             ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:60:13
+  --> tests/ui/needless_borrow.rs:61:13
    |
 LL |     mut_ref(&mut &mut x);
    |             ^^^^^^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:61:23
+  --> tests/ui/needless_borrow.rs:62:23
    |
 LL |     let y: &mut i32 = &mut x;
    |                       ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:62:23
+  --> tests/ui/needless_borrow.rs:63:23
    |
 LL |     let y: &mut i32 = &mut &mut x;
    |                       ^^^^^^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:71:14
+  --> tests/ui/needless_borrow.rs:72:14
    |
 LL |         0 => &mut x,
    |              ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:77:14
+  --> tests/ui/needless_borrow.rs:78:14
    |
 LL |         0 => &mut x,
    |              ^^^^^^ help: change this to: `x`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:89:13
+  --> tests/ui/needless_borrow.rs:90:13
    |
 LL |     let _ = (&x).0;
    |             ^^^^ help: change this to: `x`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:91:22
+  --> tests/ui/needless_borrow.rs:92:22
    |
 LL |     let _ = unsafe { (&*x).0 };
    |                      ^^^^^ help: change this to: `(*x)`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:101:5
+  --> tests/ui/needless_borrow.rs:102:5
    |
 LL |     (&&()).foo();
    |     ^^^^^^ help: change this to: `(&())`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:110:5
+  --> tests/ui/needless_borrow.rs:111:5
    |
 LL |     (&&5).foo();
    |     ^^^^^ help: change this to: `(&5)`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:136:23
+  --> tests/ui/needless_borrow.rs:137:23
    |
 LL |     let x: (&str,) = (&"",);
    |                       ^^^ help: change this to: `""`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:178:13
+  --> tests/ui/needless_borrow.rs:179:13
    |
 LL |             (&self.f)()
    |             ^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:187:13
+  --> tests/ui/needless_borrow.rs:188:13
    |
 LL |             (&mut self.f)()
    |             ^^^^^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:224:22
+  --> tests/ui/needless_borrow.rs:225:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:231:22
+  --> tests/ui/needless_borrow.rs:232:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:235:22
+  --> tests/ui/needless_borrow.rs:236:22
    |
 LL |         let _ = &mut (&mut x.u).x;
    |                      ^^^^^^^^^^ help: change this to: `x.u`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:236:22
+  --> tests/ui/needless_borrow.rs:237:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:257:23
+  --> tests/ui/needless_borrow.rs:258:23
    |
 LL |     option.unwrap_or((&x.0,));
    |                       ^^^^ help: change this to: `x.0`
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
index d1787b35abd..cfa4cf9da3c 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
@@ -329,7 +329,7 @@ mod issue2944 {
         bar: &'a Bar,
     }
 
-    impl<'a> Foo for Baz<'a> {}
+    impl Foo for Baz<'_> {}
     impl Bar {
         fn baz(&self) -> impl Foo + '_ {
             Baz { bar: self }
@@ -384,7 +384,7 @@ mod nested_elision_sites {
         f()
     }
     // lint
-    fn where_clause_elidadable<T>(i: &i32, f: T) -> &i32
+    fn where_clause_elidable<T>(i: &i32, f: T) -> &i32
     where
         T: Fn(&i32) -> &i32,
     {
@@ -543,4 +543,23 @@ mod issue5787 {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/pull/13286#issuecomment-2374245772
+mod rayon {
+    trait ParallelIterator {
+        type Item;
+    }
+
+    struct Copied<I: ParallelIterator> {
+        base: I,
+    }
+
+    impl<'a, T, I> ParallelIterator for Copied<I>
+    where
+        I: ParallelIterator<Item = &'a T>,
+        T: 'a + Copy + Send + Sync,
+    {
+        type Item = T;
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index 03d6f201358..5e9d5116426 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -384,7 +384,7 @@ mod nested_elision_sites {
         f()
     }
     // lint
-    fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
+    fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
     where
         T: Fn(&i32) -> &i32,
     {
@@ -543,4 +543,23 @@ mod issue5787 {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/pull/13286#issuecomment-2374245772
+mod rayon {
+    trait ParallelIterator {
+        type Item;
+    }
+
+    struct Copied<I: ParallelIterator> {
+        base: I,
+    }
+
+    impl<'a, T, I> ParallelIterator for Copied<I>
+    where
+        I: ParallelIterator<Item = &'a T>,
+        T: 'a + Copy + Send + Sync,
+    {
+        type Item = T;
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index 50f845e2d92..e56c914cc86 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -336,6 +336,18 @@ LL +         fn needless_lt(_x: &u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/needless_lifetimes.rs:332:10
+   |
+LL |     impl<'a> Foo for Baz<'a> {}
+   |          ^^              ^^
+   |
+help: elide the lifetimes
+   |
+LL -     impl<'a> Foo for Baz<'a> {}
+LL +     impl Foo for Baz<'_> {}
+   |
+
+error: the following explicit lifetimes could be elided: 'a
   --> tests/ui/needless_lifetimes.rs:334:16
    |
 LL |         fn baz<'a>(&'a self) -> impl Foo + 'a {
@@ -372,15 +384,15 @@ LL +     fn generics_elidable<T: Fn(&i32) -> &i32>(i: &i32, f: T) -> &i32 {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:387:32
+  --> tests/ui/needless_lifetimes.rs:387:30
    |
-LL |     fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
-   |                                ^^         ^^                ^^
+LL |     fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
+   |                              ^^         ^^                ^^
    |
 help: elide the lifetimes
    |
-LL -     fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
-LL +     fn where_clause_elidadable<T>(i: &i32, f: T) -> &i32
+LL -     fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
+LL +     fn where_clause_elidable<T>(i: &i32, f: T) -> &i32
    |
 
 error: the following explicit lifetimes could be elided: 'a
@@ -564,5 +576,5 @@ LL -         fn one_input<'a>(x: &'a u8) -> &'a u8 {
 LL +         fn one_input(x: &u8) -> &u8 {
    |
 
-error: aborting due to 47 previous errors
+error: aborting due to 48 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.rs b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
index 14cba5a7eb5..a8d9db95dcc 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
@@ -5,7 +5,8 @@
     clippy::redundant_clone,
     clippy::redundant_pattern_matching,
     clippy::single_match,
-    clippy::uninlined_format_args
+    clippy::uninlined_format_args,
+    clippy::needless_lifetimes
 )]
 //@no-rustfix
 use std::borrow::Borrow;
@@ -84,7 +85,7 @@ trait Serialize {}
 impl<'a, T> Serialize for &'a T where T: Serialize {}
 impl Serialize for i32 {}
 
-fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
+fn test_blanket_ref<T: Foo, S: Serialize>(vals: T, serializable: S) {}
 //~^ ERROR: this argument is passed by value, but not consumed in the function body
 
 fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
@@ -116,7 +117,7 @@ impl<T: Serialize, U> S<T, U> {
     ) {
     }
 
-    fn baz(&self, _u: U, _s: Self) {}
+    fn baz(&self, uu: U, ss: Self) {}
     //~^ ERROR: this argument is passed by value, but not consumed in the function body
     //~| ERROR: this argument is passed by value, but not consumed in the function body
 }
@@ -162,13 +163,13 @@ fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
 // The following 3 lines should not cause an ICE. See #2831
 trait Bar<'a, A> {}
 impl<'b, T> Bar<'b, T> for T {}
-fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {}
+fn some_fun<'b, S: Bar<'b, ()>>(items: S) {}
 //~^ ERROR: this argument is passed by value, but not consumed in the function body
 
 // Also this should not cause an ICE. See #2831
 trait Club<'a, A> {}
 impl<T> Club<'static, T> for T {}
-fn more_fun(_item: impl Club<'static, i32>) {}
+fn more_fun(items: impl Club<'static, i32>) {}
 //~^ ERROR: this argument is passed by value, but not consumed in the function body
 
 fn is_sync<T>(_: T)
@@ -177,6 +178,10 @@ where
 {
 }
 
+struct Obj(String);
+
+fn prefix_test(_unused_with_prefix: Obj) {}
+
 fn main() {
     // This should not cause an ICE either
     // https://github.com/rust-lang/rust-clippy/issues/3144
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
index 827a200ba68..2587d3f8c52 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
@@ -1,5 +1,5 @@
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:18:23
+  --> tests/ui/needless_pass_by_value.rs:19:23
    |
 LL | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
    |                       ^^^^^^ help: consider changing the type to: `&[T]`
@@ -8,55 +8,55 @@ LL | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T
    = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:34:11
+  --> tests/ui/needless_pass_by_value.rs:35:11
    |
 LL | fn bar(x: String, y: Wrapper) {
    |           ^^^^^^ help: consider changing the type to: `&str`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:34:22
+  --> tests/ui/needless_pass_by_value.rs:35:22
    |
 LL | fn bar(x: String, y: Wrapper) {
    |                      ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:42:71
+  --> tests/ui/needless_pass_by_value.rs:43:71
    |
 LL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
    |                                                                       ^ help: consider taking a reference instead: `&V`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:55:18
+  --> tests/ui/needless_pass_by_value.rs:56:18
    |
 LL | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&Option<Option<String>>`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:69:24
+  --> tests/ui/needless_pass_by_value.rs:70:24
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
    |                        ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:69:36
+  --> tests/ui/needless_pass_by_value.rs:70:36
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
    |                                    ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:87:49
+  --> tests/ui/needless_pass_by_value.rs:88:49
    |
-LL | fn test_blanket_ref<T: Foo, S: Serialize>(_foo: T, _serializable: S) {}
+LL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: T, serializable: S) {}
    |                                                 ^ help: consider taking a reference instead: `&T`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:18
+  --> tests/ui/needless_pass_by_value.rs:91:18
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                  ^^^^^^ help: consider taking a reference instead: `&String`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:29
+  --> tests/ui/needless_pass_by_value.rs:91:29
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                             ^^^^^^
@@ -71,13 +71,13 @@ LL |     let _ = t.to_string();
    |             ~~~~~~~~~~~~~
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:40
+  --> tests/ui/needless_pass_by_value.rs:91:40
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                                        ^^^^^^^^ help: consider taking a reference instead: `&Vec<i32>`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:53
+  --> tests/ui/needless_pass_by_value.rs:91:53
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                                                     ^^^^^^^^
@@ -92,87 +92,87 @@ LL |     let _ = v.to_owned();
    |             ~~~~~~~~~~~~
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:107:12
+  --> tests/ui/needless_pass_by_value.rs:108:12
    |
 LL |         s: String,
    |            ^^^^^^ help: consider changing the type to: `&str`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:109:12
+  --> tests/ui/needless_pass_by_value.rs:110:12
    |
 LL |         t: String,
    |            ^^^^^^ help: consider taking a reference instead: `&String`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:119:23
+  --> tests/ui/needless_pass_by_value.rs:120:23
    |
-LL |     fn baz(&self, _u: U, _s: Self) {}
+LL |     fn baz(&self, uu: U, ss: Self) {}
    |                       ^ help: consider taking a reference instead: `&U`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:119:30
+  --> tests/ui/needless_pass_by_value.rs:120:30
    |
-LL |     fn baz(&self, _u: U, _s: Self) {}
+LL |     fn baz(&self, uu: U, ss: Self) {}
    |                              ^^^^ help: consider taking a reference instead: `&Self`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:143:24
+  --> tests/ui/needless_pass_by_value.rs:144:24
    |
 LL | fn bar_copy(x: u32, y: CopyWrapper) {
    |                        ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
-help: consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+help: or consider marking this type as `Copy`
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:150:29
+  --> tests/ui/needless_pass_by_value.rs:151:29
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
    |                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
-help: consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+help: or consider marking this type as `Copy`
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:150:45
+  --> tests/ui/needless_pass_by_value.rs:151:45
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
    |                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
-help: consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+help: or consider marking this type as `Copy`
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:150:61
+  --> tests/ui/needless_pass_by_value.rs:151:61
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
    |                                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
-help: consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+help: or consider marking this type as `Copy`
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:165:40
+  --> tests/ui/needless_pass_by_value.rs:166:40
    |
-LL | fn some_fun<'b, S: Bar<'b, ()>>(_item: S) {}
+LL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {}
    |                                        ^ help: consider taking a reference instead: `&S`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:171:20
+  --> tests/ui/needless_pass_by_value.rs:172:20
    |
-LL | fn more_fun(_item: impl Club<'static, i32>) {}
+LL | fn more_fun(items: impl Club<'static, i32>) {}
    |                    ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>`
 
 error: aborting due to 22 previous errors
diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed
index fc4129e1db8..ca422e605d6 100644
--- a/src/tools/clippy/tests/ui/needless_return.fixed
+++ b/src/tools/clippy/tests/ui/needless_return.fixed
@@ -355,4 +355,28 @@ fn conjunctive_blocks() -> String {
     ({ "a".to_string() } + "b" + { "c" })
 }
 
+fn issue12907() -> String {
+    "".split("").next().unwrap().to_string()
+}
+
 fn main() {}
+
+fn a(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return, reason = "Use early return for errors.")]
+            return None;
+        },
+    }
+}
+
+fn b(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return)]
+            return None;
+        },
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs
index 61c7a02008f..aad6e13136f 100644
--- a/src/tools/clippy/tests/ui/needless_return.rs
+++ b/src/tools/clippy/tests/ui/needless_return.rs
@@ -365,4 +365,28 @@ fn conjunctive_blocks() -> String {
     return { "a".to_string() } + "b" + { "c" };
 }
 
+fn issue12907() -> String {
+    return "".split("").next().unwrap().to_string();
+}
+
 fn main() {}
+
+fn a(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return, reason = "Use early return for errors.")]
+            return None;
+        },
+    }
+}
+
+fn b(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return)]
+            return None;
+        },
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index ea9c230eafd..da0fa220d8c 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -665,5 +665,17 @@ LL -     return { "a".to_string() } + "b" + { "c" };
 LL +     ({ "a".to_string() } + "b" + { "c" })
    |
 
-error: aborting due to 53 previous errors
+error: unneeded `return` statement
+  --> tests/ui/needless_return.rs:369:5
+   |
+LL |     return "".split("").next().unwrap().to_string();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove `return`
+   |
+LL -     return "".split("").next().unwrap().to_string();
+LL +     "".split("").next().unwrap().to_string()
+   |
+
+error: aborting due to 54 previous errors
 
diff --git a/src/tools/clippy/tests/ui/new_without_default.fixed b/src/tools/clippy/tests/ui/new_without_default.fixed
index 85408c4e17f..5a6a92394a7 100644
--- a/src/tools/clippy/tests/ui/new_without_default.fixed
+++ b/src/tools/clippy/tests/ui/new_without_default.fixed
@@ -2,7 +2,8 @@
     dead_code,
     clippy::missing_safety_doc,
     clippy::extra_unused_lifetimes,
-    clippy::extra_unused_type_parameters
+    clippy::extra_unused_type_parameters,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::new_without_default)]
 
diff --git a/src/tools/clippy/tests/ui/new_without_default.rs b/src/tools/clippy/tests/ui/new_without_default.rs
index 3ac7292c236..12ea729253a 100644
--- a/src/tools/clippy/tests/ui/new_without_default.rs
+++ b/src/tools/clippy/tests/ui/new_without_default.rs
@@ -2,7 +2,8 @@
     dead_code,
     clippy::missing_safety_doc,
     clippy::extra_unused_lifetimes,
-    clippy::extra_unused_type_parameters
+    clippy::extra_unused_type_parameters,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::new_without_default)]
 
diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr
index a30830ae7b2..57bf4bd847c 100644
--- a/src/tools/clippy/tests/ui/new_without_default.stderr
+++ b/src/tools/clippy/tests/ui/new_without_default.stderr
@@ -1,5 +1,5 @@
 error: you should consider adding a `Default` implementation for `Foo`
-  --> tests/ui/new_without_default.rs:12:5
+  --> tests/ui/new_without_default.rs:13:5
    |
 LL | /     pub fn new() -> Foo {
 LL | |
@@ -20,7 +20,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `Bar`
-  --> tests/ui/new_without_default.rs:22:5
+  --> tests/ui/new_without_default.rs:23:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -38,7 +38,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `LtKo<'c>`
-  --> tests/ui/new_without_default.rs:87:5
+  --> tests/ui/new_without_default.rs:88:5
    |
 LL | /     pub fn new() -> LtKo<'c> {
 LL | |
@@ -56,7 +56,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `Const`
-  --> tests/ui/new_without_default.rs:120:5
+  --> tests/ui/new_without_default.rs:121:5
    |
 LL | /     pub const fn new() -> Const {
 LL | |         Const
@@ -73,7 +73,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `NewNotEqualToDerive`
-  --> tests/ui/new_without_default.rs:180:5
+  --> tests/ui/new_without_default.rs:181:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -91,7 +91,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `FooGenerics<T>`
-  --> tests/ui/new_without_default.rs:189:5
+  --> tests/ui/new_without_default.rs:190:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -109,7 +109,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `BarGenerics<T>`
-  --> tests/ui/new_without_default.rs:197:5
+  --> tests/ui/new_without_default.rs:198:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -127,7 +127,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `Foo<T>`
-  --> tests/ui/new_without_default.rs:209:9
+  --> tests/ui/new_without_default.rs:210:9
    |
 LL | /         pub fn new() -> Self {
 LL | |
@@ -147,7 +147,7 @@ LL ~     impl<T> Foo<T> {
    |
 
 error: you should consider adding a `Default` implementation for `MyStruct<K, V>`
-  --> tests/ui/new_without_default.rs:255:5
+  --> tests/ui/new_without_default.rs:256:5
    |
 LL | /     pub fn new() -> Self {
 LL | |         Self { _kv: None }
diff --git a/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed b/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed
index 237f5f5b97a..f68d5e30d27 100644
--- a/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed
+++ b/src/tools/clippy/tests/ui/non_octal_unix_permissions.fixed
@@ -1,4 +1,4 @@
-//@ignore-target-windows
+//@ignore-target: windows
 
 #![warn(clippy::non_octal_unix_permissions)]
 use std::fs::{DirBuilder, File, OpenOptions, Permissions};
diff --git a/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs b/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs
index c8da5dbcec2..647c3769d2c 100644
--- a/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs
+++ b/src/tools/clippy/tests/ui/non_octal_unix_permissions.rs
@@ -1,4 +1,4 @@
-//@ignore-target-windows
+//@ignore-target: windows
 
 #![warn(clippy::non_octal_unix_permissions)]
 use std::fs::{DirBuilder, File, OpenOptions, Permissions};
diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions.fixed b/src/tools/clippy/tests/ui/non_zero_suggestions.fixed
new file mode 100644
index 00000000000..e67c992fdde
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_zero_suggestions.fixed
@@ -0,0 +1,65 @@
+#![warn(clippy::non_zero_suggestions)]
+use std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
+
+fn main() {
+    /// Positive test cases (lint should trigger)
+    // U32 -> U64
+    let x: u64 = 100;
+    let y = NonZeroU32::new(10).unwrap();
+    let r1 = x / NonZeroU64::from(y);
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+
+    let r2 = x % NonZeroU64::from(y);
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+
+    // U16 -> U32
+    let a: u32 = 50;
+    let b = NonZeroU16::new(5).unwrap();
+    let r3 = a / NonZeroU32::from(b);
+    //~^ ERROR: consider using `NonZeroU32::from()` for more efficient and type-safe conversion
+
+    let x = NonZeroU64::from(NonZeroU32::new(5).unwrap());
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+
+    /// Negative test cases (lint should not trigger)
+    // Left hand side expressions should not be triggered
+    let c: u32 = 50;
+    let d = NonZeroU16::new(5).unwrap();
+    let r4 = u32::from(b.get()) / a;
+
+    // Should not trigger for any other operand other than `/` and `%`
+    let r5 = a + u32::from(b.get());
+    let r6 = a - u32::from(b.get());
+
+    // Same size types
+    let e: u32 = 200;
+    let f = NonZeroU32::new(20).unwrap();
+    let r7 = e / f.get();
+
+    // Smaller to larger, but not NonZero
+    let g: u64 = 1000;
+    let h: u32 = 50;
+    let r8 = g / u64::from(h);
+
+    // Using From correctly
+    let k: u64 = 300;
+    let l = NonZeroU32::new(15).unwrap();
+    let r9 = k / NonZeroU64::from(l);
+}
+
+// Additional function to test the lint in a different context
+fn divide_numbers(x: u64, y: NonZeroU32) -> u64 {
+    x / NonZeroU64::from(y)
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+}
+
+struct Calculator {
+    value: u64,
+}
+
+impl Calculator {
+    fn divide(&self, divisor: NonZeroU32) -> u64 {
+        self.value / NonZeroU64::from(divisor)
+        //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+    }
+}
diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions.rs b/src/tools/clippy/tests/ui/non_zero_suggestions.rs
new file mode 100644
index 00000000000..de82371a8f2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_zero_suggestions.rs
@@ -0,0 +1,65 @@
+#![warn(clippy::non_zero_suggestions)]
+use std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
+
+fn main() {
+    /// Positive test cases (lint should trigger)
+    // U32 -> U64
+    let x: u64 = 100;
+    let y = NonZeroU32::new(10).unwrap();
+    let r1 = x / u64::from(y.get());
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+
+    let r2 = x % u64::from(y.get());
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+
+    // U16 -> U32
+    let a: u32 = 50;
+    let b = NonZeroU16::new(5).unwrap();
+    let r3 = a / u32::from(b.get());
+    //~^ ERROR: consider using `NonZeroU32::from()` for more efficient and type-safe conversion
+
+    let x = u64::from(NonZeroU32::new(5).unwrap().get());
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+
+    /// Negative test cases (lint should not trigger)
+    // Left hand side expressions should not be triggered
+    let c: u32 = 50;
+    let d = NonZeroU16::new(5).unwrap();
+    let r4 = u32::from(b.get()) / a;
+
+    // Should not trigger for any other operand other than `/` and `%`
+    let r5 = a + u32::from(b.get());
+    let r6 = a - u32::from(b.get());
+
+    // Same size types
+    let e: u32 = 200;
+    let f = NonZeroU32::new(20).unwrap();
+    let r7 = e / f.get();
+
+    // Smaller to larger, but not NonZero
+    let g: u64 = 1000;
+    let h: u32 = 50;
+    let r8 = g / u64::from(h);
+
+    // Using From correctly
+    let k: u64 = 300;
+    let l = NonZeroU32::new(15).unwrap();
+    let r9 = k / NonZeroU64::from(l);
+}
+
+// Additional function to test the lint in a different context
+fn divide_numbers(x: u64, y: NonZeroU32) -> u64 {
+    x / u64::from(y.get())
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+}
+
+struct Calculator {
+    value: u64,
+}
+
+impl Calculator {
+    fn divide(&self, divisor: NonZeroU32) -> u64 {
+        self.value / u64::from(divisor.get())
+        //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+    }
+}
diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions.stderr b/src/tools/clippy/tests/ui/non_zero_suggestions.stderr
new file mode 100644
index 00000000000..7a57f7983be
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_zero_suggestions.stderr
@@ -0,0 +1,41 @@
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions.rs:9:18
+   |
+LL |     let r1 = x / u64::from(y.get());
+   |                  ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`
+   |
+   = note: `-D clippy::non-zero-suggestions` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]`
+
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions.rs:12:18
+   |
+LL |     let r2 = x % u64::from(y.get());
+   |                  ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`
+
+error: consider using `NonZeroU32::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions.rs:18:18
+   |
+LL |     let r3 = a / u32::from(b.get());
+   |                  ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU32::from(b)`
+
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions.rs:21:13
+   |
+LL |     let x = u64::from(NonZeroU32::new(5).unwrap().get());
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())`
+
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions.rs:52:9
+   |
+LL |     x / u64::from(y.get())
+   |         ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`
+
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions.rs:62:22
+   |
+LL |         self.value / u64::from(divisor.get())
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(divisor)`
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.rs b/src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.rs
new file mode 100644
index 00000000000..193c710e589
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.rs
@@ -0,0 +1,23 @@
+#![warn(clippy::non_zero_suggestions)]
+//@no-rustfix
+use std::num::{NonZeroI8, NonZeroI16, NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroUsize};
+
+fn main() {
+    let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get());
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+
+    let n = NonZeroU32::new(20).unwrap();
+    let y = u64::from(n.get());
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+    some_fn_that_only_takes_u64(y);
+
+    let m = NonZeroU32::try_from(1).unwrap();
+    let _z: NonZeroU64 = m.into();
+}
+
+fn return_non_zero(x: u64, y: NonZeroU32) -> u64 {
+    u64::from(y.get())
+    //~^ ERROR: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+}
+
+fn some_fn_that_only_takes_u64(_: u64) {}
diff --git a/src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.stderr b/src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.stderr
new file mode 100644
index 00000000000..787179f2a2d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_zero_suggestions_unfixable.stderr
@@ -0,0 +1,23 @@
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions_unfixable.rs:6:18
+   |
+LL |     let x: u64 = u64::from(NonZeroU32::new(5).unwrap().get());
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(NonZeroU32::new(5).unwrap())`
+   |
+   = note: `-D clippy::non-zero-suggestions` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::non_zero_suggestions)]`
+
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions_unfixable.rs:10:13
+   |
+LL |     let y = u64::from(n.get());
+   |             ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(n)`
+
+error: consider using `NonZeroU64::from()` for more efficient and type-safe conversion
+  --> tests/ui/non_zero_suggestions_unfixable.rs:19:5
+   |
+LL |     u64::from(y.get())
+   |     ^^^^^^^^^^^^^^^^^^ help: replace with: `NonZeroU64::from(y)`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
index cc91ba6ec66..a23310c1ad9 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
@@ -115,4 +115,66 @@ fn issue_12625() {
     if a as u64 > b {} //~ ERROR: this boolean expression can be simplified
 }
 
+fn issue_13436() {
+    fn not_zero(x: i32) -> bool {
+        x != 0
+    }
+
+    let opt = Some(500);
+    _ = opt.is_some_and(|x| x < 1000);
+    _ = opt.is_some_and(|x| x <= 1000);
+    _ = opt.is_some_and(|x| x > 1000);
+    _ = opt.is_some_and(|x| x >= 1000);
+    _ = opt.is_some_and(|x| x == 1000);
+    _ = opt.is_some_and(|x| x != 1000);
+    _ = opt.is_some_and(not_zero);
+    _ = opt.is_none_or(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(not_zero);
+    _ = opt.is_none_or(|x| x < 1000);
+    _ = opt.is_none_or(|x| x <= 1000);
+    _ = opt.is_none_or(|x| x > 1000);
+    _ = opt.is_none_or(|x| x >= 1000);
+    _ = opt.is_none_or(|x| x == 1000);
+    _ = opt.is_none_or(|x| x != 1000);
+    _ = opt.is_none_or(not_zero);
+    _ = opt.is_some_and(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(not_zero);
+
+    let opt = Some(true);
+    _ = opt.is_some_and(|x| x);
+    _ = opt.is_some_and(|x| !x);
+    _ = !opt.is_some_and(|x| x);
+    _ = opt.is_none_or(|x| x); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x);
+    _ = opt.is_none_or(|x| !x);
+    _ = !opt.is_none_or(|x| x);
+    _ = opt.is_some_and(|x| x); //~ ERROR: this boolean expression can be simplified
+
+    let opt: Option<Result<i32, i32>> = Some(Ok(123));
+    _ = opt.is_some_and(|x| x.is_ok());
+    _ = opt.is_some_and(|x| x.is_err());
+    _ = opt.is_none_or(|x| x.is_ok());
+    _ = opt.is_none_or(|x| x.is_err());
+    _ = opt.is_none_or(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+
+    #[clippy::msrv = "1.81"]
+    fn before_stabilization() {
+        let opt = Some(500);
+        _ = !opt.is_some_and(|x| x < 1000);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
index c812f6f0ca4..6c844373af7 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
@@ -115,4 +115,66 @@ fn issue_12625() {
     if !(a as u64 <= b) {} //~ ERROR: this boolean expression can be simplified
 }
 
+fn issue_13436() {
+    fn not_zero(x: i32) -> bool {
+        x != 0
+    }
+
+    let opt = Some(500);
+    _ = opt.is_some_and(|x| x < 1000);
+    _ = opt.is_some_and(|x| x <= 1000);
+    _ = opt.is_some_and(|x| x > 1000);
+    _ = opt.is_some_and(|x| x >= 1000);
+    _ = opt.is_some_and(|x| x == 1000);
+    _ = opt.is_some_and(|x| x != 1000);
+    _ = opt.is_some_and(not_zero);
+    _ = !opt.is_some_and(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(not_zero);
+    _ = opt.is_none_or(|x| x < 1000);
+    _ = opt.is_none_or(|x| x <= 1000);
+    _ = opt.is_none_or(|x| x > 1000);
+    _ = opt.is_none_or(|x| x >= 1000);
+    _ = opt.is_none_or(|x| x == 1000);
+    _ = opt.is_none_or(|x| x != 1000);
+    _ = opt.is_none_or(not_zero);
+    _ = !opt.is_none_or(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(not_zero);
+
+    let opt = Some(true);
+    _ = opt.is_some_and(|x| x);
+    _ = opt.is_some_and(|x| !x);
+    _ = !opt.is_some_and(|x| x);
+    _ = !opt.is_some_and(|x| !x); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x);
+    _ = opt.is_none_or(|x| !x);
+    _ = !opt.is_none_or(|x| x);
+    _ = !opt.is_none_or(|x| !x); //~ ERROR: this boolean expression can be simplified
+
+    let opt: Option<Result<i32, i32>> = Some(Ok(123));
+    _ = opt.is_some_and(|x| x.is_ok());
+    _ = opt.is_some_and(|x| x.is_err());
+    _ = opt.is_none_or(|x| x.is_ok());
+    _ = opt.is_none_or(|x| x.is_err());
+    _ = !opt.is_some_and(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+
+    #[clippy::msrv = "1.81"]
+    fn before_stabilization() {
+        let opt = Some(500);
+        _ = !opt.is_some_and(|x| x < 1000);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
index d7adc0638b3..52803e828ae 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
@@ -97,5 +97,113 @@ error: this boolean expression can be simplified
 LL |     if !(a as u64 <= b) {}
    |        ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b`
 
-error: aborting due to 16 previous errors
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:131: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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
+   |
+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
 
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.rs
new file mode 100644
index 00000000000..60b8da30a2f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::nonminimal_bool)]
+//@no-rustfix
+
+fn issue_13436() {
+    let opt_opt = Some(Some(500));
+    _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); //~ ERROR: this boolean expression can be simplified
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.stderr
new file mode 100644
index 00000000000..5a90155844c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.stderr
@@ -0,0 +1,17 @@
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:9
+   |
+LL |     _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt_opt.is_none_or(|x| x.is_some_and(|y| y != 1000))`
+   |
+   = note: `-D clippy::nonminimal-bool` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:34
+   |
+LL |     _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000));
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_none_or(|y| y == 1000)`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/panic_in_result_fn.rs b/src/tools/clippy/tests/ui/panic_in_result_fn.rs
index aaaf9a109ac..e2375aa996f 100644
--- a/src/tools/clippy/tests/ui/panic_in_result_fn.rs
+++ b/src/tools/clippy/tests/ui/panic_in_result_fn.rs
@@ -71,6 +71,15 @@ fn function_result_with_custom_todo() -> Result<bool, String> // should not emit
     Ok(true)
 }
 
+fn issue_13381<const N: usize>() -> Result<(), String> {
+    const {
+        if N == 0 {
+            panic!();
+        }
+    }
+    Ok(())
+}
+
 fn main() -> Result<(), String> {
     todo!("finish main method");
     Ok(())
diff --git a/src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.rs b/src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.rs
new file mode 100644
index 00000000000..b5abcbb3474
--- /dev/null
+++ b/src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.rs
@@ -0,0 +1,33 @@
+//@ needs-asm-support
+#![warn(clippy::pointers_in_nomem_asm_block)]
+#![crate_type = "lib"]
+#![no_std]
+
+use core::arch::asm;
+
+unsafe fn nomem_bad(p: &i32) {
+    asm!(
+        "asdf {p1}, {p2}, {p3}",
+        p1 = in(reg) p,
+        //~^ ERROR: passing pointers to nomem asm block
+        p2 = in(reg) p as *const _ as usize,
+        p3 = in(reg) p,
+        options(nomem, nostack, preserves_flags)
+    );
+}
+
+unsafe fn nomem_good(p: &i32) {
+    asm!("asdf {p}", p = in(reg) p, options(readonly, nostack, preserves_flags));
+    let p = p as *const i32 as usize;
+    asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags));
+}
+
+unsafe fn nomem_bad2(p: &mut i32) {
+    asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags));
+    //~^ ERROR: passing pointers to nomem asm block
+}
+
+unsafe fn nomem_fn(p: extern "C" fn()) {
+    asm!("call {p}", p = in(reg) p, options(nomem));
+    //~^ ERROR: passing pointers to nomem asm block
+}
diff --git a/src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.stderr b/src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.stderr
new file mode 100644
index 00000000000..cabeb37344f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/pointers_in_nomem_asm_block.stderr
@@ -0,0 +1,34 @@
+error: passing pointers to nomem asm block
+  --> tests/ui/pointers_in_nomem_asm_block.rs:11:9
+   |
+LL |         p1 = in(reg) p,
+   |         ^^^^^^^^^^^^^^
+...
+LL |         p3 = in(reg) p,
+   |         ^^^^^^^^^^^^^^
+   |
+   = note: `nomem` means that no memory write or read happens inside the asm! block
+   = note: if this is intentional and no pointers are read or written to, consider allowing the lint
+   = note: `-D clippy::pointers-in-nomem-asm-block` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::pointers_in_nomem_asm_block)]`
+
+error: passing pointers to nomem asm block
+  --> tests/ui/pointers_in_nomem_asm_block.rs:26:22
+   |
+LL |     asm!("asdf {p}", p = in(reg) p, options(nomem, nostack, preserves_flags));
+   |                      ^^^^^^^^^^^^^
+   |
+   = note: `nomem` means that no memory write or read happens inside the asm! block
+   = note: if this is intentional and no pointers are read or written to, consider allowing the lint
+
+error: passing pointers to nomem asm block
+  --> tests/ui/pointers_in_nomem_asm_block.rs:31:22
+   |
+LL |     asm!("call {p}", p = in(reg) p, options(nomem));
+   |                      ^^^^^^^^^^^^^
+   |
+   = note: `nomem` means that no memory write or read happens inside the asm! block
+   = note: if this is intentional and no pointers are read or written to, consider allowing the lint
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index e6ef6268121..e8b42d3b913 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.rs
+++ b/src/tools/clippy/tests/ui/ptr_arg.rs
@@ -309,3 +309,25 @@ mod issue_11181 {
         extern "C" fn allowed(_v: &Vec<u32>) {}
     }
 }
+
+mod issue_13308 {
+    use std::ops::Deref;
+
+    fn repro(source: &str, destination: &mut String) {
+        source.clone_into(destination);
+    }
+    fn repro2(source: &str, destination: &mut String) {
+        ToOwned::clone_into(source, destination);
+    }
+
+    fn h1(_: &<String as Deref>::Target) {}
+    fn h2<T: Deref>(_: T, _: &T::Target) {}
+
+    // Other cases that are still ok to lint and ideally shouldn't regress
+    fn good(v1: &String, v2: &String) {
+        //~^ ERROR: writing `&String` instead of `&str`
+        //~^^ ERROR: writing `&String` instead of `&str`
+        h1(v1);
+        h2(String::new(), v2);
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr
index 4246453e64c..1a6b3aa1f8d 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.stderr
+++ b/src/tools/clippy/tests/ui/ptr_arg.stderr
@@ -221,5 +221,17 @@ error: using a reference to `Cow` is not recommended
 LL |     fn cow_bad_ret_ty_2<'a, 'b>(input: &'a Cow<'a, str>) -> &'b str {
    |                                        ^^^^^^^^^^^^^^^^ help: change this to: `&str`
 
-error: aborting due to 25 previous errors
+error: writing `&String` instead of `&str` involves a new object where a slice will do
+  --> tests/ui/ptr_arg.rs:327:17
+   |
+LL |     fn good(v1: &String, v2: &String) {
+   |                 ^^^^^^^ help: change this to: `&str`
+
+error: writing `&String` instead of `&str` involves a new object where a slice will do
+  --> tests/ui/ptr_arg.rs:327:30
+   |
+LL |     fn good(v1: &String, v2: &String) {
+   |                              ^^^^^^^ help: change this to: `&str`
+
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
index 21ac42196e1..9a5272c7adc 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
@@ -68,3 +68,20 @@ fn _msrv_1_65() {
     let _ = ptr.cast_mut();
     let _ = mut_ptr.cast_const();
 }
+
+#[inline_macros]
+fn null_pointers() {
+    use std::ptr;
+    let _ = std::ptr::null_mut::<String>();
+    let _ = std::ptr::null::<u32>();
+    let _ = std::ptr::null_mut::<u32>();
+    let _ = std::ptr::null::<u32>();
+
+    // Make sure the lint is triggered inside a macro
+    let _ = inline!(std::ptr::null_mut::<u32>());
+    let _ = inline!(std::ptr::null_mut::<u32>());
+
+    // Do not lint inside macros from external crates
+    let _ = external!(ptr::null::<u32>() as *mut u32);
+    let _ = external!(ptr::null::<u32>().cast_mut());
+}
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.rs b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
index 5ce590b2b7e..43ab5f5ba7c 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.rs
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
@@ -68,3 +68,20 @@ fn _msrv_1_65() {
     let _ = ptr as *mut u32;
     let _ = mut_ptr as *const u32;
 }
+
+#[inline_macros]
+fn null_pointers() {
+    use std::ptr;
+    let _ = ptr::null::<String>() as *mut String;
+    let _ = ptr::null_mut::<u32>() as *const u32;
+    let _ = ptr::null::<u32>().cast_mut();
+    let _ = ptr::null_mut::<u32>().cast_const();
+
+    // Make sure the lint is triggered inside a macro
+    let _ = inline!(ptr::null::<u32>() as *mut u32);
+    let _ = inline!(ptr::null::<u32>().cast_mut());
+
+    // Do not lint inside macros from external crates
+    let _ = external!(ptr::null::<u32>() as *mut u32);
+    let _ = external!(ptr::null::<u32>().cast_mut());
+}
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
index 2c52ebd3464..a693793a4ae 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
@@ -43,5 +43,45 @@ error: `as` casting between raw pointers while changing only its constness
 LL |     let _ = mut_ptr as *const u32;
    |             ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
 
-error: aborting due to 7 previous errors
+error: `as` casting to make a const null pointer into a mutable null pointer
+  --> tests/ui/ptr_cast_constness.rs:75:13
+   |
+LL |     let _ = ptr::null::<String>() as *mut String;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<String>()`
+
+error: `as` casting to make a mutable null pointer into a const null pointer
+  --> tests/ui/ptr_cast_constness.rs:76:13
+   |
+LL |     let _ = ptr::null_mut::<u32>() as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null()` directly instead: `std::ptr::null::<u32>()`
+
+error: changing constness of a null pointer
+  --> tests/ui/ptr_cast_constness.rs:77:13
+   |
+LL |     let _ = ptr::null::<u32>().cast_mut();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<u32>()`
+
+error: changing constness of a null pointer
+  --> tests/ui/ptr_cast_constness.rs:78:13
+   |
+LL |     let _ = ptr::null_mut::<u32>().cast_const();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null()` directly instead: `std::ptr::null::<u32>()`
+
+error: `as` casting to make a const null pointer into a mutable null pointer
+  --> tests/ui/ptr_cast_constness.rs:81:21
+   |
+LL |     let _ = inline!(ptr::null::<u32>() as *mut u32);
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<u32>()`
+   |
+   = note: this error originates in the macro `__inline_mac_fn_null_pointers` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: changing constness of a null pointer
+  --> tests/ui/ptr_cast_constness.rs:82:21
+   |
+LL |     let _ = inline!(ptr::null::<u32>().cast_mut());
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `null_mut()` directly instead: `std::ptr::null_mut::<u32>()`
+   |
+   = note: this error originates in the macro `__inline_mac_fn_null_pointers` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ref_as_ptr.fixed b/src/tools/clippy/tests/ui/ref_as_ptr.fixed
index 466a628a002..6048267092f 100644
--- a/src/tools/clippy/tests/ui/ref_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ref_as_ptr.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::ref_as_ptr)]
-#![allow(clippy::unnecessary_mut_passed)]
+#![allow(clippy::unnecessary_mut_passed, clippy::needless_lifetimes)]
 
 fn f<T>(_: T) {}
 
diff --git a/src/tools/clippy/tests/ui/ref_as_ptr.rs b/src/tools/clippy/tests/ui/ref_as_ptr.rs
index 0fdc753dc22..7f1d59b856e 100644
--- a/src/tools/clippy/tests/ui/ref_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ref_as_ptr.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::ref_as_ptr)]
-#![allow(clippy::unnecessary_mut_passed)]
+#![allow(clippy::unnecessary_mut_passed, clippy::needless_lifetimes)]
 
 fn f<T>(_: T) {}
 
diff --git a/src/tools/clippy/tests/ui/ref_option/all/clippy.toml b/src/tools/clippy/tests/ui/ref_option/all/clippy.toml
new file mode 100644
index 00000000000..cda8d17eed4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/all/clippy.toml
@@ -0,0 +1 @@
+avoid-breaking-exported-api = false
diff --git a/src/tools/clippy/tests/ui/ref_option/private/clippy.toml b/src/tools/clippy/tests/ui/ref_option/private/clippy.toml
new file mode 100644
index 00000000000..5f304987aa9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/private/clippy.toml
@@ -0,0 +1 @@
+avoid-breaking-exported-api = true
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.all.fixed b/src/tools/clippy/tests/ui/ref_option/ref_option.all.fixed
new file mode 100644
index 00000000000..47781a97c98
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.all.fixed
@@ -0,0 +1,62 @@
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]
+#![warn(clippy::ref_option)]
+
+fn opt_u8(a: Option<&u8>) {}
+fn opt_gen<T>(a: Option<&T>) {}
+fn opt_string(a: std::option::Option<&String>) {}
+fn ret_string<'a>(p: &'a str) -> Option<&'a u8> {
+    panic!()
+}
+fn ret_string_static() -> Option<&'static u8> {
+    panic!()
+}
+fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+fn ret_box<'a>() -> Option<&'a Box<u8>> {
+    panic!()
+}
+
+pub fn pub_opt_string(a: Option<&String>) {}
+pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: Option<&Vec<u8>>);
+    fn pub_trait_ret(&self) -> Option<&Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: Option<&String>);
+    fn trait_ret(&self) -> Option<&String>;
+}
+
+pub struct PubStruct;
+
+impl PubStruct {
+    pub fn pub_opt_params(&self, a: Option<&()>) {}
+    pub fn pub_opt_ret(&self) -> Option<&String> {
+        panic!()
+    }
+
+    fn private_opt_params(&self, a: Option<&()>) {}
+    fn private_opt_ret(&self) -> Option<&String> {
+        panic!()
+    }
+}
+
+// valid, don't change
+fn mut_u8(a: &mut Option<u8>) {}
+pub fn pub_mut_u8(a: &mut Option<String>) {}
+
+// might be good to catch in the future
+fn mut_u8_ref(a: &mut &Option<u8>) {}
+pub fn pub_mut_u8_ref(a: &mut &Option<String>) {}
+fn lambdas() {
+    // Not handled for now, not sure if we should
+    let x = |a: &Option<String>| {};
+    let x = |a: &Option<String>| -> &Option<String> { panic!() };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr
new file mode 100644
index 00000000000..b4c69ac6296
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr
@@ -0,0 +1,162 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:8:1
+   |
+LL | fn opt_u8(a: &Option<u8>) {}
+   | ^^^^^^^^^^^^^-----------^^^^
+   |              |
+   |              help: change this to: `Option<&u8>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:9:1
+   |
+LL | fn opt_gen<T>(a: &Option<T>) {}
+   | ^^^^^^^^^^^^^^^^^----------^^^^
+   |                  |
+   |                  help: change this to: `Option<&T>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:10:1
+   |
+LL | fn opt_string(a: &std::option::Option<String>) {}
+   | ^^^^^^^^^^^^^^^^^----------------------------^^^^
+   |                  |
+   |                  help: change this to: `std::option::Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:11:1
+   |
+LL |   fn ret_string<'a>(p: &'a str) -> &'a Option<u8> {
+   |   ^                                -------------- help: change this to: `Option<&'a u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:14:1
+   |
+LL |   fn ret_string_static() -> &'static Option<u8> {
+   |   ^                         ------------------- help: change this to: `Option<&'static u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:17:1
+   |
+LL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL | fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+   |                   ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:18:1
+   |
+LL |   fn ret_box<'a>() -> &'a Option<Box<u8>> {
+   |   ^                   ------------------- help: change this to: `Option<&'a Box<u8>>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:22:1
+   |
+LL | pub fn pub_opt_string(a: &Option<String>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                          |
+   |                          help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:23:1
+   |
+LL | pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL | pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+   |                           ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:26:5
+   |
+LL |     fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:27:5
+   |
+LL |     fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:31:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:32:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:38:5
+   |
+LL |     pub fn pub_opt_params(&self, a: &Option<()>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                     |
+   |                                     help: change this to: `Option<&()>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:39:5
+   |
+LL |       pub fn pub_opt_ret(&self) -> &Option<String> {
+   |       ^                            --------------- help: change this to: `Option<&String>`
+   |  _____|
+   | |
+LL | |         panic!()
+LL | |     }
+   | |_____^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:43:5
+   |
+LL |     fn private_opt_params(&self, a: &Option<()>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                     |
+   |                                     help: change this to: `Option<&()>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:44:5
+   |
+LL |       fn private_opt_ret(&self) -> &Option<String> {
+   |       ^                            --------------- help: change this to: `Option<&String>`
+   |  _____|
+   | |
+LL | |         panic!()
+LL | |     }
+   | |_____^
+
+error: aborting due to 17 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.private.fixed b/src/tools/clippy/tests/ui/ref_option/ref_option.private.fixed
new file mode 100644
index 00000000000..8c42556e9b0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.private.fixed
@@ -0,0 +1,62 @@
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]
+#![warn(clippy::ref_option)]
+
+fn opt_u8(a: Option<&u8>) {}
+fn opt_gen<T>(a: Option<&T>) {}
+fn opt_string(a: std::option::Option<&String>) {}
+fn ret_string<'a>(p: &'a str) -> Option<&'a u8> {
+    panic!()
+}
+fn ret_string_static() -> Option<&'static u8> {
+    panic!()
+}
+fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+fn ret_box<'a>() -> Option<&'a Box<u8>> {
+    panic!()
+}
+
+pub fn pub_opt_string(a: &Option<String>) {}
+pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: Option<&String>);
+    fn trait_ret(&self) -> Option<&String>;
+}
+
+pub struct PubStruct;
+
+impl PubStruct {
+    pub fn pub_opt_params(&self, a: &Option<()>) {}
+    pub fn pub_opt_ret(&self) -> &Option<String> {
+        panic!()
+    }
+
+    fn private_opt_params(&self, a: Option<&()>) {}
+    fn private_opt_ret(&self) -> Option<&String> {
+        panic!()
+    }
+}
+
+// valid, don't change
+fn mut_u8(a: &mut Option<u8>) {}
+pub fn pub_mut_u8(a: &mut Option<String>) {}
+
+// might be good to catch in the future
+fn mut_u8_ref(a: &mut &Option<u8>) {}
+pub fn pub_mut_u8_ref(a: &mut &Option<String>) {}
+fn lambdas() {
+    // Not handled for now, not sure if we should
+    let x = |a: &Option<String>| {};
+    let x = |a: &Option<String>| -> &Option<String> { panic!() };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr
new file mode 100644
index 00000000000..17c90536da3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr
@@ -0,0 +1,108 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:8:1
+   |
+LL | fn opt_u8(a: &Option<u8>) {}
+   | ^^^^^^^^^^^^^-----------^^^^
+   |              |
+   |              help: change this to: `Option<&u8>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:9:1
+   |
+LL | fn opt_gen<T>(a: &Option<T>) {}
+   | ^^^^^^^^^^^^^^^^^----------^^^^
+   |                  |
+   |                  help: change this to: `Option<&T>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:10:1
+   |
+LL | fn opt_string(a: &std::option::Option<String>) {}
+   | ^^^^^^^^^^^^^^^^^----------------------------^^^^
+   |                  |
+   |                  help: change this to: `std::option::Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:11:1
+   |
+LL |   fn ret_string<'a>(p: &'a str) -> &'a Option<u8> {
+   |   ^                                -------------- help: change this to: `Option<&'a u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:14:1
+   |
+LL |   fn ret_string_static() -> &'static Option<u8> {
+   |   ^                         ------------------- help: change this to: `Option<&'static u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:17:1
+   |
+LL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL | fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+   |                   ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:18:1
+   |
+LL |   fn ret_box<'a>() -> &'a Option<Box<u8>> {
+   |   ^                   ------------------- help: change this to: `Option<&'a Box<u8>>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:31:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:32:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:43:5
+   |
+LL |     fn private_opt_params(&self, a: &Option<()>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                     |
+   |                                     help: change this to: `Option<&()>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:44:5
+   |
+LL |       fn private_opt_ret(&self) -> &Option<String> {
+   |       ^                            --------------- help: change this to: `Option<&String>`
+   |  _____|
+   | |
+LL | |         panic!()
+LL | |     }
+   | |_____^
+
+error: aborting due to 11 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.rs b/src/tools/clippy/tests/ui/ref_option/ref_option.rs
new file mode 100644
index 00000000000..05251bcf12c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.rs
@@ -0,0 +1,62 @@
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]
+#![warn(clippy::ref_option)]
+
+fn opt_u8(a: &Option<u8>) {}
+fn opt_gen<T>(a: &Option<T>) {}
+fn opt_string(a: &std::option::Option<String>) {}
+fn ret_string<'a>(p: &'a str) -> &'a Option<u8> {
+    panic!()
+}
+fn ret_string_static() -> &'static Option<u8> {
+    panic!()
+}
+fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+fn ret_box<'a>() -> &'a Option<Box<u8>> {
+    panic!()
+}
+
+pub fn pub_opt_string(a: &Option<String>) {}
+pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: &Option<String>);
+    fn trait_ret(&self) -> &Option<String>;
+}
+
+pub struct PubStruct;
+
+impl PubStruct {
+    pub fn pub_opt_params(&self, a: &Option<()>) {}
+    pub fn pub_opt_ret(&self) -> &Option<String> {
+        panic!()
+    }
+
+    fn private_opt_params(&self, a: &Option<()>) {}
+    fn private_opt_ret(&self) -> &Option<String> {
+        panic!()
+    }
+}
+
+// valid, don't change
+fn mut_u8(a: &mut Option<u8>) {}
+pub fn pub_mut_u8(a: &mut Option<String>) {}
+
+// might be good to catch in the future
+fn mut_u8_ref(a: &mut &Option<u8>) {}
+pub fn pub_mut_u8_ref(a: &mut &Option<String>) {}
+fn lambdas() {
+    // Not handled for now, not sure if we should
+    let x = |a: &Option<String>| {};
+    let x = |a: &Option<String>| -> &Option<String> { panic!() };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option_traits.all.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.all.stderr
new file mode 100644
index 00000000000..a9967168c12
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.all.stderr
@@ -0,0 +1,37 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:10:5
+   |
+LL |     fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:11:5
+   |
+LL |     fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:15:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:16:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option_traits.private.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.private.stderr
new file mode 100644
index 00000000000..36d0833af8a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.private.stderr
@@ -0,0 +1,21 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:15:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:16:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option_traits.rs b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.rs
new file mode 100644
index 00000000000..5d5f113c83d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.rs
@@ -0,0 +1,37 @@
+//@no-rustfix: fixes are only done to traits, not the impls
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::all)]
+#![warn(clippy::ref_option)]
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: &Option<String>);
+    fn trait_ret(&self) -> &Option<String>;
+}
+
+pub struct PubStruct;
+
+impl PubTrait for PubStruct {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>) {}
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>> {
+        panic!()
+    }
+}
+
+struct PrivateStruct;
+
+impl PrivateTrait for PrivateStruct {
+    fn trait_opt(&self, a: &Option<String>) {}
+    fn trait_ret(&self) -> &Option<String> {
+        panic!()
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_large_err.rs b/src/tools/clippy/tests/ui/result_large_err.rs
index b25348bf996..9c39f023da2 100644
--- a/src/tools/clippy/tests/ui/result_large_err.rs
+++ b/src/tools/clippy/tests/ui/result_large_err.rs
@@ -1,4 +1,4 @@
-//@ignore-32bit
+//@ignore-bitwidth: 32
 
 #![warn(clippy::result_large_err)]
 #![allow(clippy::large_enum_variant)]
diff --git a/src/tools/clippy/tests/ui/serde.rs b/src/tools/clippy/tests/ui/serde.rs
index 610a50020ec..af8b10f3e6a 100644
--- a/src/tools/clippy/tests/ui/serde.rs
+++ b/src/tools/clippy/tests/ui/serde.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::serde_api_misuse)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::needless_lifetimes)]
 
 extern crate serde;
 
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
index 0db6fbfb7be..8468d1d7c7d 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
@@ -2,7 +2,12 @@
 //@no-rustfix
 #![warn(clippy::significant_drop_in_scrutinee)]
 #![allow(dead_code, unused_assignments)]
-#![allow(clippy::match_single_binding, clippy::single_match, clippy::uninlined_format_args)]
+#![allow(
+    clippy::match_single_binding,
+    clippy::single_match,
+    clippy::uninlined_format_args,
+    clippy::needless_lifetimes
+)]
 
 use std::num::ParseIntError;
 use std::ops::Deref;
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
index c0c93cd10c0..62030cbe70e 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
@@ -1,5 +1,5 @@
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:55:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:60:11
    |
 LL |     match mutex.lock().unwrap().foo() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:143:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:148:11
    |
 LL |     match s.lock_m().get_the_value() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:166:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:171:11
    |
 LL |     match s.lock_m_m().get_the_value() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:216:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:221:11
    |
 LL |     match counter.temp_increment().len() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:241:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:246:16
    |
 LL |         match (mutex1.lock().unwrap().s.len(), true) {
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL ~         match (value, true) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:252:22
+  --> tests/ui/significant_drop_in_scrutinee.rs:257:22
    |
 LL |         match (true, mutex1.lock().unwrap().s.len(), true) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +118,7 @@ LL ~         match (true, value, true) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:264:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:269:16
    |
 LL |         match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -139,7 +139,7 @@ LL ~         match (value, true, mutex2.lock().unwrap().s.len()) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:264:54
+  --> tests/ui/significant_drop_in_scrutinee.rs:269:54
    |
 LL |         match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
    |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -160,7 +160,7 @@ LL ~         match (mutex1.lock().unwrap().s.len(), true, value) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:319:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:324:11
    |
 LL |     match mutex.lock().unwrap().s.len() > 1 {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -179,7 +179,7 @@ LL ~     match value > 1 {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:328:15
+  --> tests/ui/significant_drop_in_scrutinee.rs:333:15
    |
 LL |     match 1 < mutex.lock().unwrap().s.len() {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +198,7 @@ LL ~     match 1 < value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:348:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:353:11
    |
 LL |     match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -219,7 +219,7 @@ LL ~     match value < mutex2.lock().unwrap().s.len() {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:348:44
+  --> tests/ui/significant_drop_in_scrutinee.rs:353:44
    |
 LL |     match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
    |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -240,7 +240,7 @@ LL ~     match mutex1.lock().unwrap().s.len() < value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:361:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:366:11
    |
 LL |     match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -261,7 +261,7 @@ LL ~     match value >= mutex2.lock().unwrap().s.len() {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:361:45
+  --> tests/ui/significant_drop_in_scrutinee.rs:366:45
    |
 LL |     match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
    |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -282,7 +282,7 @@ LL ~     match mutex1.lock().unwrap().s.len() >= value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:398:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:403:11
    |
 LL |     match get_mutex_guard().s.len() > 1 {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -301,7 +301,7 @@ LL ~     match value > 1 {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:417:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:422:11
    |
 LL |       match match i {
    |  ___________^
@@ -334,7 +334,7 @@ LL ~     match value
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:445:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:450:11
    |
 LL |       match if i > 1 {
    |  ___________^
@@ -368,7 +368,7 @@ LL ~     match value
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:501:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:506:11
    |
 LL |     match s.lock().deref().deref() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -386,7 +386,7 @@ LL ~     match (&value) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:551:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:556:11
    |
 LL |     match mutex.lock().unwrap().i = i {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -405,7 +405,7 @@ LL ~     match () {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:559:15
+  --> tests/ui/significant_drop_in_scrutinee.rs:564:15
    |
 LL |     match i = mutex.lock().unwrap().i {
    |               ^^^^^^^^^^^^^^^^^^^^^^^
@@ -424,7 +424,7 @@ LL ~     match i = value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:567:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:572:11
    |
 LL |     match mutex.lock().unwrap().i += 1 {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -443,7 +443,7 @@ LL ~     match () {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:575:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:580:16
    |
 LL |     match i += mutex.lock().unwrap().i {
    |                ^^^^^^^^^^^^^^^^^^^^^^^
@@ -462,7 +462,7 @@ LL ~     match i += value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:640:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:645:11
    |
 LL |     match rwlock.read().unwrap().to_number() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -478,7 +478,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:668:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:673:11
    |
 LL |     match mutex.lock().unwrap().foo() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -494,7 +494,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:731:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:736:11
    |
 LL |     match guard.take().len() {
    |           ^^^^^^^^^^^^^^^^^^
@@ -510,7 +510,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:757:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:762:16
    |
 LL |     for val in mutex.lock().unwrap().copy_old_lifetime() {
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -526,7 +526,7 @@ LL ~     for val in value {
    |
 
 error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:797:17
+  --> tests/ui/significant_drop_in_scrutinee.rs:802:17
    |
 LL |     for val in [mutex.lock().unwrap()[0], 2] {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -542,7 +542,7 @@ LL ~     for val in [value, 2] {
    |
 
 error: temporary with significant `Drop` in `if let` scrutinee will live until the end of the `if let` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:807:24
+  --> tests/ui/significant_drop_in_scrutinee.rs:812:24
    |
 LL |     if let Some(val) = mutex.lock().unwrap().first().copied() {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -558,7 +558,7 @@ LL ~     if let Some(val) = value {
    |
 
 error: temporary with significant `Drop` in `while let` scrutinee will live until the end of the `while let` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:823:27
+  --> tests/ui/significant_drop_in_scrutinee.rs:828:27
    |
 LL |     while let Some(val) = mutex.lock().unwrap().pop() {
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/single_call_fn.rs b/src/tools/clippy/tests/ui/single_call_fn.rs
index 55e7508a957..a0597664da5 100644
--- a/src/tools/clippy/tests/ui/single_call_fn.rs
+++ b/src/tools/clippy/tests/ui/single_call_fn.rs
@@ -1,4 +1,4 @@
-//@ignore-32bit
+//@ignore-bitwidth: 32
 //@aux-build:proc_macros.rs
 #![allow(clippy::redundant_closure_call, unused)]
 #![warn(clippy::single_call_fn)]
diff --git a/src/tools/clippy/tests/ui/single_match.fixed b/src/tools/clippy/tests/ui/single_match.fixed
index 5249c440889..4016b2699d6 100644
--- a/src/tools/clippy/tests/ui/single_match.fixed
+++ b/src/tools/clippy/tests/ui/single_match.fixed
@@ -39,8 +39,8 @@ enum Foo {
     Bar,
     Baz(u8),
 }
-use std::borrow::Cow;
 use Foo::*;
+use std::borrow::Cow;
 
 fn single_match_know_enum() {
     let x = Some(1u8);
@@ -296,3 +296,27 @@ fn issue11365() {
 
     if let Some(A | B) = &Some(A) { println!() }
 }
+
+#[derive(Eq, PartialEq)]
+pub struct Data([u8; 4]);
+
+const DATA: Data = Data([1, 2, 3, 4]);
+const CONST_I32: i32 = 1;
+
+fn irrefutable_match() {
+    println!();
+
+    println!();
+
+    let i = 0;
+    {
+        let a = 1;
+        let b = 2;
+    }
+
+    
+
+    
+
+    println!()
+}
diff --git a/src/tools/clippy/tests/ui/single_match.rs b/src/tools/clippy/tests/ui/single_match.rs
index 882098a56e7..75edaa60605 100644
--- a/src/tools/clippy/tests/ui/single_match.rs
+++ b/src/tools/clippy/tests/ui/single_match.rs
@@ -51,8 +51,8 @@ enum Foo {
     Bar,
     Baz(u8),
 }
-use std::borrow::Cow;
 use Foo::*;
+use std::borrow::Cow;
 
 fn single_match_know_enum() {
     let x = Some(1u8);
@@ -360,3 +360,45 @@ fn issue11365() {
         None | Some(_) => {},
     }
 }
+
+#[derive(Eq, PartialEq)]
+pub struct Data([u8; 4]);
+
+const DATA: Data = Data([1, 2, 3, 4]);
+const CONST_I32: i32 = 1;
+
+fn irrefutable_match() {
+    match DATA {
+        DATA => println!(),
+        _ => {},
+    }
+
+    match CONST_I32 {
+        CONST_I32 => println!(),
+        _ => {},
+    }
+
+    let i = 0;
+    match i {
+        i => {
+            let a = 1;
+            let b = 2;
+        },
+        _ => {},
+    }
+
+    match i {
+        i => {},
+        _ => {},
+    }
+
+    match i {
+        i => (),
+        _ => (),
+    }
+
+    match CONST_I32 {
+        CONST_I32 => println!(),
+        _ => {},
+    }
+}
diff --git a/src/tools/clippy/tests/ui/single_match.stderr b/src/tools/clippy/tests/ui/single_match.stderr
index ceb2a193bf7..9240b09c50a 100644
--- a/src/tools/clippy/tests/ui/single_match.stderr
+++ b/src/tools/clippy/tests/ui/single_match.stderr
@@ -216,5 +216,70 @@ LL | |         None | Some(_) => {},
 LL | |     }
    | |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }`
 
-error: aborting due to 20 previous errors
+error: this pattern is irrefutable, `match` is useless
+  --> tests/ui/single_match.rs:371:5
+   |
+LL | /     match DATA {
+LL | |         DATA => println!(),
+LL | |         _ => {},
+LL | |     }
+   | |_____^ help: try: `println!();`
+
+error: this pattern is irrefutable, `match` is useless
+  --> tests/ui/single_match.rs:376:5
+   |
+LL | /     match CONST_I32 {
+LL | |         CONST_I32 => println!(),
+LL | |         _ => {},
+LL | |     }
+   | |_____^ help: try: `println!();`
+
+error: this pattern is irrefutable, `match` is useless
+  --> tests/ui/single_match.rs:382:5
+   |
+LL | /     match i {
+LL | |         i => {
+LL | |             let a = 1;
+LL | |             let b = 2;
+LL | |         },
+LL | |         _ => {},
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let a = 1;
+LL +         let b = 2;
+LL +     }
+   |
+
+error: this pattern is irrefutable, `match` is useless
+  --> tests/ui/single_match.rs:390:5
+   |
+LL | /     match i {
+LL | |         i => {},
+LL | |         _ => {},
+LL | |     }
+   | |_____^ help: `match` expression can be removed
+
+error: this pattern is irrefutable, `match` is useless
+  --> tests/ui/single_match.rs:395:5
+   |
+LL | /     match i {
+LL | |         i => (),
+LL | |         _ => (),
+LL | |     }
+   | |_____^ help: `match` expression can be removed
+
+error: this pattern is irrefutable, `match` is useless
+  --> tests/ui/single_match.rs:400:5
+   |
+LL | /     match CONST_I32 {
+LL | |         CONST_I32 => println!(),
+LL | |         _ => {},
+LL | |     }
+   | |_____^ help: try: `println!()`
+
+error: aborting due to 26 previous errors
 
diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed
index 163be16ad8b..c2ca746976b 100644
--- a/src/tools/clippy/tests/ui/single_match_else.fixed
+++ b/src/tools/clippy/tests/ui/single_match_else.fixed
@@ -171,3 +171,7 @@ fn issue_10808(bar: Option<i32>) {
         },
     }
 }
+
+fn irrefutable_match() -> Option<&'static ExprNode> {
+    Some(&NODE)
+}
diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs
index 3f1fd2b3183..2d9e877ee0f 100644
--- a/src/tools/clippy/tests/ui/single_match_else.rs
+++ b/src/tools/clippy/tests/ui/single_match_else.rs
@@ -199,3 +199,13 @@ fn issue_10808(bar: Option<i32>) {
         },
     }
 }
+
+fn irrefutable_match() -> Option<&'static ExprNode> {
+    match ExprNode::Butterflies {
+        ExprNode::Butterflies => Some(&NODE),
+        _ => {
+            let x = 5;
+            None
+        },
+    }
+}
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index 61c348260d0..a2801751a43 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -197,5 +197,17 @@ LL +         println!("None");
 LL +     }
    |
 
-error: aborting due to 9 previous errors
+error: this pattern is irrefutable, `match` is useless
+  --> tests/ui/single_match_else.rs:204:5
+   |
+LL | /     match ExprNode::Butterflies {
+LL | |         ExprNode::Butterflies => Some(&NODE),
+LL | |         _ => {
+LL | |             let x = 5;
+LL | |             None
+LL | |         },
+LL | |     }
+   | |_____^ help: try: `Some(&NODE)`
+
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/str_split.fixed b/src/tools/clippy/tests/ui/str_split.fixed
index 4f33241da7a..57a3c315a87 100644
--- a/src/tools/clippy/tests/ui/str_split.fixed
+++ b/src/tools/clippy/tests/ui/str_split.fixed
@@ -1,4 +1,5 @@
 #![warn(clippy::str_split_at_newline)]
+#![allow(clippy::needless_lifetimes)]
 
 use core::str::Split;
 use std::ops::Deref;
diff --git a/src/tools/clippy/tests/ui/str_split.rs b/src/tools/clippy/tests/ui/str_split.rs
index f24caa61c30..fcff036f264 100644
--- a/src/tools/clippy/tests/ui/str_split.rs
+++ b/src/tools/clippy/tests/ui/str_split.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::str_split_at_newline)]
+#![allow(clippy::needless_lifetimes)]
 
 use core::str::Split;
 use std::ops::Deref;
diff --git a/src/tools/clippy/tests/ui/str_split.stderr b/src/tools/clippy/tests/ui/str_split.stderr
index ebe0d4ef4d3..7b560468f12 100644
--- a/src/tools/clippy/tests/ui/str_split.stderr
+++ b/src/tools/clippy/tests/ui/str_split.stderr
@@ -1,5 +1,5 @@
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:59:13
+  --> tests/ui/str_split.rs:60:13
    |
 LL |     let _ = s1.trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()`
@@ -8,55 +8,55 @@ LL |     let _ = s1.trim().split('\n');
    = help: to override `-D warnings` add `#[allow(clippy::str_split_at_newline)]`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:61:13
+  --> tests/ui/str_split.rs:62:13
    |
 LL |     let _ = s1.trim().split("\n");
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:62:13
+  --> tests/ui/str_split.rs:63:13
    |
 LL |     let _ = s1.trim().split("\r\n");
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:65:13
+  --> tests/ui/str_split.rs:66:13
    |
 LL |     let _ = s2.trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:67:13
+  --> tests/ui/str_split.rs:68:13
    |
 LL |     let _ = s2.trim().split("\n");
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:68:13
+  --> tests/ui/str_split.rs:69:13
    |
 LL |     let _ = s2.trim().split("\r\n");
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:72:13
+  --> tests/ui/str_split.rs:73:13
    |
 LL |     let _ = s3.trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:74:13
+  --> tests/ui/str_split.rs:75:13
    |
 LL |     let _ = s3.trim().split("\n");
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:75:13
+  --> tests/ui/str_split.rs:76:13
    |
 LL |     let _ = s3.trim().split("\r\n");
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:78:13
+  --> tests/ui/str_split.rs:79:13
    |
 LL |     let _ = make_str!(s1).trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `make_str!(s1).lines()`
diff --git a/src/tools/clippy/tests/ui/string_slice.rs b/src/tools/clippy/tests/ui/string_slice.rs
index 1d1911aaa1d..dc519493a4d 100644
--- a/src/tools/clippy/tests/ui/string_slice.rs
+++ b/src/tools/clippy/tests/ui/string_slice.rs
@@ -1,7 +1,7 @@
-use std::borrow::Cow;
+#![warn(clippy::string_slice)]
+#![allow(clippy::no_effect)]
 
-#[warn(clippy::string_slice)]
-#[allow(clippy::no_effect)]
+use std::borrow::Cow;
 
 fn main() {
     &"Ölkanne"[1..];
diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed b/src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed
index 5d7b1e0c17f..704d6ea1bb8 100644
--- a/src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed
+++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.fixed
@@ -1,3 +1,4 @@
+#![allow(clippy::zombie_processes)]
 fn main() {
     // Things it should warn about:
     std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap();
diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs b/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs
index 8abd9803a0c..2a2a7557381 100644
--- a/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs
+++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::zombie_processes)]
 fn main() {
     // Things it should warn about:
     std::process::Command::new("echo").arg("-n hello").spawn().unwrap();
diff --git a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
index d2517b66b56..6fd07d07d7b 100644
--- a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
@@ -1,5 +1,5 @@
 error: single argument that looks like it should be multiple arguments
-  --> tests/ui/suspicious_command_arg_space.rs:3:44
+  --> tests/ui/suspicious_command_arg_space.rs:4:44
    |
 LL |     std::process::Command::new("echo").arg("-n hello").spawn().unwrap();
    |                                            ^^^^^^^^^^
@@ -12,7 +12,7 @@ LL |     std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap
    |                                        ~~~~ ~~~~~~~~~~~~~~~
 
 error: single argument that looks like it should be multiple arguments
-  --> tests/ui/suspicious_command_arg_space.rs:6:43
+  --> tests/ui/suspicious_command_arg_space.rs:7:43
    |
 LL |     std::process::Command::new("cat").arg("--number file").spawn().unwrap();
    |                                           ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.rs b/src/tools/clippy/tests/ui/suspicious_to_owned.rs
index f32b07d45f6..794c2e7174a 100644
--- a/src/tools/clippy/tests/ui/suspicious_to_owned.rs
+++ b/src/tools/clippy/tests/ui/suspicious_to_owned.rs
@@ -3,7 +3,7 @@
 #![warn(clippy::implicit_clone)]
 #![allow(clippy::redundant_clone)]
 use std::borrow::Cow;
-use std::ffi::{c_char, CStr};
+use std::ffi::{CStr, c_char};
 
 fn main() {
     let moo = "Moooo";
diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed b/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed
index 26cc5c27e88..3536c1746df 100644
--- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed
+++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.fixed
@@ -1,5 +1,4 @@
 #![warn(clippy::tabs_in_doc_comments)]
-#[allow(dead_code)]
 
 ///
 /// Struct to hold two strings:
diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs b/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs
index 14b06966ecc..033a685066e 100644
--- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs
+++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.rs
@@ -1,5 +1,4 @@
 #![warn(clippy::tabs_in_doc_comments)]
-#[allow(dead_code)]
 
 ///
 /// Struct to hold two strings:
diff --git a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
index aef6c391452..f8d30b728e5 100644
--- a/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/tabs_in_doc_comments.stderr
@@ -1,5 +1,5 @@
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:6:5
+  --> tests/ui/tabs_in_doc_comments.rs:5:5
    |
 LL | ///     - first        one
    |     ^^^^ help: consider using four spaces per tab
@@ -8,43 +8,43 @@ LL | ///     - first        one
    = help: to override `-D warnings` add `#[allow(clippy::tabs_in_doc_comments)]`
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:6:13
+  --> tests/ui/tabs_in_doc_comments.rs:5:13
    |
 LL | ///     - first        one
    |                ^^^^^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:7:5
+  --> tests/ui/tabs_in_doc_comments.rs:6:5
    |
 LL | ///     - second    one
    |     ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:7:14
+  --> tests/ui/tabs_in_doc_comments.rs:6:14
    |
 LL | ///     - second    one
    |                 ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:10:9
+  --> tests/ui/tabs_in_doc_comments.rs:9:9
    |
 LL |     ///     - First String:
    |         ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:11:9
+  --> tests/ui/tabs_in_doc_comments.rs:10:9
    |
 LL |     ///         - needs to be inside here
    |         ^^^^^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:14:9
+  --> tests/ui/tabs_in_doc_comments.rs:13:9
    |
 LL |     ///     - Second String:
    |         ^^^^ help: consider using four spaces per tab
 
 error: using tabs in doc comments is not recommended
-  --> tests/ui/tabs_in_doc_comments.rs:15:9
+  --> tests/ui/tabs_in_doc_comments.rs:14:9
    |
 LL |     ///         - needs to be inside here
    |         ^^^^^^^^ help: consider using four spaces per tab
diff --git a/src/tools/clippy/tests/ui/temporary_assignment.rs b/src/tools/clippy/tests/ui/temporary_assignment.rs
index 383e70be925..d269f91b9fa 100644
--- a/src/tools/clippy/tests/ui/temporary_assignment.rs
+++ b/src/tools/clippy/tests/ui/temporary_assignment.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::temporary_assignment)]
-#![allow(const_item_mutation)]
+#![allow(clippy::needless_lifetimes)]
 
 use std::ops::{Deref, DerefMut};
 
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs
index 1042249c5b7..7d0a37cde46 100644
--- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs
@@ -2,6 +2,16 @@
 
 #![warn(clippy::too_long_first_doc_paragraph)]
 
+pub mod foo {
+
+    // in foo.rs
+    //! A very short summary.
+    //! A much longer explanation that goes into a lot more detail about
+    //! how the thing works, possibly with doclinks and so one,
+    //! and probably spanning a many rows. Blablabla, it needs to be over
+    //! 200 characters so I needed to write something longeeeeeeer.
+}
+
 /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
 /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
 /// gravida non lacinia at, rhoncus eu lacus.
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
index 7f48e5cf884..39926647f54 100644
--- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
@@ -1,16 +1,32 @@
 error: first doc comment paragraph is too long
-  --> tests/ui/too_long_first_doc_paragraph.rs:5:1
+  --> tests/ui/too_long_first_doc_paragraph.rs:8:5
+   |
+LL | /     //! A very short summary.
+LL | |     //! A much longer explanation that goes into a lot more detail about
+LL | |     //! how the thing works, possibly with doclinks and so one,
+LL | |     //! and probably spanning a many rows. Blablabla, it needs to be over
+LL | |     //! 200 characters so I needed to write something longeeeeeeer.
+   | |____^
+   |
+   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`
+help: add an empty line
+   |
+LL ~     //! A very short summary.
+LL +     //!
+LL ~     //! A much longer explanation that goes into a lot more detail about
+   |
+
+error: first doc comment paragraph is too long
+  --> tests/ui/too_long_first_doc_paragraph.rs:15:1
    |
 LL | / /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
 LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
 LL | | /// gravida non lacinia at, rhoncus eu lacus.
    | |_
-   |
-   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`
 
 error: first doc comment paragraph is too long
-  --> tests/ui/too_long_first_doc_paragraph.rs:26:1
+  --> tests/ui/too_long_first_doc_paragraph.rs:36:1
    |
 LL | / /// Lorem
 LL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
@@ -18,5 +34,5 @@ LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris a
 LL | | /// gravida non lacinia at, rhoncus eu lacus.
    | |_
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmute_32bit.rs b/src/tools/clippy/tests/ui/transmute_32bit.rs
index 8e1316ca39d..e162bbb2d92 100644
--- a/src/tools/clippy/tests/ui/transmute_32bit.rs
+++ b/src/tools/clippy/tests/ui/transmute_32bit.rs
@@ -1,4 +1,4 @@
-//@ignore-64bit
+//@ignore-bitwidth: 64
 
 #[warn(clippy::wrong_transmute)]
 fn main() {
diff --git a/src/tools/clippy/tests/ui/transmute_64bit.rs b/src/tools/clippy/tests/ui/transmute_64bit.rs
index 767cc503a39..fd0ad74bcfa 100644
--- a/src/tools/clippy/tests/ui/transmute_64bit.rs
+++ b/src/tools/clippy/tests/ui/transmute_64bit.rs
@@ -1,4 +1,4 @@
-//@ignore-32bit
+//@ignore-bitwidth: 32
 
 #[warn(clippy::wrong_transmute)]
 fn main() {
diff --git a/src/tools/clippy/tests/ui/transmute_collection.rs b/src/tools/clippy/tests/ui/transmute_collection.rs
index e30b34a5d7d..6748b66e0eb 100644
--- a/src/tools/clippy/tests/ui/transmute_collection.rs
+++ b/src/tools/clippy/tests/ui/transmute_collection.rs
@@ -2,7 +2,7 @@
 #![allow(clippy::missing_transmute_annotations)]
 
 use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
-use std::mem::{transmute, MaybeUninit};
+use std::mem::{MaybeUninit, transmute};
 
 fn main() {
     unsafe {
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
index 83814ca43b9..075a198918a 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
@@ -1,7 +1,7 @@
 #![warn(clippy::transmute_float_to_int)]
 #![allow(clippy::missing_transmute_annotations)]
-#![feature(f128, f128_const)]
-#![feature(f16, f16_const)]
+#![feature(f128)]
+#![feature(f16)]
 
 fn float_to_int() {
     let _: u32 = unsafe { 1f32.to_bits() };
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.rs b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
index 64d6e917203..12541b2f7cf 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.rs
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
@@ -1,7 +1,7 @@
 #![warn(clippy::transmute_float_to_int)]
 #![allow(clippy::missing_transmute_annotations)]
-#![feature(f128, f128_const)]
-#![feature(f16, f16_const)]
+#![feature(f128)]
+#![feature(f16)]
 
 fn float_to_int() {
     let _: u32 = unsafe { std::mem::transmute(1f32) };
diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
index dd4bac7f1ed..5b16d71f114 100644
--- a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
+++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
@@ -8,7 +8,7 @@
 
 use core::any::TypeId;
 use core::ffi::c_void;
-use core::mem::{size_of, transmute, MaybeUninit};
+use core::mem::{MaybeUninit, size_of, transmute};
 use core::ptr::NonNull;
 
 fn value<T>() -> T {
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
index e95054a7ccb..617d32d1fa7 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
@@ -84,8 +84,11 @@ fn issue_10449() {
 }
 
 // Pointers cannot be cast to integers in const contexts
+#[allow(ptr_to_integer_transmute_in_consts, reason = "This is tested in the compiler test suite")]
 const fn issue_12402<P>(ptr: *const P) {
-    unsafe { transmute::<*const i32, usize>(&42i32) };
-    unsafe { transmute::<fn(*const P), usize>(issue_12402) };
-    let _ = unsafe { transmute::<_, usize>(ptr) };
+    // This test exists even though the compiler lints against it
+    // to test that clippy's transmute lints do not trigger on this.
+    unsafe { std::mem::transmute::<*const i32, usize>(&42i32) };
+    unsafe { std::mem::transmute::<fn(*const P), usize>(issue_12402) };
+    let _ = unsafe { std::mem::transmute::<_, usize>(ptr) };
 }
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
index e5fcdef7a1c..d68db3c2deb 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
@@ -84,8 +84,11 @@ fn issue_10449() {
 }
 
 // Pointers cannot be cast to integers in const contexts
+#[allow(ptr_to_integer_transmute_in_consts, reason = "This is tested in the compiler test suite")]
 const fn issue_12402<P>(ptr: *const P) {
-    unsafe { transmute::<*const i32, usize>(&42i32) };
-    unsafe { transmute::<fn(*const P), usize>(issue_12402) };
-    let _ = unsafe { transmute::<_, usize>(ptr) };
+    // This test exists even though the compiler lints against it
+    // to test that clippy's transmute lints do not trigger on this.
+    unsafe { std::mem::transmute::<*const i32, usize>(&42i32) };
+    unsafe { std::mem::transmute::<fn(*const P), usize>(issue_12402) };
+    let _ = unsafe { std::mem::transmute::<_, usize>(ptr) };
 }
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.rs b/src/tools/clippy/tests/ui/unconditional_recursion.rs
index a51fc567f50..b8476a7088a 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.rs
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.rs
@@ -4,7 +4,8 @@
 #![allow(
     clippy::partialeq_ne_impl,
     clippy::default_constructed_unit_structs,
-    clippy::only_used_in_recursion
+    clippy::only_used_in_recursion,
+    clippy::needless_lifetimes
 )]
 
 enum Foo {
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.stderr b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
index 03c27bd8ed8..6a0078ee090 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.stderr
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
@@ -1,5 +1,5 @@
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:46:5
+  --> tests/ui/unconditional_recursion.rs:47:5
    |
 LL |     fn ne(&self, other: &Self) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -12,7 +12,7 @@ LL |         self.ne(other)
    = help: to override `-D warnings` add `#[allow(unconditional_recursion)]`
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:50:5
+  --> tests/ui/unconditional_recursion.rs:51:5
    |
 LL |     fn eq(&self, other: &Self) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -23,7 +23,7 @@ LL |         self.eq(other)
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:215:5
+  --> tests/ui/unconditional_recursion.rs:216:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -34,7 +34,7 @@ LL |         self.to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:225:5
+  --> tests/ui/unconditional_recursion.rs:226:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -45,7 +45,7 @@ LL |         x.to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:236:5
+  --> tests/ui/unconditional_recursion.rs:237:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -56,7 +56,7 @@ LL |         (self as &Self).to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:16:5
+  --> tests/ui/unconditional_recursion.rs:17:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -65,7 +65,7 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:18:9
+  --> tests/ui/unconditional_recursion.rs:19:9
    |
 LL |         self != other
    |         ^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL |         self != other
    = help: to override `-D warnings` add `#[allow(clippy::unconditional_recursion)]`
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:20:5
+  --> tests/ui/unconditional_recursion.rs:21:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -82,13 +82,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:22:9
+  --> tests/ui/unconditional_recursion.rs:23:9
    |
 LL |         self == other
    |         ^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:32:5
+  --> tests/ui/unconditional_recursion.rs:33:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |         self != &Foo2::B // no error here
@@ -96,13 +96,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:33:9
+  --> tests/ui/unconditional_recursion.rs:34:9
    |
 LL |         self != &Foo2::B // no error here
    |         ^^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:35:5
+  --> tests/ui/unconditional_recursion.rs:36:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |         self == &Foo2::B // no error here
@@ -110,13 +110,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:36:9
+  --> tests/ui/unconditional_recursion.rs:37:9
    |
 LL |         self == &Foo2::B // no error here
    |         ^^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:46:5
+  --> tests/ui/unconditional_recursion.rs:47:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -125,13 +125,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:48:9
+  --> tests/ui/unconditional_recursion.rs:49:9
    |
 LL |         self.ne(other)
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:50:5
+  --> tests/ui/unconditional_recursion.rs:51:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -140,13 +140,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:52:9
+  --> tests/ui/unconditional_recursion.rs:53:9
    |
 LL |         self.eq(other)
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:94:5
+  --> tests/ui/unconditional_recursion.rs:95:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -155,13 +155,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:96:9
+  --> tests/ui/unconditional_recursion.rs:97:9
    |
 LL |         other != self
    |         ^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:98:5
+  --> tests/ui/unconditional_recursion.rs:99:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -170,13 +170,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:100:9
+  --> tests/ui/unconditional_recursion.rs:101:9
    |
 LL |         other == self
    |         ^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:108:5
+  --> tests/ui/unconditional_recursion.rs:109:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -185,13 +185,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:110:9
+  --> tests/ui/unconditional_recursion.rs:111:9
    |
 LL |         other != other
    |         ^^^^^^^^^^^^^^
 
 error: equal expressions as operands to `!=`
-  --> tests/ui/unconditional_recursion.rs:110:9
+  --> tests/ui/unconditional_recursion.rs:111:9
    |
 LL |         other != other
    |         ^^^^^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |         other != other
    = note: `#[deny(clippy::eq_op)]` on by default
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:112:5
+  --> tests/ui/unconditional_recursion.rs:113:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -208,19 +208,19 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:114:9
+  --> tests/ui/unconditional_recursion.rs:115:9
    |
 LL |         other == other
    |         ^^^^^^^^^^^^^^
 
 error: equal expressions as operands to `==`
-  --> tests/ui/unconditional_recursion.rs:114:9
+  --> tests/ui/unconditional_recursion.rs:115:9
    |
 LL |         other == other
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:121:5
+  --> tests/ui/unconditional_recursion.rs:122:5
    |
 LL | /     fn ne(&self, _other: &Self) -> bool {
 LL | |
@@ -229,19 +229,19 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:123:9
+  --> tests/ui/unconditional_recursion.rs:124:9
    |
 LL |         self != self
    |         ^^^^^^^^^^^^
 
 error: equal expressions as operands to `!=`
-  --> tests/ui/unconditional_recursion.rs:123:9
+  --> tests/ui/unconditional_recursion.rs:124:9
    |
 LL |         self != self
    |         ^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:125:5
+  --> tests/ui/unconditional_recursion.rs:126:5
    |
 LL | /     fn eq(&self, _other: &Self) -> bool {
 LL | |
@@ -250,19 +250,19 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:127:9
+  --> tests/ui/unconditional_recursion.rs:128:9
    |
 LL |         self == self
    |         ^^^^^^^^^^^^
 
 error: equal expressions as operands to `==`
-  --> tests/ui/unconditional_recursion.rs:127:9
+  --> tests/ui/unconditional_recursion.rs:128:9
    |
 LL |         self == self
    |         ^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:153:13
+  --> tests/ui/unconditional_recursion.rs:154:13
    |
 LL | /             fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -274,7 +274,7 @@ LL |   impl_partial_eq!(S5);
    |   -------------------- in this macro invocation
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:155:17
+  --> tests/ui/unconditional_recursion.rs:156:17
    |
 LL |                 self == other
    |                 ^^^^^^^^^^^^^
@@ -284,7 +284,7 @@ LL | impl_partial_eq!(S5);
    = note: this error originates in the macro `impl_partial_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:182:5
+  --> tests/ui/unconditional_recursion.rs:183:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -295,13 +295,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:186:9
+  --> tests/ui/unconditional_recursion.rs:187:9
    |
 LL |         mine == theirs
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:251:5
+  --> tests/ui/unconditional_recursion.rs:252:5
    |
 LL | /     fn new() -> Self {
 LL | |
@@ -310,13 +310,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:253:9
+  --> tests/ui/unconditional_recursion.rs:254:9
    |
 LL |         Self::default()
    |         ^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:290:5
+  --> tests/ui/unconditional_recursion.rs:291:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -327,13 +327,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:294:9
+  --> tests/ui/unconditional_recursion.rs:295:9
    |
 LL |         mine.eq(theirs)
    |         ^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:361:5
+  --> tests/ui/unconditional_recursion.rs:362:5
    |
 LL | /     fn from(f: BadFromTy1<'a>) -> Self {
 LL | |         f.into()
@@ -341,13 +341,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:362:9
+  --> tests/ui/unconditional_recursion.rs:363:9
    |
 LL |         f.into()
    |         ^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:370:5
+  --> tests/ui/unconditional_recursion.rs:371:5
    |
 LL | /     fn from(f: BadFromTy2<'a>) -> Self {
 LL | |         Into::into(f)
@@ -355,7 +355,7 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:371:9
+  --> tests/ui/unconditional_recursion.rs:372:9
    |
 LL |         Into::into(f)
    |         ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/uninit_vec.rs b/src/tools/clippy/tests/ui/uninit_vec.rs
index 0cc77a8775d..464f88140bd 100644
--- a/src/tools/clippy/tests/ui/uninit_vec.rs
+++ b/src/tools/clippy/tests/ui/uninit_vec.rs
@@ -150,4 +150,36 @@ fn main() {
             vec.set_len(10);
         }
     }
+
+    fn nested_union<T>() {
+        let mut vec: Vec<UnsafeCell<MaybeUninit<T>>> = Vec::with_capacity(1);
+        unsafe {
+            vec.set_len(1);
+        }
+    }
+
+    struct Recursive<T>(*const Recursive<T>, MaybeUninit<T>);
+    fn recursive_union<T>() {
+        // Make sure we don't stack overflow on recursive types.
+        // The pointer acts as the base case because it can't be uninit regardless of its pointee.
+
+        let mut vec: Vec<Recursive<T>> = Vec::with_capacity(1);
+        //~^ uninit_vec
+        unsafe {
+            vec.set_len(1);
+        }
+    }
+
+    #[repr(u8)]
+    enum Enum<T> {
+        Variant(T),
+    }
+    fn union_in_enum<T>() {
+        // Enums can have a discriminant that can't be uninit, so this should still warn
+        let mut vec: Vec<Enum<T>> = Vec::with_capacity(1);
+        //~^ uninit_vec
+        unsafe {
+            vec.set_len(1);
+        }
+    }
 }
diff --git a/src/tools/clippy/tests/ui/uninit_vec.stderr b/src/tools/clippy/tests/ui/uninit_vec.stderr
index e8b77d653f0..e7c81cf792f 100644
--- a/src/tools/clippy/tests/ui/uninit_vec.stderr
+++ b/src/tools/clippy/tests/ui/uninit_vec.stderr
@@ -125,5 +125,27 @@ LL |             vec.set_len(10);
    |
    = help: initialize the buffer or wrap the content in `MaybeUninit`
 
-error: aborting due to 12 previous errors
+error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
+  --> tests/ui/uninit_vec.rs:166:9
+   |
+LL |         let mut vec: Vec<Recursive<T>> = Vec::with_capacity(1);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |             vec.set_len(1);
+   |             ^^^^^^^^^^^^^^
+   |
+   = help: initialize the buffer or wrap the content in `MaybeUninit`
+
+error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
+  --> tests/ui/uninit_vec.rs:179:9
+   |
+LL |         let mut vec: Vec<Enum<T>> = Vec::with_capacity(1);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |             vec.set_len(1);
+   |             ^^^^^^^^^^^^^^
+   |
+   = help: initialize the buffer or wrap the content in `MaybeUninit`
+
+error: aborting due to 14 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_first_then_check.fixed b/src/tools/clippy/tests/ui/unnecessary_first_then_check.fixed
new file mode 100644
index 00000000000..7202e1bbd17
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_first_then_check.fixed
@@ -0,0 +1,22 @@
+#![warn(clippy::unnecessary_first_then_check)]
+#![allow(clippy::useless_vec, clippy::const_is_empty)]
+
+fn main() {
+    let s = [1, 2, 3];
+    let _: bool = !s.is_empty();
+    let _: bool = s.is_empty();
+
+    let v = vec![1, 2, 3];
+    let _: bool = !v.is_empty();
+
+    let n = [[1, 2, 3], [4, 5, 6]];
+    let _: bool = !n[0].is_empty();
+    let _: bool = n[0].is_empty();
+
+    struct Foo {
+        bar: &'static [i32],
+    }
+    let f = [Foo { bar: &[] }];
+    let _: bool = !f[0].bar.is_empty();
+    let _: bool = f[0].bar.is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_first_then_check.rs b/src/tools/clippy/tests/ui/unnecessary_first_then_check.rs
new file mode 100644
index 00000000000..762b9599928
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_first_then_check.rs
@@ -0,0 +1,22 @@
+#![warn(clippy::unnecessary_first_then_check)]
+#![allow(clippy::useless_vec, clippy::const_is_empty)]
+
+fn main() {
+    let s = [1, 2, 3];
+    let _: bool = s.first().is_some();
+    let _: bool = s.first().is_none();
+
+    let v = vec![1, 2, 3];
+    let _: bool = v.first().is_some();
+
+    let n = [[1, 2, 3], [4, 5, 6]];
+    let _: bool = n[0].first().is_some();
+    let _: bool = n[0].first().is_none();
+
+    struct Foo {
+        bar: &'static [i32],
+    }
+    let f = [Foo { bar: &[] }];
+    let _: bool = f[0].bar.first().is_some();
+    let _: bool = f[0].bar.first().is_none();
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_first_then_check.stderr b/src/tools/clippy/tests/ui/unnecessary_first_then_check.stderr
new file mode 100644
index 00000000000..bbaf7e68eda
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_first_then_check.stderr
@@ -0,0 +1,47 @@
+error: unnecessary use of `first().is_some()` to check if slice is not empty
+  --> tests/ui/unnecessary_first_then_check.rs:6:19
+   |
+LL |     let _: bool = s.first().is_some();
+   |                   ^^^^^^^^^^^^^^^^^^^ help: replace this with: `!s.is_empty()`
+   |
+   = note: `-D clippy::unnecessary-first-then-check` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_first_then_check)]`
+
+error: unnecessary use of `first().is_none()` to check if slice is empty
+  --> tests/ui/unnecessary_first_then_check.rs:7:21
+   |
+LL |     let _: bool = s.first().is_none();
+   |                     ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()`
+
+error: unnecessary use of `first().is_some()` to check if slice is not empty
+  --> tests/ui/unnecessary_first_then_check.rs:10:19
+   |
+LL |     let _: bool = v.first().is_some();
+   |                   ^^^^^^^^^^^^^^^^^^^ help: replace this with: `!v.is_empty()`
+
+error: unnecessary use of `first().is_some()` to check if slice is not empty
+  --> tests/ui/unnecessary_first_then_check.rs:13:19
+   |
+LL |     let _: bool = n[0].first().is_some();
+   |                   ^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `!n[0].is_empty()`
+
+error: unnecessary use of `first().is_none()` to check if slice is empty
+  --> tests/ui/unnecessary_first_then_check.rs:14:24
+   |
+LL |     let _: bool = n[0].first().is_none();
+   |                        ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()`
+
+error: unnecessary use of `first().is_some()` to check if slice is not empty
+  --> tests/ui/unnecessary_first_then_check.rs:20:19
+   |
+LL |     let _: bool = f[0].bar.first().is_some();
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this with: `!f[0].bar.is_empty()`
+
+error: unnecessary use of `first().is_none()` to check if slice is empty
+  --> tests/ui/unnecessary_first_then_check.rs:21:28
+   |
+LL |     let _: bool = f[0].bar.first().is_none();
+   |                            ^^^^^^^^^^^^^^^^^ help: replace this with: `is_empty()`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_min_or_max.fixed b/src/tools/clippy/tests/ui/unnecessary_min_or_max.fixed
index 392f6dd1fee..1f3e131516c 100644
--- a/src/tools/clippy/tests/ui/unnecessary_min_or_max.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_min_or_max.fixed
@@ -65,3 +65,32 @@ fn random_u32() -> u32 {
     // random number generator
     0
 }
+
+struct Issue13191 {
+    min: u16,
+    max: u16,
+}
+
+impl Issue13191 {
+    fn new() -> Self {
+        Self { min: 0, max: 0 }
+    }
+
+    fn min(mut self, value: u16) -> Self {
+        self.min = value;
+        self
+    }
+
+    fn max(mut self, value: u16) -> Self {
+        self.max = value;
+        self
+    }
+}
+
+fn issue_13191() {
+    // should not fixed
+    Issue13191::new().min(0);
+
+    // should not fixed
+    Issue13191::new().max(0);
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_min_or_max.rs b/src/tools/clippy/tests/ui/unnecessary_min_or_max.rs
index b03755e6d23..58356b9d49e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_min_or_max.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_min_or_max.rs
@@ -65,3 +65,32 @@ fn random_u32() -> u32 {
     // random number generator
     0
 }
+
+struct Issue13191 {
+    min: u16,
+    max: u16,
+}
+
+impl Issue13191 {
+    fn new() -> Self {
+        Self { min: 0, max: 0 }
+    }
+
+    fn min(mut self, value: u16) -> Self {
+        self.min = value;
+        self
+    }
+
+    fn max(mut self, value: u16) -> Self {
+        self.max = value;
+        self
+    }
+}
+
+fn issue_13191() {
+    // should not fixed
+    Issue13191::new().min(0);
+
+    // should not fixed
+    Issue13191::new().max(0);
+}
diff --git a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
index e0e0ded140f..e9e6c8312f5 100644
--- a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
@@ -7,7 +7,7 @@ use std::cell::UnsafeCell as TotallySafeCell;
 //~| NOTE: `-D clippy::unsafe-removed-from-name` implied by `-D warnings`
 
 use std::cell::UnsafeCell as TotallySafeCellAgain;
-//~^ ERROR: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain
+//~^ ERROR: removed `unsafe` from the name of `UnsafeCell` in use as `TotallySafeCellAgain`
 
 // Shouldn't error
 use std::cell::RefCell as ProbablyNotUnsafe;
diff --git a/src/tools/clippy/tests/ui/unused_async.rs b/src/tools/clippy/tests/ui/unused_async.rs
index 7ec8a3adb4c..838d6f0aa97 100644
--- a/src/tools/clippy/tests/ui/unused_async.rs
+++ b/src/tools/clippy/tests/ui/unused_async.rs
@@ -55,6 +55,22 @@ mod issue9695 {
     }
 }
 
+mod issue13466 {
+    use std::future::Future;
+
+    struct Wrap<F>(F);
+    impl<F> From<F> for Wrap<F> {
+        fn from(f: F) -> Self {
+            Self(f)
+        }
+    }
+    fn takes_fut<F: Fn() -> Fut, Fut: Future>(_: Wrap<F>) {}
+    async fn unused_async() {}
+    fn fp() {
+        takes_fut(unused_async.into());
+    }
+}
+
 async fn foo() -> i32 {
     //~^ ERROR: unused `async` for function with no await statements
     4
diff --git a/src/tools/clippy/tests/ui/unused_async.stderr b/src/tools/clippy/tests/ui/unused_async.stderr
index 337c650e029..4811df63658 100644
--- a/src/tools/clippy/tests/ui/unused_async.stderr
+++ b/src/tools/clippy/tests/ui/unused_async.stderr
@@ -27,7 +27,7 @@ LL |     async fn f3() {}
    = help: consider removing the `async` from this function
 
 error: unused `async` for function with no await statements
-  --> tests/ui/unused_async.rs:58:1
+  --> tests/ui/unused_async.rs:74:1
    |
 LL | / async fn foo() -> i32 {
 LL | |
@@ -38,7 +38,7 @@ LL | | }
    = help: consider removing the `async` from this function
 
 error: unused `async` for function with no await statements
-  --> tests/ui/unused_async.rs:70:5
+  --> tests/ui/unused_async.rs:86:5
    |
 LL | /     async fn unused(&self) -> i32 {
 LL | |
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.1.fixed b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed
new file mode 100644
index 00000000000..b7d1cce2870
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed
@@ -0,0 +1,35 @@
+#![warn(clippy::unused_format_specs)]
+#![allow(unused)]
+
+macro_rules! format_args_from_macro {
+    () => {
+        format_args!("from macro")
+    };
+}
+
+fn main() {
+    // prints `.`, not `     .`
+    println!("{:5}.", format!(""));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+    //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings`
+    //prints `abcde`, not `abc`
+    println!("{:.3}", format!("abcde"));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    println!("{}.", format_args_from_macro!());
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    let args = format_args!("");
+    println!("{args}");
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+}
+
+fn should_not_lint() {
+    println!("{}", format_args!(""));
+    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use
+    // debug formatting so allow it
+    println!("{:?}", format_args!(""));
+
+    let args = format_args!("");
+    println!("{args}");
+}
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.2.fixed b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed
new file mode 100644
index 00000000000..94bb6b7036b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed
@@ -0,0 +1,35 @@
+#![warn(clippy::unused_format_specs)]
+#![allow(unused)]
+
+macro_rules! format_args_from_macro {
+    () => {
+        format_args!("from macro")
+    };
+}
+
+fn main() {
+    // prints `.`, not `     .`
+    println!("{}.", format_args!(""));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+    //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings`
+    //prints `abcde`, not `abc`
+    println!("{}", format_args!("abcde"));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    println!("{}.", format_args_from_macro!());
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    let args = format_args!("");
+    println!("{args}");
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+}
+
+fn should_not_lint() {
+    println!("{}", format_args!(""));
+    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use
+    // debug formatting so allow it
+    println!("{:?}", format_args!(""));
+
+    let args = format_args!("");
+    println!("{args}");
+}
diff --git a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs b/src/tools/clippy/tests/ui/unused_format_specs.rs
index be991935366..2c85e371149 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs
+++ b/src/tools/clippy/tests/ui/unused_format_specs.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::unused_format_specs)]
 #![allow(unused)]
-//@no-rustfix
+
 macro_rules! format_args_from_macro {
     () => {
         format_args!("from macro")
diff --git a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr b/src/tools/clippy/tests/ui/unused_format_specs.stderr
index d3b334c6092..2b5c81c63d6 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unused_format_specs.stderr
@@ -1,5 +1,5 @@
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:12:15
+  --> tests/ui/unused_format_specs.rs:12:15
    |
 LL |     println!("{:5}.", format_args!(""));
    |               ^^^^
@@ -17,7 +17,7 @@ LL +     println!("{}.", format_args!(""));
    |
 
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:16:15
+  --> tests/ui/unused_format_specs.rs:16:15
    |
 LL |     println!("{:.3}", format_args!("abcde"));
    |               ^^^^^
@@ -33,7 +33,7 @@ LL +     println!("{}", format_args!("abcde"));
    |
 
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:19:15
+  --> tests/ui/unused_format_specs.rs:19:15
    |
 LL |     println!("{:5}.", format_args_from_macro!());
    |               ^^^^
@@ -46,7 +46,7 @@ LL +     println!("{}.", format_args_from_macro!());
    |
 
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:23:15
+  --> tests/ui/unused_format_specs.rs:23:15
    |
 LL |     println!("{args:5}");
    |               ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unused_trait_names.fixed b/src/tools/clippy/tests/ui/unused_trait_names.fixed
new file mode 100644
index 00000000000..7dfd0db65aa
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_trait_names.fixed
@@ -0,0 +1,286 @@
+//@aux-build:proc_macros.rs
+
+#![allow(unused)]
+#![warn(clippy::unused_trait_names)]
+#![feature(decl_macro)]
+
+extern crate proc_macros;
+
+fn main() {}
+
+fn bad() {
+    use std::any::Any as _;
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn good() {
+    use std::any::Any as _;
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn used_good() {
+    use std::any::Any;
+
+    println!("{:?}", Any::type_id("foo"));
+    println!("{:?}", "foo".type_id());
+}
+
+fn multi_bad() {
+    use std::any::{self, Any as _, TypeId};
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn multi_good() {
+    use std::any::{self, Any as _, TypeId};
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn renamed_bad() {
+    use std::any::Any as _;
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn multi_renamed_bad() {
+    use std::any::{Any as _, TypeId as MyTypeId};
+
+    println!("{:?}", "foo".type_id());
+}
+
+mod pub_good {
+    pub use std::any::Any;
+
+    fn foo() {
+        println!("{:?}", "foo".type_id());
+    }
+}
+
+mod used_mod_good {
+    use std::any::Any;
+
+    fn foo() {
+        println!("{:?}", Any::type_id("foo"));
+    }
+}
+
+mod mod_import_bad {
+    fn mod_import_bad() {
+        use std::any::Any as _;
+
+        println!("{:?}", "foo".type_id());
+    }
+}
+
+mod nested_mod_used_good1 {
+    use std::any::Any;
+
+    mod foo {
+        fn foo() {
+            super::Any::type_id("foo");
+        }
+    }
+}
+
+mod nested_mod_used_good2 {
+    use std::any::Any;
+
+    mod foo {
+        use super::Any;
+
+        fn foo() {
+            Any::type_id("foo");
+        }
+    }
+}
+
+mod nested_mod_used_good3 {
+    use std::any::Any;
+
+    mod foo {
+        use crate::nested_mod_used_good3::Any;
+
+        fn foo() {
+            println!("{:?}", Any::type_id("foo"));
+        }
+    }
+}
+
+mod nested_mod_used_bad {
+    use std::any::Any as _;
+
+    fn bar() {
+        println!("{:?}", "foo".type_id());
+    }
+
+    mod foo {
+        use std::any::Any;
+
+        fn foo() {
+            println!("{:?}", Any::type_id("foo"));
+        }
+    }
+}
+
+// More complex example where `use std::any::Any;` should be anonymised but `use std::any::Any as
+// MyAny;` should not as it is used by a sub module. Even though if you removed `use std::any::Any;`
+// the code would still compile.
+mod nested_mod_used_bad1 {
+    use std::any::Any as _;
+
+    use std::any::Any as MyAny;
+
+    fn baz() {
+        println!("{:?}", "baz".type_id());
+    }
+
+    mod foo {
+        use crate::nested_mod_used_bad1::MyAny;
+
+        fn foo() {
+            println!("{:?}", MyAny::type_id("foo"));
+        }
+    }
+}
+
+// Example of nested import with an unused import to try and trick it
+mod nested_mod_used_good5 {
+    use std::any::Any;
+
+    mod foo {
+        use std::any::Any;
+
+        fn baz() {
+            println!("{:?}", "baz".type_id());
+        }
+
+        mod bar {
+            use crate::nested_mod_used_good5::foo::Any;
+
+            fn foo() {
+                println!("{:?}", Any::type_id("foo"));
+            }
+        }
+    }
+}
+
+mod simple_trait {
+    pub trait MyTrait {
+        fn do_things(&self);
+    }
+
+    pub struct MyStruct;
+
+    impl MyTrait for MyStruct {
+        fn do_things(&self) {}
+    }
+}
+
+// Underscore imports were stabilized in 1.33
+#[clippy::msrv = "1.32"]
+fn msrv_1_32() {
+    use simple_trait::{MyStruct, MyTrait};
+    MyStruct.do_things();
+}
+
+#[clippy::msrv = "1.33"]
+fn msrv_1_33() {
+    use simple_trait::{MyStruct, MyTrait as _};
+    MyStruct.do_things();
+}
+
+mod lint_inside_macro_expansion_bad {
+    macro_rules! foo {
+        () => {
+            use std::any::Any as _;
+            fn bar() {
+                "bar".type_id();
+            }
+        };
+    }
+
+    foo!();
+}
+
+mod macro_and_trait_same_name {
+    pub macro Foo() {}
+    pub trait Foo {
+        fn bar(&self);
+    }
+    impl Foo for () {
+        fn bar(&self) {}
+    }
+}
+
+fn call_macro_and_trait_good() {
+    // importing trait and macro but only using macro by path won't allow us to change this to
+    // `use macro_and_trait_same_name::Foo as _;`
+    use macro_and_trait_same_name::Foo;
+    Foo!();
+    ().bar();
+}
+
+proc_macros::external!(
+    fn ignore_inside_external_proc_macro() {
+        use std::any::Any;
+        "foo".type_id();
+    }
+);
+
+proc_macros::with_span!(
+    span
+
+    fn ignore_inside_with_span_proc_macro() {
+        use std::any::Any;
+        "foo".type_id();
+    }
+);
+
+// This should warn the import is unused but should not trigger unused_trait_names
+#[warn(unused)]
+mod unused_import {
+    
+}
+
+#[allow(clippy::unused_trait_names)]
+fn allow_lint_fn() {
+    use std::any::Any;
+
+    "foo".type_id();
+}
+
+#[allow(clippy::unused_trait_names)]
+mod allow_lint_mod {
+    use std::any::Any;
+
+    fn foo() {
+        "foo".type_id();
+    }
+}
+
+mod allow_lint_import {
+    #[allow(clippy::unused_trait_names)]
+    use std::any::Any;
+
+    fn foo() {
+        "foo".type_id();
+    }
+}
+
+// Limitation: Suggests `use std::any::Any as _::{self};` which looks weird
+// fn use_trait_self_good() {
+//     use std::any::Any::{self};
+//     "foo".type_id();
+// }
+
+// Limitation: Suggests `use std::any::{Any as _, Any as _};`
+// mod repeated_renamed {
+//     use std::any::{Any, Any as MyAny};
+
+//     fn foo() {
+//         "foo".type_id();
+//     }
+// }
diff --git a/src/tools/clippy/tests/ui/unused_trait_names.rs b/src/tools/clippy/tests/ui/unused_trait_names.rs
new file mode 100644
index 00000000000..ce44eedbc79
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_trait_names.rs
@@ -0,0 +1,286 @@
+//@aux-build:proc_macros.rs
+
+#![allow(unused)]
+#![warn(clippy::unused_trait_names)]
+#![feature(decl_macro)]
+
+extern crate proc_macros;
+
+fn main() {}
+
+fn bad() {
+    use std::any::Any;
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn good() {
+    use std::any::Any as _;
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn used_good() {
+    use std::any::Any;
+
+    println!("{:?}", Any::type_id("foo"));
+    println!("{:?}", "foo".type_id());
+}
+
+fn multi_bad() {
+    use std::any::{self, Any, TypeId};
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn multi_good() {
+    use std::any::{self, Any as _, TypeId};
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn renamed_bad() {
+    use std::any::Any as MyAny;
+
+    println!("{:?}", "foo".type_id());
+}
+
+fn multi_renamed_bad() {
+    use std::any::{Any as MyAny, TypeId as MyTypeId};
+
+    println!("{:?}", "foo".type_id());
+}
+
+mod pub_good {
+    pub use std::any::Any;
+
+    fn foo() {
+        println!("{:?}", "foo".type_id());
+    }
+}
+
+mod used_mod_good {
+    use std::any::Any;
+
+    fn foo() {
+        println!("{:?}", Any::type_id("foo"));
+    }
+}
+
+mod mod_import_bad {
+    fn mod_import_bad() {
+        use std::any::Any;
+
+        println!("{:?}", "foo".type_id());
+    }
+}
+
+mod nested_mod_used_good1 {
+    use std::any::Any;
+
+    mod foo {
+        fn foo() {
+            super::Any::type_id("foo");
+        }
+    }
+}
+
+mod nested_mod_used_good2 {
+    use std::any::Any;
+
+    mod foo {
+        use super::Any;
+
+        fn foo() {
+            Any::type_id("foo");
+        }
+    }
+}
+
+mod nested_mod_used_good3 {
+    use std::any::Any;
+
+    mod foo {
+        use crate::nested_mod_used_good3::Any;
+
+        fn foo() {
+            println!("{:?}", Any::type_id("foo"));
+        }
+    }
+}
+
+mod nested_mod_used_bad {
+    use std::any::Any;
+
+    fn bar() {
+        println!("{:?}", "foo".type_id());
+    }
+
+    mod foo {
+        use std::any::Any;
+
+        fn foo() {
+            println!("{:?}", Any::type_id("foo"));
+        }
+    }
+}
+
+// More complex example where `use std::any::Any;` should be anonymised but `use std::any::Any as
+// MyAny;` should not as it is used by a sub module. Even though if you removed `use std::any::Any;`
+// the code would still compile.
+mod nested_mod_used_bad1 {
+    use std::any::Any;
+
+    use std::any::Any as MyAny;
+
+    fn baz() {
+        println!("{:?}", "baz".type_id());
+    }
+
+    mod foo {
+        use crate::nested_mod_used_bad1::MyAny;
+
+        fn foo() {
+            println!("{:?}", MyAny::type_id("foo"));
+        }
+    }
+}
+
+// Example of nested import with an unused import to try and trick it
+mod nested_mod_used_good5 {
+    use std::any::Any;
+
+    mod foo {
+        use std::any::Any;
+
+        fn baz() {
+            println!("{:?}", "baz".type_id());
+        }
+
+        mod bar {
+            use crate::nested_mod_used_good5::foo::Any;
+
+            fn foo() {
+                println!("{:?}", Any::type_id("foo"));
+            }
+        }
+    }
+}
+
+mod simple_trait {
+    pub trait MyTrait {
+        fn do_things(&self);
+    }
+
+    pub struct MyStruct;
+
+    impl MyTrait for MyStruct {
+        fn do_things(&self) {}
+    }
+}
+
+// Underscore imports were stabilized in 1.33
+#[clippy::msrv = "1.32"]
+fn msrv_1_32() {
+    use simple_trait::{MyStruct, MyTrait};
+    MyStruct.do_things();
+}
+
+#[clippy::msrv = "1.33"]
+fn msrv_1_33() {
+    use simple_trait::{MyStruct, MyTrait};
+    MyStruct.do_things();
+}
+
+mod lint_inside_macro_expansion_bad {
+    macro_rules! foo {
+        () => {
+            use std::any::Any;
+            fn bar() {
+                "bar".type_id();
+            }
+        };
+    }
+
+    foo!();
+}
+
+mod macro_and_trait_same_name {
+    pub macro Foo() {}
+    pub trait Foo {
+        fn bar(&self);
+    }
+    impl Foo for () {
+        fn bar(&self) {}
+    }
+}
+
+fn call_macro_and_trait_good() {
+    // importing trait and macro but only using macro by path won't allow us to change this to
+    // `use macro_and_trait_same_name::Foo as _;`
+    use macro_and_trait_same_name::Foo;
+    Foo!();
+    ().bar();
+}
+
+proc_macros::external!(
+    fn ignore_inside_external_proc_macro() {
+        use std::any::Any;
+        "foo".type_id();
+    }
+);
+
+proc_macros::with_span!(
+    span
+
+    fn ignore_inside_with_span_proc_macro() {
+        use std::any::Any;
+        "foo".type_id();
+    }
+);
+
+// This should warn the import is unused but should not trigger unused_trait_names
+#[warn(unused)]
+mod unused_import {
+    use std::any::Any;
+}
+
+#[allow(clippy::unused_trait_names)]
+fn allow_lint_fn() {
+    use std::any::Any;
+
+    "foo".type_id();
+}
+
+#[allow(clippy::unused_trait_names)]
+mod allow_lint_mod {
+    use std::any::Any;
+
+    fn foo() {
+        "foo".type_id();
+    }
+}
+
+mod allow_lint_import {
+    #[allow(clippy::unused_trait_names)]
+    use std::any::Any;
+
+    fn foo() {
+        "foo".type_id();
+    }
+}
+
+// Limitation: Suggests `use std::any::Any as _::{self};` which looks weird
+// fn use_trait_self_good() {
+//     use std::any::Any::{self};
+//     "foo".type_id();
+// }
+
+// Limitation: Suggests `use std::any::{Any as _, Any as _};`
+// mod repeated_renamed {
+//     use std::any::{Any, Any as MyAny};
+
+//     fn foo() {
+//         "foo".type_id();
+//     }
+// }
diff --git a/src/tools/clippy/tests/ui/unused_trait_names.stderr b/src/tools/clippy/tests/ui/unused_trait_names.stderr
new file mode 100644
index 00000000000..f59d8f58a17
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_trait_names.stderr
@@ -0,0 +1,73 @@
+error: unused import: `std::any::Any`
+  --> tests/ui/unused_trait_names.rs:245:9
+   |
+LL |     use std::any::Any;
+   |         ^^^^^^^^^^^^^
+   |
+   = note: `-D unused-imports` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(unused_imports)]`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:12:19
+   |
+LL |     use std::any::Any;
+   |                   ^^^ help: use: `Any as _`
+   |
+   = note: `-D clippy::unused-trait-names` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unused_trait_names)]`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:31:26
+   |
+LL |     use std::any::{self, Any, TypeId};
+   |                          ^^^ help: use: `Any as _`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:43:19
+   |
+LL |     use std::any::Any as MyAny;
+   |                   ^^^^^^^^^^^^ help: use: `Any as _`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:49:20
+   |
+LL |     use std::any::{Any as MyAny, TypeId as MyTypeId};
+   |                    ^^^^^^^^^^^^ help: use: `Any as _`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:72:23
+   |
+LL |         use std::any::Any;
+   |                       ^^^ help: use: `Any as _`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:113:19
+   |
+LL |     use std::any::Any;
+   |                   ^^^ help: use: `Any as _`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:132:19
+   |
+LL |     use std::any::Any;
+   |                   ^^^ help: use: `Any as _`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:191:34
+   |
+LL |     use simple_trait::{MyStruct, MyTrait};
+   |                                  ^^^^^^^ help: use: `MyTrait as _`
+
+error: importing trait that is only used anonymously
+  --> tests/ui/unused_trait_names.rs:198:27
+   |
+LL |             use std::any::Any;
+   |                           ^^^ help: use: `Any as _`
+...
+LL |     foo!();
+   |     ------ in this macro invocation
+   |
+   = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 10 previous errors
+
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.stderr b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
index 556e1792b3e..f9e8013d3ad 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.stderr
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
@@ -1,10 +1,10 @@
-error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
+error: used underscore-prefixed binding
   --> tests/ui/used_underscore_binding.rs:23:5
    |
 LL |     _foo + 1
    |     ^^^^
    |
-note: `_foo` is defined here
+note: binding is defined here
   --> tests/ui/used_underscore_binding.rs:22:22
    |
 LL | fn prefix_underscore(_foo: u32) -> u32 {
@@ -12,61 +12,61 @@ LL | fn prefix_underscore(_foo: u32) -> u32 {
    = note: `-D clippy::used-underscore-binding` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::used_underscore_binding)]`
 
-error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
+error: used underscore-prefixed binding
   --> tests/ui/used_underscore_binding.rs:28:20
    |
 LL |     println!("{}", _foo);
    |                    ^^^^
    |
-note: `_foo` is defined here
+note: binding is defined here
   --> tests/ui/used_underscore_binding.rs:27:24
    |
 LL | fn in_macro_or_desugar(_foo: u32) {
    |                        ^^^^
 
-error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
+error: used underscore-prefixed binding
   --> tests/ui/used_underscore_binding.rs:29:16
    |
 LL |     assert_eq!(_foo, _foo);
    |                ^^^^
    |
-note: `_foo` is defined here
+note: binding is defined here
   --> tests/ui/used_underscore_binding.rs:27:24
    |
 LL | fn in_macro_or_desugar(_foo: u32) {
    |                        ^^^^
 
-error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
+error: used underscore-prefixed binding
   --> tests/ui/used_underscore_binding.rs:29:22
    |
 LL |     assert_eq!(_foo, _foo);
    |                      ^^^^
    |
-note: `_foo` is defined here
+note: binding is defined here
   --> tests/ui/used_underscore_binding.rs:27:24
    |
 LL | fn in_macro_or_desugar(_foo: u32) {
    |                        ^^^^
 
-error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
+error: used underscore-prefixed binding
   --> tests/ui/used_underscore_binding.rs:42:5
    |
 LL |     s._underscore_field += 1;
    |     ^^^^^^^^^^^^^^^^^^^
    |
-note: `_underscore_field` is defined here
+note: binding is defined here
   --> tests/ui/used_underscore_binding.rs:36:5
    |
 LL |     _underscore_field: u32,
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
-error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
+error: used underscore-prefixed binding
   --> tests/ui/used_underscore_binding.rs:103:16
    |
 LL |         uses_i(_i);
    |                ^^
    |
-note: `_i` is defined here
+note: binding is defined here
   --> tests/ui/used_underscore_binding.rs:102:13
    |
 LL |         let _i = 5;
diff --git a/src/tools/clippy/tests/ui/used_underscore_items.rs b/src/tools/clippy/tests/ui/used_underscore_items.rs
new file mode 100644
index 00000000000..223016a5c96
--- /dev/null
+++ b/src/tools/clippy/tests/ui/used_underscore_items.rs
@@ -0,0 +1,63 @@
+//@aux-build:external_item.rs
+#![allow(unused)]
+#![warn(clippy::used_underscore_items)]
+
+extern crate external_item;
+
+// should not lint macro
+macro_rules! macro_wrap_func {
+    () => {
+        fn _marco_foo() {}
+    };
+}
+
+macro_wrap_func!();
+
+struct _FooStruct {}
+
+impl _FooStruct {
+    fn _method_call(self) {}
+}
+
+fn _foo1() {}
+
+fn _foo2() -> i32 {
+    0
+}
+
+mod a {
+    pub mod b {
+        pub mod c {
+            pub fn _foo3() {}
+
+            pub struct _FooStruct2 {}
+
+            impl _FooStruct2 {
+                pub fn _method_call(self) {}
+            }
+        }
+    }
+}
+
+fn main() {
+    _foo1();
+    let _ = _foo2();
+    a::b::c::_foo3();
+    let _ = &_FooStruct {};
+    let _ = _FooStruct {};
+
+    let foo_struct = _FooStruct {};
+    foo_struct._method_call();
+
+    let foo_struct2 = a::b::c::_FooStruct2 {};
+    foo_struct2._method_call();
+}
+
+// should not lint exteranl crate.
+// user cannot control how others name their items
+fn external_item_call() {
+    let foo_struct3 = external_item::_ExternalStruct {};
+    foo_struct3._foo();
+
+    external_item::_exernal_foo();
+}
diff --git a/src/tools/clippy/tests/ui/used_underscore_items.stderr b/src/tools/clippy/tests/ui/used_underscore_items.stderr
new file mode 100644
index 00000000000..93ac3a6fec6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/used_underscore_items.stderr
@@ -0,0 +1,112 @@
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:43:5
+   |
+LL |     _foo1();
+   |     ^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:22:1
+   |
+LL | fn _foo1() {}
+   | ^^^^^^^^^^
+   = note: `-D clippy::used-underscore-items` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::used_underscore_items)]`
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:44:13
+   |
+LL |     let _ = _foo2();
+   |             ^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:24:1
+   |
+LL | fn _foo2() -> i32 {
+   | ^^^^^^^^^^^^^^^^^
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:45:5
+   |
+LL |     a::b::c::_foo3();
+   |     ^^^^^^^^^^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:31:13
+   |
+LL |             pub fn _foo3() {}
+   |             ^^^^^^^^^^^^^^
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:46:14
+   |
+LL |     let _ = &_FooStruct {};
+   |              ^^^^^^^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:16:1
+   |
+LL | struct _FooStruct {}
+   | ^^^^^^^^^^^^^^^^^
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:47:13
+   |
+LL |     let _ = _FooStruct {};
+   |             ^^^^^^^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:16:1
+   |
+LL | struct _FooStruct {}
+   | ^^^^^^^^^^^^^^^^^
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:49:22
+   |
+LL |     let foo_struct = _FooStruct {};
+   |                      ^^^^^^^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:16:1
+   |
+LL | struct _FooStruct {}
+   | ^^^^^^^^^^^^^^^^^
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:50:5
+   |
+LL |     foo_struct._method_call();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:19:5
+   |
+LL |     fn _method_call(self) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:52:23
+   |
+LL |     let foo_struct2 = a::b::c::_FooStruct2 {};
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:33:13
+   |
+LL |             pub struct _FooStruct2 {}
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: used underscore-prefixed item
+  --> tests/ui/used_underscore_items.rs:53:5
+   |
+LL |     foo_struct2._method_call();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: item is defined here
+  --> tests/ui/used_underscore_items.rs:36:17
+   |
+LL |                 pub fn _method_call(self) {}
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
+
diff --git a/src/tools/clippy/tests/ui/useful_asref.rs b/src/tools/clippy/tests/ui/useful_asref.rs
index a9f0170a79c..d17db9371ee 100644
--- a/src/tools/clippy/tests/ui/useful_asref.rs
+++ b/src/tools/clippy/tests/ui/useful_asref.rs
@@ -1,4 +1,5 @@
 #![deny(clippy::useless_asref)]
+#![allow(clippy::needless_lifetimes)]
 
 trait Trait {
     fn as_ptr(&self);
diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.rs b/src/tools/clippy/tests/ui/wild_in_or_pats.rs
index f8bb31b83c4..bc8a1dbee71 100644
--- a/src/tools/clippy/tests/ui/wild_in_or_pats.rs
+++ b/src/tools/clippy/tests/ui/wild_in_or_pats.rs
@@ -37,4 +37,72 @@ fn main() {
             dbg!("matched (bar or) wild");
         },
     };
+
+    // shouldn't lint
+    #[non_exhaustive]
+    pub enum NonExhaustiveEnum<'a> {
+        Message(&'a str),
+        Quit(&'a str),
+        Other,
+    }
+
+    match NonExhaustiveEnum::Message("Pass") {
+        NonExhaustiveEnum::Message(_) => dbg!("message"),
+        NonExhaustiveEnum::Quit(_) => dbg!("quit"),
+        NonExhaustiveEnum::Other | _ => dbg!("wildcard"),
+    };
+
+    // should lint
+    enum ExhaustiveEnum {
+        Quit,
+        Write(String),
+        ChangeColor(i32, i32, i32),
+    }
+
+    match ExhaustiveEnum::ChangeColor(0, 160, 255) {
+        ExhaustiveEnum::Write(text) => {
+            dbg!("Write");
+        },
+        ExhaustiveEnum::ChangeColor(r, g, b) => {
+            dbg!("Change the color");
+        },
+        ExhaustiveEnum::Quit | _ => {
+            dbg!("Quit or other");
+        },
+    };
+
+    // shouldn't lint
+    #[non_exhaustive]
+    struct NonExhaustiveStruct {
+        a: u32,
+        b: u32,
+        c: u64,
+    }
+
+    let b = NonExhaustiveStruct { a: 5, b: 42, c: 342 };
+
+    match b {
+        NonExhaustiveStruct { a: 5, b: 42, .. } => {},
+        NonExhaustiveStruct { a: 0, b: 0, c: 128 } => {},
+        NonExhaustiveStruct { a: 0, b: 0, c: 128, .. } | _ => {},
+    }
+
+    // should lint
+    struct ExhaustiveStruct {
+        x: i32,
+        y: i32,
+    }
+
+    let p = ExhaustiveStruct { x: 0, y: 7 };
+    match p {
+        ExhaustiveStruct { x: 0, y: 0 } => {
+            dbg!("On the x axis at {x}");
+        },
+        ExhaustiveStruct { x: 0, y: 1 } => {
+            dbg!("On the y axis at {y}");
+        },
+        ExhaustiveStruct { x: 1, y: 1 } | _ => {
+            dbg!("On neither axis: ({x}, {y})");
+        },
+    }
 }
diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
index 06b2415d221..5e409d6dfa6 100644
--- a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
+++ b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
@@ -32,5 +32,21 @@ LL |         _ | "bar" => {
    |
    = help: consider handling `_` separately
 
-error: aborting due to 4 previous errors
+error: wildcard pattern covers any other pattern as it will match anyway
+  --> tests/ui/wild_in_or_pats.rs:69:9
+   |
+LL |         ExhaustiveEnum::Quit | _ => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider handling `_` separately
+
+error: wildcard pattern covers any other pattern as it will match anyway
+  --> tests/ui/wild_in_or_pats.rs:104:9
+   |
+LL |         ExhaustiveStruct { x: 1, y: 1 } | _ => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider handling `_` separately
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/zombie_processes.rs b/src/tools/clippy/tests/ui/zombie_processes.rs
new file mode 100644
index 00000000000..b41bcce3f7f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zombie_processes.rs
@@ -0,0 +1,145 @@
+#![warn(clippy::zombie_processes)]
+#![allow(clippy::if_same_then_else, clippy::ifs_same_cond)]
+
+use std::process::{Child, Command};
+
+fn main() {
+    {
+        // Check that #[expect] works
+        #[expect(clippy::zombie_processes)]
+        let mut x = Command::new("").spawn().unwrap();
+    }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ ERROR: spawned process is never `wait()`ed on
+        x.kill();
+        x.id();
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        x.wait().unwrap(); // OK
+    }
+    {
+        let x = Command::new("").spawn().unwrap();
+        x.wait_with_output().unwrap(); // OK
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        x.try_wait().unwrap(); // OK
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        let mut r = &mut x;
+        r.wait().unwrap(); // OK, not calling `.wait()` directly on `x` but through `r` -> `x`
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        process_child(x); // OK, other function might call `.wait()` so assume it does
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ ERROR: spawned process is never `wait()`ed on
+        let v = &x;
+        // (allow shared refs is fine because one cannot call `.wait()` through that)
+    }
+
+    // https://github.com/rust-lang/rust-clippy/pull/11476#issuecomment-1718456033
+    // Unconditionally exiting the process in various ways (should not lint)
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        std::process::exit(0);
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        std::process::abort(); // same as above, but abort instead of exit
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        if true { /* nothing */ }
+        std::process::abort(); // still unconditionally exits
+    }
+
+    // Conditionally exiting
+    // It should assume that it might not exit and still lint
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ ERROR: spawned process is never `wait()`ed on
+        if true {
+            std::process::exit(0);
+        }
+    }
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ ERROR: spawned process is never `wait()`ed on
+        if true {
+            while false {}
+            // Calling `exit()` after leaving a while loop should still be linted.
+            std::process::exit(0);
+        }
+    }
+
+    {
+        let mut x = { Command::new("").spawn().unwrap() };
+        x.wait().unwrap();
+    }
+
+    {
+        struct S {
+            c: Child,
+        }
+
+        let mut s = S {
+            c: Command::new("").spawn().unwrap(),
+        };
+        s.c.wait().unwrap();
+    }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ ERROR: spawned process is never `wait()`ed on
+        if true {
+            return;
+        }
+        x.wait().unwrap();
+    }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ ERROR: spawned process is never `wait()`ed on
+        if true {
+            x.wait().unwrap();
+        }
+    }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        if true {
+            x.wait().unwrap();
+        } else if true {
+            x.wait().unwrap();
+        } else {
+            x.wait().unwrap();
+        }
+    }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        if true {
+            x.wait().unwrap();
+            return;
+        }
+        x.wait().unwrap();
+    }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        std::thread::spawn(move || {
+            x.wait().unwrap();
+        });
+    }
+}
+
+fn process_child(c: Child) {
+    todo!()
+}
diff --git a/src/tools/clippy/tests/ui/zombie_processes.stderr b/src/tools/clippy/tests/ui/zombie_processes.stderr
new file mode 100644
index 00000000000..eec821a4c8f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zombie_processes.stderr
@@ -0,0 +1,64 @@
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes.rs:14:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider calling `.wait()`
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+   = note: `-D clippy::zombie-processes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::zombie_processes)]`
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes.rs:41:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider calling `.wait()`
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes.rs:66:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider calling `.wait()`
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes.rs:73:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider calling `.wait()`
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes.rs:99:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider calling `.wait()`
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes.rs:108:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: consider calling `.wait()`
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/zombie_processes_fixable.fixed b/src/tools/clippy/tests/ui/zombie_processes_fixable.fixed
new file mode 100644
index 00000000000..6045262f519
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zombie_processes_fixable.fixed
@@ -0,0 +1,26 @@
+#![warn(clippy::zombie_processes)]
+#![allow(clippy::needless_return)]
+
+use std::process::{Child, Command};
+
+fn main() {
+    let _ = Command::new("").spawn().unwrap().wait();
+    //~^ ERROR: spawned process is never `wait()`ed on
+    Command::new("").spawn().unwrap().wait();
+    //~^ ERROR: spawned process is never `wait()`ed on
+    spawn_proc().wait();
+    //~^ ERROR: spawned process is never `wait()`ed on
+    spawn_proc().wait().unwrap(); // OK
+}
+
+fn not_main() {
+    Command::new("").spawn().unwrap().wait();
+}
+
+fn spawn_proc() -> Child {
+    Command::new("").spawn().unwrap()
+}
+
+fn spawn_proc_2() -> Child {
+    return Command::new("").spawn().unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/zombie_processes_fixable.rs b/src/tools/clippy/tests/ui/zombie_processes_fixable.rs
new file mode 100644
index 00000000000..e1ecb771641
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zombie_processes_fixable.rs
@@ -0,0 +1,26 @@
+#![warn(clippy::zombie_processes)]
+#![allow(clippy::needless_return)]
+
+use std::process::{Child, Command};
+
+fn main() {
+    let _ = Command::new("").spawn().unwrap();
+    //~^ ERROR: spawned process is never `wait()`ed on
+    Command::new("").spawn().unwrap();
+    //~^ ERROR: spawned process is never `wait()`ed on
+    spawn_proc();
+    //~^ ERROR: spawned process is never `wait()`ed on
+    spawn_proc().wait().unwrap(); // OK
+}
+
+fn not_main() {
+    Command::new("").spawn().unwrap();
+}
+
+fn spawn_proc() -> Child {
+    Command::new("").spawn().unwrap()
+}
+
+fn spawn_proc_2() -> Child {
+    return Command::new("").spawn().unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/zombie_processes_fixable.stderr b/src/tools/clippy/tests/ui/zombie_processes_fixable.stderr
new file mode 100644
index 00000000000..e1c40472c32
--- /dev/null
+++ b/src/tools/clippy/tests/ui/zombie_processes_fixable.stderr
@@ -0,0 +1,40 @@
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes_fixable.rs:7:13
+   |
+LL |     let _ = Command::new("").spawn().unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()`
+   |
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+   = note: `-D clippy::zombie-processes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::zombie_processes)]`
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes_fixable.rs:9:5
+   |
+LL |     Command::new("").spawn().unwrap();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()`
+   |
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes_fixable.rs:11:5
+   |
+LL |     spawn_proc();
+   |     ^^^^^^^^^^^^- help: try: `.wait()`
+   |
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is never `wait()`ed on
+  --> tests/ui/zombie_processes_fixable.rs:17:5
+   |
+LL |     Command::new("").spawn().unwrap();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try: `.wait()`
+   |
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 99b3560a064..dcf00e4e384 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -20,7 +20,6 @@ new_pr = true
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
-    "flip1995",
     "matthiaskrgr",
     "giraffate",
 ]
diff --git a/src/tools/clippy/util/gh-pages/versions.html b/src/tools/clippy/util/gh-pages/versions.html
index 31ce8819329..d38fe39a464 100644
--- a/src/tools/clippy/util/gh-pages/versions.html
+++ b/src/tools/clippy/util/gh-pages/versions.html
@@ -1,4 +1,5 @@
 <!DOCTYPE html>
+<!-- Expanded by util/versions.py into the HTML file seen at https://rust-lang.github.io/rust-clippy/ -->
 <html lang="en">
 <head>
     <meta charset="UTF-8"/>
@@ -7,26 +8,15 @@
     <title>Clippy lints documentation</title>
 
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"/>
-    <style>
-        [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { display: none !important; }
-    </style>
 </head>
 <body>
-    <div class="container" ng-app="clippy" ng-controller="docVersions">
+    <div class="container">
         <div class="page-header">
             <h1>Clippy lints documentation</h1>
         </div>
 
-        <div ng-cloak>
-            <div class="alert alert-info" role="alert" ng-if="loading">
-                Loading&#x2026;
-            </div>
-            <div class="alert alert-danger" role="alert" ng-if="error">
-                Error loading versions!<br/>
-                You can always try to get <a href="master/index.html">the master branch docs</a>.
-            </div>
-
-            <article class="panel panel-default" ng-show="data">
+        <div>
+            <article class="panel panel-default">
                 <div class="panel-heading">
                     <h3 class="panel-title">
                         Available versions
@@ -34,55 +24,70 @@
                 </div>
 
                 <ul class="list-group">
-                    <a class="list-group-item" ng-repeat="version in data | orderBy:versionOrder:true"
-                       href="./{{version}}/index.html">
-                        {{version}}
-                    </a>
+                    $list
                 </ul>
             </article>
         </div>
     </div>
 
-    <a href="https://github.com/rust-lang/rust-clippy">
-        <img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"/>
-    </a>
-
-
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.12/angular.min.js"></script>
-    <script>
-        angular.module('clippy', [])
-        .controller('docVersions', function ($scope, $http) {
-            $scope.loading = true;
-
-            $scope.normalizeVersion = function(v) {
-                return v.replace(/^rust-/, '');
-            };
-
-            $scope.versionOrder = function(v) {
-                if (v === 'master') { return Infinity; }
-                if (v === 'stable') { return Number.MAX_VALUE; }
-                if (v === 'beta') { return Number.MAX_VALUE - 1; }
-                if (v === 'pre-1.29.0') { return Number.MIN_VALUE; }
-
-                return $scope.normalizeVersion(v)
-                    .split('.')
-                    .reverse()
-                    .reduce(function(acc, val, index) {
-                        return acc + (val * Math.pow(100, index));
-                    }, 0);
+    <a
+        aria-label="View source on GitHub"
+        class="github-corner"
+        href="https://github.com/rust-lang/rust-clippy"
+        rel="noopener noreferrer"
+        target="_blank"
+    >
+        <svg
+            width="80"
+            height="80"
+            viewBox="0 0 250 250"
+            style="position: absolute; top: 0; border: 0; right: 0"
+            aria-hidden="true"
+        >
+            <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" fill="var(--theme-color)"></path>
+            <path
+                d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
+                fill="currentColor"
+                style="transform-origin: 130px 106px"
+                class="octo-arm"
+            ></path>
+            <path
+                d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
+                fill="currentColor"
+                class="octo-body"
+            ></path>
+        </svg>
+        <style>
+            .github-corner svg {
+                fill: black;
+                color: white;
             }
-
-            $http.get('./versions.json')
-            .success(function (data) {
-                $scope.data = data;
-                $scope.loading = false;
-            })
-            .error(function (data) {
-                $scope.error = data;
-                $scope.loading = false;
-            });
-        })
-        ;
-    </script>
+            .github-corner:hover .octo-arm {
+                animation: octocat-wave 560ms ease-in-out;
+            }
+            @keyframes octocat-wave {
+                0%,
+                100% {
+                    transform: rotate(0);
+                }
+                20%,
+                60% {
+                    transform: rotate(-25deg);
+                }
+                40%,
+                80% {
+                    transform: rotate(10deg);
+                }
+            }
+            @media (max-width: 500px) {
+                .github-corner:hover .octo-arm {
+                    animation: none;
+                }
+                .github-corner .octo-arm {
+                    animation: octocat-wave 560ms ease-in-out;
+                }
+            }
+        </style>
+    </a>
 </body>
 </html>
diff --git a/src/tools/clippy/util/versions.py b/src/tools/clippy/util/versions.py
index c041fc606a8..fee0d292df1 100755
--- a/src/tools/clippy/util/versions.py
+++ b/src/tools/clippy/util/versions.py
@@ -1,22 +1,21 @@
 #!/usr/bin/env python
 
-import json
-import logging as log
+from string import Template
+import argparse
 import os
 import sys
 
-log.basicConfig(level=log.INFO, format="%(levelname)s: %(message)s")
-
-
 def key(v):
     if v == "master":
-        return float("inf")
-    if v == "stable":
         return sys.maxsize
-    if v == "beta":
+    if v == "stable":
         return sys.maxsize - 1
+    if v == "beta":
+        return sys.maxsize - 2
     if v == "pre-1.29.0":
         return -1
+    if not v.startswith("rust-"):
+        return None
 
     v = v.replace("rust-", "")
 
@@ -26,26 +25,27 @@ def key(v):
 
     return s
 
-
 def main():
-    if len(sys.argv) < 2:
-        log.error("specify output directory")
-        return
+    parser = argparse.ArgumentParser()
+    parser.add_argument("input", help="path to the versions.html template", type=argparse.FileType("r"))
+    parser.add_argument("outdir", help="path to write the output HTML")
+    args = parser.parse_args()
 
-    outdir = sys.argv[1]
     versions = [
         dir
-        for dir in os.listdir(outdir)
-        if not dir.startswith(".")
-        and not dir.startswith("v")
-        and os.path.isdir(os.path.join(outdir, dir))
+        for dir in os.listdir(args.outdir)
+        if key(dir) is not None
     ]
-    versions.sort(key=key)
+    versions.sort(key=key, reverse=True)
+    links = [f'<a class="list-group-item" href="./{version}/index.html">{version}</a>' for version in versions]
 
-    with open(os.path.join(outdir, "versions.json"), "w") as fp:
-        json.dump(versions, fp, indent=2)
-        log.info("wrote JSON for great justice")
+    template = Template(args.input.read())
+    html = template.substitute(list="\n".join(links))
 
+    path = os.path.join(args.outdir, "index.html")
+    with open(path, "w") as out:
+        out.write(html)
+        print(f"wrote HTML to {path}")
 
 if __name__ == "__main__":
     main()