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.sh2
-rwxr-xr-xsrc/tools/clippy/.github/driver.sh6
-rw-r--r--src/tools/clippy/.github/workflows/clippy_changelog.yml59
-rw-r--r--src/tools/clippy/.github/workflows/clippy_mq.yml34
-rw-r--r--src/tools/clippy/.github/workflows/lintcheck.yml8
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml2
-rw-r--r--src/tools/clippy/CHANGELOG.md12
-rw-r--r--src/tools/clippy/CONTRIBUTING.md6
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/README.md6
-rw-r--r--src/tools/clippy/book/book.toml2
-rw-r--r--src/tools/clippy/book/src/attribs.md2
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md15
-rw-r--r--src/tools/clippy/book/src/development/common_tools_writing_lints.md10
-rw-r--r--src/tools/clippy/book/src/development/defining_lints.md4
-rw-r--r--src/tools/clippy/book/src/development/infrastructure/release.md4
-rw-r--r--src/tools/clippy/book/src/development/macro_expansions.md6
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md4
-rw-r--r--src/tools/clippy/book/src/lints.md13
-rw-r--r--src/tools/clippy/book/src/usage.md9
-rw-r--r--src/tools/clippy/clippy_config/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs4
-rw-r--r--src/tools/clippy/clippy_dev/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_dev/src/new_lint.rs32
-rw-r--r--src/tools/clippy/clippy_dev/src/setup/intellij.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs30
-rw-r--r--src/tools/clippy/clippy_dummy/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/almost_complete_range.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/as_conversions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/box_default.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/mod.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_underscore.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/checked_conversions.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/ctfe.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/dbg_macro.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/deprecated_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs101
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_macros.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_types.rs4
-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.rs110
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs124
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/else_if_without_else.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_line_after.rs492
-rw-r--r--src/tools/clippy/clippy_lints/src/endian_bytes.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_clike.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/equatable_if_let.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs58
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_bools.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_nesting.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/format_push_string.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/formatting.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs3
-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.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_return.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_to_string.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/items_after_statements.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_enum_variant.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/large_futures.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_arrays.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/let_underscore.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs126
-rw-r--r--src/tools/clippy/clippy_lints/src/literal_representation.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_slice_fill.rs111
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_div_ceil.rs51
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_float_methods.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_is_ascii_check.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs225
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_range_patterns.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_filter.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs144
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_utils.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_bool.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs48
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/needless_match.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/try_err.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytecount.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytes_nth.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/drain_collect.rs7
-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.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_empty.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_repeat_n.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_try_fold.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs179
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_option_take.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/return_and_then.rs67
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/sliced_string_as_bytes.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs68
-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_lazy_eval.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unused_enumerate_index.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs59
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/mod.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/multi_assignments.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_mut.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/mutex_atomic.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_if.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_late_init.rs6
-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.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/non_expressive_names.rs5
-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.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs305
-rw-r--r--src/tools/clippy/clippy_lints/src/octal_escapes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/double_comparison.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/float_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/modulo_one.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/op_ref.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/option_if_let_else.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/precedence.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/raw_strings.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_async_block.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_else.rs49
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ref_option_ref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/single_call_fn.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs5
-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/missing_transmute_annotations.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/types/borrowed_box.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/types/type_complexity.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/types/vec_box.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unconditional_recursion.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/uninhabited_references.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/uninit_vec.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs121
-rw-r--r--src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs76
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_result_ok.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_trait_names.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/attr_collector.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/vec.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/vec_init_then_push.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/visibility.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs7
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/README.md2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs20
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs17
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs36
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs82
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs11
-rw-r--r--src/tools/clippy/clippy_utils/src/numeric_literal.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs16
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs22
-rw-r--r--src/tools/clippy/clippy_utils/src/str_utils.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs21
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs17
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs9
-rw-r--r--src/tools/clippy/lintcheck/Cargo.toml2
-rw-r--r--src/tools/clippy/lintcheck/src/config.rs11
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs57
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/rustc_tools_util/Cargo.toml2
-rw-r--r--src/tools/clippy/rustfmt.toml4
-rw-r--r--src/tools/clippy/src/driver.rs21
-rw-r--r--src/tools/clippy/tests/compile-test.rs4
-rw-r--r--src/tools/clippy/tests/missing-test-files.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr31
-rw-r--r--src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr5
-rw-r--r--src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr5
-rw-r--r--src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr5
-rw-r--r--src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr5
-rw-r--r--src/tools/clippy/tests/ui-toml/unwrap_used/unwrap_used.stderr75
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.rs11
-rw-r--r--src/tools/clippy/tests/ui/arithmetic_side_effects.stderr274
-rw-r--r--src/tools/clippy/tests/ui/assign_ops2.stderr90
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs21
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr20
-rw-r--r--src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr10
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.fixed1
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.rs1
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.stderr6
-rw-r--r--src/tools/clippy/tests/ui/cast.stderr103
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_bool.stderr75
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_float.stderr65
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.stderr198
-rw-r--r--src/tools/clippy/tests/ui/cast_size.64bit.stderr45
-rw-r--r--src/tools/clippy/tests/ui/cmp_null.fixed32
-rw-r--r--src/tools/clippy/tests/ui/cmp_null.rs12
-rw-r--r--src/tools/clippy/tests/ui/cmp_null.stderr26
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11230.fixed16
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11230.rs10
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11230.stderr20
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11422.fixed2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11422.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-11422.stderr10
-rw-r--r--src/tools/clippy/tests/ui/create_dir.stderr10
-rw-r--r--src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr81
-rw-r--r--src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr25
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.stderr161
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed1
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_list.rs1
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr22
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr5
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_overindented_list_items.fixed28
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_overindented_list_items.rs28
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_overindented_list_items.stderr41
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_10262.stderr5
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_12795.stderr20
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_9473.stderr5
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs16
-rw-r--r--src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr29
-rw-r--r--src/tools/clippy/tests/ui/double_neg.rs10
-rw-r--r--src/tools/clippy/tests/ui/double_neg.stderr11
-rw-r--r--src/tools/clippy/tests/ui/drain_collect_nostd.fixed8
-rw-r--r--src/tools/clippy/tests/ui/drain_collect_nostd.rs8
-rw-r--r--src/tools/clippy/tests/ui/drain_collect_nostd.stderr11
-rw-r--r--src/tools/clippy/tests/ui/eager_transmute.stderr85
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.1.fixed9
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.2.fixed9
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs10
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr56
-rw-r--r--src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr30
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed5
-rw-r--r--src/tools/clippy/tests/ui/eta.rs5
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr54
-rw-r--r--src/tools/clippy/tests/ui/eta_nostd.fixed10
-rw-r--r--src/tools/clippy/tests/ui/eta_nostd.rs10
-rw-r--r--src/tools/clippy/tests/ui/eta_nostd.stderr11
-rw-r--r--src/tools/clippy/tests/ui/excessive_precision.stderr80
-rw-r--r--src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr81
-rw-r--r--src/tools/clippy/tests/ui/for_kv_map.stderr30
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes.stderr8
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr2
-rw-r--r--src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed2
-rw-r--r--src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs2
-rw-r--r--src/tools/clippy/tests/ui/get_unwrap.stderr85
-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_hasher.fixed2
-rw-r--r--src/tools/clippy/tests/ui/implicit_hasher.rs2
-rw-r--r--src/tools/clippy/tests/ui/implicit_hasher.stderr17
-rw-r--r--src/tools/clippy/tests/ui/implicit_return.stderr67
-rw-r--r--src/tools/clippy/tests/ui/iter_nth.stderr40
-rw-r--r--src/tools/clippy/tests/ui/join_absolute_paths.stderr40
-rw-r--r--src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr65
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants.stderr80
-rw-r--r--src/tools/clippy/tests/ui/literals.stderr35
-rw-r--r--src/tools/clippy/tests/ui/lossy_float_literal.stderr55
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2018.stderr10
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2021.stderr10
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.stderr60
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil.fixed11
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil.rs11
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil.stderr14
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil_with_feature.fixed11
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil_with_feature.rs11
-rw-r--r--src/tools/clippy/tests/ui/manual_div_ceil_with_feature.stderr32
-rw-r--r--src/tools/clippy/tests/ui/manual_float_methods.stderr45
-rw-r--r--src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr245
-rw-r--r--src/tools/clippy/tests/ui/manual_is_ascii_check.stderr20
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs7
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr36
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_err.fixed91
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_err.rs125
-rw-r--r--src/tools/clippy/tests/ui/manual_ok_err.stderr95
-rw-r--r--src/tools/clippy/tests/ui/manual_option_as_slice.fixed62
-rw-r--r--src/tools/clippy/tests/ui/manual_option_as_slice.rs71
-rw-r--r--src/tools/clippy/tests/ui/manual_option_as_slice.stderr58
-rw-r--r--src/tools/clippy/tests/ui/manual_repeat_n.fixed30
-rw-r--r--src/tools/clippy/tests/ui/manual_repeat_n.rs30
-rw-r--r--src/tools/clippy/tests/ui/manual_repeat_n.stderr35
-rw-r--r--src/tools/clippy/tests/ui/manual_slice_fill.fixed101
-rw-r--r--src/tools/clippy/tests/ui/manual_slice_fill.rs110
-rw-r--r--src/tools/clippy/tests/ui/manual_slice_fill.stderr38
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_str_repeat.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.rs15
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.stderr34
-rw-r--r--src/tools/clippy/tests/ui/map_all_any_identity.stderr10
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed4
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs4
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr10
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed8
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.rs8
-rw-r--r--src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr16
-rw-r--r--src/tools/clippy/tests/ui/match_bool.fixed58
-rw-r--r--src/tools/clippy/tests/ui/match_bool.rs54
-rw-r--r--src/tools/clippy/tests/ui/match_bool.stderr108
-rw-r--r--src/tools/clippy/tests/ui/match_result_ok.stderr15
-rw-r--r--src/tools/clippy/tests/ui/match_str_case_mismatch.stderr35
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs6
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed5
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs5
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr16
-rw-r--r--src/tools/clippy/tests/ui/needless_as_bytes.fixed36
-rw-r--r--src/tools/clippy/tests/ui/needless_as_bytes.rs36
-rw-r--r--src/tools/clippy/tests/ui/needless_as_bytes.stderr42
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow_pat.stderr10
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr5
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.fixed11
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.rs11
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.fixed109
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.rs101
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.stderr205
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.fixed58
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.stderr36
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.stderr20
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop.stderr98
-rw-r--r--src/tools/clippy/tests/ui/needless_range_loop2.stderr40
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr50
-rw-r--r--src/tools/clippy/tests/ui/never_loop.stderr10
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr5
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/lazy_static.rs20
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/once_cell.rs55
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.fixed72
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs72
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr103
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs20
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs12
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs43
-rw-r--r--src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr69
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.stderr50
-rw-r--r--src/tools/clippy/tests/ui/obfuscated_if_else.fixed13
-rw-r--r--src/tools/clippy/tests/ui/obfuscated_if_else.rs13
-rw-r--r--src/tools/clippy/tests/ui/obfuscated_if_else.stderr36
-rw-r--r--src/tools/clippy/tests/ui/octal_escapes.stderr110
-rw-r--r--src/tools/clippy/tests/ui/op_ref.stderr5
-rw-r--r--src/tools/clippy/tests/ui/option_as_ref_cloned.stderr15
-rw-r--r--src/tools/clippy/tests/ui/precedence.fixed8
-rw-r--r--src/tools/clippy/tests/ui/precedence.stderr40
-rw-r--r--src/tools/clippy/tests/ui/precedence_bits.fixed35
-rw-r--r--src/tools/clippy/tests/ui/precedence_bits.rs35
-rw-r--r--src/tools/clippy/tests/ui/precedence_bits.stderr29
-rw-r--r--src/tools/clippy/tests/ui/print_literal.fixed14
-rw-r--r--src/tools/clippy/tests/ui/print_literal.rs15
-rw-r--r--src/tools/clippy/tests/ui/print_literal.stderr38
-rw-r--r--src/tools/clippy/tests/ui/redundant_else.fixed154
-rw-r--r--src/tools/clippy/tests/ui/redundant_else.stderr77
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.stderr5
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.fixed7
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.rs7
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.stderr32
-rw-r--r--src/tools/clippy/tests/ui/ref_binding_to_reference.stderr10
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr10
-rw-r--r--src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr5
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed15
-rw-r--r--src/tools/clippy/tests/ui/rename.rs15
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr126
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr15
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.fixed10
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.rs10
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr17
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.fixed67
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.rs63
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.stderr101
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr20
-rw-r--r--src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr30
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.rs20
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.stderr36
-rw-r--r--src/tools/clippy/tests/ui/short_circuit_statement.fixed36
-rw-r--r--src/tools/clippy/tests/ui/short_circuit_statement.rs36
-rw-r--r--src/tools/clippy/tests/ui/short_circuit_statement.stderr30
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs32
-rw-r--r--src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr34
-rw-r--r--src/tools/clippy/tests/ui/single_range_in_vec_init.stderr90
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs17
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr12
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs43
-rw-r--r--src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr110
-rw-r--r--src/tools/clippy/tests/ui/sliced_string_as_bytes.fixed34
-rw-r--r--src/tools/clippy/tests/ui/sliced_string_as_bytes.rs34
-rw-r--r--src/tools/clippy/tests/ui/sliced_string_as_bytes.stderr23
-rw-r--r--src/tools/clippy/tests/ui/slow_vector_initialization.fixed86
-rw-r--r--src/tools/clippy/tests/ui/slow_vector_initialization.rs3
-rw-r--r--src/tools/clippy/tests/ui/slow_vector_initialization.stderr26
-rw-r--r--src/tools/clippy/tests/ui/string_lit_chars_any.stderr25
-rw-r--r--src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr10
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.fixed1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.rs1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_doc_comments.stderr33
-rw-r--r--src/tools/clippy/tests/ui/suspicious_to_owned.stderr40
-rw-r--r--src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr35
-rw-r--r--src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr4
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr55
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr10
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.stderr18
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.stderr10
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr315
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr20
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr50
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.fixed17
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.rs17
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.stderr206
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.fixed63
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.stderr23
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.fixed63
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.stderr29
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_semicolon.fixed32
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_semicolon.rs63
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_semicolon.stderr17
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_wraps.stderr44
-rw-r--r--src/tools/clippy/tests/ui/unneeded_struct_pattern.fixed177
-rw-r--r--src/tools/clippy/tests/ui/unneeded_struct_pattern.rs177
-rw-r--r--src/tools/clippy/tests/ui/unneeded_struct_pattern.stderr203
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.stderr85
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns2.stderr40
-rw-r--r--src/tools/clippy/tests/ui/unused_enumerate_index.stderr10
-rw-r--r--src/tools/clippy/tests/ui/unused_format_specs.stderr20
-rw-r--r--src/tools/clippy/tests/ui/unused_result_ok.stderr20
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.fixed53
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.rs53
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.stderr123
-rw-r--r--src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.fixed52
-rw-r--r--src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.rs52
-rw-r--r--src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.stderr37
-rw-r--r--src/tools/clippy/tests/ui/write_literal.fixed16
-rw-r--r--src/tools/clippy/tests/ui/write_literal.rs17
-rw-r--r--src/tools/clippy/tests/ui/write_literal.stderr38
-rw-r--r--src/tools/clippy/tests/versioncheck.rs2
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/clippy/util/gh-pages/index_template.html23
-rw-r--r--src/tools/clippy/util/gh-pages/script.js91
-rw-r--r--src/tools/clippy/util/gh-pages/style.css8
-rw-r--r--src/tools/clippy/util/gh-pages/theme.js9
564 files changed, 11855 insertions, 3966 deletions
diff --git a/src/tools/clippy/.github/deploy.sh b/src/tools/clippy/.github/deploy.sh
index ea118a3b6fc..2f062799a36 100644
--- a/src/tools/clippy/.github/deploy.sh
+++ b/src/tools/clippy/.github/deploy.sh
@@ -45,6 +45,8 @@ if [[ -n $TAG_NAME ]]; then
   git add "$TAG_NAME"
   # Update the symlink
   git add stable
+  # Update the index.html file
+  git add index.html
   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/driver.sh b/src/tools/clippy/.github/driver.sh
index 09202b1878b..5a81b411291 100755
--- a/src/tools/clippy/.github/driver.sh
+++ b/src/tools/clippy/.github/driver.sh
@@ -47,9 +47,9 @@ unset CARGO_MANIFEST_DIR
 
 # Run a lint and make sure it produces the expected output. It's also expected to exit with code 1
 # FIXME: How to match the clippy invocation in compile-test.rs?
-./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/double_neg.rs 2>double_neg.stderr && exit 1
-sed -e "/= help: for/d" double_neg.stderr > normalized.stderr
-diff -u normalized.stderr tests/ui/double_neg.stderr
+./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/string_to_string.rs 2>string_to_string.stderr && exit 1
+sed -e "/= help: for/d" string_to_string.stderr > normalized.stderr
+diff -u normalized.stderr tests/ui/string_to_string.stderr
 
 # make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
 SYSROOT=$(rustc --print sysroot)
diff --git a/src/tools/clippy/.github/workflows/clippy_changelog.yml b/src/tools/clippy/.github/workflows/clippy_changelog.yml
new file mode 100644
index 00000000000..a2657bfea49
--- /dev/null
+++ b/src/tools/clippy/.github/workflows/clippy_changelog.yml
@@ -0,0 +1,59 @@
+name: Clippy changelog check
+
+on:
+  merge_group:
+  pull_request:
+    types: [opened, reopened, synchronize, edited]
+
+concurrency:
+  # For a given workflow, if we push to the same PR, cancel all previous builds on that PR.
+  # If the push is not attached to a PR, we will cancel all builds on the same branch.
+  group: "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}"
+  cancel-in-progress: true
+
+jobs:
+  changelog:
+    runs-on: ubuntu-latest
+
+    defaults:
+      run:
+        shell: bash
+
+    steps:
+    # Run
+    - name: Check Changelog
+      if: ${{ github.event_name == 'pull_request' }}
+      run: |
+        body=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -s "https://api.github.com/repos/rust-lang/rust-clippy/pulls/$PR_NUMBER" | \
+          python -c "import sys, json; print(json.load(sys.stdin)['body'])")
+        output=$(awk '/^changelog:\s*\S/ && !/changelog: \[.*\]: your change/' <<< "$body" | sed "s/changelog:\s*//g")
+        if [ -z "$output" ]; then
+          echo "ERROR: pull request message must contain 'changelog: ...' with your changelog. Please add it."
+          exit 1
+        else
+          echo "changelog: $output"
+        fi
+      env:
+        PYTHONIOENCODING: 'utf-8'
+        PR_NUMBER: '${{ github.event.number }}'
+
+  # We need to have the "conclusion" job also on PR CI, to make it possible
+  # to add PRs to a merge queue.
+  conclusion_changelog:
+    needs: [ changelog ]
+    # We need to ensure this job does *not* get skipped if its dependencies fail,
+    # because a skipped job is considered a success by GitHub. So we have to
+    # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
+    # when the workflow is canceled manually.
+    #
+    # ALL THE PREVIOUS JOBS NEED TO BE ADDED TO THE `needs` SECTION OF THIS JOB!
+    if: ${{ !cancelled() }}
+    runs-on: ubuntu-latest
+    steps:
+      # Manually check the status of all dependencies. `if: failure()` does not work.
+      - name: Conclusion
+        run: |
+          # Print the dependent jobs to see them in the CI log
+          jq -C <<< '${{ toJson(needs) }}'
+          # Check if all jobs that we depend on (in the needs array) were successful.
+          jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
diff --git a/src/tools/clippy/.github/workflows/clippy_mq.yml b/src/tools/clippy/.github/workflows/clippy_mq.yml
index dee7d028655..c337a96bdac 100644
--- a/src/tools/clippy/.github/workflows/clippy_mq.yml
+++ b/src/tools/clippy/.github/workflows/clippy_mq.yml
@@ -15,37 +15,7 @@ defaults:
     shell: bash
 
 jobs:
-  changelog:
-    runs-on: ubuntu-latest
-
-    steps:
-    - name: Checkout
-      uses: actions/checkout@v4
-      with:
-        ref: ${{ github.ref }}
-        # Unsetting this would make so that any malicious package could get our Github Token
-        persist-credentials: false
-
-    # Run
-    - name: Check Changelog
-      run: |
-        MESSAGE=$(git log --format=%B -n 1)
-        PR=$(echo "$MESSAGE" | grep -o "#[0-9]*" | head -1 | sed -e 's/^#//')
-        body=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -s "https://api.github.com/repos/rust-lang/rust-clippy/pulls/$PR" | \
-          python -c "import sys, json; print(json.load(sys.stdin)['body'])")
-        output=$(grep "^changelog:\s*\S" <<< "$body" | sed "s/changelog:\s*//g") || {
-          echo "ERROR: PR body must contain 'changelog: ...'"
-          exit 1
-        }
-        if [[ "$output" = "none" ]]; then
-          echo "WARNING: changelog is 'none'"
-        else
-          echo "changelog: $output"
-        fi
-      env:
-        PYTHONIOENCODING: 'utf-8'
   base:
-    needs: changelog
     strategy:
       matrix:
         include:
@@ -119,7 +89,6 @@ jobs:
         OS: ${{ runner.os }}
 
   metadata_collection:
-    needs: changelog
     runs-on: ubuntu-latest
 
     steps:
@@ -138,7 +107,6 @@ jobs:
       run: cargo collect-metadata
 
   integration_build:
-    needs: changelog
     runs-on: ubuntu-latest
 
     steps:
@@ -228,7 +196,7 @@ jobs:
         INTEGRATION: ${{ matrix.integration }}
 
   conclusion:
-    needs: [ changelog, base, metadata_collection, integration_build, integration ]
+    needs: [ base, metadata_collection, integration_build, integration ]
     # We need to ensure this job does *not* get skipped if its dependencies fail,
     # because a skipped job is considered a success by GitHub. So we have to
     # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run
diff --git a/src/tools/clippy/.github/workflows/lintcheck.yml b/src/tools/clippy/.github/workflows/lintcheck.yml
index 64966f1d189..d487c7d9498 100644
--- a/src/tools/clippy/.github/workflows/lintcheck.yml
+++ b/src/tools/clippy/.github/workflows/lintcheck.yml
@@ -1,6 +1,12 @@
 name: Lintcheck
 
-on: pull_request
+on:
+  pull_request:
+    paths-ignore:
+      - 'book/**'
+      - 'util/**'
+      - 'tests/**'
+      - '*.md'
 
 env:
   RUST_BACKTRACE: 1
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 69d00dc027e..13902f78b54 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -27,7 +27,7 @@ jobs:
     - name: Install mdbook
       run: |
         mkdir mdbook
-        curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdbook-v0.4.34-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
+        curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.43/mdbook-v0.4.43-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
         echo `pwd`/mdbook >> $GITHUB_PATH
 
     # Run
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 1770e8095a0..fa03c953aa5 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5533,6 +5533,7 @@ Released 2018-09-13
 [`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes
 [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown
 [`doc_nested_refdefs`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_nested_refdefs
+[`doc_overindented_list_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_overindented_list_items
 [`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
 [`double_ended_iterator_last`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_ended_iterator_last
 [`double_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use
@@ -5762,14 +5763,18 @@ Released 2018-09-13
 [`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy
 [`manual_next_back`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_next_back
 [`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
+[`manual_ok_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_err
 [`manual_ok_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_ok_or
+[`manual_option_as_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_option_as_slice
 [`manual_pattern_char_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison
 [`manual_range_contains`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains
 [`manual_range_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_patterns
 [`manual_rem_euclid`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid
+[`manual_repeat_n`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n
 [`manual_retain`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain
 [`manual_rotate`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_rotate
 [`manual_saturating_arithmetic`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_saturating_arithmetic
+[`manual_slice_fill`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill
 [`manual_slice_size_calculation`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_size_calculation
 [`manual_split_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once
 [`manual_str_repeat`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat
@@ -5904,6 +5909,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_std_lazy_statics`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics
 [`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
@@ -5950,6 +5956,7 @@ Released 2018-09-13
 [`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
+[`precedence_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence_bits
 [`print_in_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_in_format_impl
 [`print_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_literal
 [`print_stderr`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr
@@ -6022,6 +6029,7 @@ Released 2018-09-13
 [`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else
 [`result_unit_err`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unit_err
 [`result_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unwrap_used
+[`return_and_then`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_and_then
 [`return_self_not_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#return_self_not_must_use
 [`reverse_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#reverse_range_loop
 [`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges
@@ -6063,6 +6071,7 @@ Released 2018-09-13
 [`size_of_in_element_count`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_in_element_count
 [`size_of_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#size_of_ref
 [`skip_while_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#skip_while_next
+[`sliced_string_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#sliced_string_as_bytes
 [`slow_vector_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#slow_vector_initialization
 [`stable_sort_primitive`]: https://rust-lang.github.io/rust-clippy/master/index.html#stable_sort_primitive
 [`std_instead_of_alloc`]: https://rust-lang.github.io/rust-clippy/master/index.html#std_instead_of_alloc
@@ -6172,12 +6181,14 @@ Released 2018-09-13
 [`unnecessary_safety_comment`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_comment
 [`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc
 [`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports
+[`unnecessary_semicolon`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_semicolon
 [`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by
 [`unnecessary_struct_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_struct_initialization
 [`unnecessary_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned
 [`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap
 [`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps
 [`unneeded_field_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_field_pattern
+[`unneeded_struct_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_struct_pattern
 [`unneeded_wildcard_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#unneeded_wildcard_pattern
 [`unnested_or_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns
 [`unreachable`]: https://rust-lang.github.io/rust-clippy/master/index.html#unreachable
@@ -6216,6 +6227,7 @@ Released 2018-09-13
 [`useless_conversion`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
 [`useless_format`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_format
 [`useless_let_if_seq`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_let_if_seq
+[`useless_nonzero_new_unchecked`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_nonzero_new_unchecked
 [`useless_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_transmute
 [`useless_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec
 [`vec_box`]: https://rust-lang.github.io/rust-clippy/master/index.html#vec_box
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index 1f6c918fc6c..3b33f719063 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -199,7 +199,7 @@ currently. Between writing new lints, fixing issues, reviewing pull requests and
 responding to issues there may not always be enough time to stay on top of it
 all.
 
-Our highest priority is fixing [crashes][l-crash] and [bugs][l-bug], for example
+Our highest priority is fixing [ICEs][I-ICE] and [bugs][C-bug], for example
 an ICE in a popular crate that many other crates depend on. We don't
 want Clippy to crash on your code and we want it to be as reliable as the
 suggestions from Rust compiler errors.
@@ -213,8 +213,8 @@ Or rather: before the sync this should be addressed,
 e.g. by removing a lint again, so it doesn't hit beta/stable.
 
 [triage]: https://forge.rust-lang.org/release/triage-procedure.html
-[l-crash]: https://github.com/rust-lang/rust-clippy/labels/L-crash
-[l-bug]: https://github.com/rust-lang/rust-clippy/labels/L-bug
+[I-ICE]: https://github.com/rust-lang/rust-clippy/labels/I-ICE
+[C-bug]: https://github.com/rust-lang/rust-clippy/labels/C-bug
 [p-low]: https://github.com/rust-lang/rust-clippy/labels/P-low
 [p-medium]: https://github.com/rust-lang/rust-clippy/labels/P-medium
 [p-high]: https://github.com/rust-lang/rust-clippy/labels/P-high
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index efa59fecc0e..c9e4f15afbf 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -10,7 +10,7 @@ license = "MIT OR Apache-2.0"
 keywords = ["clippy", "lint", "plugin"]
 categories = ["development-tools", "development-tools::cargo-plugins"]
 build = "build.rs"
-edition = "2021"
+edition = "2024"
 publish = false
 
 [[bin]]
diff --git a/src/tools/clippy/README.md b/src/tools/clippy/README.md
index cb3a22d4288..32c1d33e2ed 100644
--- a/src/tools/clippy/README.md
+++ b/src/tools/clippy/README.md
@@ -159,11 +159,11 @@ line. (You can swap `clippy::all` with the specific lint category you are target
 You can add options to your code to `allow`/`warn`/`deny` Clippy lints:
 
 * the whole set of `Warn` lints using the `clippy` lint group (`#![deny(clippy::all)]`).
-    Note that `rustc` has additional [lint groups](https://doc.rust-lang.org/rustc/lints/groups.html).
+  Note that `rustc` has additional [lint groups](https://doc.rust-lang.org/rustc/lints/groups.html).
 
 * all lints using both the `clippy` and `clippy::pedantic` lint groups (`#![deny(clippy::all)]`,
-    `#![deny(clippy::pedantic)]`). Note that `clippy::pedantic` contains some very aggressive
-    lints prone to false positives.
+  `#![deny(clippy::pedantic)]`). Note that `clippy::pedantic` contains some very aggressive
+  lints prone to false positives.
 
 * only some lints (`#![deny(clippy::single_match, clippy::box_vec)]`, etc.)
 
diff --git a/src/tools/clippy/book/book.toml b/src/tools/clippy/book/book.toml
index 93b6641f7e1..c918aadf83c 100644
--- a/src/tools/clippy/book/book.toml
+++ b/src/tools/clippy/book/book.toml
@@ -6,7 +6,7 @@ src = "src"
 title = "Clippy Documentation"
 
 [rust]
-edition = "2018"
+edition = "2024"
 
 [output.html]
 edit-url-template = "https://github.com/rust-lang/rust-clippy/edit/master/book/{path}"
diff --git a/src/tools/clippy/book/src/attribs.md b/src/tools/clippy/book/src/attribs.md
index cf99497bc0f..9b7f5970504 100644
--- a/src/tools/clippy/book/src/attribs.md
+++ b/src/tools/clippy/book/src/attribs.md
@@ -5,7 +5,7 @@ To do this, Clippy provides attributes that can be applied to items in the 3rd p
 
 ## `#[clippy::format_args]`
 
-_Available since Clippy v1.84_
+_Available since Clippy v1.85_
 
 This attribute can be added to a macro that supports `format!`, `println!`, or similar syntax.
 It tells Clippy that the macro is a formatting macro, and that the arguments to the macro
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index c07568697d0..48506127dee 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -299,10 +299,11 @@ This is good, because it makes writing this particular lint less complicated.
 We have to make this decision with every new Clippy lint. It boils down to using
 either [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass].
 
-In short, the `EarlyLintPass` runs before type checking and
-[HIR](https://rustc-dev-guide.rust-lang.org/hir.html) lowering and the `LateLintPass`
-has access to type information. Consider using the `LateLintPass` unless you need
-something specific from the `EarlyLintPass`.
+`EarlyLintPass` runs before type checking and
+[HIR](https://rustc-dev-guide.rust-lang.org/hir.html) lowering, while `LateLintPass`
+runs after these stages, providing access to type information. The `cargo dev new_lint` command
+defaults to the recommended `LateLintPass`, but you can specify `--pass=early` if your lint
+only needs AST level analysis.
 
 Since we don't need type information for checking the function name, we used
 `--pass=early` when running the new lint automation and all the imports were
@@ -537,7 +538,7 @@ via `Tools -> Clippy` and you should see the generated code in the output below.
 If the command was executed successfully, you can copy the code over to where
 you are implementing your lint.
 
-[author_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9a12cb60e5c6ad4e3003ac6d5e63cf55
+[author_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=9a12cb60e5c6ad4e3003ac6d5e63cf55
 
 ## Print HIR lint
 
@@ -552,7 +553,7 @@ attribute to expressions you often need to enable
 _Clippy_.
 
 [_High-Level Intermediate Representation (HIR)_]: https://rustc-dev-guide.rust-lang.org/hir.html
-[print_hir_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=daf14db3a7f39ca467cd1b86c34b9afb
+[print_hir_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=daf14db3a7f39ca467cd1b86c34b9afb
 
 ## Documentation
 
@@ -787,7 +788,7 @@ don't hesitate to ask on [Zulip] or in the issue/PR.
 [`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
 [let-chains]: https://github.com/rust-lang/rust/pull/94927
 [from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
-[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
+[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
 [span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html
 [applicability]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
 [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
diff --git a/src/tools/clippy/book/src/development/common_tools_writing_lints.md b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
index c354e8914f5..051febc2ca5 100644
--- a/src/tools/clippy/book/src/development/common_tools_writing_lints.md
+++ b/src/tools/clippy/book/src/development/common_tools_writing_lints.md
@@ -218,7 +218,7 @@ functions to deal with macros:
   > context. And so just using `span.from_expansion()` is often good enough.
 
 
-- `in_external_macro(span)`: detect if the given span is from a macro defined in
+- `span.in_external_macro(sm)`: detect if the given span is from a macro defined in
   a foreign crate. If you want the lint to work with macro-generated code, this
   is the next line of defense to avoid macros not defined in the current crate.
   It doesn't make sense to lint code that the coder can't change.
@@ -227,15 +227,13 @@ functions to deal with macros:
   crates
 
   ```rust
-  use rustc_middle::lint::in_external_macro;
-
   use a_crate_with_macros::foo;
 
   // `foo` is defined in `a_crate_with_macros`
   foo!("bar");
 
   // if we lint the `match` of `foo` call and test its span
-  assert_eq!(in_external_macro(cx.sess(), match_span), true);
+  assert_eq!(match_span.in_external_macro(cx.sess().source_map()), true);
   ```
 
 - `span.ctxt()`: the span's context represents whether it is from expansion, and
@@ -265,10 +263,10 @@ functions to deal with macros:
    ```
 
 [Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
-[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html
+[TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html
 [TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html
 [expr_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.expr_ty
 [LateContext]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LateContext.html
 [TyCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html
-[pat_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TypeckResults.html#method.pat_ty
+[pat_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html#method.pat_ty
 [paths]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/paths/index.html
diff --git a/src/tools/clippy/book/src/development/defining_lints.md b/src/tools/clippy/book/src/development/defining_lints.md
index ceabb255e2d..169cecd7d11 100644
--- a/src/tools/clippy/book/src/development/defining_lints.md
+++ b/src/tools/clippy/book/src/development/defining_lints.md
@@ -139,10 +139,10 @@ Untracked files:
 ```
 
 
-## The `define_clippy_lints` macro
+## The `declare_clippy_lint` macro
 
 After `cargo dev new_lint`, you should see a macro with the name
-`define_clippy_lints`. It will be in the same file if you defined a standalone
+`declare_clippy_lint`. It will be in the same file if you defined a standalone
 lint, and it will be in `mod.rs` if you defined a type-specific lint.
 
 The macro looks something like this:
diff --git a/src/tools/clippy/book/src/development/infrastructure/release.md b/src/tools/clippy/book/src/development/infrastructure/release.md
index 20b870eb69a..8b080c099b8 100644
--- a/src/tools/clippy/book/src/development/infrastructure/release.md
+++ b/src/tools/clippy/book/src/development/infrastructure/release.md
@@ -96,9 +96,9 @@ git tag rust-1.XX.0               # XX should be exchanged with the correspondin
 git push upstream rust-1.XX.0     # `upstream` is the `rust-lang/rust-clippy` remote
 ```
 
-After this, the release should be available on the Clippy [release page].
+After this, the release should be available on the Clippy [tags page].
 
-[release page]: https://github.com/rust-lang/rust-clippy/releases
+[tags page]: https://github.com/rust-lang/rust-clippy/tags
 
 ## Publish `clippy_utils`
 
diff --git a/src/tools/clippy/book/src/development/macro_expansions.md b/src/tools/clippy/book/src/development/macro_expansions.md
index 125b6c4bc5b..36092f82e26 100644
--- a/src/tools/clippy/book/src/development/macro_expansions.md
+++ b/src/tools/clippy/book/src/development/macro_expansions.md
@@ -120,7 +120,7 @@ assert_ne!(x_is_some_span.ctxt(), x_unwrap_span.ctxt());
 
 ### The `in_external_macro` function
 
-`rustc_middle::lint` provides a function ([`in_external_macro`]) that can
+`Span` provides a method ([`in_external_macro`]) that can
 detect if the given span is from a macro defined in a foreign crate.
 
 Therefore, if we really want a new lint to work with macro-generated code,
@@ -144,7 +144,7 @@ Also assume that we get the corresponding variable `foo_span` for the
 results in `true` (note that `cx` can be `EarlyContext` or `LateContext`):
 
 ```rust
-if in_external_macro(cx.sess(), foo_span) {
+if foo_span.in_external_macro(cx.sess().source_map()) {
     // We should ignore macro from a foreign crate.
     return;
 }
@@ -153,6 +153,6 @@ if in_external_macro(cx.sess(), foo_span) {
 [`ctxt`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.ctxt
 [expansion]: https://rustc-dev-guide.rust-lang.org/macro-expansion.html#expansion-and-ast-integration
 [`from_expansion`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
-[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
+[`in_external_macro`]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html#method.in_external_macro
 [Span]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/struct.Span.html
 [SyntaxContext]: https://doc.rust-lang.org/stable/nightly-rustc/rustc_span/hygiene/struct.SyntaxContext.html
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 181e794e6e4..dab2630a56f 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -750,7 +750,9 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`manual_pattern_char_comparison`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_pattern_char_comparison)
 * [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains)
 * [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid)
+* [`manual_repeat_n`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_repeat_n)
 * [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain)
+* [`manual_slice_fill`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_slice_fill)
 * [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)
 * [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)
 * [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)
@@ -762,11 +764,13 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)
 * [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)
 * [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
+* [`non_std_lazy_statics`](https://rust-lang.github.io/rust-clippy/master/index.html#non_std_lazy_statics)
 * [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
 * [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
 * [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
 * [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
 * [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
+* [`same_item_push`](https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push)
 * [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
 * [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
 * [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
diff --git a/src/tools/clippy/book/src/lints.md b/src/tools/clippy/book/src/lints.md
index 442dc63914e..1dd51797660 100644
--- a/src/tools/clippy/book/src/lints.md
+++ b/src/tools/clippy/book/src/lints.md
@@ -101,5 +101,18 @@ The `clippy::cargo` group gives you suggestions on how to improve your
 your crate and are not sure if you have all useful information in your
 `Cargo.toml`.
 
+## Nursery
+
+The `clippy::nursery` group contains lints which are buggy or need more work. It is **not** 
+recommended to enable the whole group, but rather cherry-pick lints that are useful for your 
+code base and your use case. 
+
+## Deprecated
+
+The `clippy::deprecated` is empty lints that exist to ensure that `#[allow(lintname)]` still 
+compiles after the lint was deprecated. Deprecation "removes" lints by removing their 
+functionality and marking them as deprecated, which may cause further warnings but cannot 
+cause a compiler error.
+
 [Clippy lint documentation]: https://rust-lang.github.io/rust-clippy/
 [Clippy 1.0 RFC]: https://github.com/rust-lang/rfcs/blob/master/text/2476-clippy-uno.md#lint-audit-and-categories
diff --git a/src/tools/clippy/book/src/usage.md b/src/tools/clippy/book/src/usage.md
index 7a0be6994fe..23edf6c2aba 100644
--- a/src/tools/clippy/book/src/usage.md
+++ b/src/tools/clippy/book/src/usage.md
@@ -33,7 +33,7 @@ You can configure lint levels on the command line by adding
 `-A/W/D clippy::lint_name` like this:
 
 ```bash
-cargo clippy -- -Aclippy::style -Wclippy::double_neg -Dclippy::perf
+cargo clippy -- -Aclippy::style -Wclippy::box_default -Dclippy::perf
 ```
 
 For [CI] all warnings can be elevated to errors which will in turn fail
@@ -101,11 +101,10 @@ You can configure lint levels in source code the same way you can configure
 ```rust,ignore
 #![allow(clippy::style)]
 
-#[warn(clippy::double_neg)]
+#[warn(clippy::box_default)]
 fn main() {
-    let x = 1;
-    let y = --x;
-    //      ^^ warning: double negation
+    let _ = Box::<String>::new(Default::default());
+    // ^ warning: `Box::new(_)` of default value
 }
 ```
 
diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml
index c761e207c6b..e473a583940 100644
--- a/src/tools/clippy/clippy_config/Cargo.toml
+++ b/src/tools/clippy/clippy_config/Cargo.toml
@@ -3,7 +3,7 @@ name = "clippy_config"
 # begin autogenerated version
 version = "0.1.86"
 # end autogenerated version
-edition = "2021"
+edition = "2024"
 publish = false
 
 # 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 c616589c56e..a1591188bee 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -619,7 +619,9 @@ define_Conf! {
         manual_pattern_char_comparison,
         manual_range_contains,
         manual_rem_euclid,
+        manual_repeat_n,
         manual_retain,
+        manual_slice_fill,
         manual_split_once,
         manual_str_repeat,
         manual_strip,
@@ -631,11 +633,13 @@ define_Conf! {
         mem_replace_with_default,
         missing_const_for_fn,
         needless_borrow,
+        non_std_lazy_statics,
         option_as_ref_deref,
         option_map_unwrap_or,
         ptr_as_ptr,
         redundant_field_names,
         redundant_static_lifetimes,
+        same_item_push,
         seek_from_current,
         seek_rewind,
         transmute_ptr_to_ref,
diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml
index d3a103eaf4c..47b7b375861 100644
--- a/src/tools/clippy/clippy_dev/Cargo.toml
+++ b/src/tools/clippy/clippy_dev/Cargo.toml
@@ -2,7 +2,7 @@
 name = "clippy_dev"
 description = "Clippy developer tooling"
 version = "0.0.1"
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 aho-corasick = "1.0"
diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs
index 24d1a53266a..cc4b26867a2 100644
--- a/src/tools/clippy/clippy_dev/src/new_lint.rs
+++ b/src/tools/clippy/clippy_dev/src/new_lint.rs
@@ -255,8 +255,9 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
     let name_camel = to_camel_case(lint.name);
     let name_upper = lint_name.to_uppercase();
 
-    result.push_str(&if enable_msrv {
-        formatdoc!(
+    if enable_msrv {
+        let _: fmt::Result = writedoc!(
+            result,
             r"
             use clippy_utils::msrvs::{{self, Msrv}};
             use clippy_config::Conf;
@@ -265,22 +266,24 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
             use rustc_session::impl_lint_pass;
 
         "
-        )
+        );
     } else {
-        formatdoc!(
+        let _: fmt::Result = writedoc!(
+            result,
             r"
             {pass_import}
             use rustc_lint::{{{context_import}, {pass_type}}};
             use rustc_session::declare_lint_pass;
 
         "
-        )
-    });
+        );
+    }
 
     let _: fmt::Result = writeln!(result, "{}", get_lint_declaration(&name_upper, category));
 
-    result.push_str(&if enable_msrv {
-        formatdoc!(
+    if enable_msrv {
+        let _: fmt::Result = writedoc!(
+            result,
             r"
             pub struct {name_camel} {{
                 msrv: Msrv,
@@ -301,16 +304,17 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
             // TODO: Add MSRV level to `clippy_config/src/msrvs.rs` if needed.
             // TODO: Update msrv config comment in `clippy_config/src/conf.rs`
         "
-        )
+        );
     } else {
-        formatdoc!(
+        let _: fmt::Result = writedoc!(
+            result,
             r"
             declare_lint_pass!({name_camel} => [{name_upper}]);
 
             impl {pass_type}{pass_lifetimes} for {name_camel} {{}}
         "
-        )
-    });
+        );
+    }
 
     result
 }
@@ -455,7 +459,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str>
     });
 
     // Find both the last lint declaration (declare_clippy_lint!) and the lint pass impl
-    while let Some(LintDeclSearchResult { content, .. }) = iter.find(|result| result.token == TokenKind::Ident) {
+    while let Some(LintDeclSearchResult { content, .. }) = iter.find(|result| result.token_kind == TokenKind::Ident) {
         let mut iter = iter
             .by_ref()
             .filter(|t| !matches!(t.token_kind, TokenKind::Whitespace | TokenKind::LineComment { .. }));
@@ -465,7 +469,7 @@ fn setup_mod_file(path: &Path, lint: &LintData<'_>) -> io::Result<&'static str>
                 // matches `!{`
                 match_tokens!(iter, Bang OpenBrace);
                 if let Some(LintDeclSearchResult { range, .. }) =
-                    iter.find(|result| result.token == TokenKind::CloseBrace)
+                    iter.find(|result| result.token_kind == TokenKind::CloseBrace)
                 {
                     last_decl_curly_offset = Some(range.end);
                 }
diff --git a/src/tools/clippy/clippy_dev/src/setup/intellij.rs b/src/tools/clippy/clippy_dev/src/setup/intellij.rs
index a7138f36a4e..c56811ee0a0 100644
--- a/src/tools/clippy/clippy_dev/src/setup/intellij.rs
+++ b/src/tools/clippy/clippy_dev/src/setup/intellij.rs
@@ -62,7 +62,7 @@ fn check_and_get_rustc_dir(rustc_path: &str) -> Result<PathBuf, ()> {
                 eprintln!("error: unable to get the absolute path of rustc ({err})");
                 return Err(());
             },
-        };
+        }
     }
 
     let path = path.join("compiler");
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index 612d1c0ae13..b80ee5aac7e 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -842,7 +842,7 @@ fn try_rename_file(old_name: &Path, new_name: &Path) -> bool {
         Ok(file) => drop(file),
         Err(e) if matches!(e.kind(), io::ErrorKind::AlreadyExists | io::ErrorKind::NotFound) => return false,
         Err(e) => panic_file(e, new_name, "create"),
-    };
+    }
     match fs::rename(old_name, new_name) {
         Ok(()) => true,
         Err(e) => {
@@ -985,17 +985,23 @@ 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_dummy/Cargo.toml b/src/tools/clippy/clippy_dummy/Cargo.toml
index c206a1eb07b..61bdd421c76 100644
--- a/src/tools/clippy/clippy_dummy/Cargo.toml
+++ b/src/tools/clippy/clippy_dummy/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "clippy_dummy" # rename to clippy before publishing
 version = "0.0.303"
-edition = "2018"
+edition = "2024"
 readme = "crates-readme.md"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust."
 build = 'build.rs'
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index b575ac1bf4c..c62a7ec783b 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -8,7 +8,7 @@ repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
 license = "MIT OR Apache-2.0"
 keywords = ["clippy", "lint", "plugin"]
-edition = "2021"
+edition = "2024"
 
 [dependencies]
 arrayvec = { version = "0.7", default-features = false }
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 2af5178920d..0f7f779e8ea 100644
--- a/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
+++ b/src/tools/clippy/clippy_lints/src/almost_complete_range.rs
@@ -5,7 +5,6 @@ use clippy_utils::source::{trim_span, walk_span_to_context};
 use rustc_ast::ast::{Expr, ExprKind, LitKind, Pat, PatKind, RangeEnd, RangeLimits};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -45,7 +44,7 @@ impl EarlyLintPass for AlmostCompleteRange {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &Expr) {
         if let ExprKind::Range(Some(start), Some(end), RangeLimits::HalfOpen) = &e.kind
             && is_incomplete_range(start, end)
-            && !in_external_macro(cx.sess(), e.span)
+            && !e.span.in_external_macro(cx.sess().source_map())
         {
             span_lint_and_then(
                 cx,
@@ -74,7 +73,7 @@ impl EarlyLintPass for AlmostCompleteRange {
         if let PatKind::Range(Some(start), Some(end), kind) = &p.kind
             && matches!(kind.node, RangeEnd::Excluded)
             && is_incomplete_range(start, end)
-            && !in_external_macro(cx.sess(), p.span)
+            && !p.span.in_external_macro(cx.sess().source_map())
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 95c85f250e9..95f64b74044 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -3,10 +3,10 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
 use rustc_attr_parsing::RustcVersion;
-use rustc_hir::{Expr, ExprKind};
+use rustc_hir::{HirId, Lit};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol;
+use rustc_span::{Span, symbol};
 use std::f64::consts as f64;
 
 declare_clippy_lint! {
@@ -73,22 +73,28 @@ impl ApproxConstant {
             msrv: conf.msrv.clone(),
         }
     }
+}
 
-    fn check_lit(&self, cx: &LateContext<'_>, lit: &LitKind, e: &Expr<'_>) {
-        match *lit {
+impl<'tcx> LateLintPass<'tcx> for ApproxConstant {
+    fn check_lit(&mut self, cx: &LateContext<'_>, _hir_id: HirId, lit: &Lit, _negated: bool) {
+        match lit.node {
             LitKind::Float(s, LitFloatType::Suffixed(fty)) => match fty {
-                FloatTy::F16 => self.check_known_consts(cx, e, s, "f16"),
-                FloatTy::F32 => self.check_known_consts(cx, e, s, "f32"),
-                FloatTy::F64 => self.check_known_consts(cx, e, s, "f64"),
-                FloatTy::F128 => self.check_known_consts(cx, e, s, "f128"),
+                FloatTy::F16 => self.check_known_consts(cx, lit.span, s, "f16"),
+                FloatTy::F32 => self.check_known_consts(cx, lit.span, s, "f32"),
+                FloatTy::F64 => self.check_known_consts(cx, lit.span, s, "f64"),
+                FloatTy::F128 => self.check_known_consts(cx, lit.span, s, "f128"),
             },
             // FIXME(f16_f128): add `f16` and `f128` when these types become stable.
-            LitKind::Float(s, LitFloatType::Unsuffixed) => self.check_known_consts(cx, e, s, "f{32, 64}"),
+            LitKind::Float(s, LitFloatType::Unsuffixed) => self.check_known_consts(cx, lit.span, s, "f{32, 64}"),
             _ => (),
         }
     }
 
-    fn check_known_consts(&self, cx: &LateContext<'_>, e: &Expr<'_>, s: symbol::Symbol, module: &str) {
+    extract_msrv_attr!(LateContext);
+}
+
+impl ApproxConstant {
+    fn check_known_consts(&self, cx: &LateContext<'_>, span: Span, s: symbol::Symbol, module: &str) {
         let s = s.as_str();
         if s.parse::<f64>().is_ok() {
             for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {
@@ -96,7 +102,7 @@ impl ApproxConstant {
                     span_lint_and_help(
                         cx,
                         APPROX_CONSTANT,
-                        e.span,
+                        span,
                         format!("approximate value of `{module}::consts::{name}` found"),
                         None,
                         "consider using the constant directly",
@@ -110,16 +116,6 @@ impl ApproxConstant {
 
 impl_lint_pass!(ApproxConstant => [APPROX_CONSTANT]);
 
-impl<'tcx> LateLintPass<'tcx> for ApproxConstant {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
-        if let ExprKind::Lit(lit) = &e.kind {
-            self.check_lit(cx, &lit.node, e);
-        }
-    }
-
-    extract_msrv_attr!(LateContext);
-}
-
 /// Returns `false` if the number of significant figures in `value` are
 /// less than `min_digits`; otherwise, returns true if `value` is equal
 /// to `constant`, rounded to the number of digits present in `value`.
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
index 380b094d017..f519a65fc27 100644
--- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -9,7 +9,6 @@ use rustc_hir::{
     Variant, VariantData,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -248,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             ItemKind::Enum(enum_def, _generics) if self.enable_ordering_for_enum => {
                 let mut cur_v: Option<&Variant<'_>> = None;
                 for variant in enum_def.variants {
-                    if in_external_macro(cx.sess(), variant.span) {
+                    if variant.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -263,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             ItemKind::Struct(VariantData::Struct { fields, .. }, _generics) if self.enable_ordering_for_struct => {
                 let mut cur_f: Option<&FieldDef<'_>> = None;
                 for field in *fields {
-                    if in_external_macro(cx.sess(), field.span) {
+                    if field.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -281,7 +280,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                 let mut cur_t: Option<&TraitItemRef> = None;
 
                 for item in *item_ref {
-                    if in_external_macro(cx.sess(), item.span) {
+                    if item.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -304,7 +303,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                 let mut cur_t: Option<&ImplItemRef> = None;
 
                 for item in trait_impl.items {
-                    if in_external_macro(cx.sess(), item.span) {
+                    if item.span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
@@ -348,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
         // as no sorting by source map/line of code has to be applied.
         //
         for item in items {
-            if in_external_macro(cx.sess(), item.span) {
+            if item.span.in_external_macro(cx.sess().source_map()) {
                 continue;
             }
 
@@ -445,8 +444,8 @@ fn convert_assoc_item_kind(value: AssocItemKind) -> SourceItemOrderingTraitAssoc
     #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
     use SourceItemOrderingTraitAssocItemKind::*;
     match value {
-        AssocItemKind::Const { .. } => Const,
-        AssocItemKind::Type { .. } => Type,
+        AssocItemKind::Const => Const,
+        AssocItemKind::Type => Type,
         AssocItemKind::Fn { .. } => Fn,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/as_conversions.rs b/src/tools/clippy/clippy_lints/src/as_conversions.rs
index fefd8195f8e..847653ed6e9 100644
--- a/src/tools/clippy/clippy_lints/src/as_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/as_conversions.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -49,7 +48,7 @@ declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);
 impl<'tcx> LateLintPass<'tcx> for AsConversions {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
         if let ExprKind::Cast(_, _) = expr.kind
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, expr)
         {
             #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
index c8dd77d9578..c01155ca86e 100644
--- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -257,7 +257,7 @@ fn build_sugg<'tcx>(
                         // The receiver may have been a value type, so we need to add an `&` to
                         // be sure the argument to clone_from will be a reference.
                         arg_sugg = arg_sugg.addr();
-                    };
+                    }
 
                     format!("{receiver_sugg}.clone_from({arg_sugg})")
                 },
diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs
index 1879391ec29..53d9725703c 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs
@@ -4,11 +4,10 @@ use clippy_utils::is_from_proc_macro;
 use rustc_ast::{AttrStyle, Attribute};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 
 // Separate each crate's features.
 pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) {
-    if !in_external_macro(cx.sess(), attr.span)
+    if !attr.span.in_external_macro(cx.sess().source_map())
         && let AttrStyle::Outer = attr.style
         && let Some(ident) = attr.ident()
         && !is_from_proc_macro(cx, attr)
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 788377fe83c..5bf077990e1 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
@@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
 use rustc_ast::{MetaItemInner, MetaItemKind};
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 use rustc_span::symbol::Symbol;
 
@@ -17,7 +16,7 @@ pub(super) fn check<'cx>(cx: &EarlyContext<'cx>, name: Symbol, items: &[MetaItem
     }
 
     // Check if the attribute is in an external macro and therefore out of the developer's control
-    if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, attr) {
+    if attr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, attr) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
index 8c91c65eaf7..5a26ba8bf93 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
@@ -1,8 +1,8 @@
+use std::sync::Arc;
 use super::MIXED_ATTRIBUTES_STYLE;
 use clippy_utils::diagnostics::span_lint;
 use rustc_ast::{AttrKind, AttrStyle, Attribute};
 use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::sync::Lrc;
 use rustc_lint::{EarlyContext, LintContext};
 use rustc_span::source_map::SourceMap;
 use rustc_span::{SourceFile, Span, Symbol};
@@ -60,7 +60,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item_span: Span, attrs: &[Attribute])
                 }
                 outer_attr_kind.insert(kind);
             },
-        };
+        }
     }
 }
 
@@ -79,7 +79,7 @@ fn lint_mixed_attrs(cx: &EarlyContext<'_>, attrs: &[Attribute]) {
     );
 }
 
-fn attr_in_same_src_as_item(source_map: &SourceMap, item_src: &Lrc<SourceFile>, attr_span: Span) -> bool {
+fn attr_in_same_src_as_item(source_map: &SourceMap, item_src: &Arc<SourceFile>, attr_span: Span) -> bool {
     let attr_src = source_map.lookup_source_file(attr_span.lo());
-    Lrc::ptr_eq(item_src, &attr_src)
+    Arc::ptr_eq(item_src, &attr_src)
 }
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 e7158a6a6b6..e3e081ce08e 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -5,14 +5,13 @@ use clippy_utils::source::{SpanRangeExt, first_line_of_span};
 use rustc_ast::{Attribute, Item, ItemKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 
 pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
     let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
 
     for attr in attrs {
-        if in_external_macro(cx.sess(), attr.span) {
+        if attr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         if let Some(lint_list) = &attr.meta_item_list() {
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
index eb05dc96cde..aab0af0d743 100644
--- a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
@@ -4,7 +4,6 @@ use clippy_utils::{higher, is_from_proc_macro};
 use rustc_errors::Applicability;
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -54,7 +53,7 @@ const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression conditio
 
 impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs
index a1ca23e65ff..3b861848f94 100644
--- a/src/tools/clippy/clippy_lints/src/box_default.rs
+++ b/src/tools/clippy/clippy_lints/src/box_default.rs
@@ -4,12 +4,11 @@ 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::{Visitor, walk_ty};
-use rustc_hir::{Block, Expr, ExprKind, LetStmt, Node, QPath, Ty, TyKind};
+use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
+use rustc_hir::{AmbigArg, Block, Expr, ExprKind, HirId, LetStmt, Node, QPath, Ty, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -50,7 +49,7 @@ impl LateLintPass<'_> for BoxDefault {
             // This is the `T::default()` (or default equivalent) of `Box::new(T::default())`
             && let ExprKind::Call(arg_path, _) = arg.kind
             // And we are not in a foreign crate's macro
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             // And the argument expression has the same context as the outer call expression
             // or that we are inside a `vec!` macro expansion
             && (expr.span.eq_ctxt(arg.span) || is_local_vec_expn(cx, arg, expr))
@@ -92,8 +91,13 @@ fn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>)
 struct InferVisitor(bool);
 
 impl Visitor<'_> for InferVisitor {
-    fn visit_ty(&mut self, t: &Ty<'_>) {
-        self.0 |= matches!(t.kind, TyKind::Infer | TyKind::OpaqueDef(..) | TyKind::TraitObject(..));
+    fn visit_infer(&mut self, inf_id: HirId, _inf_span: Span, _kind: InferKind<'_>) -> Self::Result {
+        self.0 = true;
+        self.visit_id(inf_id);
+    }
+
+    fn visit_ty(&mut self, t: &Ty<'_, AmbigArg>) {
+        self.0 |= matches!(t.kind, TyKind::OpaqueDef(..) | TyKind::TraitObject(..));
         if !self.0 {
             walk_ty(self, t);
         }
@@ -104,7 +108,7 @@ fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match cx.tcx.parent_hir_node(expr.hir_id) {
         Node::LetStmt(LetStmt { ty: Some(ty), .. }) => {
             let mut v = InferVisitor::default();
-            v.visit_ty(ty);
+            v.visit_ty_unambig(ty);
             !v.0
         },
         Node::Expr(Expr {
diff --git a/src/tools/clippy/clippy_lints/src/cargo/mod.rs b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
index 96a2b161464..60371dcd771 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
@@ -161,6 +161,15 @@ declare_clippy_lint! {
     /// [dependencies]
     /// regex = "*"
     /// ```
+    /// Use instead:
+    /// ```toml
+    /// [dependencies]
+    /// # allow patch updates, but not minor or major version changes
+    /// some_crate_1 = "~1.2.3"
+    ///
+    /// # pin the version to a specific version
+    /// some_crate_2 = "=1.2.3"
+    /// ```
     #[clippy::version = "1.32.0"]
     pub WILDCARD_DEPENDENCIES,
     cargo,
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs b/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs
index 536126fd02b..3ab6693756f 100644
--- a/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/as_pointer_underscore.rs
@@ -4,7 +4,7 @@ use rustc_middle::ty::Ty;
 
 pub fn check<'tcx>(cx: &LateContext<'tcx>, ty_into: Ty<'_>, cast_to_hir: &'tcx rustc_hir::Ty<'tcx>) {
     if let rustc_hir::TyKind::Ptr(rustc_hir::MutTy { ty, .. }) = cast_to_hir.kind
-        && matches!(ty.kind, rustc_hir::TyKind::Infer)
+        && matches!(ty.kind, rustc_hir::TyKind::Infer(()))
     {
         clippy_utils::diagnostics::span_lint_and_sugg(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_underscore.rs b/src/tools/clippy/clippy_lints/src/casts/as_underscore.rs
index 56e894c6261..3ac486dd63f 100644
--- a/src/tools/clippy/clippy_lints/src/casts/as_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/as_underscore.rs
@@ -7,7 +7,7 @@ use rustc_middle::ty;
 use super::AS_UNDERSCORE;
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, ty: &'tcx Ty<'_>) {
-    if matches!(ty.kind, TyKind::Infer) {
+    if matches!(ty.kind, TyKind::Infer(())) {
         span_lint_and_then(cx, AS_UNDERSCORE, expr.span, "using `as _` conversion", |diag| {
             let ty_resolved = cx.typeck_results().expr_ty(expr);
             if let ty::Error(_) = ty_resolved.kind() {
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 4ad39d9160d..c326a0d935c 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -38,7 +38,7 @@ pub(super) fn check(
                 return;
             };
             match cast_to_hir.kind {
-                TyKind::Infer => {
+                TyKind::Infer(()) => {
                     diag.span_suggestion_verbose(
                         expr.span,
                         "use `Into::into` instead",
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 48e9f1d690e..ca973f4bb1a 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
@@ -4,13 +4,13 @@ use clippy_utils::expr_or_init;
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
+use rustc_abi::IntegerType;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, FloatTy, Ty};
 use rustc_span::Span;
-use rustc_target::abi::IntegerType;
 
 use super::{CAST_ENUM_TRUNCATION, CAST_POSSIBLE_TRUNCATION, utils};
 
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 3cf4a43b0d4..504d0a267e4 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
@@ -84,6 +84,6 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca
             diag
                 .note("`usize` and `isize` may be as small as 16 bits on some platforms")
                 .note("for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types");
-        };
+        }
     });
 }
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index 205357afd84..e4c0db5d9ef 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
             && let Some(generic_args) = method_path.args
             && let [GenericArg::Type(cast_to)] = generic_args.args
             // There probably is no obvious reason to do this, just to be consistent with `as` cases.
-            && !is_hir_ty_cfg_dependant(cx, cast_to)
+            && !is_hir_ty_cfg_dependant(cx, cast_to.as_unambig_ty())
         {
             let (cast_from, cast_to) = (cx.typeck_results().expr_ty(self_arg), cx.typeck_results().expr_ty(expr));
             lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
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 4be53ace687..45045e58ac7 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
@@ -205,7 +205,7 @@ fn expr_muldiv_sign(cx: &LateContext<'_>, expr: &Expr<'_>) -> Sign {
             // - uncertain if there are any uncertain values (because they could be negative or positive),
             Sign::Uncertain => return Sign::Uncertain,
             Sign::ZeroOrPositive => (),
-        };
+        }
     }
 
     // A mul/div is:
@@ -236,7 +236,7 @@ fn expr_add_sign(cx: &LateContext<'_>, expr: &Expr<'_>) -> Sign {
             // - uncertain if there are any uncertain values (because they could be negative or positive),
             Sign::Uncertain => return Sign::Uncertain,
             Sign::ZeroOrPositive => positive_count += 1,
-        };
+        }
     }
 
     // A sum is:
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index d90cf124fe4..521bd394901 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -29,7 +29,6 @@ use clippy_utils::is_hir_ty_cfg_dependant;
 use clippy_utils::msrvs::{self, Msrv};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -796,7 +795,7 @@ impl_lint_pass!(Casts => [
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index a138ade54aa..bdc389d39dd 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -43,9 +43,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
     {
         let mut app = Applicability::MachineApplicable;
         let turbofish = match &cast_to_hir_ty.kind {
-            TyKind::Infer => String::new(),
+            TyKind::Infer(()) => String::new(),
             TyKind::Ptr(mut_ty) => {
-                if matches!(mut_ty.ty.kind, TyKind::Infer) {
+                if matches!(mut_ty.ty.kind, TyKind::Infer(())) {
                     String::new()
                 } else {
                     format!(
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 f699bba20ed..592c820a25e 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
@@ -34,9 +34,9 @@ pub(super) fn check<'tcx>(
 
         let mut app = Applicability::MachineApplicable;
         let turbofish = match &cast_to_hir_ty.kind {
-            TyKind::Infer => String::new(),
+            TyKind::Infer(()) => String::new(),
             TyKind::Ptr(mut_ty) => {
-                if matches!(mut_ty.ty.kind, TyKind::Infer) {
+                if matches!(mut_ty.ty.kind, TyKind::Infer(())) {
                     String::new()
                 } else {
                     format!(
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 332e897def7..7885f171461 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -8,7 +8,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, Lit, Node, Path, QPath, TyKind, UnOp};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, FloatTy, InferTy, Ty};
 use std::ops::ControlFlow;
 
@@ -43,7 +42,7 @@ pub(super) fn check<'tcx>(
                 }
             },
             // Ignore `p as *const _`
-            TyKind::Infer => return false,
+            TyKind::Infer(()) => return false,
             _ => {},
         }
 
@@ -142,7 +141,7 @@ pub(super) fn check<'tcx>(
         }
     }
 
-    if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
+    if cast_from.kind() == cast_to.kind() && !expr.span.in_external_macro(cx.sess().source_map()) {
         if let Some(id) = path_to_local(cast_expr)
             && !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
         {
diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
index c5c4a28646d..a34af6bc226 100644
--- a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
@@ -18,7 +18,7 @@ pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>
             Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
         };
 
-        let sugg = if let TyKind::Infer = mut_ty.ty.kind {
+        let sugg = if let TyKind::Infer(()) = mut_ty.ty.kind {
             format!("{std_or_core}::{sugg_fn}()")
         } else if let Some(mut_ty_snip) = mut_ty.ty.span.get_source_text(cx) {
             format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()")
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index 364f5c7dc7a..9516af7334d 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -6,7 +6,6 @@ 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};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -64,7 +63,7 @@ impl LateLintPass<'_> for CheckedConversions {
                 },
                 _ => return,
             }
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && !is_in_const_context(cx)
             && self.msrv.meets(msrvs::TRY_FROM)
             && let Some(cv) = match op2 {
@@ -273,7 +272,7 @@ fn get_types_from_cast<'a>(
             },
             _ => {},
         }
-    };
+    }
     None
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/ctfe.rs b/src/tools/clippy/clippy_lints/src/ctfe.rs
index 589b99518a0..7bae04a10f1 100644
--- a/src/tools/clippy/clippy_lints/src/ctfe.rs
+++ b/src/tools/clippy/clippy_lints/src/ctfe.rs
@@ -21,6 +21,6 @@ impl<'tcx> LateLintPass<'tcx> for ClippyCtfe {
         _: Span,
         defid: LocalDefId,
     ) {
-        cx.tcx.ensure().mir_drops_elaborated_and_const_checked(defid); // Lint
+        cx.tcx.ensure_ok().mir_drops_elaborated_and_const_checked(defid); // Lint
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
index a96c86f0765..06376c57119 100644
--- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs
+++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
@@ -7,7 +7,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 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::{Span, SyntaxContext, sym};
 
@@ -60,7 +59,7 @@ impl LateLintPass<'_> for DbgMacro {
 
         if cur_syntax_ctxt != self.prev_ctxt &&
             let Some(macro_call) = first_dbg_macro_in_expansion(cx, expr.span) &&
-            !in_external_macro(cx.sess(), macro_call.span) &&
+            !macro_call.span.in_external_macro(cx.sess().source_map()) &&
             self.checked_dbg_call_site.insert(macro_call.span) &&
             // allows `dbg!` in test code if allow-dbg-in-test is set to true in clippy.toml
             !(self.allow_dbg_in_tests && is_in_test(cx.tcx, expr.hir_id))
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 3ff10d850f8..5c5978b5559 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -142,9 +142,8 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::doc::DOC_LINK_WITH_QUOTES_INFO,
     crate::doc::DOC_MARKDOWN_INFO,
     crate::doc::DOC_NESTED_REFDEFS_INFO,
+    crate::doc::DOC_OVERINDENTED_LIST_ITEMS_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,
@@ -161,6 +160,8 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO,
     crate::empty_drop::EMPTY_DROP_INFO,
     crate::empty_enum::EMPTY_ENUM_INFO,
+    crate::empty_line_after::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
+    crate::empty_line_after::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
     crate::empty_with_brackets::EMPTY_ENUM_VARIANTS_WITH_BRACKETS_INFO,
     crate::empty_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO,
     crate::endian_bytes::BIG_ENDIAN_BYTES_INFO,
@@ -291,6 +292,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::loops::MANUAL_FIND_INFO,
     crate::loops::MANUAL_FLATTEN_INFO,
     crate::loops::MANUAL_MEMCPY_INFO,
+    crate::loops::MANUAL_SLICE_FILL_INFO,
     crate::loops::MANUAL_WHILE_LET_SOME_INFO,
     crate::loops::MISSING_SPIN_LOOP_INFO,
     crate::loops::MUT_RANGE_BOUND_INFO,
@@ -320,6 +322,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     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,
+    crate::manual_option_as_slice::MANUAL_OPTION_AS_SLICE_INFO,
     crate::manual_range_patterns::MANUAL_RANGE_PATTERNS_INFO,
     crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO,
     crate::manual_retain::MANUAL_RETAIN_INFO,
@@ -335,6 +338,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::matches::INFALLIBLE_DESTRUCTURING_MATCH_INFO,
     crate::matches::MANUAL_FILTER_INFO,
     crate::matches::MANUAL_MAP_INFO,
+    crate::matches::MANUAL_OK_ERR_INFO,
     crate::matches::MANUAL_UNWRAP_OR_INFO,
     crate::matches::MATCH_AS_REF_INFO,
     crate::matches::MATCH_BOOL_INFO,
@@ -419,6 +423,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::methods::MANUAL_IS_VARIANT_AND_INFO,
     crate::methods::MANUAL_NEXT_BACK_INFO,
     crate::methods::MANUAL_OK_OR_INFO,
+    crate::methods::MANUAL_REPEAT_N_INFO,
     crate::methods::MANUAL_SATURATING_ARITHMETIC_INFO,
     crate::methods::MANUAL_SPLIT_ONCE_INFO,
     crate::methods::MANUAL_STR_REPEAT_INFO,
@@ -460,12 +465,14 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::methods::REPEAT_ONCE_INFO,
     crate::methods::RESULT_FILTER_MAP_INFO,
     crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,
+    crate::methods::RETURN_AND_THEN_INFO,
     crate::methods::SEARCH_IS_SOME_INFO,
     crate::methods::SEEK_FROM_CURRENT_INFO,
     crate::methods::SEEK_TO_START_INSTEAD_OF_REWIND_INFO,
     crate::methods::SHOULD_IMPLEMENT_TRAIT_INFO,
     crate::methods::SINGLE_CHAR_ADD_STR_INFO,
     crate::methods::SKIP_WHILE_NEXT_INFO,
+    crate::methods::SLICED_STRING_AS_BYTES_INFO,
     crate::methods::STABLE_SORT_PRIMITIVE_INFO,
     crate::methods::STRING_EXTEND_CHARS_INFO,
     crate::methods::STRING_LIT_CHARS_ANY_INFO,
@@ -495,6 +502,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::methods::UNWRAP_OR_DEFAULT_INFO,
     crate::methods::UNWRAP_USED_INFO,
     crate::methods::USELESS_ASREF_INFO,
+    crate::methods::USELESS_NONZERO_NEW_UNCHECKED_INFO,
     crate::methods::VEC_RESIZE_TO_ZERO_INFO,
     crate::methods::VERBOSE_FILE_READS_INFO,
     crate::methods::WAKER_CLONE_WAKE_INFO,
@@ -507,7 +515,6 @@ pub static LINTS: &[&crate::LintInfo] = &[
     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,
     crate::misc_early::MIXED_CASE_HEX_LITERALS_INFO,
     crate::misc_early::REDUNDANT_AT_REST_PATTERN_INFO,
@@ -573,6 +580,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_std_lazy_statics::NON_STD_LAZY_STATICS_INFO,
     crate::non_zero_suggestions::NON_ZERO_SUGGESTIONS_INFO,
     crate::nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES_INFO,
     crate::octal_escapes::OCTAL_ESCAPES_INFO,
@@ -621,6 +629,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     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::precedence::PRECEDENCE_BITS_INFO,
     crate::ptr::CMP_NULL_INFO,
     crate::ptr::INVALID_NULL_PTR_USAGE_INFO,
     crate::ptr::MUT_FROM_REF_INFO,
@@ -754,8 +763,10 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
     crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
     crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
+    crate::unnecessary_semicolon::UNNECESSARY_SEMICOLON_INFO,
     crate::unnecessary_struct_initialization::UNNECESSARY_STRUCT_INITIALIZATION_INFO,
     crate::unnecessary_wraps::UNNECESSARY_WRAPS_INFO,
+    crate::unneeded_struct_pattern::UNNEEDED_STRUCT_PATTERN_INFO,
     crate::unnested_or_patterns::UNNESTED_OR_PATTERNS_INFO,
     crate::unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME_INFO,
     crate::unused_async::UNUSED_ASYNC_INFO,
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 33a97222b8f..bbd5dc15542 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
@@ -80,6 +80,6 @@ impl LateLintPass<'_> for DefaultConstructedUnitStructs {
                 String::new(),
                 Applicability::MachineApplicable,
             );
-        };
+        }
     }
 }
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 c04a73c890f..772268e7899 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -9,7 +9,6 @@ use rustc_hir::{
     StructTailExpr,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
 use rustc_session::declare_lint_pass;
 use std::iter;
@@ -86,7 +85,7 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
 
     /// Check whether a passed literal has potential to cause fallback or not.
     fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>, emit_hir_id: HirId) {
-        if !in_external_macro(self.cx.sess(), lit.span)
+        if !lit.span.in_external_macro(self.cx.sess().source_map())
             && matches!(self.ty_bounds.last(), Some(ExplicitTyBound(false)))
             && matches!(
                 lit.node,
@@ -223,19 +222,17 @@ impl<'tcx> Visitor<'tcx> for NumericFallbackVisitor<'_, 'tcx> {
     }
 
     fn visit_pat(&mut self, pat: &'tcx Pat<'_>) {
-        match pat.kind {
-            PatKind::Expr(&PatExpr {
-                hir_id,
-                kind: PatExprKind::Lit { lit, .. },
-                ..
-            }) => {
-                let ty = self.cx.typeck_results().node_type(hir_id);
-                self.check_lit(lit, ty, hir_id);
-                return;
-            },
-            _ => {},
+        if let PatKind::Expr(&PatExpr {
+            hir_id,
+            kind: PatExprKind::Lit { lit, .. },
+            ..
+        }) = pat.kind
+        {
+            let ty = self.cx.typeck_results().node_type(hir_id);
+            self.check_lit(lit, ty, hir_id);
+            return;
         }
-        walk_pat(self, pat)
+        walk_pat(self, pat);
     }
 
     fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
index 3ea792d8b83..5604172d6f3 100644
--- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
@@ -129,6 +129,8 @@ declare_with_version! { RENAMED(RENAMED_VERSION): &[(&str, &str)] = &[
     ("clippy::clone_double_ref", "suspicious_double_ref_op"),
     #[clippy::version = ""]
     ("clippy::cmp_nan", "invalid_nan_comparisons"),
+    #[clippy::version = "1.86.0"]
+    ("clippy::double_neg", "double_negations"),
     #[clippy::version = ""]
     ("clippy::drop_bounds", "drop_bounds"),
     #[clippy::version = ""]
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 653726872c6..233ebe00d8e 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -11,10 +11,10 @@ use rustc_ast::util::parser::ExprPrecedence;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
-use rustc_hir::intravisit::{Visitor, walk_ty};
+use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
 use rustc_hir::{
-    self as hir, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node, Pat,
-    PatKind, Path, QPath, TyKind, UnOp,
+    self as hir, AmbigArg, BindingMode, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node,
+    Pat, PatKind, Path, QPath, TyKind, UnOp,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
@@ -291,10 +291,13 @@ 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 }
@@ -331,7 +334,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                                     deref_count += 1;
                                 },
                                 None => break None,
-                            };
+                            }
                         };
 
                         let use_node = use_cx.use_node(cx);
@@ -456,10 +459,13 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                             && next_adjust.is_none_or(|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,
+                                },
+                            ));
                         }
                     },
                     _ => {},
@@ -503,10 +509,13 @@ 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) => {
@@ -531,10 +540,13 @@ 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,
+                        },
+                    ));
                 }
             },
 
@@ -796,7 +808,7 @@ impl TyCoercionStability {
                     if let Some(args) = path.args
                         && args.args.iter().any(|arg| match arg {
                             hir::GenericArg::Infer(_) => true,
-                            hir::GenericArg::Type(ty) => ty_contains_infer(ty),
+                            hir::GenericArg::Type(ty) => ty_contains_infer(ty.as_unambig_ty()),
                             _ => false,
                         })
                     {
@@ -815,7 +827,7 @@ impl TyCoercionStability {
                 | TyKind::Path(_) => Self::Deref,
                 TyKind::OpaqueDef(..)
                 | TyKind::TraitAscription(..)
-                | TyKind::Infer
+                | TyKind::Infer(())
                 | TyKind::Typeof(..)
                 | TyKind::TraitObject(..)
                 | TyKind::InferDelegation(..)
@@ -889,29 +901,23 @@ impl TyCoercionStability {
 fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
     struct V(bool);
     impl Visitor<'_> for V {
-        fn visit_ty(&mut self, ty: &hir::Ty<'_>) {
-            if self.0
-                || matches!(
-                    ty.kind,
-                    TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(_) | TyKind::Err(_)
-                )
-            {
+        fn visit_infer(&mut self, inf_id: HirId, _inf_span: Span, kind: InferKind<'_>) -> Self::Result {
+            if let InferKind::Ty(_) | InferKind::Ambig(_) = kind {
                 self.0 = true;
-            } else {
-                walk_ty(self, ty);
             }
+            self.visit_id(inf_id);
         }
 
-        fn visit_generic_arg(&mut self, arg: &hir::GenericArg<'_>) {
-            if self.0 || matches!(arg, hir::GenericArg::Infer(_)) {
+        fn visit_ty(&mut self, ty: &hir::Ty<'_, AmbigArg>) {
+            if self.0 || matches!(ty.kind, TyKind::OpaqueDef(..) | TyKind::Typeof(_) | TyKind::Err(_)) {
                 self.0 = true;
-            } else if let hir::GenericArg::Type(ty) = arg {
-                self.visit_ty(ty);
+            } else {
+                walk_ty(self, ty);
             }
         }
     }
     let mut v = V(false);
-    v.visit_ty(ty);
+    v.visit_ty_unambig(ty);
     v.0
 }
 
@@ -1130,17 +1136,20 @@ 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/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index a78c392e208..4e8853821c3 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Diag;
 use rustc_hir::def_id::DefIdMap;
 use rustc_hir::{
-    Expr, ExprKind, ForeignItem, HirId, ImplItem, Item, ItemKind, OwnerId, Pat, Path, Stmt, TraitItem, Ty,
+    AmbigArg, Expr, ExprKind, ForeignItem, HirId, ImplItem, Item, ItemKind, OwnerId, Pat, Path, Stmt, TraitItem, Ty,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
@@ -140,7 +140,7 @@ impl LateLintPass<'_> for DisallowedMacros {
         self.check(cx, stmt.span, None);
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &Ty<'_>) {
+    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &Ty<'_, AmbigArg>) {
         self.check(cx, ty.span, None);
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_types.rs b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
index 3265404f2b2..947677e14bd 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_types.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::DefIdMap;
-use rustc_hir::{Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
+use rustc_hir::{AmbigArg, Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
@@ -108,7 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) {
         if let TyKind::Path(path) = &ty.kind {
             self.check_res_emit(cx, &cx.qpath_res(path, ty.hir_id), ty.span);
         }
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
deleted file mode 100644
index 099194d4e74..00000000000
--- a/src/tools/clippy/clippy_lints/src/doc/empty_line_after.rs
+++ /dev/null
@@ -1,342 +0,0 @@
-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::AttrStyle;
-use rustc_ast::token::CommentKind;
-use rustc_errors::{Applicability, Diag, SuggestionStyle};
-use rustc_hir::{AttrKind, Attribute, 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 f9e4a43c0e7..2577324f23d 100644
--- a/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/lazy_continuation.rs
@@ -1,11 +1,12 @@
-use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use itertools::Itertools;
 use rustc_errors::Applicability;
 use rustc_lint::LateContext;
 use rustc_span::{BytePos, Span};
+use std::cmp::Ordering;
 use std::ops::Range;
 
-use super::DOC_LAZY_CONTINUATION;
+use super::{DOC_LAZY_CONTINUATION, DOC_OVERINDENTED_LIST_ITEMS};
 
 fn map_container_to_text(c: &super::Container) -> &'static str {
     match c {
@@ -28,12 +29,57 @@ pub(super) fn check(
         return;
     }
 
+    // Blockquote
     let ccount = doc[range.clone()].chars().filter(|c| *c == '>').count();
     let blockquote_level = containers
         .iter()
         .filter(|c| matches!(c, super::Container::Blockquote))
         .count();
-    let lcount = doc[range.clone()].chars().filter(|c| *c == ' ').count();
+    if ccount < blockquote_level {
+        span_lint_and_then(
+            cx,
+            DOC_LAZY_CONTINUATION,
+            span,
+            "doc quote line without `>` marker",
+            |diag| {
+                let mut doc_start_range = &doc[range];
+                let mut suggested = String::new();
+                for c in containers {
+                    let text = map_container_to_text(c);
+                    if doc_start_range.starts_with(text) {
+                        doc_start_range = &doc_start_range[text.len()..];
+                        span = span.with_lo(
+                            span.lo() + BytePos(u32::try_from(text.len()).expect("text is not 2**32 or bigger")),
+                        );
+                    } else if matches!(c, super::Container::Blockquote)
+                        && let Some(i) = doc_start_range.find('>')
+                    {
+                        doc_start_range = &doc_start_range[i + 1..];
+                        span = span
+                            .with_lo(span.lo() + BytePos(u32::try_from(i).expect("text is not 2**32 or bigger") + 1));
+                    } else {
+                        suggested.push_str(text);
+                    }
+                }
+                diag.span_suggestion_verbose(
+                    span,
+                    "add markers to start of line",
+                    suggested,
+                    Applicability::MachineApplicable,
+                );
+                diag.help("if this not intended to be a quote at all, escape it with `\\>`");
+            },
+        );
+        return;
+    }
+
+    if ccount != 0 && blockquote_level != 0 {
+        // If this doc is a blockquote, we don't go further.
+        return;
+    }
+
+    // List
+    let leading_spaces = doc[range].chars().filter(|c| *c == ' ').count();
     let list_indentation = containers
         .iter()
         .map(|c| {
@@ -44,50 +90,36 @@ pub(super) fn check(
             }
         })
         .sum();
-    if ccount < blockquote_level || lcount < list_indentation {
-        let msg = if ccount < blockquote_level {
-            "doc quote line without `>` marker"
-        } else {
-            "doc list item without indentation"
-        };
-        span_lint_and_then(cx, DOC_LAZY_CONTINUATION, span, msg, |diag| {
-            if ccount == 0 && blockquote_level == 0 {
+    match leading_spaces.cmp(&list_indentation) {
+        Ordering::Less => span_lint_and_then(
+            cx,
+            DOC_LAZY_CONTINUATION,
+            span,
+            "doc list item without indentation",
+            |diag| {
                 // simpler suggestion style for indentation
-                let indent = list_indentation - lcount;
+                let indent = list_indentation - leading_spaces;
                 diag.span_suggestion_verbose(
                     span.shrink_to_hi(),
                     "indent this line",
-                    std::iter::repeat(" ").take(indent).join(""),
+                    std::iter::repeat_n(" ", indent).join(""),
                     Applicability::MaybeIncorrect,
                 );
                 diag.help("if this is supposed to be its own paragraph, add a blank line");
-                return;
-            }
-            let mut doc_start_range = &doc[range];
-            let mut suggested = String::new();
-            for c in containers {
-                let text = map_container_to_text(c);
-                if doc_start_range.starts_with(text) {
-                    doc_start_range = &doc_start_range[text.len()..];
-                    span = span
-                        .with_lo(span.lo() + BytePos(u32::try_from(text.len()).expect("text is not 2**32 or bigger")));
-                } else if matches!(c, super::Container::Blockquote)
-                    && let Some(i) = doc_start_range.find('>')
-                {
-                    doc_start_range = &doc_start_range[i + 1..];
-                    span =
-                        span.with_lo(span.lo() + BytePos(u32::try_from(i).expect("text is not 2**32 or bigger") + 1));
-                } else {
-                    suggested.push_str(text);
-                }
-            }
-            diag.span_suggestion_verbose(
+            },
+        ),
+        Ordering::Greater => {
+            let sugg = std::iter::repeat_n(" ", list_indentation).join("");
+            span_lint_and_sugg(
+                cx,
+                DOC_OVERINDENTED_LIST_ITEMS,
                 span,
-                "add markers to start of line",
-                suggested,
-                Applicability::MachineApplicable,
+                "doc list item overindented",
+                format!("try using `{sugg}` ({list_indentation} spaces)"),
+                sugg,
+                Applicability::MaybeIncorrect,
             );
-            diag.help("if this not intended to be a quote at all, escape it with `\\>`");
-        });
+        },
+        Ordering::Equal => {},
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 7561a6cf2a7..42e1f7fd950 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -22,7 +22,6 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_resolve::rustdoc::{
     DocFragment, add_doc_fragment, attrs_to_doc_fragments, main_body_opts, source_span_for_markdown_range,
@@ -34,7 +33,6 @@ use rustc_span::{Span, sym};
 use std::ops::Range;
 use url::Url;
 
-mod empty_line_after;
 mod include_in_doc_without_cfg;
 mod link_with_quotes;
 mod markdown;
@@ -430,6 +428,39 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
+    ///
+    /// Detects overindented list items in doc comments where the continuation
+    /// lines are indented more than necessary.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// Overindented list items in doc comments can lead to inconsistent and
+    /// poorly formatted documentation when rendered. Excessive indentation may
+    /// cause the text to be misinterpreted as a nested list item or code block,
+    /// affecting readability and the overall structure of the documentation.
+    ///
+    /// ### Example
+    ///
+    /// ```no_run
+    /// /// - This is the first item in a list
+    /// ///      and this line is overindented.
+    /// # fn foo() {}
+    /// ```
+    ///
+    /// Fixes this into:
+    /// ```no_run
+    /// /// - This is the first item in a list
+    /// ///   and this line is overindented.
+    /// # fn foo() {}
+    /// ```
+    #[clippy::version = "1.80.0"]
+    pub DOC_OVERINDENTED_LIST_ITEMS,
+    style,
+    "ensure list items are not overindented"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     /// Checks if the first paragraph in the documentation of items listed in the module page is too long.
     ///
     /// ### Why is this bad?
@@ -461,82 +492,6 @@ declare_clippy_lint! {
 
 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"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks if included files in doc comments are included only for `cfg(doc)`.
     ///
     /// ### Why restrict this?
@@ -617,8 +572,7 @@ impl_lint_pass!(Documentation => [
     SUSPICIOUS_DOC_COMMENTS,
     EMPTY_DOCS,
     DOC_LAZY_CONTINUATION,
-    EMPTY_LINE_AFTER_OUTER_ATTR,
-    EMPTY_LINE_AFTER_DOC_COMMENTS,
+    DOC_OVERINDENTED_LIST_ITEMS,
     TOO_LONG_FIRST_DOC_PARAGRAPH,
     DOC_INCLUDE_WITHOUT_CFG,
 ]);
@@ -641,7 +595,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
                 match item.kind {
                     ItemKind::Fn { sig, body: body_id, .. } => {
                         if !(is_entrypoint_fn(cx, item.owner_id.to_def_id())
-                            || in_external_macro(cx.tcx.sess, item.span))
+                            || item.span.in_external_macro(cx.tcx.sess.source_map()))
                         {
                             let body = cx.tcx.hir().body(body_id);
 
@@ -677,7 +631,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
             },
             Node::TraitItem(trait_item) => {
                 if let TraitItemKind::Fn(sig, ..) = trait_item.kind
-                    && !in_external_macro(cx.tcx.sess, trait_item.span)
+                    && !trait_item.span.in_external_macro(cx.tcx.sess.source_map())
                 {
                     missing_headers::check(
                         cx,
@@ -692,7 +646,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
             },
             Node::ImplItem(impl_item) => {
                 if let ImplItemKind::Fn(sig, body_id) = impl_item.kind
-                    && !in_external_macro(cx.tcx.sess, impl_item.span)
+                    && !impl_item.span.in_external_macro(cx.tcx.sess.source_map())
                     && !is_trait_impl_item(cx, impl_item.hir_id())
                 {
                     let body = cx.tcx.hir().body(body_id);
@@ -751,13 +705,13 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
     }
 
     include_in_doc_without_cfg::check(cx, attrs);
-    if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) {
+    if suspicious_doc_comments::check(cx, attrs) || is_doc_hidden(attrs) {
         return None;
     }
 
     let (fragments, _) = attrs_to_doc_fragments(
         attrs.iter().filter_map(|attr| {
-            if in_external_macro(cx.sess(), attr.span) {
+            if attr.span.in_external_macro(cx.sess().source_map()) {
                 None
             } else {
                 Some((attr, None))
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 9ba2723157a..ce5beab24bf 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
@@ -1,10 +1,10 @@
 use std::ops::Range;
 use std::{io, thread};
+use std::sync::Arc;
 
 use crate::doc::{NEEDLESS_DOCTEST_MAIN, TEST_ATTR_IN_DOCTEST};
 use clippy_utils::diagnostics::span_lint;
 use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::HumanEmitter;
 use rustc_errors::{Diag, DiagCtxt};
 use rustc_lint::LateContext;
@@ -46,8 +46,8 @@ pub fn check(
                     rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
                 let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle);
                 let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings();
-                #[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_dcx
-                let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
+                #[expect(clippy::arc_with_non_send_sync)] // `Arc` is expected by with_dcx
+                let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
                 let psess = ParseSess::with_dcx(dcx, sm);
 
                 let mut parser = match new_parser_from_source_str(&psess, filename, code) {
diff --git a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
index 5315f55ba38..a38e853172f 100644
--- a/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
+++ b/src/tools/clippy/clippy_lints/src/else_if_without_else.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -50,7 +49,7 @@ impl EarlyLintPass for ElseIfWithoutElse {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, item: &Expr) {
         if let ExprKind::If(_, _, Some(ref els)) = item.kind
             && let ExprKind::If(_, _, None) = els.kind
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
         {
             #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
new file mode 100644
index 00000000000..578ff6e38a6
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/empty_line_after.rs
@@ -0,0 +1,492 @@
+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::{AssocItemKind, AttrKind, AttrStyle, Attribute, Crate, Item, ItemKind, ModKind, NodeId};
+use rustc_errors::{Applicability, Diag, SuggestionStyle};
+use rustc_lexer::TokenKind;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+use rustc_session::impl_lint_pass;
+use rustc_span::symbol::kw;
+use rustc_span::{BytePos, ExpnKind, Ident, InnerSpan, Span, SpanData, Symbol};
+
+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"
+}
+
+#[derive(Debug)]
+struct ItemInfo {
+    kind: &'static str,
+    name: Symbol,
+    span: Span,
+    mod_items: Option<NodeId>,
+}
+
+pub struct EmptyLineAfter {
+    items: Vec<ItemInfo>,
+}
+
+impl_lint_pass!(EmptyLineAfter => [
+    EMPTY_LINE_AFTER_OUTER_ATTR,
+    EMPTY_LINE_AFTER_DOC_COMMENTS,
+]);
+
+impl EmptyLineAfter {
+    pub fn new() -> Self {
+        Self { items: Vec::new() }
+    }
+}
+
+#[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: &EarlyContext<'_>, suggestions: &mut Vec<(Span, String)>) {
+        match self.kind {
+            StopKind::Attr => {
+                if cx.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: &EarlyContext<'_>, attr: &Attribute) -> Option<Self> {
+        let SpanData { lo, hi, .. } = attr.span.data();
+        let file = cx.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: &EarlyContext<'_>, 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())
+            })
+    }
+}
+
+impl EmptyLineAfter {
+    fn check_gaps(&self, cx: &EarlyContext<'_>, gaps: &[Gap<'_>], id: NodeId) {
+        let Some(first_gap) = gaps.first() else {
+            return;
+        };
+        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| {
+                let info = self.items.last().unwrap();
+                diag.span_label(info.span, match kind {
+                    StopKind::Attr => format!("the attribute applies to this {}", info.kind),
+                    StopKind::Doc(_) => format!("the comment documents this {}", info.kind),
+                });
+
+                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);
+                    }
+                    diag.multipart_suggestion_verbose(
+                        format!("if the doc comment should not document `{}` comment it out", info.name),
+                        suggestions,
+                        Applicability::MaybeIncorrect,
+                    );
+                } else {
+                    self.suggest_inner(diag, kind, gaps, id);
+                }
+
+                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,
+                    );
+                }
+            },
+        );
+    }
+
+    /// 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(&self, diag: &mut Diag<'_, ()>, kind: StopKind, gaps: &[Gap<'_>], id: NodeId) {
+        if let Some(parent) = self.items.iter().rev().nth(1)
+            && (parent.kind == "module" || parent.kind == "crate")
+            && parent.mod_items == Some(id)
+        {
+            let desc = if parent.kind == "module" {
+                "parent module"
+            } else {
+                parent.kind
+            };
+            diag.multipart_suggestion_verbose(
+                match kind {
+                    StopKind::Attr => format!("if the attribute should apply to the {desc} use an inner attribute"),
+                    StopKind::Doc(_) => format!("if the comment should document the {desc} use an inner doc comment"),
+                },
+                gaps.iter()
+                    .flat_map(|gap| gap.prev_chunk)
+                    .map(Stop::convert_to_inner)
+                    .collect(),
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
+    fn check_item_kind(
+        &mut self,
+        cx: &EarlyContext<'_>,
+        kind: &ItemKind,
+        ident: &Ident,
+        span: Span,
+        attrs: &[Attribute],
+        id: NodeId,
+    ) {
+        self.items.push(ItemInfo {
+            kind: kind.descr(),
+            name: ident.name,
+            span: if span.contains(ident.span) {
+                span.with_hi(ident.span.hi())
+            } else {
+                span.with_hi(span.lo())
+            },
+            mod_items: match kind {
+                ItemKind::Mod(_, ModKind::Loaded(items, _, _, _)) => items
+                    .iter()
+                    .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
+                    .map(|i| i.id)
+                    .next(),
+                _ => None,
+            },
+        });
+
+        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;
+        }
+
+        // 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 = self.items.last().unwrap().span;
+        if !span.from_expansion()
+            && let Ok(line) = cx.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);
+            }
+        }
+
+        self.check_gaps(cx, &gaps, id);
+    }
+}
+
+impl EarlyLintPass for EmptyLineAfter {
+    fn check_crate(&mut self, _: &EarlyContext<'_>, krate: &Crate) {
+        self.items.push(ItemInfo {
+            kind: "crate",
+            name: kw::Crate,
+            span: krate.spans.inner_span.with_hi(krate.spans.inner_span.lo()),
+            mod_items: krate
+                .items
+                .iter()
+                .filter(|i| !matches!(i.span.ctxt().outer_expn_data().kind, ExpnKind::AstPass(_)))
+                .map(|i| i.id)
+                .next(),
+        });
+    }
+
+    fn check_item_post(&mut self, _: &EarlyContext<'_>, _: &Item) {
+        self.items.pop();
+    }
+    fn check_impl_item_post(&mut self, _: &EarlyContext<'_>, _: &Item<AssocItemKind>) {
+        self.items.pop();
+    }
+    fn check_trait_item_post(&mut self, _: &EarlyContext<'_>, _: &Item<AssocItemKind>) {
+        self.items.pop();
+    }
+
+    fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &Item<AssocItemKind>) {
+        self.check_item_kind(
+            cx,
+            &item.kind.clone().into(),
+            &item.ident,
+            item.span,
+            &item.attrs,
+            item.id,
+        );
+    }
+
+    fn check_trait_item(&mut self, cx: &EarlyContext<'_>, item: &Item<AssocItemKind>) {
+        self.check_item_kind(
+            cx,
+            &item.kind.clone().into(),
+            &item.ident,
+            item.span,
+            &item.attrs,
+            item.id,
+        );
+    }
+
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        self.check_item_kind(cx, &item.kind, &item.ident, item.span, &item.attrs, item.id);
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/endian_bytes.rs b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
index 209104c5385..a7670ffce88 100644
--- a/src/tools/clippy/clippy_lints/src/endian_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
@@ -3,10 +3,10 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_lint_allowed;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::Symbol;
+use std::fmt::Write;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -119,7 +119,7 @@ impl LateLintPass<'_> for EndianBytes {
             },
             _ => return,
         };
-        if !in_external_macro(cx.sess(), expr.span)
+        if !expr.span.in_external_macro(cx.sess().source_map())
             && let ty = cx.typeck_results().expr_ty(ty_expr)
             && ty.is_primitive_ty()
         {
@@ -184,7 +184,7 @@ fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix
                     help_str.push_str("either of ");
                 }
 
-                help_str.push_str(&format!("`{ty}::{}` ", lint.as_name(prefix)));
+                write!(help_str, "`{ty}::{}` ", lint.as_name(prefix)).unwrap();
 
                 if i != len && !only_one {
                     help_str.push_str("or ");
diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs
index e9e9d00907e..a090a987d4f 100644
--- a/src/tools/clippy/clippy_lints/src/enum_clike.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
                             var.span,
                             "C-like enum variant discriminant is not portable to 32-bit targets",
                         );
-                    };
+                    }
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
index 8a5cf7f56d5..cd9ab2764ac 100644
--- a/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
+++ b/src/tools/clippy/clippy_lints/src/equatable_if_let.rs
@@ -4,7 +4,6 @@ use clippy_utils::ty::implements_trait;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
 use rustc_session::declare_lint_pass;
 
@@ -56,7 +55,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
         PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
         PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),
         PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x),
-        PatKind::Path(_) | PatKind::Expr(_) => true,
+        PatKind::Expr(_) => true,
     }
 }
 
@@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if let ExprKind::Let(let_expr) = expr.kind
             && unary_pattern(let_expr.pat)
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
             let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index a89f0d9c432..c55d4387d69 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -10,7 +10,7 @@ use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 pub struct BoxedLocal {
     too_large_for_stack: u64,
@@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
         fn_def_id: LocalDefId,
     ) {
         if let Some(header) = fn_kind.header() {
-            if header.abi != Abi::Rust {
+            if header.abi != ExternAbi::Rust {
                 return;
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index c0b4743fd71..ae3acc1c4b1 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -1,11 +1,13 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::higher::VecArgs;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::{snippet_opt, snippet_with_applicability};
 use clippy_utils::ty::get_type_diagnostic_name;
 use clippy_utils::usage::{local_used_after_expr, local_used_in};
-use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, path_to_local, path_to_local_id};
+use clippy_utils::{
+    get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id,
+};
 use rustc_errors::Applicability;
-use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, Safety, TyKind};
+use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{
@@ -13,7 +15,7 @@ use rustc_middle::ty::{
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt as _;
 
 declare_clippy_lint! {
@@ -76,22 +78,22 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
         if let ExprKind::MethodCall(_method, receiver, args, _) = expr.kind {
             for arg in args {
-                check_clousure(cx, Some(receiver), arg);
+                check_closure(cx, Some(receiver), arg);
             }
         }
         if let ExprKind::Call(func, args) = expr.kind {
-            check_clousure(cx, None, func);
+            check_closure(cx, None, func);
             for arg in args {
-                check_clousure(cx, None, arg);
+                check_closure(cx, None, arg);
             }
         }
     }
 }
 
 #[allow(clippy::too_many_lines)]
-fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx>>, expr: &Expr<'tcx>) {
+fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx>>, expr: &Expr<'tcx>) {
     let body = if let ExprKind::Closure(c) = expr.kind
-        && c.fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer))
+        && c.fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer(())))
         && matches!(c.fn_decl.output, FnRetTy::DefaultReturn(_))
         && !expr.span.from_expansion()
     {
@@ -101,19 +103,20 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
     };
 
     if body.value.span.from_expansion() {
-        if body.params.is_empty() {
-            if let Some(VecArgs::Vec(&[])) = VecArgs::hir(cx, body.value) {
-                // replace `|| vec![]` with `Vec::new`
-                span_lint_and_sugg(
-                    cx,
-                    REDUNDANT_CLOSURE,
-                    expr.span,
-                    "redundant closure",
-                    "replace the closure with `Vec::new`",
-                    "std::vec::Vec::new".into(),
-                    Applicability::MachineApplicable,
-                );
-            }
+        if body.params.is_empty()
+            && let Some(VecArgs::Vec(&[])) = VecArgs::hir(cx, body.value)
+        {
+            let vec_crate = if is_no_std_crate(cx) { "alloc" } else { "std" };
+            // replace `|| vec![]` with `Vec::new`
+            span_lint_and_sugg(
+                cx,
+                REDUNDANT_CLOSURE,
+                expr.span,
+                "redundant closure",
+                "replace the closure with `Vec::new`",
+                format!("{vec_crate}::vec::Vec::new"),
+                Applicability::MachineApplicable,
+            );
         }
         // skip `foo(|| macro!())`
         return;
@@ -169,7 +172,7 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
                         && let output = typeck.expr_ty(body.value)
                         && let ty::Tuple(tys) = *subs.type_at(1).kind()
                     {
-                        cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, Abi::Rust)
+                        cx.tcx.mk_fn_sig(tys, output, false, Safety::Safe, ExternAbi::Rust)
                     } else {
                         return;
                     }
@@ -236,6 +239,11 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
                 && !cx.tcx.has_attr(method_def_id, sym::track_caller)
                 && check_sig(closure_sig, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())
             {
+                let mut app = Applicability::MachineApplicable;
+                let generic_args = match path.args.and_then(GenericArgs::span_ext) {
+                    Some(span) => format!("::{}", snippet_with_applicability(cx, span, "<..>", &mut app)),
+                    None => String::new(),
+                };
                 span_lint_and_then(
                     cx,
                     REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
@@ -248,8 +256,8 @@ fn check_clousure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tc
                         diag.span_suggestion(
                             expr.span,
                             "replace the closure with the method itself",
-                            format!("{}::{}", type_name, path.ident.name),
-                            Applicability::MachineApplicable,
+                            format!("{}::{}{}", type_name, path.ident.name, generic_args),
+                            app,
                         );
                     },
                 );
diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
index 0011da03dda..15afe3e8c14 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
@@ -7,7 +7,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) {
         // functions with a body are already checked by `check_fn`
         if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind
-            && fn_sig.header.abi == Abi::Rust
+            && fn_sig.header.abi == ExternAbi::Rust
             && fn_sig.decl.inputs.len() as u64 > self.max_fn_params_bools
         {
             check_fn_decl(cx, fn_sig.decl, fn_sig.span, self.max_fn_params_bools);
@@ -162,7 +162,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
         def_id: LocalDefId,
     ) {
         if let Some(fn_header) = fn_kind.header()
-            && fn_header.abi == Abi::Rust
+            && fn_header.abi == ExternAbi::Rust
             && fn_decl.inputs.len() as u64 > self.max_fn_params_bools
             && get_parent_as_impl(cx.tcx, cx.tcx.local_def_id_to_hir_id(def_id))
                 .is_none_or(|impl_item| impl_item.of_trait.is_none())
diff --git a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
index dfea40db182..1d3ae894944 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
@@ -5,7 +5,6 @@ use rustc_ast::node_id::NodeSet;
 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;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
@@ -125,7 +124,9 @@ struct NestingVisitor<'conf, 'cx> {
 
 impl NestingVisitor<'_, '_> {
     fn check_indent(&mut self, span: Span, id: NodeId) -> bool {
-        if self.nest_level > self.conf.excessive_nesting_threshold && !in_external_macro(self.cx.sess(), span) {
+        if self.nest_level > self.conf.excessive_nesting_threshold
+            && !span.in_external_macro(self.cx.sess().source_map())
+        {
             self.conf.nodes.insert(id);
 
             return true;
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 d0159ab89e1..5d93aceb33f 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,14 +3,13 @@ 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::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty};
+use rustc_hir::intravisit::{Visitor, walk_impl_item, walk_item, walk_param_bound, walk_ty, walk_unambig_ty};
 use rustc_hir::{
-    BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind,
-    PredicateOrigin, Ty, WherePredicate, WherePredicateKind,
+    AmbigArg, BodyId, ExprKind, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item,
+    ItemKind, PredicateOrigin, Ty, WherePredicate, WherePredicateKind,
 };
 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::Span;
 use rustc_span::def_id::{DefId, LocalDefId};
@@ -183,7 +182,7 @@ impl<'cx, 'tcx> TypeWalker<'cx, 'tcx> {
                     .collect()
             };
             self.emit_sugg(spans, msg, help);
-        };
+        }
     }
 }
 
@@ -196,7 +195,7 @@ fn bound_to_trait_def_id(bound: &GenericBound<'_>) -> Option<LocalDefId> {
 impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
-    fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
+    fn visit_ty(&mut self, t: &'tcx Ty<'tcx, AmbigArg>) {
         if let Some((def_id, _)) = t.peel_refs().as_generic_param() {
             self.ty_params.remove(&def_id);
         } else {
@@ -234,7 +233,7 @@ impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
                 // type, any params we find nested inside of it are being used as concrete types,
                 // and can therefore can be considered used. So, we're fine to walk the left-hand
                 // side of the where bound.
-                walk_ty(self, predicate.bounded_ty);
+                walk_unambig_ty(self, predicate.bounded_ty);
             }
             for bound in predicate.bounds {
                 walk_param_bound(self, bound);
@@ -261,7 +260,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
             && !generics.params.is_empty()
             && !is_empty_body(cx, body_id)
             && (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, item)
         {
             let mut walker = TypeWalker::new(cx, generics);
@@ -277,7 +276,7 @@ impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
             && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
             && !is_empty_body(cx, body_id)
             && (!self.avoid_breaking_exported_api || !cx.effective_visibilities.is_exported(item.owner_id.def_id))
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, item)
         {
             let mut walker = TypeWalker::new(cx, item.generics);
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 8b1f86cbb91..68cc50f3939 100644
--- a/src/tools/clippy/clippy_lints/src/format_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/format_push_string.rs
@@ -11,7 +11,7 @@ declare_clippy_lint! {
     /// Detects cases where the result of a `format!` call is
     /// appended to an existing `String`.
     ///
-    /// ### Why restrict this?
+    /// ### Why is this bad?
     /// Introduces an extra, avoidable heap allocation.
     ///
     /// ### Known problems
@@ -35,7 +35,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.62.0"]
     pub FORMAT_PUSH_STRING,
-    restriction,
+    pedantic,
     "`format!(..)` appended to existing `String`"
 }
 declare_lint_pass!(FormatPushString => [FORMAT_PUSH_STRING]);
diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs
index 34e93bdb9b9..c8fe7ac73cb 100644
--- a/src/tools/clippy/clippy_lints/src/formatting.rs
+++ b/src/tools/clippy/clippy_lints/src/formatting.rs
@@ -3,7 +3,6 @@ use clippy_utils::is_span_if;
 use clippy_utils::source::snippet_opt;
 use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
@@ -202,7 +201,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
     if let ExprKind::If(_, then, Some(else_)) = &expr.kind
         && (is_block(else_) || is_if(else_))
         && !then.span.from_expansion() && !else_.span.from_expansion()
-        && !in_external_macro(cx.sess(), expr.span)
+        && !expr.span.in_external_macro(cx.sess().source_map())
 
         // workaround for rust-lang/rust#43081
         && expr.span.lo().0 != 0 && expr.span.hi().0 != 0
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 e43c311eb85..9a73d0c0993 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -103,7 +103,9 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
                         "replace the `Into` implementation with `From<{}>`",
                         middle_trait_ref.self_ty()
                     );
-                    if let Some(suggestions) = convert_to_from(cx, into_trait_seg, target_ty, self_ty, impl_item_ref) {
+                    if let Some(suggestions) =
+                        convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, impl_item_ref)
+                    {
                         diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable);
                     } else {
                         diag.help(message);
diff --git a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
index 05e341e06fd..752dbc0db4d 100644
--- a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
@@ -45,7 +45,7 @@ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body:
         for param in generics.params {
             if param.is_impl_trait() {
                 report(cx, param, generics);
-            };
+            }
         }
     }
 }
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 1a01f5f885c..e480805cac2 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -5,7 +5,6 @@ use rustc_hir::def_id::DefIdSet;
 use rustc_hir::{self as hir, Attribute, QPath};
 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::{Span, sym};
 
@@ -107,7 +106,7 @@ fn check_needless_must_use(
     attrs: &[Attribute],
     sig: &FnSig<'_>,
 ) {
-    if in_external_macro(cx.sess(), item_span) {
+    if item_span.in_external_macro(cx.sess().source_map()) {
         return;
     }
     if returns_unit(decl) {
@@ -160,7 +159,7 @@ fn check_needless_must_use(
                 && !is_must_use_ty(cx, future_ty)
             {
                 return;
-            };
+            }
         }
 
         span_lint_and_help(
@@ -185,7 +184,7 @@ fn check_must_use_candidate<'tcx>(
 ) {
     if has_mutable_arg(cx, body)
         || mutates_static(cx, body)
-        || in_external_macro(cx.sess(), item_span)
+        || item_span.in_external_macro(cx.sess().source_map())
         || returns_unit(decl)
         || !cx.effective_visibilities.is_exported(item_id.def_id)
         || is_must_use_ty(cx, return_ty(cx, item_id))
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
index 9c396986f62..74d365a7255 100644
--- a/src/tools/clippy/clippy_lints/src/functions/result.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -2,7 +2,6 @@ use clippy_utils::msrvs::{self, Msrv};
 use rustc_errors::Diag;
 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::{Span, sym};
 
@@ -20,7 +19,7 @@ fn result_err_ty<'tcx>(
     id: hir::def_id::LocalDefId,
     item_span: Span,
 ) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> {
-    if !in_external_macro(cx.sess(), item_span)
+    if !item_span.in_external_macro(cx.sess().source_map())
         && let hir::FnRetTy::Return(hir_ty) = decl.output
         && let ty = cx
             .tcx
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
index e72a2ad49d8..f17f687719f 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
@@ -1,7 +1,7 @@
 use rustc_hir::{self as hir, intravisit};
 use rustc_lint::LateContext;
 use rustc_span::Span;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_trait_impl_item;
@@ -23,11 +23,11 @@ pub(super) fn check_fn(
             intravisit::FnKind::Method(
                 _,
                 &hir::FnSig {
-                    header: hir::FnHeader { abi: Abi::Rust, .. },
+                    header: hir::FnHeader { abi: ExternAbi::Rust, .. },
                     ..
                 },
             )
-            | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }) => check_arg_number(
+            | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: ExternAbi::Rust, .. }) => check_arg_number(
                 cx,
                 decl,
                 span.with_hi(decl.output.span().hi()),
@@ -41,7 +41,7 @@ pub(super) fn check_fn(
 pub(super) fn check_trait_item(cx: &LateContext<'_>, item: &hir::TraitItem<'_>, too_many_arguments_threshold: u64) {
     if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
         // don't lint extern functions decls, it's not their fault
-        if sig.header.abi == Abi::Rust {
+        if sig.header.abi == ExternAbi::Rust {
             check_arg_number(
                 cx,
                 sig.decl,
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
index 0f5ce340c44..4f90d9655b4 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
@@ -3,7 +3,6 @@ use clippy_utils::source::SpanRangeExt;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::Span;
 
 use super::TOO_MANY_LINES;
@@ -17,7 +16,7 @@ pub(super) fn check_fn(
 ) {
     // Closures must be contained in a parent body, which will be checked for `too_many_lines`.
     // Don't check closures for `too_many_lines` to avoid duplicated lints.
-    if matches!(kind, FnKind::Closure) || in_external_macro(cx.sess(), span) {
+    if matches!(kind, FnKind::Closure) || span.in_external_macro(cx.sess().source_map()) {
         return;
     }
 
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 bb2dc9995df..3ccfa51ab70 100644
--- a/src/tools/clippy/clippy_lints/src/future_not_send.rs
+++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs
@@ -79,7 +79,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
             && let Some(future_trait) = cx.tcx.lang_items().future_trait()
             && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)
         {
-            let preds = cx.tcx.explicit_item_super_predicates(def_id);
+            let preds = cx.tcx.explicit_item_self_bounds(def_id);
             let is_future = preds.iter_instantiated_copied(cx.tcx, args).any(|(p, _)| {
                 p.as_trait_clause()
                     .is_some_and(|trait_pred| trait_pred.skip_binder().trait_ref.def_id == future_trait)
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 3fc0a696522..51e2944e6f9 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
@@ -11,7 +11,6 @@ use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -79,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
             && is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone)
             && !is_else_clause(cx.tcx, expr)
             && !is_in_const_context(cx)
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && self.msrv.meets(msrvs::BOOL_THEN)
             && !contains_return(then_block.stmts)
         {
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index ad2da3c7fcd..47a5c19215b 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -2,9 +2,8 @@ use std::borrow::Cow;
 use std::collections::BTreeMap;
 
 use rustc_errors::{Applicability, Diag};
-use rustc_hir as hir;
-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::intravisit::{Visitor, VisitorExt, walk_body, walk_expr, walk_ty};
+use rustc_hir::{self as hir, AmbigArg, 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;
@@ -112,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
         match item.kind {
             ItemKind::Impl(impl_) => {
                 let mut vis = ImplicitHasherTypeVisitor::new(cx);
-                vis.visit_ty(impl_.self_ty);
+                vis.visit_ty_unambig(impl_.self_ty);
 
                 for target in &vis.found {
                     if !item.span.eq_ctxt(target.span()) {
@@ -159,7 +158,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
 
                 for ty in sig.decl.inputs {
                     let mut vis = ImplicitHasherTypeVisitor::new(cx);
-                    vis.visit_ty(ty);
+                    vis.visit_ty_unambig(ty);
 
                     for target in &vis.found {
                         if generics.span.from_expansion() {
@@ -287,21 +286,13 @@ impl<'a, 'tcx> 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) {
+    fn visit_ty(&mut self, t: &'tcx hir::Ty<'_, AmbigArg>) {
+        if let Some(target) = ImplicitHasherType::new(self.cx, t.as_unambig_ty()) {
             self.found.push(target);
         }
 
         walk_ty(self, t);
     }
-
-    fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
-        if let Some(target) = ImplicitHasherType::new(self.cx, &inf.to_ty()) {
-            self.found.push(target);
-        }
-
-        walk_inf(self, inf);
-    }
 }
 
 /// Looks for default-hasher-dependent constructors like `HashMap::new`.
diff --git a/src/tools/clippy/clippy_lints/src/implicit_return.rs b/src/tools/clippy/clippy_lints/src/implicit_return.rs
index ba06567b957..5f95464e4d4 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_return.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_return.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, FnRetTy, HirId};
 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, SyntaxContext};
@@ -227,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitReturn {
     ) {
         if (!matches!(kind, FnKind::Closure) && matches!(decl.output, FnRetTy::DefaultReturn(_)))
             || !span.eq_ctxt(body.value.span)
-            || in_external_macro(cx.sess(), span)
+            || span.in_external_macro(cx.sess().source_map())
         {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
index dd5908553e5..41d2b18803d 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
@@ -120,7 +120,7 @@ fn get_const<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<(u128, B
         let ecx = ConstEvalCtxt::new(cx);
         if let Some(Constant::Int(c)) = ecx.eval(r) {
             return Some((c, op.node, l));
-        };
+        }
         if let Some(Constant::Int(c)) = ecx.eval(l) {
             return Some((c, invert_op(op.node)?, r));
         }
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 37481dc7feb..152d506a7c0 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs
@@ -350,7 +350,7 @@ fn check_with_condition<'tcx>(
                     if cx.typeck_results().expr_ty(cond_left).is_signed() {
                     } else {
                         print_lint_and_sugg(cx, var_name, expr);
-                    };
+                    }
                 }
             },
             ExprKind::Path(QPath::TypeRelative(_, name)) => {
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 ef272c305d3..d02d9b2102b 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,8 +3,8 @@ use clippy_utils::source::snippet;
 use rustc_errors::{Applicability, SuggestionStyle};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
-    AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers, TyKind,
-    WherePredicateKind,
+    AmbigArg, AssocItemConstraint, GenericArg, GenericBound, GenericBounds, PredicateOrigin, TraitBoundModifiers,
+    TyKind, WherePredicateKind,
 };
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
@@ -146,7 +146,9 @@ fn try_resolve_type<'tcx>(
     index: usize,
 ) -> Option<Ty<'tcx>> {
     match args.get(index - 1) {
-        Some(GenericArg::Type(ty)) => Some(lower_ty(tcx, ty)),
+        // I don't think we care about `GenericArg::Infer` since this is all for stuff in type signatures
+        // which do not permit inference variables.
+        Some(GenericArg::Type(ty)) => Some(lower_ty(tcx, ty.as_unambig_ty())),
         Some(_) => None,
         None => Some(tcx.type_of(generics.own_params[index].def_id).skip_binder()),
     }
@@ -335,7 +337,7 @@ impl<'tcx> LateLintPass<'tcx> for ImpliedBoundsInImpls {
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &rustc_hir::Ty<'tcx>) {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &rustc_hir::Ty<'tcx, AmbigArg>) {
         if let TyKind::OpaqueDef(opaque_ty, ..) = ty.kind {
             check(cx, opaque_ty.bounds);
         }
diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
index 415b47adac5..c58e8773e3a 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
@@ -5,7 +5,7 @@ use rustc_hir::{GenericParamKind, ImplItem, ImplItemKind, LangItem};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for InherentToString {
             // #11201
             && let header = signature.header
             && header.is_safe()
-            && header.abi == Abi::Rust
+            && header.abi == ExternAbi::Rust
             && impl_item.ident.name == sym::to_string
             && let decl = signature.decl
             && decl.implicit_self.has_implicit_self()
diff --git a/src/tools/clippy/clippy_lints/src/items_after_statements.rs b/src/tools/clippy/clippy_lints/src/items_after_statements.rs
index 4f066113aea..f5ad79a0027 100644
--- a/src/tools/clippy/clippy_lints/src/items_after_statements.rs
+++ b/src/tools/clippy/clippy_lints/src/items_after_statements.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_hir;
 use rustc_hir::{Block, ItemKind, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -70,7 +69,7 @@ impl LateLintPass<'_> for ItemsAfterStatements {
                 // Don't use `next` due to the complex filter chain.
                 .for_each(|item| {
                     // Only do the macro check once, but delay it until it's needed.
-                    if !*in_external.get_or_insert_with(|| in_external_macro(cx.sess(), block.span)) {
+                    if !*in_external.get_or_insert_with(|| block.span.in_external_macro(cx.sess().source_map())) {
                         span_lint_hir(
                             cx,
                             ITEMS_AFTER_STATEMENTS,
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 5131f5b7269..b1cb6da9475 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
@@ -65,6 +65,6 @@ impl LateLintPass<'_> for IterOverHashType {
                 expr.span,
                 "iteration over unordered hash-based type",
             );
-        };
+        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
index 906da81b183..238f66d6675 100644
--- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -6,7 +6,6 @@ use rustc_ast::Mutability;
 use rustc_errors::Applicability;
 use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
@@ -131,7 +130,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
             && trait_ref
                 .trait_def_id()
                 .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did))
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
             && let expected_method_name = match mtbl {
                 Mutability::Mut => sym::iter_mut,
@@ -193,7 +192,7 @@ impl {self_ty_without_ref} {{
             _ => return,
         };
 
-        if !in_external_macro(cx.sess(), item.span)
+        if !item.span.in_external_macro(cx.sess().source_map())
             && let ImplItemKind::Fn(sig, _) = item.kind
             && let FnRetTy::Return(ret) = sig.decl.output
             && is_nameable_in_impl_trait(ret)
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index 623b6b4fcc1..cabf10b7e0e 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -56,9 +56,8 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
             && !item.span.from_expansion()
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Array(element_type, cst) = ty.kind()
-            && let Some((ty::ValTree::Leaf(element_count), _)) = cx.tcx
-                .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_valtree()
-            && let element_count = element_count.to_target_usize(cx.tcx)
+            && let Some(element_count) = cx.tcx
+                .try_normalize_erasing_regions(cx.typing_env(), *cst).unwrap_or(*cst).try_to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)
         {
diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
index 923089c7223..d9953dbc261 100644
--- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
+++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs
@@ -5,7 +5,6 @@ use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_copy};
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
@@ -78,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Adt(adt, subst) = ty.kind()
             && adt.variants().len() > 1
-            && !in_external_macro(cx.tcx.sess, item.span)
+            && !item.span.in_external_macro(cx.tcx.sess.source_map())
         {
             let variants_size = AdtVariantInfo::new(cx, *adt, subst);
 
diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs
index 593704f206a..fd7965d564d 100644
--- a/src/tools/clippy/clippy_lints/src/large_futures.rs
+++ b/src/tools/clippy/clippy_lints/src/large_futures.rs
@@ -2,11 +2,11 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::implements_trait;
+use rustc_abi::Size;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, LangItem, MatchSource, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_target::abi::Size;
 
 declare_clippy_lint! {
     /// ### What it does
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 46d7df6995a..c68499ce9f7 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
@@ -7,8 +7,8 @@ use clippy_utils::macros::macro_backtrace;
 use clippy_utils::source::snippet;
 use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::{self, ConstKind};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
 
@@ -81,8 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
             && let ExprKind::Repeat(_, _) | ExprKind::Array(_) = expr.kind
             && !self.is_from_vec_macro(cx, expr.span)
             && let ty::Array(element_type, cst) = cx.typeck_results().expr_ty(expr).kind()
-            && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
-            && let element_count = element_count.to_target_usize(cx.tcx)
+            && let Some(element_count) = cst.try_to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && !cx.tcx.hir().parent_iter(expr.hir_id).any(|(_, node)| {
                 matches!(
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 fb46bdcab6e..6f2ce04e8f8 100644
--- a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
 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::{Symbol, sym};
@@ -54,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
         // so lint on the `use` statement directly.
         if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind
             && self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
-            && !in_external_macro(cx.sess(), item.span)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && let Some(def_id) = path.res[0].opt_def_id()
         {
             let module = if is_integer_module(cx, def_id) {
@@ -139,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
         };
 
         if self.msrv.meets(msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, expr)
         {
             span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs
index b522c22a44d..bdbf5b37c5f 100644
--- a/src/tools/clippy/clippy_lints/src/let_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs
@@ -3,7 +3,6 @@ use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
 use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
 use rustc_hir::{LetStmt, LocalSource, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{GenericArgKind, IsSuggestable};
 use rustc_session::declare_lint_pass;
 use rustc_span::{BytePos, Span};
@@ -141,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
         if matches!(local.source, LocalSource::Normal)
             && let PatKind::Wild = local.pat.kind
             && let Some(init) = local.init
-            && !in_external_macro(cx.tcx.sess, local.span)
+            && !local.span.in_external_macro(cx.tcx.sess.source_map())
         {
             let init_ty = cx.typeck_results().expr_ty(init);
             let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
diff --git a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
index 5a11702d7ce..9c8488ff381 100644
--- a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::is_from_proc_macro;
 use rustc_hir::{LetStmt, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -28,9 +27,9 @@ declare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]);
 impl<'tcx> LateLintPass<'tcx> for UnderscoreTyped {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
         if let Some(ty) = local.ty // Ensure that it has a type defined
-            && let TyKind::Infer = &ty.kind // that type is '_'
+            && let TyKind::Infer(()) = &ty.kind // that type is '_'
             && local.span.eq_ctxt(ty.span)
-            && !in_external_macro(cx.tcx.sess, local.span)
+            && !local.span.in_external_macro(cx.tcx.sess.source_map())
             && !is_from_proc_macro(cx, ty)
         {
             span_lint_and_help(
@@ -41,6 +40,6 @@ impl<'tcx> LateLintPass<'tcx> for UnderscoreTyped {
                 Some(ty.span.with_lo(local.pat.span.hi())),
                 "remove the explicit type `_` declaration",
             );
-        };
+        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index fad6f9d0880..13218331a67 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -126,6 +126,7 @@ mod duplicate_mod;
 mod else_if_without_else;
 mod empty_drop;
 mod empty_enum;
+mod empty_line_after;
 mod empty_with_brackets;
 mod endian_bytes;
 mod entry;
@@ -217,6 +218,7 @@ mod manual_is_power_of_two;
 mod manual_let_else;
 mod manual_main_separator_str;
 mod manual_non_exhaustive;
+mod manual_option_as_slice;
 mod manual_range_patterns;
 mod manual_rem_euclid;
 mod manual_retain;
@@ -279,6 +281,7 @@ mod non_copy_const;
 mod non_expressive_names;
 mod non_octal_unix_permissions;
 mod non_send_fields_in_send_ty;
+mod non_std_lazy_statics;
 mod non_zero_suggestions;
 mod nonstandard_macro_braces;
 mod octal_escapes;
@@ -372,8 +375,10 @@ mod unnecessary_literal_bound;
 mod unnecessary_map_on_constructor;
 mod unnecessary_owned_empty_strings;
 mod unnecessary_self_imports;
+mod unnecessary_semicolon;
 mod unnecessary_struct_initialization;
 mod unnecessary_wraps;
+mod unneeded_struct_pattern;
 mod unnested_or_patterns;
 mod unsafe_removed_from_name;
 mod unused_async;
@@ -680,7 +685,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(unit_types::UnitTypes));
     store.register_late_pass(move |_| Box::new(loops::Loops::new(conf)));
     store.register_late_pass(|_| Box::<main_recursion::MainRecursion>::default());
-    store.register_late_pass(|_| Box::new(lifetimes::Lifetimes));
+    store.register_late_pass(move |_| Box::new(lifetimes::Lifetimes::new(conf)));
     store.register_late_pass(|_| Box::new(entry::HashMapPass));
     store.register_late_pass(|_| Box::new(minmax::MinMaxPass));
     store.register_late_pass(|_| Box::new(zero_div_zero::ZeroDiv));
@@ -969,6 +974,11 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| Box::new(unused_trait_names::UnusedTraitNames::new(conf)));
     store.register_late_pass(|_| Box::new(manual_ignore_case_cmp::ManualIgnoreCaseCmp));
     store.register_late_pass(|_| Box::new(unnecessary_literal_bound::UnnecessaryLiteralBound));
+    store.register_early_pass(|| Box::new(empty_line_after::EmptyLineAfter::new()));
     store.register_late_pass(move |_| Box::new(arbitrary_source_item_ordering::ArbitrarySourceItemOrdering::new(conf)));
+    store.register_late_pass(|_| Box::new(unneeded_struct_pattern::UnneededStructPattern));
+    store.register_late_pass(|_| Box::<unnecessary_semicolon::UnnecessarySemicolon>::default());
+    store.register_late_pass(move |_| Box::new(non_std_lazy_statics::NonStdLazyStatic::new(conf)));
+    store.register_late_pass(|_| Box::new(manual_option_as_slice::ManualOptionAsSlice::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 239822f4085..860c0584acc 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -1,4 +1,6 @@
+use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::trait_ref_of_method;
 use itertools::Itertools;
 use rustc_ast::visit::{try_visit, walk_list};
@@ -7,20 +9,19 @@ 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::{
-    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,
+    Visitor, VisitorExt, 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_unambig_ty, walk_where_predicate,
 };
 use rustc_hir::{
-    BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics,
-    HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
-    PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate,
+    AmbigArg, BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind,
+    Generics, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node,
+    PolyTraitRef, PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereBoundPredicate, WherePredicate,
     WherePredicateKind, 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_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{Ident, kw};
@@ -91,7 +92,19 @@ declare_clippy_lint! {
     "unused lifetimes in function definitions"
 }
 
-declare_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]);
+pub struct Lifetimes {
+    msrv: Msrv,
+}
+
+impl Lifetimes {
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+        }
+    }
+}
+
+impl_lint_pass!(Lifetimes => [NEEDLESS_LIFETIMES, EXTRA_UNUSED_LIFETIMES]);
 
 impl<'tcx> LateLintPass<'tcx> for Lifetimes {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
@@ -102,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
             ..
         } = item.kind
         {
-            check_fn_inner(cx, sig, Some(id), None, generics, item.span, true);
+            check_fn_inner(cx, sig, Some(id), None, generics, item.span, true, &self.msrv);
         } else if let ItemKind::Impl(impl_) = item.kind {
             if !item.span.from_expansion() {
                 report_extra_impl_lifetimes(cx, impl_);
@@ -121,6 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
                 item.generics,
                 item.span,
                 report_extra_lifetimes,
+                &self.msrv,
             );
         }
     }
@@ -131,11 +145,14 @@ impl<'tcx> LateLintPass<'tcx> for Lifetimes {
                 TraitFn::Required(sig) => (None, Some(sig)),
                 TraitFn::Provided(id) => (Some(id), None),
             };
-            check_fn_inner(cx, sig, body, trait_sig, item.generics, item.span, true);
+            check_fn_inner(cx, sig, body, trait_sig, item.generics, item.span, true, &self.msrv);
         }
     }
+
+    extract_msrv_attr!(LateContext);
 }
 
+#[allow(clippy::too_many_arguments)]
 fn check_fn_inner<'tcx>(
     cx: &LateContext<'tcx>,
     sig: &'tcx FnSig<'_>,
@@ -144,8 +161,9 @@ fn check_fn_inner<'tcx>(
     generics: &'tcx Generics<'_>,
     span: Span,
     report_extra_lifetimes: bool,
+    msrv: &Msrv,
 ) {
-    if in_external_macro(cx.sess(), span) || has_where_lifetimes(cx, generics) {
+    if span.in_external_macro(cx.sess().source_map()) || has_where_lifetimes(cx, generics) {
         return;
     }
 
@@ -195,7 +213,7 @@ fn check_fn_inner<'tcx>(
         }
     }
 
-    if let Some((elidable_lts, usages)) = could_use_elision(cx, sig.decl, body, trait_sig, generics.params) {
+    if let Some((elidable_lts, usages)) = could_use_elision(cx, sig.decl, body, trait_sig, generics.params, msrv) {
         if usages.iter().any(|usage| !usage.ident.span.eq_ctxt(span)) {
             return;
         }
@@ -216,6 +234,7 @@ fn could_use_elision<'tcx>(
     body: Option<BodyId>,
     trait_sig: Option<&[Ident]>,
     named_generics: &'tcx [GenericParam<'_>],
+    msrv: &Msrv,
 ) -> Option<(Vec<LocalDefId>, Vec<Lifetime>)> {
     // There are two scenarios where elision works:
     // * no output references, all input references have different LT
@@ -232,11 +251,11 @@ fn could_use_elision<'tcx>(
 
     // extract lifetimes in input argument types
     for arg in func.inputs {
-        input_visitor.visit_ty(arg);
+        input_visitor.visit_ty_unambig(arg);
     }
     // extract lifetimes in output type
     if let Return(ty) = func.output {
-        output_visitor.visit_ty(ty);
+        output_visitor.visit_ty_unambig(ty);
     }
     for lt in named_generics {
         input_visitor.visit_generic_param(lt);
@@ -249,17 +268,17 @@ fn could_use_elision<'tcx>(
     let input_lts = input_visitor.lts;
     let output_lts = output_visitor.lts;
 
-    if let Some(trait_sig) = trait_sig {
-        if explicit_self_type(cx, func, trait_sig.first().copied()) {
-            return None;
-        }
+    if let Some(trait_sig) = trait_sig
+        && non_elidable_self_type(cx, func, trait_sig.first().copied(), msrv)
+    {
+        return None;
     }
 
     if let Some(body_id) = body {
         let body = cx.tcx.hir().body(body_id);
 
         let first_ident = body.params.first().and_then(|param| param.pat.simple_ident());
-        if explicit_self_type(cx, func, first_ident) {
+        if non_elidable_self_type(cx, func, first_ident, msrv) {
             return None;
         }
 
@@ -332,15 +351,21 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxIndexSet<LocalDefI
         .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
+// elision doesn't work for explicit self types before Rust 1.81, see rust-lang/rust#69064
+fn non_elidable_self_type<'tcx>(
+    cx: &LateContext<'tcx>,
+    func: &FnDecl<'tcx>,
+    ident: Option<Ident>,
+    msrv: &Msrv,
+) -> bool {
+    if !msrv.meets(msrvs::EXPLICIT_SELF_TYPE_ELISION)
+        && 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.visit_ty_unambig(self_ty);
 
         !visitor.all_lts().is_empty()
     } else {
@@ -426,14 +451,14 @@ impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
         }
     }
 
-    fn visit_ty(&mut self, ty: &'tcx Ty<'_>) {
+    fn visit_ty(&mut self, ty: &'tcx Ty<'_, AmbigArg>) {
         match ty.kind {
             TyKind::BareFn(&BareFnTy { decl, .. }) => {
                 let mut sub_visitor = RefVisitor::new(self.cx);
                 sub_visitor.visit_fn_decl(decl);
                 self.nested_elision_site_lts.append(&mut sub_visitor.all_lts());
             },
-            TyKind::TraitObject(bounds, lt, _) => {
+            TyKind::TraitObject(bounds, lt) => {
                 if !lt.is_elided() {
                     self.unelided_trait_object_lifetime = true;
                 }
@@ -456,7 +481,7 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
                 // a predicate like F: Trait or F: for<'a> Trait<'a>
                 let mut visitor = RefVisitor::new(cx);
                 // walk the type F, it may not contain LT refs
-                walk_ty(&mut visitor, pred.bounded_ty);
+                walk_unambig_ty(&mut visitor, pred.bounded_ty);
                 if !visitor.all_lts().is_empty() {
                     return true;
                 }
@@ -477,8 +502,8 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
             },
             WherePredicateKind::EqPredicate(ref pred) => {
                 let mut visitor = RefVisitor::new(cx);
-                walk_ty(&mut visitor, pred.lhs_ty);
-                walk_ty(&mut visitor, pred.rhs_ty);
+                walk_unambig_ty(&mut visitor, pred.lhs_ty);
+                walk_unambig_ty(&mut visitor, pred.rhs_ty);
                 if !visitor.lts.is_empty() {
                     return true;
                 }
@@ -488,11 +513,13 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
     false
 }
 
+#[allow(clippy::struct_excessive_bools)]
 struct Usage {
     lifetime: Lifetime,
     in_where_predicate: bool,
     in_bounded_ty: bool,
     in_generics_arg: bool,
+    lifetime_elision_impossible: bool,
 }
 
 struct LifetimeChecker<'cx, 'tcx, F> {
@@ -501,6 +528,7 @@ struct LifetimeChecker<'cx, 'tcx, F> {
     where_predicate_depth: usize,
     bounded_ty_depth: usize,
     generic_args_depth: usize,
+    lifetime_elision_impossible: bool,
     phantom: std::marker::PhantomData<F>,
 }
 
@@ -525,6 +553,7 @@ where
             where_predicate_depth: 0,
             bounded_ty_depth: 0,
             generic_args_depth: 0,
+            lifetime_elision_impossible: false,
             phantom: std::marker::PhantomData,
         }
     }
@@ -541,7 +570,7 @@ where
         try_visit!(self.visit_id(hir_id));
 
         self.bounded_ty_depth += 1;
-        try_visit!(self.visit_ty(bounded_ty));
+        try_visit!(self.visit_ty_unambig(bounded_ty));
         self.bounded_ty_depth -= 1;
 
         walk_list!(self, visit_param_bound, bounds);
@@ -566,6 +595,7 @@ where
                 in_where_predicate: self.where_predicate_depth != 0,
                 in_bounded_ty: self.bounded_ty_depth != 0,
                 in_generics_arg: self.generic_args_depth != 0,
+                lifetime_elision_impossible: self.lifetime_elision_impossible,
             });
         }
     }
@@ -592,11 +622,44 @@ where
         self.generic_args_depth -= 1;
     }
 
+    fn visit_fn_decl(&mut self, fd: &'tcx FnDecl<'tcx>) -> Self::Result {
+        self.lifetime_elision_impossible = !is_candidate_for_elision(fd);
+        walk_fn_decl(self, fd);
+        self.lifetime_elision_impossible = false;
+    }
+
     fn nested_visit_map(&mut self) -> Self::Map {
         self.cx.tcx.hir()
     }
 }
 
+/// Check if `fd` supports function elision with an anonymous (or elided) lifetime,
+/// and has a lifetime somewhere in its output type.
+fn is_candidate_for_elision(fd: &FnDecl<'_>) -> bool {
+    struct V;
+
+    impl Visitor<'_> for V {
+        type Result = ControlFlow<bool>;
+
+        fn visit_lifetime(&mut self, lifetime: &Lifetime) -> Self::Result {
+            ControlFlow::Break(lifetime.is_elided() || lifetime.is_anonymous())
+        }
+    }
+
+    if fd.lifetime_elision_allowed
+        && let Return(ret_ty) = fd.output
+        && walk_unambig_ty(&mut V, ret_ty).is_break()
+    {
+        // The first encountered input lifetime will either be one on `self`, or will be the only lifetime.
+        fd.inputs
+            .iter()
+            .find_map(|ty| walk_unambig_ty(&mut V, ty).break_value())
+            .unwrap()
+    } else {
+        false
+    }
+}
+
 fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, generics: &'tcx Generics<'_>) {
     let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, generics);
 
@@ -625,7 +688,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
     if let Some(ref trait_ref) = impl_.of_trait {
         walk_trait_ref(&mut checker, trait_ref);
     }
-    walk_ty(&mut checker, impl_.self_ty);
+    walk_unambig_ty(&mut checker, impl_.self_ty);
     for item in impl_.items {
         walk_impl_item_ref(&mut checker, item);
     }
@@ -662,6 +725,7 @@ fn report_elidable_impl_lifetimes<'tcx>(
                 Usage {
                     lifetime,
                     in_where_predicate: false,
+                    lifetime_elision_impossible: false,
                     ..
                 },
             ] = usages.as_slice()
@@ -719,7 +783,7 @@ fn report_elidable_lifetimes(
         |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);
diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs
index e2dcb20f906..805de23408b 100644
--- a/src/tools/clippy/clippy_lints/src/literal_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs
@@ -6,7 +6,6 @@ use rustc_ast::ast::{Expr, ExprKind, LitKind};
 use rustc_ast::token;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, Lint, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use std::iter;
@@ -207,7 +206,7 @@ impl_lint_pass!(LiteralDigitGrouping => [
 impl EarlyLintPass for LiteralDigitGrouping {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if let ExprKind::Lit(lit) = expr.kind
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             self.check_lit(cx, lit, expr.span);
         }
@@ -251,7 +250,7 @@ impl LiteralDigitGrouping {
                     );
                     if !consistent {
                         return Err(WarningType::InconsistentDigitGrouping);
-                    };
+                    }
                 }
 
                 Ok(())
@@ -421,7 +420,7 @@ impl_lint_pass!(DecimalLiteralRepresentation => [DECIMAL_LITERAL_REPRESENTATION]
 impl EarlyLintPass for DecimalLiteralRepresentation {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if let ExprKind::Lit(lit) = expr.kind
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             self.check_lit(cx, lit, expr.span);
         }
diff --git a/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs b/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs
index 49353a1b76b..a957c0e22a2 100644
--- a/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs
+++ b/src/tools/clippy/clippy_lints/src/literal_string_with_formatting_args.rs
@@ -29,9 +29,9 @@ declare_clippy_lint! {
     /// let y = "hello";
     /// x.expect(&format!("{y:?}"));
     /// ```
-    #[clippy::version = "1.83.0"]
+    #[clippy::version = "1.85.0"]
     pub LITERAL_STRING_WITH_FORMATTING_ARGS,
-    suspicious,
+    nursery,
     "Checks if string literals have formatting arguments"
 }
 
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 6be30f3c957..4d206850c99 100644
--- a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
@@ -6,7 +6,6 @@ use rustc_ast::Label;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 
 use super::INFINITE_LOOP;
@@ -30,7 +29,7 @@ pub(super) fn check<'tcx>(
         return;
     }
 
-    if in_external_macro(cx.sess(), expr.span) || is_from_proc_macro(cx, expr) {
+    if expr.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, expr) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_slice_fill.rs b/src/tools/clippy/clippy_lints/src/loops/manual_slice_fill.rs
new file mode 100644
index 00000000000..7c656423579
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_slice_fill.rs
@@ -0,0 +1,111 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::eager_or_lazy::switch_to_eager_eval;
+use clippy_utils::macros::span_is_local;
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::{HasSession, snippet_with_applicability};
+use clippy_utils::ty::implements_trait;
+use clippy_utils::{higher, peel_blocks_with_stmt, span_contains_comment};
+use rustc_ast::ast::LitKind;
+use rustc_ast::{RangeLimits, UnOp};
+use rustc_data_structures::packed::Pu128;
+use rustc_errors::Applicability;
+use rustc_hir::QPath::Resolved;
+use rustc_hir::def::Res;
+use rustc_hir::{Expr, ExprKind, Pat};
+use rustc_lint::LateContext;
+use rustc_span::source_map::Spanned;
+use rustc_span::sym;
+
+use super::MANUAL_SLICE_FILL;
+
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    pat: &'tcx Pat<'_>,
+    arg: &'tcx Expr<'_>,
+    body: &'tcx Expr<'_>,
+    expr: &'tcx Expr<'_>,
+    msrv: &Msrv,
+) {
+    if !msrv.meets(msrvs::SLICE_FILL) {
+        return;
+    }
+
+    // `for _ in 0..slice.len() { slice[_] = value; }`
+    if let Some(higher::Range {
+        start: Some(start),
+        end: Some(end),
+        limits: RangeLimits::HalfOpen,
+    }) = higher::Range::hir(arg)
+        && let ExprKind::Lit(Spanned {
+            node: LitKind::Int(Pu128(0), _),
+            ..
+        }) = start.kind
+        && let ExprKind::Block(..) = body.kind
+        // Check if the body is an assignment to a slice element.
+        && let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind
+        && let ExprKind::Index(slice, _, _) = assignee.kind
+        // Check if `len()` is used for the range end.
+        && let ExprKind::MethodCall(path, recv,..) = end.kind
+        && path.ident.name == sym::len
+        // Check if the slice which is being assigned to is the same as the one being iterated over.
+        && let ExprKind::Path(Resolved(_, recv_path)) = recv.kind
+        && let ExprKind::Path(Resolved(_, slice_path)) = slice.kind
+        && recv_path.res == slice_path.res
+        && !assignval.span.from_expansion()
+        // It is generally not equivalent to use the `fill` method if `assignval` can have side effects
+        && switch_to_eager_eval(cx, assignval)
+        && span_is_local(assignval.span)
+        // The `fill` method requires that the slice's element type implements the `Clone` trait.
+        && let Some(clone_trait) = cx.tcx.lang_items().clone_trait()
+        && implements_trait(cx, cx.typeck_results().expr_ty(slice), clone_trait, &[])
+    {
+        sugg(cx, body, expr, slice.span, assignval.span);
+    }
+    // `for _ in &mut slice { *_ = value; }`
+    else if let ExprKind::AddrOf(_, _, recv) = arg.kind
+        // Check if the body is an assignment to a slice element.
+        && let ExprKind::Assign(assignee, assignval, _) = peel_blocks_with_stmt(body).kind
+        && let ExprKind::Unary(UnOp::Deref, slice_iter) = assignee.kind
+        && let ExprKind::Path(Resolved(_, recv_path)) = recv.kind
+        // Check if the slice which is being assigned to is the same as the one being iterated over.
+        && let ExprKind::Path(Resolved(_, slice_path)) = slice_iter.kind
+        && let Res::Local(local) = slice_path.res
+        && local == pat.hir_id
+        && !assignval.span.from_expansion()
+        && switch_to_eager_eval(cx, assignval)
+        && span_is_local(assignval.span)
+        // The `fill` method cannot be used if the slice's element type does not implement the `Clone` trait.
+        && let Some(clone_trait) = cx.tcx.lang_items().clone_trait()
+        && implements_trait(cx, cx.typeck_results().expr_ty(recv), clone_trait, &[])
+    {
+        sugg(cx, body, expr, recv_path.span, assignval.span);
+    }
+}
+
+fn sugg<'tcx>(
+    cx: &LateContext<'tcx>,
+    body: &'tcx Expr<'_>,
+    expr: &'tcx Expr<'_>,
+    slice_span: rustc_span::Span,
+    assignval_span: rustc_span::Span,
+) {
+    let mut app = if span_contains_comment(cx.sess().source_map(), body.span) {
+        Applicability::MaybeIncorrect // Comments may be informational.
+    } else {
+        Applicability::MachineApplicable
+    };
+
+    span_lint_and_sugg(
+        cx,
+        MANUAL_SLICE_FILL,
+        expr.span,
+        "manually filling a slice",
+        "try",
+        format!(
+            "{}.fill({});",
+            snippet_with_applicability(cx, slice_span, "..", &mut app),
+            snippet_with_applicability(cx, assignval_span, "..", &mut app),
+        ),
+        app,
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index f3ca4a4a571..cdc8c18c3b7 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -8,6 +8,7 @@ mod iter_next_loop;
 mod manual_find;
 mod manual_flatten;
 mod manual_memcpy;
+mod manual_slice_fill;
 mod manual_while_let_some;
 mod missing_spin_loop;
 mod mut_range_bound;
@@ -714,6 +715,31 @@ declare_clippy_lint! {
     "possibly unintended infinite loop"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for manually filling a slice with a value.
+    ///
+    /// ### Why is this bad?
+    /// Using the `fill` method is more idiomatic and concise.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let mut some_slice = [1, 2, 3, 4, 5];
+    /// for i in 0..some_slice.len() {
+    ///     some_slice[i] = 0;
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let mut some_slice = [1, 2, 3, 4, 5];
+    /// some_slice.fill(0);
+    /// ```
+    #[clippy::version = "1.86.0"]
+    pub MANUAL_SLICE_FILL,
+    style,
+    "manually filling a slice with a value"
+}
+
 pub struct Loops {
     msrv: Msrv,
     enforce_iter_loop_reborrow: bool,
@@ -750,6 +776,7 @@ impl_lint_pass!(Loops => [
     MANUAL_WHILE_LET_SOME,
     UNUSED_ENUMERATE_INDEX,
     INFINITE_LOOP,
+    MANUAL_SLICE_FILL,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Loops {
@@ -823,6 +850,7 @@ impl Loops {
     ) {
         let is_manual_memcpy_triggered = manual_memcpy::check(cx, pat, arg, body, expr);
         if !is_manual_memcpy_triggered {
+            manual_slice_fill::check(cx, pat, arg, body, expr, &self.msrv);
             needless_range_loop::check(cx, pat, arg, body, expr);
             explicit_counter_loop::check(cx, pat, arg, body, expr, label);
         }
@@ -830,7 +858,7 @@ impl Loops {
         for_kv_map::check(cx, pat, arg, body);
         mut_range_bound::check(cx, arg, body);
         single_element_loop::check(cx, pat, arg, body, expr);
-        same_item_push::check(cx, pat, arg, body, expr);
+        same_item_push::check(cx, pat, arg, body, expr, &self.msrv);
         manual_flatten::check(cx, pat, arg, body, span);
         manual_find::check(cx, pat, arg, body, span, expr);
         unused_enumerate_index::check(cx, pat, arg, body);
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 951ebc9caef..c27e930c99a 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
@@ -1,8 +1,9 @@
 use super::SAME_ITEM_PUSH;
-use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::path_to_local;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
+use clippy_utils::{msrvs, path_to_local, std_or_core};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -19,19 +20,30 @@ pub(super) fn check<'tcx>(
     _: &'tcx Expr<'_>,
     body: &'tcx Expr<'_>,
     _: &'tcx Expr<'_>,
+    msrv: &Msrv,
 ) {
-    fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>, ctxt: SyntaxContext) {
+    fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>, ctxt: SyntaxContext, msrv: &Msrv) {
         let mut app = Applicability::Unspecified;
         let vec_str = snippet_with_context(cx, vec.span, ctxt, "", &mut app).0;
         let item_str = snippet_with_context(cx, pushed_item.span, ctxt, "", &mut app).0;
 
-        span_lint_and_help(
+        let secondary_help = if msrv.meets(msrvs::REPEAT_N)
+            && let Some(std_or_core) = std_or_core(cx)
+        {
+            format!("or `{vec_str}.extend({std_or_core}::iter::repeat_n({item_str}, SIZE))`")
+        } else {
+            format!("or `{vec_str}.resize(NEW_SIZE, {item_str})`")
+        };
+
+        span_lint_and_then(
             cx,
             SAME_ITEM_PUSH,
             vec.span,
-            "it looks like the same item is being pushed into this Vec",
-            None,
-            format!("consider using vec![{item_str};SIZE] or {vec_str}.resize(NEW_SIZE, {item_str})"),
+            "it looks like the same item is being pushed into this `Vec`",
+            |diag| {
+                diag.help(format!("consider using `vec![{item_str};SIZE]`"))
+                    .help(secondary_help);
+            },
         );
     }
 
@@ -67,11 +79,11 @@ pub(super) fn check<'tcx>(
                         {
                             match init.kind {
                                 // immutable bindings that are initialized with literal
-                                ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt),
+                                ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt, msrv),
                                 // immutable bindings that are initialized with constant
                                 ExprKind::Path(ref path) => {
                                     if let Res::Def(DefKind::Const, ..) = cx.qpath_res(path, init.hir_id) {
-                                        emit_lint(cx, vec, pushed_item, ctxt);
+                                        emit_lint(cx, vec, pushed_item, ctxt, msrv);
                                     }
                                 },
                                 _ => {},
@@ -79,11 +91,11 @@ pub(super) fn check<'tcx>(
                         }
                     },
                     // constant
-                    Res::Def(DefKind::Const, ..) => emit_lint(cx, vec, pushed_item, ctxt),
+                    Res::Def(DefKind::Const, ..) => emit_lint(cx, vec, pushed_item, ctxt, msrv),
                     _ => {},
                 }
             },
-            ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt),
+            ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt, msrv),
             _ => {},
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index 3c669d94d69..37412866539 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::snippet;
 use hir::def::{DefKind, Res};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_hir as hir;
+use rustc_hir::{self as hir, AmbigArg};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::edition::Edition;
@@ -123,7 +123,7 @@ impl LateLintPass<'_> for MacroUseImports {
             self.push_unique_macro_pat_ty(cx, pat.span);
         }
     }
-    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_>) {
+    fn check_ty(&mut self, cx: &LateContext<'_>, ty: &hir::Ty<'_, AmbigArg>) {
         if ty.span.from_expansion() {
             self.push_unique_macro_pat_ty(cx, ty.span);
         }
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index c31656f8a05..17e25635ce1 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -10,7 +10,7 @@ use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -57,13 +57,13 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits {
             && let ctxt = expr.span.ctxt()
             && left_expr.span.ctxt() == ctxt
             && right_expr.span.ctxt() == ctxt
-            && let Some((real_ty, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr)
+            && let Some((real_ty_span, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr)
             && matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_))
             && let ExprKind::Lit(lit) = &other_expr.kind
             && let LitKind::Int(Pu128(8), _) = lit.node
         {
             let mut app = Applicability::MachineApplicable;
-            let ty_snip = snippet_with_context(cx, real_ty.span, ctxt, "..", &mut app).0;
+            let ty_snip = snippet_with_context(cx, real_ty_span, ctxt, "..", &mut app).0;
             let sugg = create_sugg(cx, expr, format!("{ty_snip}::BITS"));
 
             span_lint_and_sugg(
@@ -85,21 +85,21 @@ fn get_one_size_of_ty<'tcx>(
     cx: &LateContext<'tcx>,
     expr1: &'tcx Expr<'_>,
     expr2: &'tcx Expr<'_>,
-) -> Option<(&'tcx rustc_hir::Ty<'tcx>, Ty<'tcx>, &'tcx Expr<'tcx>)> {
+) -> Option<(Span, Ty<'tcx>, &'tcx Expr<'tcx>)> {
     match (get_size_of_ty(cx, expr1), get_size_of_ty(cx, expr2)) {
-        (Some((real_ty, resolved_ty)), None) => Some((real_ty, resolved_ty, expr2)),
-        (None, Some((real_ty, resolved_ty))) => Some((real_ty, resolved_ty, expr1)),
+        (Some((real_ty_span, resolved_ty)), None) => Some((real_ty_span, resolved_ty, expr2)),
+        (None, Some((real_ty_span, resolved_ty))) => Some((real_ty_span, resolved_ty, expr1)),
         _ => None,
     }
 }
 
-fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<(&'tcx rustc_hir::Ty<'tcx>, Ty<'tcx>)> {
+fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<(Span, Ty<'tcx>)> {
     if let ExprKind::Call(count_func, []) = expr.kind
         && let ExprKind::Path(ref count_func_qpath) = count_func.kind
         && let QPath::Resolved(_, count_func_path) = count_func_qpath
         && let Some(segment_zero) = count_func_path.segments.first()
         && let Some(args) = segment_zero.args
-        && let Some(GenericArg::Type(real_ty)) = args.args.first()
+        && let Some(real_ty_span) = args.args.first().map(GenericArg::span)
         && let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id()
         && cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id)
     {
@@ -107,7 +107,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<
             .node_args(count_func.hir_id)
             .types()
             .next()
-            .map(|resolved_ty| (*real_ty, resolved_ty))
+            .map(|resolved_ty| (real_ty_span, resolved_ty))
     } else {
         None
     }
diff --git a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
index aa59b047b16..04357cdd8f6 100644
--- a/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_div_ceil.rs
@@ -102,12 +102,48 @@ impl<'tcx> LateLintPass<'tcx> for ManualDivCeil {
             {
                 build_suggestion(cx, expr, add_lhs, div_rhs, &mut applicability);
             }
+
+            // (x + (Y - 1)) / Y
+            if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, div_rhs) {
+                build_suggestion(cx, expr, inner_lhs, div_rhs, &mut applicability);
+            }
+
+            // ((Y - 1) + x) / Y
+            if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, div_rhs) {
+                build_suggestion(cx, expr, inner_rhs, div_rhs, &mut applicability);
+            }
+
+            // (x - (-Y - 1)) / Y
+            if inner_op.node == BinOpKind::Sub
+                && let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = div_rhs.kind
+                && differ_by_one(abs_div_rhs, inner_rhs)
+            {
+                build_suggestion(cx, expr, inner_lhs, div_rhs, &mut applicability);
+            }
         }
     }
 
     extract_msrv_attr!(LateContext);
 }
 
+/// Checks if two expressions represent non-zero integer literals such that `small_expr + 1 ==
+/// large_expr`.
+fn differ_by_one(small_expr: &Expr<'_>, large_expr: &Expr<'_>) -> bool {
+    if let ExprKind::Lit(small) = small_expr.kind
+        && let ExprKind::Lit(large) = large_expr.kind
+        && let LitKind::Int(s, _) = small.node
+        && let LitKind::Int(l, _) = large.node
+    {
+        Some(l.get()) == s.get().checked_add(1)
+    } else if let ExprKind::Unary(UnOp::Neg, small_inner_expr) = small_expr.kind
+        && let ExprKind::Unary(UnOp::Neg, large_inner_expr) = large_expr.kind
+    {
+        differ_by_one(large_inner_expr, small_inner_expr)
+    } else {
+        false
+    }
+}
+
 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() {
@@ -145,13 +181,16 @@ fn build_suggestion(
             ExprKind::Lit(Spanned {
                 node: LitKind::Int(_, LitIntType::Unsuffixed),
                 ..
-            }) | ExprKind::Unary(UnOp::Neg, Expr {
-                kind: ExprKind::Lit(Spanned {
-                    node: LitKind::Int(_, LitIntType::Unsuffixed),
+            }) | ExprKind::Unary(
+                UnOp::Neg,
+                Expr {
+                    kind: ExprKind::Lit(Spanned {
+                        node: LitKind::Int(_, LitIntType::Unsuffixed),
+                        ..
+                    }),
                     ..
-                }),
-                ..
-            })
+                }
+            )
         ) {
         format!("_{}", cx.typeck_results().expr_ty(rhs))
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
index a1951b9da44..052e6502da9 100644
--- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
@@ -9,7 +9,6 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
 
@@ -142,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
             // 16 possible alignments of constants/operands. For now, let's use `partition`.
             && let mut exprs = [lhs_lhs, lhs_rhs, rhs_lhs, rhs_rhs]
             && exprs.iter_mut().partition_in_place(|i| path_to_local(i).is_some()) == 2
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && (
                 is_not_const(cx.tcx, cx.tcx.hir().enclosing_body_owner(expr.hir_id).into())
                     || self.msrv.meets(msrvs::CONST_FLOAT_CLASSIFY)
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 9860deba843..38106277a88 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
@@ -7,7 +7,7 @@ use clippy_utils::{higher, is_in_const_context, path_to_local, peel_ref_operator
 use rustc_ast::LitKind::{Byte, Char};
 use rustc_ast::ast::RangeLimits;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Node, Param, PatKind, RangeEnd, PatExpr, PatExprKind, Lit};
+use rustc_hir::{Expr, ExprKind, Lit, Node, Param, PatExpr, PatExprKind, PatKind, RangeEnd};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
@@ -202,8 +202,14 @@ fn check_expr_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange {
 }
 
 fn check_range(start: &PatExpr<'_>, end: &PatExpr<'_>) -> CharRange {
-    if let PatExprKind::Lit{ lit: start_lit, negated: false } = &start.kind
-        && let PatExprKind::Lit{ lit: end_lit, negated: false  } = &end.kind
+    if let PatExprKind::Lit {
+        lit: start_lit,
+        negated: false,
+    } = &start.kind
+        && let PatExprKind::Lit {
+            lit: end_lit,
+            negated: false,
+        } = &end.kind
     {
         check_lit_range(start_lit, end_lit)
     } else {
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 a70955a7c78..3643b8c4425 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -7,9 +7,8 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{is_lint_allowed, is_never_expr, msrvs, pat_and_expr_can_be_question_mark, peel_blocks};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind};
+use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 
 use rustc_span::Span;
 use rustc_span::symbol::{Symbol, sym};
@@ -55,7 +54,7 @@ impl<'tcx> QuestionMark {
             && init.span.eq_ctxt(stmt.span)
             && let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init)
             && self.msrv.meets(msrvs::LET_ELSE)
-            && !in_external_macro(cx.sess(), stmt.span)
+            && !stmt.span.in_external_macro(cx.sess().source_map())
         {
             match if_let_or_match {
                 IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else, ..) => {
@@ -106,7 +105,7 @@ impl<'tcx> QuestionMark {
                     emit_manual_let_else(cx, stmt.span, match_expr, &ident_map, pat_arm.pat, diverging_arm.body);
                 },
             }
-        };
+        }
     }
 }
 
@@ -292,10 +291,15 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: boo
         // Only do the check if the type is "spelled out" in the pattern
         if !matches!(
             pat.kind,
-            PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..)
+            PatKind::Struct(..)
+                | PatKind::TupleStruct(..)
+                | PatKind::Expr(PatExpr {
+                    kind: PatExprKind::Path(..),
+                    ..
+                },)
         ) {
             return;
-        };
+        }
         let ty = typeck_results.pat_ty(pat);
         // Option and Result are allowed, everything else isn't.
         if !(is_type_diagnostic_item(cx, ty, sym::Option) || is_type_diagnostic_item(cx, ty, sym::Result)) {
diff --git a/src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs b/src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs
new file mode 100644
index 00000000000..5c40c945c69
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_option_as_slice.rs
@@ -0,0 +1,225 @@
+use clippy_config::Conf;
+use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::{is_none_arm, msrvs, peel_hir_expr_refs};
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{Arm, Expr, ExprKind, LangItem, Pat, PatKind, QPath, is_range_literal};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
+use rustc_session::impl_lint_pass;
+use rustc_span::{Span, Symbol, sym};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// This detects various manual reimplementations of `Option::as_slice`.
+    ///
+    /// ### Why is this bad?
+    /// Those implementations are both more complex than calling `as_slice`
+    /// and unlike that incur a branch, pessimizing performance and leading
+    /// to more generated code.
+    ///
+    /// ### Example
+    /// ```no_run
+    ///# let opt = Some(1);
+    /// _ = opt.as_ref().map_or(&[][..], std::slice::from_ref);
+    /// _ = match opt.as_ref() {
+    ///     Some(f) => std::slice::from_ref(f),
+    ///     None => &[],
+    /// };
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    ///# let opt = Some(1);
+    /// _ = opt.as_slice();
+    /// _ = opt.as_slice();
+    /// ```
+    #[clippy::version = "1.85.0"]
+    pub MANUAL_OPTION_AS_SLICE,
+    complexity,
+    "manual `Option::as_slice`"
+}
+
+pub struct ManualOptionAsSlice {
+    msrv: msrvs::Msrv,
+}
+
+impl ManualOptionAsSlice {
+    pub fn new(conf: &Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+        }
+    }
+}
+
+impl_lint_pass!(ManualOptionAsSlice => [MANUAL_OPTION_AS_SLICE]);
+
+impl LateLintPass<'_> for ManualOptionAsSlice {
+    extract_msrv_attr!(LateContext);
+
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        let span = expr.span;
+        if span.from_expansion()
+            || !self.msrv.meets(if clippy_utils::is_in_const_context(cx) {
+                msrvs::CONST_OPTION_AS_SLICE
+            } else {
+                msrvs::OPTION_AS_SLICE
+            })
+        {
+            return;
+        }
+        match expr.kind {
+            ExprKind::Match(scrutinee, [arm1, arm2], _) => {
+                if is_none_arm(cx, arm2) && check_arms(cx, arm2, arm1)
+                    || is_none_arm(cx, arm1) && check_arms(cx, arm1, arm2)
+                {
+                    check_as_ref(cx, scrutinee, span);
+                }
+            },
+            ExprKind::If(cond, then, Some(other)) => {
+                if let ExprKind::Let(let_expr) = cond.kind
+                    && let Some(binding) = extract_ident_from_some_pat(cx, let_expr.pat)
+                    && check_some_body(cx, binding, then)
+                    && is_empty_slice(cx, other.peel_blocks())
+                {
+                    check_as_ref(cx, let_expr.init, span);
+                }
+            },
+            ExprKind::MethodCall(seg, callee, [], _) => {
+                if seg.ident.name.as_str() == "unwrap_or_default" {
+                    check_map(cx, callee, span);
+                }
+            },
+            ExprKind::MethodCall(seg, callee, [or], _) => match seg.ident.name.as_str() {
+                "unwrap_or" => {
+                    if is_empty_slice(cx, or) {
+                        check_map(cx, callee, span);
+                    }
+                },
+                "unwrap_or_else" => {
+                    if returns_empty_slice(cx, or) {
+                        check_map(cx, callee, span);
+                    }
+                },
+                _ => {},
+            },
+            ExprKind::MethodCall(seg, callee, [or_else, map], _) => match seg.ident.name.as_str() {
+                "map_or" => {
+                    if is_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) {
+                        check_as_ref(cx, callee, span);
+                    }
+                },
+                "map_or_else" => {
+                    if returns_empty_slice(cx, or_else) && is_slice_from_ref(cx, map) {
+                        check_as_ref(cx, callee, span);
+                    }
+                },
+                _ => {},
+            },
+            _ => {},
+        }
+    }
+}
+
+fn check_map(cx: &LateContext<'_>, map: &Expr<'_>, span: Span) {
+    if let ExprKind::MethodCall(seg, callee, [mapping], _) = map.kind
+        && seg.ident.name == sym::map
+        && is_slice_from_ref(cx, mapping)
+    {
+        check_as_ref(cx, callee, span);
+    }
+}
+
+fn check_as_ref(cx: &LateContext<'_>, expr: &Expr<'_>, span: Span) {
+    if let ExprKind::MethodCall(seg, callee, [], _) = expr.kind
+        && seg.ident.name == sym::as_ref
+        && let ty::Adt(adtdef, ..) = cx.typeck_results().expr_ty(callee).kind()
+        && cx.tcx.is_diagnostic_item(sym::Option, adtdef.did())
+    {
+        if let Some(snippet) = clippy_utils::source::snippet_opt(cx, callee.span) {
+            span_lint_and_sugg(
+                cx,
+                MANUAL_OPTION_AS_SLICE,
+                span,
+                "use `Option::as_slice`",
+                "use",
+                format!("{snippet}.as_slice()"),
+                Applicability::MachineApplicable,
+            );
+        } else {
+            span_lint(cx, MANUAL_OPTION_AS_SLICE, span, "use `Option_as_slice`");
+        }
+    }
+}
+
+fn extract_ident_from_some_pat(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<Symbol> {
+    if let PatKind::TupleStruct(QPath::Resolved(None, path), [binding], _) = pat.kind
+        && let Res::Def(DefKind::Ctor(..), def_id) = path.res
+        && let PatKind::Binding(_mode, _hir_id, ident, _inner_pat) = binding.kind
+        && clippy_utils::is_lang_item_or_ctor(cx, def_id, LangItem::OptionSome)
+    {
+        Some(ident.name)
+    } else {
+        None
+    }
+}
+
+/// Returns true if `expr` is `std::slice::from_ref(<name>)`. Used in `if let`s.
+fn check_some_body(cx: &LateContext<'_>, name: Symbol, expr: &Expr<'_>) -> bool {
+    if let ExprKind::Call(slice_from_ref, [arg]) = expr.peel_blocks().kind
+        && is_slice_from_ref(cx, slice_from_ref)
+        && let ExprKind::Path(QPath::Resolved(None, path)) = arg.kind
+        && let [seg] = path.segments
+    {
+        seg.ident.name == name
+    } else {
+        false
+    }
+}
+
+fn check_arms(cx: &LateContext<'_>, none_arm: &Arm<'_>, some_arm: &Arm<'_>) -> bool {
+    if none_arm.guard.is_none()
+        && some_arm.guard.is_none()
+        && is_empty_slice(cx, none_arm.body)
+        && let Some(name) = extract_ident_from_some_pat(cx, some_arm.pat)
+    {
+        check_some_body(cx, name, some_arm.body)
+    } else {
+        false
+    }
+}
+
+fn returns_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    match expr.kind {
+        ExprKind::Path(_) => clippy_utils::is_path_diagnostic_item(cx, expr, sym::default_fn),
+        ExprKind::Closure(cl) => is_empty_slice(cx, cx.tcx.hir().body(cl.body).value),
+        _ => false,
+    }
+}
+
+/// Returns if expr returns an empty slice. If:
+/// - An indexing operation to an empty array with a built-in range. `[][..]`
+/// - An indexing operation with a zero-ended range. `expr[..0]`
+/// - A reference to an empty array. `&[]`
+/// - Or a call to `Default::default`.
+fn is_empty_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    let expr = peel_hir_expr_refs(expr.peel_blocks()).0;
+    match expr.kind {
+        ExprKind::Index(arr, range, _) => match arr.kind {
+            ExprKind::Array([]) => is_range_literal(range),
+            ExprKind::Array(_) => {
+                let Some(range) = clippy_utils::higher::Range::hir(range) else {
+                    return false;
+                };
+                range.end.is_some_and(|e| clippy_utils::is_integer_const(cx, e, 0))
+            },
+            _ => false,
+        },
+        ExprKind::Array([]) => true,
+        ExprKind::Call(def, []) => clippy_utils::is_path_diagnostic_item(cx, def, sym::default_fn),
+        _ => false,
+    }
+}
+
+fn is_slice_from_ref(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    clippy_utils::is_expr_path_def_path(cx, expr, &["core", "slice", "raw", "from_ref"])
+}
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 2e5a92915d9..bf4f2bff319 100644
--- a/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_range_patterns.rs
@@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::{PatExpr, PatExprKind, PatKind, RangeEnd};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::{DUMMY_SP, Span};
 
@@ -80,7 +79,7 @@ impl LateLintPass<'_> for ManualRangePatterns {
         // like described https://github.com/rust-lang/rust-clippy/issues/11825)
         if let PatKind::Or(pats) = pat.kind
             && (pats.len() >= 3 || (pats.len() > 1 && pats.iter().any(|p| matches!(p.kind, PatKind::Range(..)))))
-            && !in_external_macro(cx.sess(), pat.span)
+            && !pat.span.in_external_macro(cx.sess().source_map())
         {
             let mut min = Num::dummy(i128::MAX);
             let mut max = Num::dummy(i128::MIN);
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 5e58054a986..469b4b7cf89 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -7,7 +7,6 @@ use clippy_utils::{is_in_const_context, path_to_local};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -60,7 +59,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
             && rem_rhs.span.ctxt() == ctxt
             && add_lhs.span.ctxt() == ctxt
             && add_rhs.span.ctxt() == ctxt
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && self.msrv.meets(msrvs::REM_EUCLID)
             && (self.msrv.meets(msrvs::REM_EUCLID_CONST) || !is_in_const_context(cx))
             && let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs)
@@ -80,12 +79,12 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
                 Node::Param(..) => (),
                 Node::LetStmt(local) => {
                     let Some(ty) = local.ty else { return };
-                    if matches!(ty.kind, TyKind::Infer) {
+                    if matches!(ty.kind, TyKind::Infer(())) {
                         return;
                     }
                 },
                 _ => return,
-            };
+            }
 
             let mut app = Applicability::MachineApplicable;
             let rem_of = snippet_with_context(cx, rem2_lhs.span, ctxt, "_", &mut app).0;
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 79de41db343..d69384a2cb7 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -86,7 +86,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
             let target_res = cx.qpath_res(target_path, target_arg.hir_id);
             if target_res == Res::Err {
                 return;
-            };
+            }
 
             if let Res::Local(hir_id) = target_res
                 && let Some(used_mutably) = mutated_variables(then, cx)
diff --git a/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs b/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs
index 8f8390b6f3f..87d2faa225c 100644
--- a/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs
@@ -1,6 +1,6 @@
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::{Arm, Expr, ExprKind, HirId, LangItem, MatchSource, Pat, PatKind, QPath};
+use rustc_hir::{Arm, Expr, ExprKind, HirId, LangItem, MatchSource, Pat, PatExpr, PatExprKind, PatKind, QPath};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::GenericArgKind;
 use rustc_session::declare_lint_pass;
@@ -9,8 +9,8 @@ use rustc_span::sym;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::higher::IfLetOrMatch;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::implements_trait;
-use clippy_utils::{is_default_equivalent, is_in_const_context, peel_blocks, span_contains_comment};
+use clippy_utils::ty::{expr_type_is_certain, implements_trait};
+use clippy_utils::{is_default_equivalent, is_in_const_context, path_res, peel_blocks, span_contains_comment};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -68,7 +68,7 @@ fn get_some<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'tcx>) -> Option<HirId> {
 }
 
 fn get_none<'tcx>(cx: &LateContext<'tcx>, arm: &Arm<'tcx>) -> Option<&'tcx Expr<'tcx>> {
-    if let PatKind::Path(QPath::Resolved(_, path)) = arm.pat.kind
+    if let PatKind::Expr(PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. }) = arm.pat.kind
         && let Some(def_id) = path.res.opt_def_id()
         // Since it comes from a pattern binding, we need to get the parent to actually match
         // against it.
@@ -158,6 +158,36 @@ fn handle<'tcx>(cx: &LateContext<'tcx>, if_let_or_match: IfLetOrMatch<'tcx>, exp
         } else {
             Applicability::MachineApplicable
         };
+
+        // We now check if the condition is a None variant, in which case we need to specify the type
+        if path_res(cx, condition)
+            .opt_def_id()
+            .is_some_and(|id| Some(cx.tcx.parent(id)) == cx.tcx.lang_items().option_none_variant())
+        {
+            return span_lint_and_sugg(
+                cx,
+                MANUAL_UNWRAP_OR_DEFAULT,
+                expr.span,
+                format!("{expr_name} can be simplified with `.unwrap_or_default()`"),
+                "replace it with",
+                format!("{receiver}::<{expr_type}>.unwrap_or_default()"),
+                applicability,
+            );
+        }
+
+        // We check if the expression type is still uncertain, in which case we ask the user to specify it
+        if !expr_type_is_certain(cx, condition) {
+            return span_lint_and_sugg(
+                cx,
+                MANUAL_UNWRAP_OR_DEFAULT,
+                expr.span,
+                format!("{expr_name} can be simplified with `.unwrap_or_default()`"),
+                format!("ascribe the type {expr_type} and replace your expression with"),
+                format!("{receiver}.unwrap_or_default()"),
+                Applicability::Unspecified,
+            );
+        }
+
         span_lint_and_sugg(
             cx,
             MANUAL_UNWRAP_OR_DEFAULT,
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 99a7b8c74be..97e8423695d 100644
--- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
@@ -8,7 +8,7 @@ use clippy_utils::{
 };
 use rustc_errors::MultiSpan;
 use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, Expr, HirId, Pat, PatKind};
+use rustc_hir::{Arm, Expr, HirId, Pat, PatExpr, PatExprKind, PatKind};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
@@ -119,7 +119,11 @@ fn arm_is_wild_like(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
     }
     match arm.pat.kind {
         PatKind::Binding(..) | PatKind::Wild => true,
-        PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone),
+        PatKind::Expr(PatExpr {
+            kind: PatExprKind::Path(qpath),
+            hir_id,
+            ..
+        }) => is_res_lang_ctor(cx, cx.qpath_res(qpath, *hir_id), OptionNone),
         _ => false,
     }
 }
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 cfa054706d6..4cc43e427ec 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_filter.rs
@@ -34,7 +34,7 @@ fn get_cond_expr<'tcx>(
             needs_negated: is_none_expr(cx, then_expr), /* if the `then_expr` resolves to `None`, need to negate the
                                                          * cond */
         });
-    };
+    }
     None
 }
 
@@ -45,7 +45,7 @@ fn peels_blocks_incl_unsafe_opt<'a>(expr: &'a Expr<'a>) -> Option<&'a Expr<'a>>
         if block.stmts.is_empty() {
             return block.expr;
         }
-    };
+    }
     None
 }
 
@@ -68,14 +68,14 @@ fn is_some_expr(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr:
                 && is_res_lang_ctor(cx, path_res(cx, callee), OptionSome)
                 && path_to_local_id(arg, target);
         }
-    };
+    }
     false
 }
 
 fn is_none_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     if let Some(inner_expr) = peels_blocks_incl_unsafe_opt(expr) {
         return is_res_lang_ctor(cx, path_res(cx, inner_expr), OptionNone);
-    };
+    }
     false
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs b/src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs
new file mode 100644
index 00000000000..3deaaf96c1e
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_ok_err.rs
@@ -0,0 +1,144 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::ty::option_arg_ty;
+use clippy_utils::{is_res_lang_ctor, path_res, peel_blocks, span_contains_comment};
+use rustc_ast::BindingMode;
+use rustc_errors::Applicability;
+use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr};
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{Arm, Expr, ExprKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath};
+use rustc_lint::{LateContext, LintContext};
+use rustc_middle::ty::Ty;
+use rustc_span::symbol::Ident;
+
+use super::MANUAL_OK_ERR;
+
+pub(crate) fn check_if_let(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    let_pat: &Pat<'_>,
+    let_expr: &Expr<'_>,
+    if_then: &Expr<'_>,
+    else_expr: &Expr<'_>,
+) {
+    if let Some(inner_expr_ty) = option_arg_ty(cx, cx.typeck_results().expr_ty(expr))
+        && let Some((is_ok, ident)) = is_ok_or_err(cx, let_pat)
+        && is_some_ident(cx, if_then, ident, inner_expr_ty)
+        && is_none(cx, else_expr)
+    {
+        apply_lint(cx, expr, let_expr, is_ok);
+    }
+}
+
+pub(crate) fn check_match(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>]) {
+    if let Some(inner_expr_ty) = option_arg_ty(cx, cx.typeck_results().expr_ty(expr))
+        && arms.len() == 2
+        && arms.iter().all(|arm| arm.guard.is_none())
+        && let Some((idx, is_ok)) = arms.iter().enumerate().find_map(|(arm_idx, arm)| {
+            // Check if the arm is a `Ok(x) => x` or `Err(x) => x` alternative.
+            // In this case, return its index and whether it uses `Ok` or `Err`.
+             if let Some((is_ok, ident)) = is_ok_or_err(cx, arm.pat)
+                && is_some_ident(cx, arm.body, ident, inner_expr_ty)
+            {
+                Some((arm_idx, is_ok))
+            } else {
+                None
+            }
+        })
+        // Accept wildcard only as the second arm
+        && is_variant_or_wildcard(cx, arms[1-idx].pat, idx == 0, is_ok)
+        // Check that the body of the non `Ok`/`Err` arm is `None`
+        && is_none(cx, arms[1 - idx].body)
+    {
+        apply_lint(cx, expr, scrutinee, is_ok);
+    }
+}
+
+/// Check that `pat` applied to a `Result` only matches `Ok(_)`, `Err(_)`, not a subset or a
+/// superset of it. If `can_be_wild` is `true`, wildcards are also accepted. In the case of
+/// a non-wildcard, `must_match_err` indicates whether the `Err` or the `Ok` variant should be
+/// accepted.
+fn is_variant_or_wildcard(cx: &LateContext<'_>, pat: &Pat<'_>, can_be_wild: bool, must_match_err: bool) -> bool {
+    match pat.kind {
+        PatKind::Wild
+        | PatKind::Expr(PatExpr {
+            kind: PatExprKind::Path(_),
+            ..
+        })
+        | PatKind::Binding(_, _, _, None)
+            if can_be_wild =>
+        {
+            true
+        },
+        PatKind::TupleStruct(qpath, ..) => {
+            is_res_lang_ctor(cx, cx.qpath_res(&qpath, pat.hir_id), ResultErr) == must_match_err
+        },
+        PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) => {
+            is_variant_or_wildcard(cx, pat, can_be_wild, must_match_err)
+        },
+        _ => false,
+    }
+}
+
+/// Return `Some((true, IDENT))` if `pat` contains `Ok(IDENT)`, `Some((false, IDENT))` if it
+/// contains `Err(IDENT)`, `None` otherwise.
+fn is_ok_or_err<'hir>(cx: &LateContext<'_>, pat: &Pat<'hir>) -> Option<(bool, &'hir Ident)> {
+    if let PatKind::TupleStruct(qpath, [arg], _) = &pat.kind
+        && let PatKind::Binding(BindingMode::NONE, _, ident, _) = &arg.kind
+        && let res = cx.qpath_res(qpath, pat.hir_id)
+        && let Res::Def(DefKind::Ctor(..), id) = res
+        && let id @ Some(_) = cx.tcx.opt_parent(id)
+    {
+        let lang_items = cx.tcx.lang_items();
+        if id == lang_items.result_ok_variant() {
+            return Some((true, ident));
+        } else if id == lang_items.result_err_variant() {
+            return Some((false, ident));
+        }
+    }
+    None
+}
+
+/// Check if `expr` contains `Some(ident)`, possibly as a block
+fn is_some_ident<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, ident: &Ident, ty: Ty<'tcx>) -> bool {
+    if let ExprKind::Call(body_callee, [body_arg]) = peel_blocks(expr).kind
+        && is_res_lang_ctor(cx, path_res(cx, body_callee), OptionSome)
+        && cx.typeck_results().expr_ty(body_arg) == ty
+        && let ExprKind::Path(QPath::Resolved(
+            _,
+            Path {
+                segments: [segment], ..
+            },
+        )) = body_arg.kind
+    {
+        segment.ident.name == ident.name
+    } else {
+        false
+    }
+}
+
+/// Check if `expr` is `None`, possibly as a block
+fn is_none(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    is_res_lang_ctor(cx, path_res(cx, peel_blocks(expr)), OptionNone)
+}
+
+/// Suggest replacing `expr` by `scrutinee.METHOD()`, where `METHOD` is either `ok` or
+/// `err`, depending on `is_ok`.
+fn apply_lint(cx: &LateContext<'_>, expr: &Expr<'_>, scrutinee: &Expr<'_>, is_ok: bool) {
+    let method = if is_ok { "ok" } else { "err" };
+    let mut app = if span_contains_comment(cx.sess().source_map(), expr.span) {
+        Applicability::MaybeIncorrect
+    } else {
+        Applicability::MachineApplicable
+    };
+    let scrut = Sugg::hir_with_applicability(cx, scrutinee, "..", &mut app).maybe_par();
+    span_lint_and_sugg(
+        cx,
+        MANUAL_OK_ERR,
+        expr.span,
+        format!("manual implementation of `{method}`"),
+        "replace with",
+        format!("{scrut}.{method}()"),
+        app,
+    );
+}
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 59d37520011..b69294d567d 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
@@ -7,7 +7,7 @@ use clippy_utils::{is_res_lang_ctor, path_to_local_id, peel_blocks, sugg};
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, ResultErr};
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::{Arm, Expr, Pat, PatKind};
+use rustc_hir::{Arm, Expr, Pat, PatExpr, PatExprKind, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::Ty;
 use rustc_span::sym;
@@ -89,7 +89,11 @@ fn applicable_or_arm<'a>(cx: &LateContext<'_>, arms: &'a [Arm<'a>]) -> Option<(&
     if arms.len() == 2
         && arms.iter().all(|arm| arm.guard.is_none())
         && let Some((idx, or_arm)) = arms.iter().enumerate().find(|(_, arm)| match arm.pat.kind {
-            PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone),
+            PatKind::Expr(PatExpr {
+                hir_id,
+                kind: PatExprKind::Path(qpath),
+                ..
+            }) => is_res_lang_ctor(cx, cx.qpath_res(qpath, *hir_id), OptionNone),
             PatKind::TupleStruct(ref qpath, [pat], _) => {
                 matches!(pat.kind, PatKind::Wild)
                     && is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), ResultErr)
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 bac5cf88cfb..2ad55d9bf1f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_utils.rs
@@ -11,7 +11,7 @@ use rustc_ast::util::parser::ExprPrecedence;
 use rustc_errors::Applicability;
 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_hir::{BindingMode, Expr, ExprKind, HirId, Mutability, Pat, PatExpr, PatExprKind, PatKind, Path, QPath};
 use rustc_lint::LateContext;
 use rustc_span::{SyntaxContext, sym};
 
@@ -109,7 +109,7 @@ where
             }
         },
         None => return None,
-    };
+    }
 
     let mut app = Applicability::MachineApplicable;
 
@@ -256,9 +256,11 @@ pub(super) fn try_parse_pattern<'tcx>(
         match pat.kind {
             PatKind::Wild => Some(OptionPat::Wild),
             PatKind::Ref(pat, _) => f(cx, pat, ref_count + 1, ctxt),
-            PatKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, pat.hir_id), OptionNone) => {
-                Some(OptionPat::None)
-            },
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(qpath),
+                hir_id,
+                ..
+            }) if is_res_lang_ctor(cx, cx.qpath_res(qpath, *hir_id), OptionNone) => Some(OptionPat::None),
             PatKind::TupleStruct(ref qpath, [pattern], _)
                 if is_res_lang_ctor(cx, cx.qpath_res(qpath, pat.hir_id), OptionSome) && pat.span.ctxt() == ctxt =>
             {
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
index 6c123649afc..1cb4b512a30 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_res_lang_ctor, path_res, peel_blocks};
+use clippy_utils::{is_none_arm, is_res_lang_ctor, path_res, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, LangItem, Mutability, PatKind, QPath};
 use rustc_lint::LateContext;
@@ -55,14 +55,6 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
     }
 }
 
-// Checks if arm has the form `None => None`
-fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
-    matches!(
-        arm.pat.kind,
-        PatKind::Path(ref qpath) if is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionNone)
-    )
-}
-
 // Checks if arm has the form `Some(ref v) => Some(v)` (checks for `ref` and `ref mut`)
 fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {
     if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_bool.rs b/src/tools/clippy/clippy_lints/src/matches/match_bool.rs
index 7e43d222a66..b90cf6357c5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_bool.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_unit_expr;
-use clippy_utils::source::{expr_block, snippet};
+use clippy_utils::source::expr_block;
 use clippy_utils::sugg::Sugg;
 use rustc_ast::LitKind;
 use rustc_errors::Applicability;
@@ -17,17 +17,28 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>]
             cx,
             MATCH_BOOL,
             expr.span,
-            "you seem to be trying to match on a boolean expression",
+            "`match` on a boolean expression",
             move |diag| {
                 if arms.len() == 2 {
-                    // no guards
-                    let exprs = if let PatKind::Expr(arm_bool) = arms[0].pat.kind {
+                    let mut app = Applicability::MachineApplicable;
+                    let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind {
+                        let test = Sugg::hir_with_applicability(cx, scrutinee, "_", &mut app);
                         if let PatExprKind::Lit { lit, .. } = arm_bool.kind {
-                            match lit.node {
-                                LitKind::Bool(true) => Some((arms[0].body, arms[1].body)),
-                                LitKind::Bool(false) => Some((arms[1].body, arms[0].body)),
+                            match &lit.node {
+                                LitKind::Bool(true) => Some(test),
+                                LitKind::Bool(false) => Some(!test),
                                 _ => None,
                             }
+                            .map(|test| {
+                                if let Some(guard) = &arms[0]
+                                    .guard
+                                    .map(|g| Sugg::hir_with_applicability(cx, g, "_", &mut app))
+                                {
+                                    test.and(guard)
+                                } else {
+                                    test
+                                }
+                            })
                         } else {
                             None
                         }
@@ -35,39 +46,31 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>]
                         None
                     };
 
-                    if let Some((true_expr, false_expr)) = exprs {
-                        let mut app = Applicability::HasPlaceholders;
+                    if let Some(test_sugg) = test_sugg {
                         let ctxt = expr.span.ctxt();
+                        let (true_expr, false_expr) = (arms[0].body, arms[1].body);
                         let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
                             (false, false) => Some(format!(
                                 "if {} {} else {}",
-                                snippet(cx, scrutinee.span, "b"),
+                                test_sugg,
                                 expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app),
                                 expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app)
                             )),
                             (false, true) => Some(format!(
                                 "if {} {}",
-                                snippet(cx, scrutinee.span, "b"),
+                                test_sugg,
                                 expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app)
                             )),
-                            (true, false) => {
-                                let test = Sugg::hir(cx, scrutinee, "..");
-                                Some(format!(
-                                    "if {} {}",
-                                    !test,
-                                    expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app)
-                                ))
-                            },
+                            (true, false) => Some(format!(
+                                "if {} {}",
+                                !test_sugg,
+                                expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app)
+                            )),
                             (true, true) => None,
                         };
 
                         if let Some(sugg) = sugg {
-                            diag.span_suggestion(
-                                expr.span,
-                                "consider using an `if`/`else` expression",
-                                sugg,
-                                Applicability::HasPlaceholders,
-                            );
+                            diag.span_suggestion(expr.span, "consider using an `if`/`else` expression", sugg, app);
                         }
                     }
                 }
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
index 223d0dc7656..d697f427c70 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
@@ -117,7 +117,7 @@ where
             if let ty::Ref(..) = cx.typeck_results().expr_ty(ex_inner).kind() {
                 ex_new = ex_inner;
             }
-        };
+        }
         span_lint_and_sugg(
             cx,
             MATCH_LIKE_MATCHES_MACRO,
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 28e05c273d5..41e4c75f843 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
@@ -7,7 +7,7 @@ use rustc_arena::DroplessArena;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{Arm, Expr, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatExprKind, PatKind, RangeEnd};
+use rustc_hir::{Arm, Expr, HirId, HirIdMap, HirIdMapEntry, HirIdSet, Pat, PatExpr, PatExprKind, PatKind, RangeEnd};
 use rustc_lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty;
@@ -292,7 +292,11 @@ impl<'a> NormalizedPat<'a> {
                 Self::Tuple(var_id, pats)
             },
             PatKind::Or(pats) => Self::Or(arena.alloc_from_iter(pats.iter().map(|pat| Self::from_pat(cx, arena, pat)))),
-            PatKind::Path(ref path) => Self::Path(cx.qpath_res(path, pat.hir_id).opt_def_id()),
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(path),
+                hir_id,
+                ..
+            }) => Self::Path(cx.qpath_res(path, *hir_id).opt_def_id()),
             PatKind::Tuple(pats, wild_idx) => {
                 let field_count = match cx.typeck_results().pat_ty(pat).kind() {
                     ty::Tuple(subs) => subs.len(),
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 9f5b7c855a1..df1b83cbb51 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
@@ -5,7 +5,7 @@ use clippy_utils::ty::is_type_lang_item;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_expr};
-use rustc_hir::{Arm, Expr, ExprKind, PatExpr, PatExprKind, LangItem, PatKind};
+use rustc_hir::{Arm, Expr, ExprKind, LangItem, PatExpr, PatExprKind, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_span::Span;
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
index 91e40e4275c..11b588b3355 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs
@@ -3,7 +3,7 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{is_refutable, peel_hir_pat_refs, recurse_or_patterns};
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::{Arm, Expr, PatKind, PathSegment, QPath, Ty, TyKind};
+use rustc_hir::{Arm, Expr, PatExpr, PatExprKind, PatKind, PathSegment, QPath, Ty, TyKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, VariantDef};
 use rustc_span::sym;
@@ -60,8 +60,13 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
         // covered by the set of guards that cover it, but that's really hard to do.
         recurse_or_patterns(arm.pat, |pat| {
             let path = match &peel_hir_pat_refs(pat).0.kind {
-                PatKind::Path(path) => {
-                    let id = match cx.qpath_res(path, pat.hir_id) {
+                PatKind::Expr(PatExpr {
+                    hir_id,
+                    kind: PatExprKind::Path(path),
+                    ..
+                }) => {
+                    // FIXME(clippy): don't you want to use the hir id of the peeled pat?
+                    let id = match cx.qpath_res(path, *hir_id) {
                         Res::Def(
                             DefKind::Const | DefKind::ConstParam | DefKind::AnonConst | DefKind::InlineConst,
                             _,
@@ -170,7 +175,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
                 );
             });
         },
-    };
+    }
 }
 
 enum CommonPrefixSearcher<'a> {
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index ac1eae07eff..9ca914af281 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -2,6 +2,7 @@ mod collapsible_match;
 mod infallible_destructuring_match;
 mod manual_filter;
 mod manual_map;
+mod manual_ok_err;
 mod manual_unwrap_or;
 mod manual_utils;
 mod match_as_ref;
@@ -32,7 +33,6 @@ use clippy_utils::{
 };
 use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{SpanData, SyntaxContext};
 
@@ -972,6 +972,40 @@ declare_clippy_lint! {
     "checks for unnecessary guards in match expressions"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for manual implementation of `.ok()` or `.err()`
+    /// on `Result` values.
+    ///
+    /// ### Why is this bad?
+    /// Using `.ok()` or `.err()` rather than a `match` or
+    /// `if let` is less complex and more readable.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// # fn func() -> Result<u32, &'static str> { Ok(0) }
+    /// let a = match func() {
+    ///     Ok(v) => Some(v),
+    ///     Err(_) => None,
+    /// };
+    /// let b = if let Err(v) = func() {
+    ///     Some(v)
+    /// } else {
+    ///     None
+    /// };
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// # fn func() -> Result<u32, &'static str> { Ok(0) }
+    /// let a = func().ok();
+    /// let b = func().err();
+    /// ```
+    #[clippy::version = "1.86.0"]
+    pub MANUAL_OK_ERR,
+    complexity,
+    "find manual implementations of `.ok()` or `.err()` on `Result`"
+}
+
 pub struct Matches {
     msrv: Msrv,
     infallible_destructuring_match_linted: bool,
@@ -1013,12 +1047,13 @@ impl_lint_pass!(Matches => [
     MANUAL_MAP,
     MANUAL_FILTER,
     REDUNDANT_GUARDS,
+    MANUAL_OK_ERR,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Matches {
     #[expect(clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if is_direct_expn_of(expr.span, "matches").is_none() && in_external_macro(cx.sess(), expr.span) {
+        if is_direct_expn_of(expr.span, "matches").is_none() && expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         let from_expansion = expr.span.from_expansion();
@@ -1091,6 +1126,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                         manual_unwrap_or::check_match(cx, expr, ex, arms);
                         manual_map::check_match(cx, expr, ex, arms);
                         manual_filter::check_match(cx, ex, arms, expr);
+                        manual_ok_err::check_match(cx, expr, ex, arms);
                     }
 
                     if self.infallible_destructuring_match_linted {
@@ -1134,6 +1170,14 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                             if_let.if_then,
                             else_expr,
                         );
+                        manual_ok_err::check_if_let(
+                            cx,
+                            expr,
+                            if_let.let_pat,
+                            if_let.let_expr,
+                            if_let.if_then,
+                            else_expr,
+                        );
                     }
                 }
                 redundant_pattern_match::check_if_let(
diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
index 0d5575efc22..7e65d586110 100644
--- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
@@ -8,7 +8,9 @@ use clippy_utils::{
 };
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, BindingMode, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatExprKind, PatKind, Path, QPath};
+use rustc_hir::{
+    Arm, BindingMode, ByRef, Expr, ExprKind, ItemKind, Node, Pat, PatExpr, PatExprKind, PatKind, Path, QPath,
+};
 use rustc_lint::LateContext;
 use rustc_span::sym;
 
@@ -183,7 +185,13 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
             return !matches!(annot, BindingMode(ByRef::Yes(_), _)) && pat_ident.name == first_seg.ident.name;
         },
         // Example: `Custom::TypeA => Custom::TypeB`, or `None => None`
-        (PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => {
+        (
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(QPath::Resolved(_, p_path)),
+                ..
+            }),
+            ExprKind::Path(QPath::Resolved(_, e_path)),
+        ) => {
             return over(p_path.segments, e_path.segments, |p_seg, e_seg| {
                 p_seg.ident.name == e_seg.ident.name
             });
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 4a5d3c516b8..4184f8b9e6e 100644
--- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
@@ -3,7 +3,6 @@ use clippy_utils::diagnostics::span_lint_and_note;
 use core::cmp::Ordering;
 use rustc_hir::{Arm, Expr, PatKind, RangeEnd};
 use rustc_lint::LateContext;
-use rustc_middle::mir;
 use rustc_middle::ty::Ty;
 use rustc_span::Span;
 
@@ -36,14 +35,12 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
                     let lhs_const = if let Some(lhs) = lhs {
                         ConstEvalCtxt::new(cx).eval_pat_expr(lhs)?
                     } else {
-                        let min_val_const = ty.numeric_min_val(cx.tcx)?;
-                        mir_to_const(cx.tcx, mir::Const::from_ty_const(min_val_const, ty, cx.tcx))?
+                        mir_to_const(cx.tcx, ty.numeric_min_val(cx.tcx)?)?
                     };
                     let rhs_const = if let Some(rhs) = rhs {
                         ConstEvalCtxt::new(cx).eval_pat_expr(rhs)?
                     } else {
-                        let max_val_const = ty.numeric_max_val(cx.tcx)?;
-                        mir_to_const(cx.tcx, mir::Const::from_ty_const(max_val_const, ty, cx.tcx))?
+                        mir_to_const(cx.tcx, ty.numeric_max_val(cx.tcx)?)?
                     };
                     let lhs_val = lhs_const.int_value(cx.tcx, ty)?;
                     let rhs_val = rhs_const.int_value(cx.tcx, ty)?;
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 edac97344a0..39339966013 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
@@ -9,7 +9,7 @@ use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 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, PatExprKind, PatKind, QPath, UnOp};
+use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatExpr, PatExprKind, PatKind, QPath, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
 use rustc_span::{Span, Symbol, sym};
@@ -149,8 +149,12 @@ fn find_method_and_type<'tcx>(
                 None
             }
         },
-        PatKind::Path(ref path) => {
-            if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(path, check_pat.hir_id)
+        PatKind::Expr(PatExpr {
+            kind: PatExprKind::Path(path),
+            hir_id,
+            ..
+        }) => {
+            if let Res::Def(DefKind::Ctor(..), ctor_id) = cx.qpath_res(path, *hir_id)
                 && let Some(variant_id) = cx.tcx.opt_parent(ctor_id)
             {
                 let method = if cx.tcx.lang_items().option_none_variant() == Some(variant_id) {
@@ -351,10 +355,20 @@ fn found_good_method<'tcx>(
                 None
             }
         },
-        (PatKind::TupleStruct(path_left, patterns, _), PatKind::Path(path_right))
-        | (PatKind::Path(path_left), PatKind::TupleStruct(path_right, patterns, _))
-            if patterns.len() == 1 =>
-        {
+        (
+            PatKind::TupleStruct(path_left, patterns, _),
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(path_right),
+                ..
+            }),
+        )
+        | (
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(path_left),
+                ..
+            }),
+            PatKind::TupleStruct(path_right, patterns, _),
+        ) if patterns.len() == 1 => {
             if let PatKind::Wild = patterns[0].kind {
                 find_good_method_for_match(
                     cx,
@@ -389,7 +403,13 @@ fn found_good_method<'tcx>(
                 None
             }
         },
-        (PatKind::Path(path_left), PatKind::Wild) => get_good_method(cx, arms, path_left),
+        (
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(path_left),
+                ..
+            }),
+            PatKind::Wild,
+        ) => get_good_method(cx, arms, path_left),
         _ => None,
     }
 }
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 2ce6a8a85a5..35f2e780d2e 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
@@ -2,7 +2,7 @@ use std::ops::ControlFlow;
 
 use crate::FxHashSet;
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::{indent_of, snippet};
+use clippy_utils::source::{first_line_of_span, indent_of, snippet};
 use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy};
 use clippy_utils::{get_attr, is_lint_allowed};
 use itertools::Itertools;
@@ -152,7 +152,7 @@ fn set_suggestion<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: &
     diag.multipart_suggestion(
         suggestion_message,
         vec![
-            (expr.span.shrink_to_lo(), replacement),
+            (first_line_of_span(cx, expr.span).shrink_to_lo(), replacement),
             (found.found_span, scrutinee_replacement),
         ],
         Applicability::MaybeIncorrect,
@@ -441,8 +441,9 @@ impl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> {
         let parent_expr_before = self.parent_expr.replace(ex);
 
         match ex.kind {
-            // Skip blocks because values in blocks will be dropped as usual.
-            ExprKind::Block(..) => (),
+            // Skip blocks because values in blocks will be dropped as usual, and await
+            // desugaring because temporary insides the future will have been dropped.
+            ExprKind::Block(..) | ExprKind::Match(_, _, MatchSource::AwaitDesugar) => (),
             _ => walk_expr(self, ex),
         }
 
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 38f876fed80..2f46eaaabb3 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -114,7 +114,7 @@ fn report_single_pattern(cx: &LateContext<'_>, ex: &Expr<'_>, arm: &Arm<'_>, exp
     }
 
     let (pat, pat_ref_count) = peel_hir_pat_refs(arm.pat);
-    let (msg, sugg) = if let PatKind::Path(_) | PatKind::Expr(_) = pat.kind
+    let (msg, sugg) = if let PatKind::Expr(_) = pat.kind
         && let (ty, ty_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(ex))
         && let Some(spe_trait_id) = cx.tcx.lang_items().structural_peq_trait()
         && let Some(pe_trait_id) = cx.tcx.lang_items().eq_trait()
@@ -331,14 +331,16 @@ impl<'a> PatState<'a> {
     #[expect(clippy::similar_names)]
     fn add_pat<'tcx>(&mut self, cx: &'a PatCtxt<'tcx>, pat: &'tcx Pat<'_>) -> bool {
         match pat.kind {
-            PatKind::Path(_)
-                if match *cx.typeck.pat_ty(pat).peel_refs().kind() {
-                    ty::Adt(adt, _) => adt.is_enum() || (adt.is_struct() && !adt.non_enum_variant().fields.is_empty()),
-                    ty::Tuple(tys) => !tys.is_empty(),
-                    ty::Array(_, len) => len.try_to_target_usize(cx.tcx) != Some(1),
-                    ty::Slice(..) => true,
-                    _ => false,
-                } =>
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(_),
+                ..
+            }) if match *cx.typeck.pat_ty(pat).peel_refs().kind() {
+                ty::Adt(adt, _) => adt.is_enum() || (adt.is_struct() && !adt.non_enum_variant().fields.is_empty()),
+                ty::Tuple(tys) => !tys.is_empty(),
+                ty::Array(_, len) => len.try_to_target_usize(cx.tcx) != Some(1),
+                ty::Slice(..) => true,
+                _ => false,
+            } =>
             {
                 matches!(self, Self::Wild)
             },
@@ -386,7 +388,6 @@ impl<'a> PatState<'a> {
             | PatKind::Binding(_, _, _, None)
             | PatKind::Expr(_)
             | PatKind::Range(..)
-            | PatKind::Path(_)
             | PatKind::Never
             | PatKind::Err(_) => {
                 *self = PatState::Wild;
diff --git a/src/tools/clippy/clippy_lints/src/matches/try_err.rs b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
index 6c02207af49..ff7769af1df 100644
--- a/src/tools/clippy/clippy_lints/src/matches/try_err.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/try_err.rs
@@ -46,7 +46,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, scrutine
             err_ty = ty;
         } else {
             return;
-        };
+        }
 
         span_lint_and_then(
             cx,
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 390ba889fd2..b75d1ab9a7a 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
@@ -13,7 +13,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arms: &[Arm<'_>]) {
         && 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 5597cd85abc..41528c5dee3 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -11,7 +11,6 @@ use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
 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::Span;
 use rustc_span::symbol::sym;
@@ -188,7 +187,7 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
     if is_non_aggregate_primitive_type(expr_type) {
         return;
     }
-    if is_default_equivalent(cx, src) && !in_external_macro(cx.tcx.sess, expr_span) {
+    if is_default_equivalent(cx, src) && !expr_span.in_external_macro(cx.tcx.sess.source_map()) {
         let Some(top_crate) = std_or_core(cx) else { return };
         span_lint_and_then(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytecount.rs b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs
index 4a2124c74a8..687272e550b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bytecount.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bytecount.rs
@@ -62,5 +62,5 @@ pub(super) fn check<'tcx>(
             ),
             applicability,
         );
-    };
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
index 34159f2d150..a9f6a41c235 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs
@@ -32,5 +32,5 @@ pub(super) fn check<'tcx>(
             ),
             applicability,
         );
-    };
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
index a82abc79f2a..de22514c37c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
@@ -46,5 +46,5 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
             format!("{receiver}.as_bytes().get({n}).copied()"),
             applicability,
         );
-    };
+    }
 }
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 2a0a9d3710d..223a960b800 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
@@ -32,7 +32,7 @@ pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span,
         // &T where T: Copy
         ty::Ref(_, ty, _) if is_copy(cx, *ty) => {},
         _ => return,
-    };
+    }
     span_lint_and_sugg(
         cx,
         CLONED_INSTEAD_OF_COPIED,
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 10360b4817b..cbf713a3b17 100644
--- a/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
@@ -1,8 +1,8 @@
 use crate::methods::DRAIN_COLLECT;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_range_full;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_lang_item;
+use clippy_utils::{is_range_full, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, LangItem, Path, QPath};
 use rustc_lint::LateContext;
@@ -58,12 +58,13 @@ pub(super) fn check(cx: &LateContext<'_>, args: &[Expr<'_>], expr: &Expr<'_>, re
             .then_some("Vec")
             .or_else(|| check_string(cx, args, expr_ty, recv_ty_no_refs, recv_path).then_some("String"))
             .or_else(|| check_collections(cx, expr_ty, recv_ty_no_refs))
+        && let Some(exec_context) = std_or_core(cx)
     {
         let recv = snippet(cx, recv.span, "<expr>");
         let sugg = if let ty::Ref(..) = recv_ty.kind() {
-            format!("std::mem::take({recv})")
+            format!("{exec_context}::mem::take({recv})")
         } else {
-            format!("std::mem::take(&mut {recv})")
+            format!("{exec_context}::mem::take(&mut {recv})")
         };
 
         span_lint_and_sugg(
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 44b55570eea..f2786efa44c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs
@@ -37,7 +37,7 @@ pub(super) fn check(
             "expect_err".to_string(),
             Applicability::MachineApplicable,
         );
-    };
+    }
 }
 
 /// Given a `Result<T, E>` type, return its data (`T`).
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 6dc48c26ba9..daa6e0e7f94 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
@@ -58,7 +58,7 @@ pub(super) fn check<'tcx>(
             if ty.is_str() && can_be_static_str(cx, arg) {
                 return false;
             }
-        };
+        }
         true
     }
 
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 129e6925428..d550c145466 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
@@ -6,13 +6,12 @@ use clippy_utils::{is_from_proc_macro, is_trait_method, peel_blocks};
 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::Binder;
 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)
+    if !expr.span.in_external_macro(cx.sess().source_map())
         && is_trait_method(cx, expr, sym::Iterator)
         && let ExprKind::Closure(closure) = arg.kind
         && let body = cx.tcx.hir().body(closure.body)
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
index a0c21faaa4c..92c81b3c49d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
@@ -4,7 +4,6 @@ use clippy_utils::macros::{is_assert_macro, root_macro_call};
 use clippy_utils::{find_binding_init, get_parent_expr, is_inside_always_const_context, path_to_local};
 use rustc_hir::{Expr, HirId};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_span::sym;
 
 use super::CONST_IS_EMPTY;
@@ -12,7 +11,7 @@ use super::CONST_IS_EMPTY;
 /// Expression whose initialization depend on a constant conditioned by a `#[cfg(…)]` directive will
 /// not trigger the lint.
 pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_>) {
-    if in_external_macro(cx.sess(), expr.span) || !receiver.span.eq_ctxt(expr.span) {
+    if expr.span.in_external_macro(cx.sess().source_map()) || !receiver.span.eq_ctxt(expr.span) {
         return;
     }
     if let Some(parent) = get_parent_expr(cx, expr) {
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 16305871337..aa45969c898 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
@@ -25,5 +25,5 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span
             "into_iter()".to_string(),
             Applicability::MaybeIncorrect,
         );
-    };
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_repeat_n.rs b/src/tools/clippy/clippy_lints/src/methods/manual_repeat_n.rs
new file mode 100644
index 00000000000..6e09bf132aa
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_repeat_n.rs
@@ -0,0 +1,43 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::{snippet, snippet_with_context};
+use clippy_utils::{expr_use_ctxt, fn_def_id, is_trait_method, std_or_core};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::MANUAL_REPEAT_N;
+
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &'tcx Expr<'tcx>,
+    repeat_expr: &Expr<'_>,
+    take_arg: &Expr<'_>,
+    msrv: &Msrv,
+) {
+    if msrv.meets(msrvs::REPEAT_N)
+        && !expr.span.from_expansion()
+        && is_trait_method(cx, expr, sym::Iterator)
+        && let ExprKind::Call(_, [repeat_arg]) = repeat_expr.kind
+        && let Some(def_id) = fn_def_id(cx, repeat_expr)
+        && cx.tcx.is_diagnostic_item(sym::iter_repeat, def_id)
+        && !expr_use_ctxt(cx, expr).is_ty_unified
+        && let Some(std_or_core) = std_or_core(cx)
+    {
+        let mut app = Applicability::MachineApplicable;
+        span_lint_and_sugg(
+            cx,
+            MANUAL_REPEAT_N,
+            expr.span,
+            "this `repeat().take()` can be written more concisely",
+            "consider using `repeat_n()` instead",
+            format!(
+                "{std_or_core}::iter::repeat_n({}, {})",
+                snippet_with_context(cx, repeat_arg.span, expr.span.ctxt(), "..", &mut app).0,
+                snippet(cx, take_arg.span, "..")
+            ),
+            app,
+        );
+    }
+}
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 4a48d4b547c..a56378b5b73 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
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 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::{Span, sym};
 
 use super::MANUAL_TRY_FOLD;
@@ -20,7 +19,7 @@ pub(super) fn check<'tcx>(
     fold_span: Span,
     msrv: &Msrv,
 ) {
-    if !in_external_macro(cx.sess(), fold_span)
+    if !fold_span.in_external_macro(cx.sess().source_map())
         && msrv.meets(msrvs::ITERATOR_TRY_FOLD)
         && is_trait_method(cx, expr, sym::Iterator)
         && let init_ty = cx.typeck_results().expr_ty(init)
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
index 1ebb71e251a..78656ace831 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{eager_or_lazy, higher, usage};
+use clippy_utils::{eager_or_lazy, higher, std_or_core, usage};
 use rustc_ast::LitKind;
 use rustc_ast::ast::RangeLimits;
 use rustc_data_structures::packed::Pu128;
@@ -75,6 +75,7 @@ pub(super) fn check(
         } = body_hir
         && !usage::BindingUsageFinder::are_params_used(cx, body_hir)
         && let Some(count) = extract_count_with_applicability(cx, range, &mut applicability)
+        && let Some(exec_context) = std_or_core(cx)
     {
         let method_to_use_name;
         let new_span;
@@ -105,7 +106,7 @@ pub(super) fn check(
         let mut parts = vec![
             (
                 receiver.span.to(method_call_span),
-                format!("std::iter::{method_to_use_name}"),
+                format!("{exec_context}::iter::{method_to_use_name}"),
             ),
             new_span,
         ];
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 3965c4d4087..0a8eafad0e8 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -58,6 +58,7 @@ mod manual_inspect;
 mod manual_is_variant_and;
 mod manual_next_back;
 mod manual_ok_or;
+mod manual_repeat_n;
 mod manual_saturating_arithmetic;
 mod manual_str_repeat;
 mod manual_try_fold;
@@ -94,6 +95,7 @@ mod readonly_write_lock;
 mod redundant_as_str;
 mod repeat_once;
 mod result_map_or_else_none;
+mod return_and_then;
 mod search_is_some;
 mod seek_from_current;
 mod seek_to_start_instead_of_rewind;
@@ -101,6 +103,7 @@ mod single_char_add_str;
 mod single_char_insert_string;
 mod single_char_push_string;
 mod skip_while_next;
+mod sliced_string_as_bytes;
 mod stable_sort_primitive;
 mod str_split;
 mod str_splitn;
@@ -130,6 +133,7 @@ mod unnecessary_to_owned;
 mod unused_enumerate_index;
 mod unwrap_expect_used;
 mod useless_asref;
+mod useless_nonzero_new_unchecked;
 mod utils;
 mod vec_resize_to_zero;
 mod verbose_file_reads;
@@ -145,11 +149,11 @@ use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
 use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
 pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
+use rustc_abi::ExternAbi;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
 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::{Span, sym};
@@ -2416,14 +2420,14 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for usage of `.then_some(..).unwrap_or(..)`
+    /// Checks for unnecessary method chains that can be simplified into `if .. else ..`.
     ///
     /// ### Why is this bad?
     /// This can be written more clearly with `if .. else ..`
     ///
     /// ### Limitations
     /// This lint currently only looks for usages of
-    /// `.then_some(..).unwrap_or(..)`, but will be expanded
+    /// `.then_some(..).unwrap_or(..)` and `.then(..).unwrap_or(..)`, but will be expanded
     /// to account for similar patterns.
     ///
     /// ### Example
@@ -3515,7 +3519,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.73.0"]
     pub FORMAT_COLLECT,
-    perf,
+    pedantic,
     "`format!`ing every element in a collection, then collecting the strings into a new `String`"
 }
 
@@ -4311,6 +4315,124 @@ declare_clippy_lint! {
     "using `Iterator::last` on a `DoubleEndedIterator`"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Checks for `NonZero*::new_unchecked()` being used in a `const` context.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// Using `NonZero*::new_unchecked()` is an `unsafe` function and requires an `unsafe` context. When used in a
+    /// context evaluated at compilation time, `NonZero*::new().unwrap()` will provide the same result with identical
+    /// runtime performances while not requiring `unsafe`.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// use std::num::NonZeroUsize;
+    /// const PLAYERS: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// use std::num::NonZeroUsize;
+    /// const PLAYERS: NonZeroUsize = NonZeroUsize::new(3).unwrap();
+    /// ```
+    #[clippy::version = "1.86.0"]
+    pub USELESS_NONZERO_NEW_UNCHECKED,
+    complexity,
+    "using `NonZero::new_unchecked()` in a `const` context"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Checks for `repeat().take()` that can be replaced with `repeat_n()`.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// Using `repeat_n()` is more concise and clearer. Also, `repeat_n()` is sometimes faster than `repeat().take()` when the type of the element is non-trivial to clone because the original value can be reused for the last `.next()` call rather than always cloning.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let _ = std::iter::repeat(10).take(3);
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let _ = std::iter::repeat_n(10, 3);
+    /// ```
+    #[clippy::version = "1.86.0"]
+    pub MANUAL_REPEAT_N,
+    style,
+    "detect `repeat().take()` that can be replaced with `repeat_n()`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for string slices immediately followed by `as_bytes`.
+    ///
+    /// ### Why is this bad?
+    /// It involves doing an unnecessary UTF-8 alignment check which is less efficient, and can cause a panic.
+    ///
+    /// ### Known problems
+    /// In some cases, the UTF-8 validation and potential panic from string slicing may be required for
+    /// the code's correctness. If you need to ensure the slice boundaries fall on valid UTF-8 character
+    /// boundaries, the original form (`s[1..5].as_bytes()`) should be preferred.
+    ///
+    /// ### Example
+    /// ```rust
+    /// let s = "Lorem ipsum";
+    /// s[1..5].as_bytes();
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// let s = "Lorem ipsum";
+    /// &s.as_bytes()[1..5];
+    /// ```
+     #[clippy::version = "1.86.0"]
+     pub SLICED_STRING_AS_BYTES,
+     perf,
+     "slicing a string and immediately calling as_bytes is less efficient and can lead to panics"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Detect functions that end with `Option::and_then` or `Result::and_then`, and suggest using a question mark (`?`) instead.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// The `and_then` method is used to chain a computation that returns an `Option` or a `Result`.
+    /// This can be replaced with the `?` operator, which is more concise and idiomatic.
+    ///
+    /// ### Example
+    ///
+    /// ```no_run
+    /// fn test(opt: Option<i32>) -> Option<i32> {
+    ///     opt.and_then(|n| {
+    ///         if n > 1 {
+    ///             Some(n + 1)
+    ///         } else {
+    ///             None
+    ///        }
+    ///     })
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// fn test(opt: Option<i32>) -> Option<i32> {
+    ///     let n = opt?;
+    ///     if n > 1 {
+    ///         Some(n + 1)
+    ///     } else {
+    ///         None
+    ///     }
+    /// }
+    /// ```
+    #[clippy::version = "1.86.0"]
+    pub RETURN_AND_THEN,
+    restriction,
+    "using `Option::and_then` or `Result::and_then` to chain a computation that returns an `Option` or a `Result`"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Msrv,
@@ -4477,6 +4599,10 @@ impl_lint_pass!(Methods => [
     MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
     UNNECESSARY_MAP_OR,
     DOUBLE_ENDED_ITERATOR_LAST,
+    USELESS_NONZERO_NEW_UNCHECKED,
+    MANUAL_REPEAT_N,
+    SLICED_STRING_AS_BYTES,
+    RETURN_AND_THEN,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -4505,6 +4631,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                 from_iter_instead_of_collect::check(cx, expr, args, func);
                 unnecessary_fallible_conversions::check_function(cx, expr, func);
                 manual_c_str_literals::check(cx, expr, func, args, &self.msrv);
+                useless_nonzero_new_unchecked::check(cx, expr, func, args, &self.msrv);
             },
             ExprKind::MethodCall(method_call, receiver, args, _) => {
                 let method_span = method_call.ident.span;
@@ -4540,7 +4667,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
 
     #[allow(clippy::too_many_lines)]
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
-        if in_external_macro(cx.sess(), impl_item.span) {
+        if impl_item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         let name = impl_item.ident.name.as_str();
@@ -4628,7 +4755,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
-        if in_external_macro(cx.tcx.sess, item.span) {
+        if item.span.in_external_macro(cx.tcx.sess.source_map()) {
             return;
         }
 
@@ -4705,7 +4832,10 @@ impl Methods {
                     let biom_option_linted = bind_instead_of_map::check_and_then_some(cx, expr, recv, arg);
                     let biom_result_linted = bind_instead_of_map::check_and_then_ok(cx, expr, recv, arg);
                     if !biom_option_linted && !biom_result_linted {
-                        unnecessary_lazy_eval::check(cx, expr, recv, arg, "and");
+                        let ule_and_linted = unnecessary_lazy_eval::check(cx, expr, recv, arg, "and");
+                        if !ule_and_linted {
+                            return_and_then::check(cx, expr, recv, arg);
+                        }
                     }
                 },
                 ("any", [arg]) => {
@@ -4743,6 +4873,7 @@ impl Methods {
                     if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) {
                         redundant_as_str::check(cx, expr, recv, as_str_span, span);
                     }
+                    sliced_string_as_bytes::check(cx, expr, recv);
                 },
                 ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
                 ("as_ptr", []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, &self.msrv),
@@ -4918,14 +5049,16 @@ impl Methods {
                     get_first::check(cx, expr, recv, arg);
                     get_last_with_len::check(cx, expr, recv, arg);
                 },
-                ("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"),
+                ("get_or_insert_with", [arg]) => {
+                    unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert");
+                },
                 ("hash", [arg]) => {
                     unit_hash::check(cx, expr, recv, arg);
                 },
                 ("is_empty", []) => {
                     match method_call(recv) {
-                        Some(("as_bytes", prev_recv, [], _, _)) => {
-                            needless_as_bytes::check(cx, "is_empty", recv, prev_recv, expr.span);
+                        Some((prev_method @ ("as_bytes" | "bytes"), prev_recv, [], _, _)) => {
+                            needless_as_bytes::check(cx, prev_method, "is_empty", prev_recv, expr.span);
                         },
                         Some(("as_str", recv, [], as_str_span, _)) => {
                             redundant_as_str::check(cx, expr, recv, as_str_span, span);
@@ -4962,8 +5095,8 @@ impl Methods {
                     double_ended_iterator_last::check(cx, expr, recv, call_span);
                 },
                 ("len", []) => {
-                    if let Some(("as_bytes", prev_recv, [], _, _)) = method_call(recv) {
-                        needless_as_bytes::check(cx, "len", recv, prev_recv, expr.span);
+                    if let Some((prev_method @ ("as_bytes" | "bytes"), prev_recv, [], _, _)) = method_call(recv) {
+                        needless_as_bytes::check(cx, prev_method, "len", prev_recv, expr.span);
                     }
                 },
                 ("lock", []) => {
@@ -5015,7 +5148,7 @@ impl Methods {
                     option_map_or_none::check(cx, expr, recv, def, map);
                     manual_ok_or::check(cx, expr, recv, def, map);
                     option_map_or_err_ok::check(cx, expr, recv, def, map);
-                    unnecessary_map_or::check(cx, expr, recv, def, map, &self.msrv);
+                    unnecessary_map_or::check(cx, expr, recv, def, map, span, &self.msrv);
                 },
                 ("map_or_else", [def, map]) => {
                     result_map_or_else_none::check(cx, expr, recv, def, map);
@@ -5059,7 +5192,9 @@ impl Methods {
                     },
                     _ => iter_nth_zero::check(cx, expr, recv, n_arg),
                 },
-                ("ok_or_else", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"),
+                ("ok_or_else", [arg]) => {
+                    unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or");
+                },
                 ("open", [_]) => {
                     open_options::check(cx, expr, recv);
                 },
@@ -5146,6 +5281,7 @@ impl Methods {
                 ("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
                 ("take", [arg]) => {
                     iter_out_of_bounds::check_take(cx, expr, recv, arg);
+                    manual_repeat_n::check(cx, expr, recv, arg, &self.msrv);
                     if let Some(("cloned", recv2, [], _span2, _)) = method_call(recv) {
                         iter_overeager_cloned::check(
                             cx,
@@ -5220,8 +5356,8 @@ impl Methods {
                         Some(("map", m_recv, [m_arg], span, _)) => {
                             option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span, &self.msrv);
                         },
-                        Some(("then_some", t_recv, [t_arg], _, _)) => {
-                            obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg);
+                        Some((then_method @ ("then" | "then_some"), t_recv, [t_arg], _, _)) => {
+                            obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg, then_method);
                         },
                         _ => {},
                     }
@@ -5312,7 +5448,7 @@ const FN_HEADER: hir::FnHeader = hir::FnHeader {
     safety: hir::HeaderSafety::Normal(hir::Safety::Safe),
     constness: hir::Constness::NotConst,
     asyncness: hir::IsAsync::NotAsync,
-    abi: rustc_target::spec::abi::Abi::Rust,
+    abi: ExternAbi::Rust,
 };
 
 struct ShouldImplTraitCase {
@@ -5351,9 +5487,12 @@ 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/needless_as_bytes.rs b/src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs
index 75e9f317230..7c9f7bae990 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_as_bytes.rs
@@ -8,18 +8,16 @@ use rustc_span::Span;
 
 use super::NEEDLESS_AS_BYTES;
 
-pub fn check(cx: &LateContext<'_>, method: &str, recv: &Expr<'_>, prev_recv: &Expr<'_>, span: Span) {
-    if cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice()
-        && let ty1 = cx.typeck_results().expr_ty_adjusted(prev_recv).peel_refs()
-        && (is_type_lang_item(cx, ty1, LangItem::String) || ty1.is_str())
-    {
+pub fn check(cx: &LateContext<'_>, prev_method: &str, method: &str, prev_recv: &Expr<'_>, span: Span) {
+    let ty1 = cx.typeck_results().expr_ty_adjusted(prev_recv).peel_refs();
+    if is_type_lang_item(cx, ty1, LangItem::String) || ty1.is_str() {
         let mut app = Applicability::MachineApplicable;
         let sugg = Sugg::hir_with_context(cx, prev_recv, span.ctxt(), "..", &mut app);
         span_lint_and_sugg(
             cx,
             NEEDLESS_AS_BYTES,
             span,
-            "needless call to `as_bytes()`",
+            format!("needless call to `{prev_method}`"),
             format!("`{method}()` can be called directly on strings"),
             format!("{sugg}.{method}()"),
             app,
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_option_take.rs b/src/tools/clippy/clippy_lints/src/methods/needless_option_take.rs
index c41ce2481d7..88b9c69f6f9 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_option_take.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_option_take.rs
@@ -1,5 +1,6 @@
-use clippy_utils::diagnostics::span_lint_and_note;
+use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_span::sym;
@@ -10,13 +11,22 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'
     // Checks if expression type is equal to sym::Option and if the expr is not a syntactic place
     if !recv.is_syntactic_place_expr() && is_expr_option(cx, recv) {
         if let Some(function_name) = source_of_temporary_value(recv) {
-            span_lint_and_note(
+            span_lint_and_then(
                 cx,
                 NEEDLESS_OPTION_TAKE,
                 expr.span,
                 "called `Option::take()` on a temporary value",
-                None,
-                format!("`{function_name}` creates a temporary value, so calling take() has no effect"),
+                |diag| {
+                    diag.note(format!(
+                        "`{function_name}` creates a temporary value, so calling take() has no effect"
+                    ));
+                    diag.span_suggestion(
+                        expr.span.with_lo(recv.span.hi()),
+                        "remove",
+                        "",
+                        Applicability::MachineApplicable,
+                    );
+                },
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs b/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs
index 697eab32a33..b71f79f8482 100644
--- a/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/obfuscated_if_else.rs
@@ -1,8 +1,11 @@
 use super::OBFUSCATED_IF_ELSE;
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::eager_or_lazy::switch_to_eager_eval;
 use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_hir::ExprKind;
 use rustc_lint::LateContext;
 
 pub(super) fn check<'tcx>(
@@ -11,19 +14,30 @@ pub(super) fn check<'tcx>(
     then_recv: &'tcx hir::Expr<'_>,
     then_arg: &'tcx hir::Expr<'_>,
     unwrap_arg: &'tcx hir::Expr<'_>,
+    then_method_name: &str,
 ) {
-    // something.then_some(blah).unwrap_or(blah)
-    // ^^^^^^^^^-then_recv ^^^^-then_arg   ^^^^- unwrap_arg
-    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- expr
-
     let recv_ty = cx.typeck_results().expr_ty(then_recv);
 
     if recv_ty.is_bool() {
-        let mut applicability = Applicability::MachineApplicable;
+        let mut applicability = if switch_to_eager_eval(cx, then_arg) && switch_to_eager_eval(cx, unwrap_arg) {
+            Applicability::MachineApplicable
+        } else {
+            Applicability::MaybeIncorrect
+        };
+
+        let if_then = match then_method_name {
+            "then" if let ExprKind::Closure(closure) = then_arg.kind => {
+                let body = cx.tcx.hir().body(closure.body);
+                snippet_with_applicability(cx, body.value.span, "..", &mut applicability)
+            },
+            "then_some" => snippet_with_applicability(cx, then_arg.span, "..", &mut applicability),
+            _ => String::new().into(),
+        };
+
         let sugg = format!(
             "if {} {{ {} }} else {{ {} }}",
-            snippet_with_applicability(cx, then_recv.span, "..", &mut applicability),
-            snippet_with_applicability(cx, then_arg.span, "..", &mut applicability),
+            Sugg::hir_with_applicability(cx, then_recv, "..", &mut applicability),
+            if_then,
             snippet_with_applicability(cx, unwrap_arg.span, "..", &mut applicability)
         );
 
@@ -31,8 +45,7 @@ pub(super) fn check<'tcx>(
             cx,
             OBFUSCATED_IF_ELSE,
             expr.span,
-            "use of `.then_some(..).unwrap_or(..)` can be written \
-            more clearly with `if .. else ..`",
+            "this method chain can be written more clearly with `if .. else ..`",
             "try",
             sugg,
             applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
index febd7fd5cf2..b3811a335e1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
@@ -37,7 +37,7 @@ pub(super) fn check(
             let _ = write!(sugg, r#".extension().is_some_and(|ext| ext == "{path}")"#);
         } else {
             let _ = write!(sugg, r#".extension().map_or(false, |ext| ext == "{path}")"#);
-        };
+        }
 
         span_lint_and_sugg(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
new file mode 100644
index 00000000000..7b1199ad1e2
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
@@ -0,0 +1,67 @@
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self, GenericArg, Ty};
+use rustc_span::sym;
+use std::ops::ControlFlow;
+
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};
+use clippy_utils::ty::get_type_diagnostic_name;
+use clippy_utils::visitors::for_each_unconsumed_temporary;
+use clippy_utils::{is_expr_final_block_expr, peel_blocks};
+
+use super::RETURN_AND_THEN;
+
+/// lint if `and_then` is the last expression in a block, and
+/// there are no references or temporaries in the receiver
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &hir::Expr<'_>,
+    recv: &'tcx hir::Expr<'tcx>,
+    arg: &'tcx hir::Expr<'_>,
+) {
+    if !is_expr_final_block_expr(cx.tcx, expr) {
+        return;
+    }
+
+    let recv_type = cx.typeck_results().expr_ty(recv);
+    if !matches!(get_type_diagnostic_name(cx, recv_type), Some(sym::Option | sym::Result)) {
+        return;
+    }
+
+    let has_ref_type = matches!(recv_type.kind(), ty::Adt(_, args) if args
+        .first()
+        .and_then(|arg0: &GenericArg<'tcx>| GenericArg::as_type(*arg0))
+        .is_some_and(Ty::is_ref));
+    let has_temporaries = for_each_unconsumed_temporary(cx, recv, |_| ControlFlow::Break(())).is_break();
+    if has_ref_type && has_temporaries {
+        return;
+    }
+
+    let hir::ExprKind::Closure(&hir::Closure { body, fn_decl, .. }) = arg.kind else {
+        return;
+    };
+
+    let closure_arg = fn_decl.inputs[0];
+    let closure_expr = peel_blocks(cx.tcx.hir().body(body).value);
+
+    let mut applicability = Applicability::MachineApplicable;
+    let arg_snip = snippet_with_applicability(cx, closure_arg.span, "_", &mut applicability);
+    let recv_snip = snippet_with_applicability(cx, recv.span, "_", &mut applicability);
+    let body_snip = snippet_with_applicability(cx, closure_expr.span, "..", &mut applicability);
+    let inner = match body_snip.strip_prefix('{').and_then(|s| s.strip_suffix('}')) {
+        Some(s) => s.trim_start_matches('\n').trim_end(),
+        None => &body_snip,
+    };
+
+    let msg = "use the question mark operator instead of an `and_then` call";
+    let sugg = format!(
+        "let {} = {}?;\n{}",
+        arg_snip,
+        recv_snip,
+        reindent_multiline(inner.into(), false, indent_of(cx, expr.span))
+    );
+
+    span_lint_and_sugg(cx, RETURN_AND_THEN, expr.span, msg, "try", sugg, applicability);
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/sliced_string_as_bytes.rs b/src/tools/clippy/clippy_lints/src/methods/sliced_string_as_bytes.rs
new file mode 100644
index 00000000000..6d4cfdb34f3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/sliced_string_as_bytes.rs
@@ -0,0 +1,29 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::is_type_lang_item;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, LangItem, is_range_literal};
+use rustc_lint::LateContext;
+
+use super::SLICED_STRING_AS_BYTES;
+
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>) {
+    if let ExprKind::Index(indexed, index, _) = recv.kind
+        && is_range_literal(index)
+        && let ty = cx.typeck_results().expr_ty(indexed).peel_refs()
+        && (ty.is_str() || is_type_lang_item(cx, ty, LangItem::String))
+    {
+        let mut applicability = Applicability::MaybeIncorrect;
+        let stringish = snippet_with_applicability(cx, indexed.span, "_", &mut applicability);
+        let range = snippet_with_applicability(cx, index.span, "_", &mut applicability);
+        span_lint_and_sugg(
+            cx,
+            SLICED_STRING_AS_BYTES,
+            expr.span,
+            "calling `as_bytes` after slicing a string",
+            "try",
+            format!("&{stringish}.as_bytes()[{range}]"),
+            applicability,
+        );
+    }
+}
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 c27d1fb4903..e7adf3b43ba 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
@@ -123,32 +123,60 @@ 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 {
-                    method_name: "any",
-                    has_args: true,
-                    has_generic_return: false,
-                });
+                check_fold_with_op(
+                    cx,
+                    expr,
+                    acc,
+                    fold_span,
+                    hir::BinOpKind::Or,
+                    Replacement {
+                        method_name: "any",
+                        has_args: true,
+                        has_generic_return: false,
+                    },
+                );
             },
             ast::LitKind::Bool(true) => {
-                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::And, Replacement {
-                    method_name: "all",
-                    has_args: true,
-                    has_generic_return: false,
-                });
+                check_fold_with_op(
+                    cx,
+                    expr,
+                    acc,
+                    fold_span,
+                    hir::BinOpKind::And,
+                    Replacement {
+                        method_name: "all",
+                        has_args: true,
+                        has_generic_return: false,
+                    },
+                );
             },
             ast::LitKind::Int(Pu128(0), _) => {
-                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Add, Replacement {
-                    method_name: "sum",
-                    has_args: false,
-                    has_generic_return: needs_turbofish(cx, expr),
-                });
+                check_fold_with_op(
+                    cx,
+                    expr,
+                    acc,
+                    fold_span,
+                    hir::BinOpKind::Add,
+                    Replacement {
+                        method_name: "sum",
+                        has_args: false,
+                        has_generic_return: needs_turbofish(cx, expr),
+                    },
+                );
             },
             ast::LitKind::Int(Pu128(1), _) => {
-                check_fold_with_op(cx, expr, acc, fold_span, hir::BinOpKind::Mul, Replacement {
-                    method_name: "product",
-                    has_args: false,
-                    has_generic_return: needs_turbofish(cx, expr),
-                });
+                check_fold_with_op(
+                    cx,
+                    expr,
+                    acc,
+                    fold_span,
+                    hir::BinOpKind::Mul,
+                    Replacement {
+                        method_name: "product",
+                        has_args: false,
+                        has_generic_return: needs_turbofish(cx, expr),
+                    },
+                );
             },
             _ => (),
         }
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 671c189a98e..c0e01568588 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
@@ -87,7 +87,7 @@ pub fn check_for_loop_iter(
                 // skip lint
                 return true;
             }
-        };
+        }
 
         // the lint should not be executed if no violation happens
         let snippet = if let ExprKind::MethodCall(maybe_iter_method_name, collection, [], _) = receiver.kind
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
index b84594c0da1..7af550fa7c6 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
@@ -18,7 +18,7 @@ pub(super) fn check<'tcx>(
     recv: &'tcx hir::Expr<'_>,
     arg: &'tcx hir::Expr<'_>,
     simplify_using: &str,
-) {
+) -> bool {
     let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option);
     let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
     let is_bool = cx.typeck_results().expr_ty(recv).is_bool();
@@ -29,7 +29,7 @@ pub(super) fn check<'tcx>(
             let body_expr = &body.value;
 
             if usage::BindingUsageFinder::are_params_used(cx, body) || is_from_proc_macro(cx, expr) {
-                return;
+                return false;
             }
 
             if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {
@@ -49,7 +49,7 @@ pub(super) fn check<'tcx>(
                         fn_decl.output,
                         FnRetTy::DefaultReturn(_)
                             | FnRetTy::Return(hir::Ty {
-                                kind: hir::TyKind::Infer,
+                                kind: hir::TyKind::Infer(()),
                                 ..
                             })
                     ) {
@@ -71,8 +71,10 @@ pub(super) fn check<'tcx>(
                             applicability,
                         );
                     });
+                    return true;
                 }
             }
         }
     }
+    false
 }
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 6dc8adb42df..10112b62878 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,14 +1,14 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{MaybePath, is_res_lang_ctor, last_path_segment, path_res};
 use rustc_errors::Applicability;
-use rustc_hir as hir;
+use rustc_hir::{self as hir, AmbigArg};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
 use rustc_middle::ty::print::with_forced_trimmed_paths;
 
 use super::UNNECESSARY_LITERAL_UNWRAP;
 
-fn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) -> Option<&'a hir::Ty<'a>> {
+fn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) -> Option<&'a hir::Ty<'a, AmbigArg>> {
     let args = args?;
 
     if args.len() <= index {
@@ -16,10 +16,7 @@ fn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) -
     }
 
     match args[index] {
-        hir::GenericArg::Type(ty) => match ty.kind {
-            hir::TyKind::Infer => None,
-            _ => Some(ty),
-        },
+        hir::GenericArg::Type(ty) => Some(ty),
         _ => None,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
index b7dbebe60a4..6dea1506d0e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
@@ -1,9 +1,8 @@
 use std::borrow::Cow;
 
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::eager_or_lazy::switch_to_eager_eval;
 use clippy_utils::msrvs::{self, Msrv};
-use clippy_utils::source::snippet_opt;
 use clippy_utils::sugg::{Sugg, make_binop};
 use clippy_utils::ty::{get_type_diagnostic_name, implements_trait};
 use clippy_utils::visitors::is_local_used;
@@ -12,7 +11,7 @@ use rustc_ast::LitKind::Bool;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, PatKind};
 use rustc_lint::LateContext;
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 
 use super::UNNECESSARY_MAP_OR;
 
@@ -42,13 +41,14 @@ pub(super) fn check<'a>(
     recv: &Expr<'_>,
     def: &Expr<'_>,
     map: &Expr<'_>,
+    method_span: Span,
     msrv: &Msrv,
 ) {
     let ExprKind::Lit(def_kind) = def.kind else {
         return;
     };
 
-    let recv_ty = cx.typeck_results().expr_ty(recv);
+    let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
 
     let Bool(def_bool) = def_kind.node else {
         return;
@@ -60,6 +60,8 @@ pub(super) fn check<'a>(
         Some(_) | None => return,
     };
 
+    let ext_def_span = def.span.until(map.span);
+
     let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind
             && let closure_body = cx.tcx.hir().body(map_closure.body)
             && let closure_body_value = closure_body.value.peel_blocks()
@@ -114,26 +116,17 @@ pub(super) fn check<'a>(
         }
         .into_string();
 
-        (sugg, "a standard comparison", app)
-    } else if !def_bool
-        && msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND)
-        && let Some(recv_callsite) = snippet_opt(cx, recv.span.source_callsite())
-        && let Some(span_callsite) = snippet_opt(cx, map.span.source_callsite())
-    {
+        (vec![(expr.span, sugg)], "a standard comparison", app)
+    } else if !def_bool && msrv.meets(msrvs::OPTION_RESULT_IS_VARIANT_AND) {
         let suggested_name = variant.method_name();
         (
-            format!("{recv_callsite}.{suggested_name}({span_callsite})",),
+            vec![(method_span, suggested_name.into()), (ext_def_span, String::default())],
             suggested_name,
             Applicability::MachineApplicable,
         )
-    } else if def_bool
-        && matches!(variant, Variant::Some)
-        && msrv.meets(msrvs::IS_NONE_OR)
-        && let Some(recv_callsite) = snippet_opt(cx, recv.span.source_callsite())
-        && let Some(span_callsite) = snippet_opt(cx, map.span.source_callsite())
-    {
+    } else if def_bool && matches!(variant, Variant::Some) && msrv.meets(msrvs::IS_NONE_OR) {
         (
-            format!("{recv_callsite}.is_none_or({span_callsite})"),
+            vec![(method_span, "is_none_or".into()), (ext_def_span, String::default())],
             "is_none_or",
             Applicability::MachineApplicable,
         )
@@ -145,13 +138,13 @@ pub(super) fn check<'a>(
         return;
     }
 
-    span_lint_and_sugg(
+    span_lint_and_then(
         cx,
         UNNECESSARY_MAP_OR,
         expr.span,
         "this `map_or` can be simplified",
-        format!("use {method} instead"),
-        sugg,
-        applicability,
+        |diag| {
+            diag.multipart_suggestion_verbose(format!("use {method} instead"), sugg, applicability);
+        },
     );
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
index 9a45b04d1a6..f0b29213e1e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
@@ -43,8 +43,7 @@ fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident
                 && iter::zip(*left_args, *right_args).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident))
         },
         // The two exprs are method calls.
-        // Check to see that the function is the same and the arguments are mirrored
-        // This is enough because the receiver of the method is listed in the arguments
+        // Check to see that the function is the same and the arguments and receivers are mirrored
         (
             ExprKind::MethodCall(left_segment, left_receiver, left_args, _),
             ExprKind::MethodCall(right_segment, right_receiver, right_args, _),
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 964f1603f0e..7d72310c1c4 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
@@ -217,10 +217,13 @@ fn check_into_iter_call_arg(
         && implements_trait(cx, parent_ty, iterator_trait_id, &[])
         && let Some(item_ty) = get_iterator_item_ty(cx, parent_ty)
         && let Some(receiver_snippet) = receiver.span.get_source_text(cx)
+        // If the receiver is a `Cow`, we can't remove the `into_owned` generally, see https://github.com/rust-lang/rust-clippy/issues/13624.
+        && !is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver), sym::Cow)
     {
         if unnecessary_iter_cloned::check_for_loop_iter(cx, parent, method_name, receiver, true) {
             return true;
         }
+
         let cloned_or_copied = if is_copy(cx, item_ty) && msrv.meets(msrvs::ITERATOR_COPIED) {
             "copied"
         } else {
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 6c2ae9cc6bf..0aec26f1011 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
@@ -130,7 +130,7 @@ pub(super) fn check(cx: &LateContext<'_>, call_expr: &Expr<'_>, recv: &Expr<'_>,
 fn find_elem_explicit_type_span(fn_decl: &FnDecl<'_>) -> Option<Span> {
     if let [tuple_ty] = fn_decl.inputs
         && let TyKind::Tup([_idx_ty, elem_ty]) = tuple_ty.kind
-        && !matches!(elem_ty.kind, TyKind::Err(..) | TyKind::Infer)
+        && !matches!(elem_ty.kind, TyKind::Err(..) | TyKind::Infer(()))
     {
         Some(elem_ty.span)
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs b/src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs
new file mode 100644
index 00000000000..0bd50429c09
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/useless_nonzero_new_unchecked.rs
@@ -0,0 +1,59 @@
+use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
+use clippy_utils::is_inside_always_const_context;
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_errors::Applicability;
+use rustc_hir::{Block, BlockCheckMode, Expr, ExprKind, Node, QPath, UnsafeSource};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::USELESS_NONZERO_NEW_UNCHECKED;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<'tcx>, args: &[Expr<'_>], msrv: &Msrv) {
+    if msrv.meets(msrvs::CONST_UNWRAP)
+        && let ExprKind::Path(QPath::TypeRelative(ty, segment)) = func.kind
+        && segment.ident.name == sym::new_unchecked
+        && let [init_arg] = args
+        && is_inside_always_const_context(cx.tcx, expr.hir_id)
+        && is_type_diagnostic_item(cx, cx.typeck_results().node_type(ty.hir_id), sym::NonZero)
+    {
+        let mut app = Applicability::MachineApplicable;
+        let ty_str = snippet_with_applicability(cx, ty.span, "_", &mut app);
+        let msg = format!("`{ty_str}::new()` and `Option::unwrap()` can be safely used in a `const` context");
+        let sugg = format!(
+            "{ty_str}::new({}).unwrap()",
+            snippet_with_applicability(cx, init_arg.span, "_", &mut app)
+        );
+
+        if let Node::Block(Block {
+            stmts: [],
+            span: block_span,
+            rules: BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
+            ..
+        }) = cx.tcx.parent_hir_node(expr.hir_id)
+        {
+            if !block_span.from_expansion() {
+                // The expression is the only component of an `unsafe` block. Propose
+                // to replace the block altogether.
+                span_lint_and_sugg(
+                    cx,
+                    USELESS_NONZERO_NEW_UNCHECKED,
+                    *block_span,
+                    msg,
+                    "use instead",
+                    sugg,
+                    app,
+                );
+            }
+        } else {
+            // The expression is enclosed in a larger `unsafe` context. Indicate that
+            // this may no longer be needed for the fixed expression.
+            span_lint_and_then(cx, USELESS_NONZERO_NEW_UNCHECKED, expr.span, msg, |diagnostic| {
+                diagnostic
+                    .span_suggestion(expr.span, "use instead", sugg, app)
+                    .note("the fixed expression does not require an `unsafe` context");
+            });
+        }
+    }
+}
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 a99e21d938c..4119b1d1051 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -6,7 +6,6 @@ use rustc_hir::def::{DefKind, Res};
 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;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use std::borrow::Cow;
@@ -55,7 +54,7 @@ impl MinIdentChars {
 
     #[expect(clippy::cast_possible_truncation)]
     fn is_ident_too_short(&self, cx: &LateContext<'_>, str: &str, span: Span) -> bool {
-        !in_external_macro(cx.sess(), span)
+        !span.in_external_macro(cx.sess().source_map())
             && str.len() <= self.min_ident_chars_threshold as usize
             && !str.starts_with('_')
             && !str.is_empty()
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index b856c929cf6..fca416d9e64 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -13,7 +13,6 @@ use rustc_hir::{
     BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
@@ -162,14 +161,14 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
             for arg in iter_input_pats(decl, body) {
                 if let PatKind::Binding(BindingMode(ByRef::Yes(_), _), ..) = arg.pat.kind
                     && is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id)
-                    && !in_external_macro(cx.tcx.sess, arg.span)
+                    && !arg.span.in_external_macro(cx.tcx.sess.source_map())
                 {
                     span_lint_hir(
                         cx,
                         TOPLEVEL_REF_ARG,
                         arg.hir_id,
                         arg.pat.span,
-                        "`ref` directly on a function argument is ignored. \
+                        "`ref` directly on a function parameter does not prevent taking ownership of the passed argument. \
                         Consider using a reference type instead",
                     );
                 }
@@ -183,7 +182,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
             && let Some(init) = local.init
             // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue.
             && is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id)
-            && !in_external_macro(cx.tcx.sess, stmt.span)
+            && !stmt.span.in_external_macro(cx.tcx.sess.source_map())
         {
             let ctxt = local.span.ctxt();
             let mut app = Applicability::MachineApplicable;
@@ -214,11 +213,12 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
                     );
                 },
             );
-        };
+        }
         if let StmtKind::Semi(expr) = stmt.kind
-            && let ExprKind::Binary(ref binop, a, b) = expr.kind
-            && (binop.node == BinOpKind::And || binop.node == BinOpKind::Or)
-            && let Some(sugg) = Sugg::hir_opt(cx, a)
+            && let ExprKind::Binary(binop, a, b) = &expr.kind
+            && matches!(binop.node, BinOpKind::And | BinOpKind::Or)
+            && !stmt.span.from_expansion()
+            && expr.span.eq_ctxt(stmt.span)
         {
             span_lint_hir_and_then(
                 cx,
@@ -227,20 +227,18 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
                 stmt.span,
                 "boolean short circuit operator in statement may be clearer using an explicit test",
                 |diag| {
-                    let sugg = if binop.node == BinOpKind::Or { !sugg } else { sugg };
-                    diag.span_suggestion(
-                        stmt.span,
-                        "replace it with",
-                        format!("if {sugg} {{ {}; }}", &snippet(cx, b.span, ".."),),
-                        Applicability::MachineApplicable, // snippet
-                    );
+                    let mut app = Applicability::MachineApplicable;
+                    let test = Sugg::hir_with_context(cx, a, expr.span.ctxt(), "_", &mut app);
+                    let test = if binop.node == BinOpKind::Or { !test } else { test };
+                    let then = Sugg::hir_with_context(cx, b, expr.span.ctxt(), "_", &mut app);
+                    diag.span_suggestion(stmt.span, "replace it with", format!("if {test} {{ {then}; }}"), app);
                 },
             );
-        };
+        }
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span)
+        if expr.span.in_external_macro(cx.sess().source_map())
             || expr.span.desugaring_kind().is_some()
             || in_automatically_derived(cx.tcx, expr.hir_id)
         {
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs b/src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs
deleted file mode 100644
index 06ba968fa4e..00000000000
--- a/src/tools/clippy/clippy_lints/src/misc_early/double_neg.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-use clippy_utils::diagnostics::span_lint;
-use rustc_ast::ast::{Expr, ExprKind, UnOp};
-use rustc_lint::EarlyContext;
-
-use super::DOUBLE_NEG;
-
-pub(super) fn check(cx: &EarlyContext<'_>, expr: &Expr) {
-    if let ExprKind::Unary(UnOp::Neg, ref inner) = expr.kind {
-        if let ExprKind::Unary(UnOp::Neg, _) = inner.kind {
-            span_lint(
-                cx,
-                DOUBLE_NEG,
-                expr.span,
-                "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
-            );
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
index 37d7427f9a5..f880f1f329f 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
@@ -1,5 +1,4 @@
 mod builtin_type_shadow;
-mod double_neg;
 mod literal_suffix;
 mod mixed_case_hex_literals;
 mod redundant_at_rest_pattern;
@@ -15,7 +14,6 @@ use rustc_ast::token;
 use rustc_ast::visit::FnKind;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 
@@ -87,25 +85,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Detects expressions of the form `--x`.
-    ///
-    /// ### Why is this bad?
-    /// It can mislead C/C++ programmers to think `x` was
-    /// decremented.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// let mut x = 3;
-    /// --x;
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub DOUBLE_NEG,
-    style,
-    "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Warns on hexadecimal literals with mixed-case letter
     /// digits.
     ///
@@ -352,7 +331,6 @@ declare_clippy_lint! {
 declare_lint_pass!(MiscEarlyLints => [
     UNNEEDED_FIELD_PATTERN,
     DUPLICATE_UNDERSCORE_ARGUMENT,
-    DOUBLE_NEG,
     MIXED_CASE_HEX_LITERALS,
     UNSEPARATED_LITERAL_SUFFIX,
     SEPARATED_LITERAL_SUFFIX,
@@ -371,7 +349,7 @@ impl EarlyLintPass for MiscEarlyLints {
     }
 
     fn check_pat(&mut self, cx: &EarlyContext<'_>, pat: &Pat) {
-        if in_external_macro(cx.sess(), pat.span) {
+        if pat.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
@@ -408,14 +386,13 @@ impl EarlyLintPass for MiscEarlyLints {
     }
 
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
         if let ExprKind::Lit(lit) = expr.kind {
             MiscEarlyLints::check_lit(cx, lit, expr.span);
         }
-        double_neg::check(cx, expr);
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs
index 0c81ee5eced..f2cf93465c0 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/redundant_at_rest_pattern.rs
@@ -2,12 +2,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_ast::{Pat, PatKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
-use rustc_middle::lint::in_external_macro;
 
 use super::REDUNDANT_AT_REST_PATTERN;
 
 pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
-    if !in_external_macro(cx.sess(), pat.span)
+    if !pat.span.in_external_macro(cx.sess().source_map())
         && let PatKind::Slice(slice) = &pat.kind
         && let [one] = &**slice
         && let PatKind::Ident(annotation, ident, Some(rest)) = &one.kind
diff --git a/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs b/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
index 748289454be..d52fe7e7d5b 100644
--- a/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
+++ b/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {
                     }) => impl_params.push((path.segments[0].ident.to_string(), path.span)),
                     GenericArg::Type(_) => return,
                     _ => (),
-                };
+                }
             }
 
             // find the type that the Impl is for
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 2572e186ce6..ba4af134ccd 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,3 +1,4 @@
+
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::msrvs::{self, Msrv};
@@ -8,12 +9,11 @@ use rustc_hir::def_id::CRATE_DEF_ID;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{self as hir, Body, Constness, FnDecl, GenericParamKind};
 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::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -106,7 +106,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
             return;
         }
 
-        if in_external_macro(cx.tcx.sess, span) || is_entrypoint_fn(cx, def_id.to_def_id()) {
+        if span.in_external_macro(cx.tcx.sess.source_map()) || is_entrypoint_fn(cx, def_id.to_def_id()) {
             return;
         }
 
@@ -184,11 +184,11 @@ fn already_const(header: hir::FnHeader) -> bool {
     header.constness == Constness::Const
 }
 
-fn could_be_const_with_abi(msrv: &Msrv, abi: Abi) -> bool {
+fn could_be_const_with_abi(msrv: &Msrv, abi: ExternAbi) -> bool {
     match abi {
-        Abi::Rust => true,
+        ExternAbi::Rust => true,
         // `const extern "C"` was stabilized after 1.62.0
-        Abi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN),
+        ExternAbi::C { unwind: false } => msrv.meets(msrvs::CONST_EXTERN_C_FN),
         // Rest ABIs are still unstable and need the `const_extern_fn` feature enabled.
         _ => msrv.meets(msrvs::CONST_EXTERN_FN),
     }
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 29dcbaa9e62..06e92985e66 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -220,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
             | hir::ItemKind::GlobalAsm(..)
             | hir::ItemKind::Impl { .. }
             | hir::ItemKind::Use(..) => note_prev_span_then_ret!(self.prev_span, it.span),
-        };
+        }
 
         let (article, desc) = cx.tcx.article_and_description(it.owner_id.to_def_id());
 
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 f28b431ab99..e9ec23b1efa 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
@@ -207,7 +207,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
             // this prevents ICEs such as when self is a type parameter or a primitive type
             // (see #10887, #11063)
             && let Res::Def(DefKind::Struct | DefKind::Enum | DefKind::Union, self_path_did) = self_path.res
-            && cx.match_def_path(trait_def_id, &[sym::core, sym::fmt, sym::Debug])
+            && cx.tcx.is_diagnostic_item(sym::Debug, trait_def_id)
             // don't trigger if this impl was derived
             && !cx.tcx.has_attr(item.owner_id, sym::automatically_derived)
             && !item.span.from_expansion()
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 05aa425de9e..18385ac9269 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -88,7 +88,7 @@ declare_lint_pass!(MissingInline => [MISSING_INLINE_IN_PUBLIC_ITEMS]);
 
 impl<'tcx> LateLintPass<'tcx> for MissingInline {
     fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
-        if rustc_middle::lint::in_external_macro(cx.sess(), it.span) || is_executable_or_proc_macro(cx) {
+        if it.span.in_external_macro(cx.sess().source_map()) || is_executable_or_proc_macro(cx) {
             return;
         }
 
@@ -135,11 +135,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
             | hir::ItemKind::ForeignMod { .. }
             | hir::ItemKind::Impl { .. }
             | hir::ItemKind::Use(..) => {},
-        };
+        }
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
-        if rustc_middle::lint::in_external_macro(cx.sess(), impl_item.span) || is_executable_or_proc_macro(cx) {
+        if impl_item.span.in_external_macro(cx.sess().source_map()) || is_executable_or_proc_macro(cx) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/multi_assignments.rs b/src/tools/clippy/clippy_lints/src/multi_assignments.rs
index 9a6b1dfc52b..4383f28717d 100644
--- a/src/tools/clippy/clippy_lints/src/multi_assignments.rs
+++ b/src/tools/clippy/clippy_lints/src/multi_assignments.rs
@@ -56,10 +56,10 @@ impl EarlyLintPass for MultiAssignments {
         if let ExprKind::Assign(target, source, _) = &expr.kind {
             if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(target).kind {
                 span_lint(cx, MULTI_ASSIGNMENTS, expr.span, "assignments don't nest intuitively");
-            };
+            }
             if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(source).kind {
                 span_lint(cx, MULTI_ASSIGNMENTS, expr.span, "assignments don't nest intuitively");
             }
-        };
+        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
index 882ab2dda7a..0e1980a6acb 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_bound_locations.rs
@@ -1,5 +1,5 @@
 use rustc_ast::visit::FnKind;
-use rustc_ast::{NodeId, WherePredicateKind};
+use rustc_ast::{Fn, NodeId, WherePredicateKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::declare_lint_pass;
@@ -39,7 +39,7 @@ declare_lint_pass!(MultipleBoundLocations => [MULTIPLE_BOUND_LOCATIONS]);
 
 impl EarlyLintPass for MultipleBoundLocations {
     fn check_fn(&mut self, cx: &EarlyContext<'_>, kind: FnKind<'_>, _: Span, _: NodeId) {
-        if let FnKind::Fn(_, _, _, _, generics, _) = kind
+        if let FnKind::Fn(_, _, _, Fn { generics, .. }) = kind
             && !generics.params.is_empty()
             && !generics.where_clause.predicates.is_empty()
         {
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 79252bba74d..9acede4f32d 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
@@ -6,7 +6,6 @@ use hir::{BlockCheckMode, ExprKind, QPath, UnOp};
 use rustc_ast::Mutability;
 use rustc_hir as hir;
 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::{DesugaringKind, Span};
@@ -65,7 +64,7 @@ declare_lint_pass!(MultipleUnsafeOpsPerBlock => [MULTIPLE_UNSAFE_OPS_PER_BLOCK])
 impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
         if !matches!(block.rules, BlockCheckMode::UnsafeBlock(_))
-            || in_external_macro(cx.tcx.sess, block.span)
+            || block.span.in_external_macro(cx.tcx.sess.source_map())
             || block.span.is_desugaring(DesugaringKind::Await)
         {
             return;
@@ -153,16 +152,19 @@ 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);
@@ -171,7 +173,7 @@ fn collect_unsafe_exprs<'tcx>(
             },
 
             _ => {},
-        };
+        }
 
         Continue::<(), _>(Descend::Yes)
     });
diff --git a/src/tools/clippy/clippy_lints/src/mut_mut.rs b/src/tools/clippy/clippy_lints/src/mut_mut.rs
index e2ab5e98504..3c4ba5141dd 100644
--- a/src/tools/clippy/clippy_lints/src/mut_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_mut.rs
@@ -1,9 +1,7 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_hir};
 use clippy_utils::higher;
-use rustc_hir as hir;
-use rustc_hir::intravisit;
+use rustc_hir::{self as hir, AmbigArg, intravisit};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 
@@ -34,12 +32,12 @@ impl<'tcx> LateLintPass<'tcx> for MutMut {
         intravisit::walk_block(&mut MutVisitor { cx }, block);
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'_>) {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx hir::Ty<'_, AmbigArg>) {
         if let hir::TyKind::Ref(_, mty) = ty.kind
             && mty.mutbl == hir::Mutability::Mut
             && let hir::TyKind::Ref(_, mty) = mty.ty.kind
             && mty.mutbl == hir::Mutability::Mut
-            && !in_external_macro(cx.sess(), ty.span)
+            && !ty.span.in_external_macro(cx.sess().source_map())
         {
             span_lint(
                 cx,
@@ -57,7 +55,7 @@ pub struct 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) {
+        if expr.span.in_external_macro(self.cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
index 38841496458..49fd29d1dd6 100644
--- a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
+++ b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
@@ -18,11 +18,14 @@ declare_clippy_lint! {
     ///
     /// On the other hand, `Mutex`es are, in general, easier to
     /// verify correctness. An atomic does not behave the same as
-    /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s commentary for more details.
+    /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s
+    /// commentary for more details.
     ///
     /// ### Known problems
-    /// This lint cannot detect if the mutex is actually used
-    /// for waiting before a critical section.
+    /// * This lint cannot detect if the mutex is actually used
+    ///   for waiting before a critical section.
+    /// * This lint has a false positive that warns without considering the case
+    ///   where `Mutex` is used together with `Condvar`.
     ///
     /// ### Example
     /// ```no_run
@@ -48,14 +51,23 @@ declare_clippy_lint! {
     /// Checks for usage of `Mutex<X>` where `X` is an integral
     /// type.
     ///
-    /// ### Why is this bad?
+    /// ### Why restrict this?
     /// Using a mutex just to make access to a plain integer
     /// sequential is
     /// shooting flies with cannons. `std::sync::atomic::AtomicUsize` is leaner and faster.
     ///
+    /// On the other hand, `Mutex`es are, in general, easier to
+    /// verify correctness. An atomic does not behave the same as
+    /// an equivalent mutex. See [this issue](https://github.com/rust-lang/rust-clippy/issues/4295)'s
+    /// commentary for more details.
+    ///
     /// ### Known problems
-    /// This lint cannot detect if the mutex is actually used
-    /// for waiting before a critical section.
+    /// * This lint cannot detect if the mutex is actually used
+    ///   for waiting before a critical section.
+    /// * This lint has a false positive that warns without considering the case
+    ///   where `Mutex` is used together with `Condvar`.
+    /// * This lint suggest using `AtomicU64` instead of `Mutex<u64>`, but
+    ///   `AtomicU64` is not available on some 32-bit platforms.
     ///
     /// ### Example
     /// ```no_run
@@ -70,7 +82,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "pre 1.29.0"]
     pub MUTEX_INTEGER,
-    nursery,
+    restriction,
     "using a mutex for an integer type"
 }
 
@@ -91,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for Mutex {
                         ty::Uint(t) if t != UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, msg),
                         ty::Int(t) if t != IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, msg),
                         _ => span_lint(cx, MUTEX_ATOMIC, expr.span, msg),
-                    };
+                    }
                 }
             }
         }
@@ -108,7 +120,7 @@ fn get_atomic_name(ty: Ty<'_>) -> Option<&'static str> {
                 UintTy::U32 => Some("AtomicU32"),
                 UintTy::U64 => Some("AtomicU64"),
                 UintTy::Usize => Some("AtomicUsize"),
-                // There's no `AtomicU128`.
+                // `AtomicU128` is unstable and only available on a few platforms: https://github.com/rust-lang/rust/issues/99069
                 UintTy::U128 => None,
             }
         },
@@ -119,7 +131,7 @@ fn get_atomic_name(ty: Ty<'_>) -> Option<&'static str> {
                 IntTy::I32 => Some("AtomicI32"),
                 IntTy::I64 => Some("AtomicI64"),
                 IntTy::Isize => Some("AtomicIsize"),
-                // There's no `AtomicI128`.
+                // `AtomicU128` is unstable and only available on a few platforms: https://github.com/rust-lang/rust/issues/99069
                 IntTy::I128 => None,
             }
         },
diff --git a/src/tools/clippy/clippy_lints/src/needless_if.rs b/src/tools/clippy/clippy_lints/src/needless_if.rs
index 8e14fbf2f80..7eefb016aca 100644
--- a/src/tools/clippy/clippy_lints/src/needless_if.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_if.rs
@@ -5,7 +5,6 @@ use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::{ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -47,7 +46,7 @@ impl LateLintPass<'_> for NeedlessIf {
             && let ExprKind::Block(block, ..) = then.kind
             && block.stmts.is_empty()
             && block.expr.is_none()
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && then.span.check_source_text(cx, |src| {
                 // Ignore
                 // - empty macro expansions
diff --git a/src/tools/clippy/clippy_lints/src/needless_late_init.rs b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
index a67addea948..4e19a2f409d 100644
--- a/src/tools/clippy/clippy_lints/src/needless_late_init.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_late_init.rs
@@ -107,6 +107,10 @@ struct LocalAssign {
 
 impl LocalAssign {
     fn from_expr(expr: &Expr<'_>, span: Span) -> Option<Self> {
+        if expr.span.from_expansion() {
+            return None;
+        }
+
         if let ExprKind::Assign(lhs, rhs, _) = expr.kind {
             if lhs.span.from_expansion() {
                 return None;
@@ -336,7 +340,7 @@ fn check<'tcx>(
             );
         },
         _ => {},
-    };
+    }
 
     Some(())
 }
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 b7dc269061c..996251fdf16 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
@@ -20,7 +20,7 @@ use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -149,7 +149,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
                     return;
                 }
                 let attrs = cx.tcx.hir().attrs(hir_id);
-                if header.abi != Abi::Rust || requires_exact_signature(attrs) {
+                if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) {
                     return;
                 }
                 header.is_async()
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 30846fb46ac..40c65d1ef9e 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
@@ -19,7 +19,7 @@ use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::kw;
 use rustc_span::{Span, sym};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 use rustc_trait_selection::traits;
 use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy;
 
@@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
         match kind {
             FnKind::ItemFn(.., header) => {
                 let attrs = cx.tcx.hir().attrs(hir_id);
-                if header.abi != Abi::Rust || requires_exact_signature(attrs) {
+                if header.abi != ExternAbi::Rust || requires_exact_signature(attrs) {
                     return;
                 }
             },
@@ -181,9 +181,14 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
                 && !is_copy(cx, ty)
                 && ty.is_sized(cx.tcx, cx.typing_env())
                 && !allowed_traits.iter().any(|&t| {
-                    implements_trait_with_env_from_iter(cx.tcx, cx.typing_env(), ty, t, None, [None::<
-                        ty::GenericArg<'tcx>,
-                    >])
+                    implements_trait_with_env_from_iter(
+                        cx.tcx,
+                        cx.typing_env(),
+                        ty,
+                        t,
+                        None,
+                        [None::<ty::GenericArg<'tcx>>],
+                    )
                 })
                 && !implements_borrow_trait
                 && !all_borrowable_trait
diff --git a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
index fa90ee60612..4f62ba2e58d 100644
--- a/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/neg_cmp_op_on_partial_ord.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::ty::implements_trait;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
@@ -48,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for NoNegCompOpForPartialOrd {
         if let ExprKind::Unary(UnOp::Not, inner) = expr.kind
             && let ExprKind::Binary(ref op, left, _) = inner.kind
             && let BinOpKind::Le | BinOpKind::Ge | BinOpKind::Lt | BinOpKind::Gt = op.node
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             let ty = cx.typeck_results().expr_ty(left);
 
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index 688374b5676..cc56df3a23d 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::HirIdSet;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
 
@@ -69,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
             for assoc_item in *items {
                 if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
                     let impl_item = cx.tcx.hir().impl_item(assoc_item.id);
-                    if in_external_macro(cx.sess(), impl_item.span) {
+                    if impl_item.span.in_external_macro(cx.sess().source_map()) {
                         return;
                     }
                     if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index ccd50758044..4d3e6aa79d0 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -12,7 +12,6 @@ use rustc_hir::{
 };
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
@@ -268,7 +267,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 
 fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
     if let StmtKind::Semi(expr) = stmt.kind
-        && !in_external_macro(cx.sess(), stmt.span)
+        && !stmt.span.in_external_macro(cx.sess().source_map())
         && let ctxt = stmt.span.ctxt()
         && expr.span.ctxt() == ctxt
         && let Some(reduced) = reduce_expression(cx, expr)
diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
index 9ee4e493277..b73b9083a99 100644
--- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
+++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
@@ -5,7 +5,7 @@ use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::{BytePos, Pos};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -37,14 +37,16 @@ declare_lint_pass!(NoMangleWithRustAbi => [NO_MANGLE_WITH_RUST_ABI]);
 
 impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
-        if let ItemKind::Fn { sig: fn_sig, .. } = &item.kind {
+        if let ItemKind::Fn { sig: fn_sig, .. } = &item.kind
+            && !item.span.from_expansion()
+        {
             let attrs = cx.tcx.hir().attrs(item.hir_id());
             let mut app = Applicability::MaybeIncorrect;
             let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(item.ident.span.lo()), "..", &mut app);
             for attr in attrs {
                 if let Some(ident) = attr.ident()
                     && ident.name == rustc_span::sym::no_mangle
-                    && fn_sig.header.abi == Abi::Rust
+                    && fn_sig.header.abi == ExternAbi::Rust
                     && let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn")
                     && !fn_attrs.contains("extern")
                 {
diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
index 94855c46567..dad1e8a3d6a 100644
--- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -5,7 +5,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::EarlyBinder;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
@@ -129,7 +128,7 @@ impl LateLintPass<'_> for NonCanonicalImpls {
         let ExprKind::Block(block, ..) = body.value.kind else {
             return;
         };
-        if in_external_macro(cx.sess(), block.span) || is_from_proc_macro(cx, impl_item) {
+        if block.span.in_external_macro(cx.sess().source_map()) || is_from_proc_macro(cx, impl_item) {
             return;
         }
 
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 8409d179b0f..405bbfc9c6f 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -5,6 +5,7 @@ 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::{InteriorMut, implements_trait};
+use rustc_abi::VariantIdx;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{
@@ -16,7 +17,6 @@ use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::impl_lint_pass;
 use rustc_span::{DUMMY_SP, Span, sym};
-use rustc_target::abi::VariantIdx;
 
 // FIXME: this is a correctness problem but there's no suitable
 // warn-by-default category.
@@ -89,16 +89,6 @@ declare_clippy_lint! {
     ///
     /// The `const` value should be stored inside a `static` item.
     ///
-    /// ### Known problems
-    /// When an enum has variants with interior mutability, use of its non
-    /// interior mutable variants can generate false positives. See issue
-    /// [#3962](https://github.com/rust-lang/rust-clippy/issues/3962)
-    ///
-    /// Types that have underlying or potential interior mutability trigger the lint whether
-    /// the interior mutable field is used or not. See issues
-    /// [#5812](https://github.com/rust-lang/rust-clippy/issues/5812) and
-    /// [#3825](https://github.com/rust-lang/rust-clippy/issues/3825)
-    ///
     /// ### Example
     /// ```no_run
     /// use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
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 56c4157d6fe..1a3b43cbb10 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -5,7 +5,6 @@ use rustc_ast::ast::{
 };
 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::{Span, sym};
@@ -381,7 +380,7 @@ impl<'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'_, 'tcx> {
 
 impl EarlyLintPass for NonExpressiveNames {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if in_external_macro(cx.sess(), item.span) {
+        if item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
@@ -396,7 +395,7 @@ impl EarlyLintPass for NonExpressiveNames {
     }
 
     fn check_impl_item(&mut self, cx: &EarlyContext<'_>, item: &AssocItem) {
-        if in_external_macro(cx.sess(), item.span) {
+        if item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
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 0caa19cd844..852c3885f56 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
@@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
                 }
             },
             _ => {},
-        };
+        }
     }
 }
 
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 793eb5d9456..9542fed3875 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
@@ -7,7 +7,6 @@ use rustc_ast::ImplPolarity;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{FieldDef, Item, ItemKind, Node};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
@@ -81,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
         // We start from `Send` impl instead of `check_field_def()` because
         // single `AdtDef` may have multiple `Send` impls due to generic
         // parameters, and the lint is much easier to implement in this way.
-        if !in_external_macro(cx.tcx.sess, item.span)
+        if !item.span.in_external_macro(cx.tcx.sess.source_map())
             && let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send)
             && let ItemKind::Impl(hir_impl) = &item.kind
             && let Some(trait_ref) = &hir_impl.of_trait
diff --git a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
new file mode 100644
index 00000000000..22116505a1c
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
@@ -0,0 +1,305 @@
+use clippy_config::Conf;
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
+use clippy_utils::msrvs::Msrv;
+use clippy_utils::visitors::for_each_expr;
+use clippy_utils::{def_path_def_ids, fn_def_id, path_def_id};
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::{CrateNum, DefId};
+use rustc_hir::{self as hir, BodyId, Expr, ExprKind, Item, ItemKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_session::impl_lint_pass;
+use rustc_span::Span;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Lints when `once_cell::sync::Lazy` or `lazy_static!` are used to define a static variable,
+    /// and suggests replacing such cases with `std::sync::LazyLock` instead.
+    ///
+    /// Note: This lint will not trigger in crate with `no_std` context, or with MSRV < 1.80.0. It
+    /// also will not trigger on `once_cell::sync::Lazy` usage in crates which use other types
+    /// from `once_cell`, such as `once_cell::race::OnceBox`.
+    ///
+    /// ### Why restrict this?
+    /// - Reduces the need for an extra dependency
+    /// - Enforce convention of using standard library types when possible
+    ///
+    /// ### Example
+    /// ```ignore
+    /// lazy_static! {
+    ///     static ref FOO: String = "foo".to_uppercase();
+    /// }
+    /// static BAR: once_cell::sync::Lazy<String> = once_cell::sync::Lazy::new(|| "BAR".to_lowercase());
+    /// ```
+    /// Use instead:
+    /// ```ignore
+    /// static FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "FOO".to_lowercase());
+    /// static BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "BAR".to_lowercase());
+    /// ```
+    #[clippy::version = "1.81.0"]
+    pub NON_STD_LAZY_STATICS,
+    pedantic,
+    "lazy static that could be replaced by `std::sync::LazyLock`"
+}
+
+/// A list containing functions with corresponding replacements in `LazyLock`.
+///
+/// Some functions could be replaced as well if we have replaced `Lazy` to `LazyLock`,
+/// therefore after suggesting replace the type, we need to make sure the function calls can be
+/// replaced, otherwise the suggestions cannot be applied thus the applicability should be
+/// `Unspecified` or `MaybeIncorret`.
+static FUNCTION_REPLACEMENTS: &[(&str, Option<&str>)] = &[
+    ("once_cell::sync::Lazy::force", Some("std::sync::LazyLock::force")),
+    ("once_cell::sync::Lazy::get", None), // `std::sync::LazyLock::get` is experimental
+    ("once_cell::sync::Lazy::new", Some("std::sync::LazyLock::new")),
+    // Note: `Lazy::{into_value, get_mut, force_mut}` are not in the list.
+    // Because the lint only checks for `static`s, and using these functions with statics
+    // will either be a hard error or triggers `static_mut_ref` that will be hard errors.
+    // But keep in mind that if somehow we decide to expand this lint to catch non-statics,
+    // add those functions into the list.
+];
+
+pub struct NonStdLazyStatic {
+    msrv: Msrv,
+    lazy_static_lazy_static: Vec<DefId>,
+    once_cell_crate: Vec<CrateNum>,
+    once_cell_sync_lazy: Vec<DefId>,
+    once_cell_sync_lazy_new: Vec<DefId>,
+    sugg_map: FxIndexMap<DefId, Option<String>>,
+    lazy_type_defs: FxIndexMap<DefId, LazyInfo>,
+    uses_other_once_cell_types: bool,
+}
+
+impl NonStdLazyStatic {
+    #[must_use]
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+            lazy_static_lazy_static: Vec::new(),
+            once_cell_crate: Vec::new(),
+            once_cell_sync_lazy: Vec::new(),
+            once_cell_sync_lazy_new: Vec::new(),
+            sugg_map: FxIndexMap::default(),
+            lazy_type_defs: FxIndexMap::default(),
+            uses_other_once_cell_types: false,
+        }
+    }
+}
+
+impl_lint_pass!(NonStdLazyStatic => [NON_STD_LAZY_STATICS]);
+
+/// Return if current MSRV does not meet the requirement for `lazy_cell` feature,
+/// or current context has `no_std` attribute.
+macro_rules! ensure_prerequisite {
+    ($msrv:expr, $cx:ident) => {
+        if !$msrv.meets(clippy_utils::msrvs::LAZY_CELL) || clippy_utils::is_no_std_crate($cx) {
+            return;
+        }
+    };
+}
+
+impl<'hir> LateLintPass<'hir> for NonStdLazyStatic {
+    extract_msrv_attr!(LateContext);
+
+    fn check_crate(&mut self, cx: &LateContext<'hir>) {
+        // Do not lint if current crate does not support `LazyLock`.
+        ensure_prerequisite!(self.msrv, cx);
+
+        // Fetch def_ids for external paths
+        self.lazy_static_lazy_static = def_path_def_ids(cx.tcx, &["lazy_static", "lazy_static"]).collect();
+        self.once_cell_sync_lazy = def_path_def_ids(cx.tcx, &["once_cell", "sync", "Lazy"]).collect();
+        self.once_cell_sync_lazy_new = def_path_def_ids(cx.tcx, &["once_cell", "sync", "Lazy", "new"]).collect();
+        // And CrateNums for `once_cell` crate
+        self.once_cell_crate = self.once_cell_sync_lazy.iter().map(|d| d.krate).collect();
+
+        // Convert hardcoded fn replacement list into a map with def_id
+        for (path, sugg) in FUNCTION_REPLACEMENTS {
+            let path_vec: Vec<&str> = path.split("::").collect();
+            for did in def_path_def_ids(cx.tcx, &path_vec) {
+                self.sugg_map.insert(did, sugg.map(ToOwned::to_owned));
+            }
+        }
+    }
+
+    fn check_item(&mut self, cx: &LateContext<'hir>, item: &Item<'hir>) {
+        ensure_prerequisite!(self.msrv, cx);
+
+        if let ItemKind::Static(..) = item.kind
+            && let Some(macro_call) = clippy_utils::macros::root_macro_call(item.span)
+            && self.lazy_static_lazy_static.contains(&macro_call.def_id)
+        {
+            span_lint(
+                cx,
+                NON_STD_LAZY_STATICS,
+                macro_call.span,
+                "this macro has been superceded by `std::sync::LazyLock`",
+            );
+            return;
+        }
+
+        if item.span.in_external_macro(cx.sess().source_map()) {
+            return;
+        }
+
+        if let Some(lazy_info) = LazyInfo::from_item(self, cx, item) {
+            self.lazy_type_defs.insert(item.owner_id.to_def_id(), lazy_info);
+        }
+    }
+
+    fn check_expr(&mut self, cx: &LateContext<'hir>, expr: &Expr<'hir>) {
+        ensure_prerequisite!(self.msrv, cx);
+
+        // All functions in the `FUNCTION_REPLACEMENTS` have only one args
+        if let ExprKind::Call(callee, [arg]) = expr.kind
+            && let Some(call_def_id) = fn_def_id(cx, expr)
+            && self.sugg_map.contains_key(&call_def_id)
+            && let ExprKind::Path(qpath) = arg.peel_borrows().kind
+            && let Some(arg_def_id) = cx.typeck_results().qpath_res(&qpath, arg.hir_id).opt_def_id()
+            && let Some(lazy_info) = self.lazy_type_defs.get_mut(&arg_def_id)
+        {
+            lazy_info.calls_span_and_id.insert(callee.span, call_def_id);
+        }
+    }
+
+    fn check_ty(&mut self, cx: &LateContext<'hir>, ty: &'hir rustc_hir::Ty<'hir, rustc_hir::AmbigArg>) {
+        ensure_prerequisite!(self.msrv, cx);
+
+        // Record if types from `once_cell` besides `sync::Lazy` are used.
+        if let rustc_hir::TyKind::Path(qpath) = ty.peel_refs().kind
+            && let Some(ty_def_id) = cx.qpath_res(&qpath, ty.hir_id).opt_def_id()
+            // Is from `once_cell` crate
+            && self.once_cell_crate.contains(&ty_def_id.krate)
+            // And is NOT `once_cell::sync::Lazy`
+            && !self.once_cell_sync_lazy.contains(&ty_def_id)
+        {
+            self.uses_other_once_cell_types = true;
+        }
+    }
+
+    fn check_crate_post(&mut self, cx: &LateContext<'hir>) {
+        ensure_prerequisite!(self.msrv, cx);
+
+        if !self.uses_other_once_cell_types {
+            for (_, lazy_info) in &self.lazy_type_defs {
+                lazy_info.lint(cx, &self.sugg_map);
+            }
+        }
+    }
+}
+
+struct LazyInfo {
+    /// Span of the [`hir::Ty`] without including args.
+    /// i.e.:
+    /// ```ignore
+    /// static FOO: Lazy<String> = Lazy::new(...);
+    /// //          ^^^^
+    /// ```
+    ty_span_no_args: Span,
+    /// `Span` and `DefId` of calls on `Lazy` type.
+    /// i.e.:
+    /// ```ignore
+    /// static FOO: Lazy<String> = Lazy::new(...);
+    /// //                         ^^^^^^^^^
+    /// ```
+    calls_span_and_id: FxIndexMap<Span, DefId>,
+}
+
+impl LazyInfo {
+    fn from_item(state: &NonStdLazyStatic, cx: &LateContext<'_>, item: &Item<'_>) -> Option<Self> {
+        // Check if item is a `once_cell:sync::Lazy` static.
+        if let ItemKind::Static(ty, _, body_id) = item.kind
+            && let Some(path_def_id) = path_def_id(cx, ty)
+            && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
+            && state.once_cell_sync_lazy.contains(&path_def_id)
+        {
+            let ty_span_no_args = path_span_without_args(path);
+            let body = cx.tcx.hir().body(body_id);
+
+            // visit body to collect `Lazy::new` calls
+            let mut new_fn_calls = FxIndexMap::default();
+            for_each_expr::<(), ()>(cx, body, |ex| {
+                if let Some((fn_did, call_span)) = fn_def_id_and_span_from_body(cx, ex, body_id)
+                    && state.once_cell_sync_lazy_new.contains(&fn_did)
+                {
+                    new_fn_calls.insert(call_span, fn_did);
+                }
+                std::ops::ControlFlow::Continue(())
+            });
+
+            Some(LazyInfo {
+                ty_span_no_args,
+                calls_span_and_id: new_fn_calls,
+            })
+        } else {
+            None
+        }
+    }
+
+    fn lint(&self, cx: &LateContext<'_>, sugg_map: &FxIndexMap<DefId, Option<String>>) {
+        // Applicability might get adjusted to `Unspecified` later if any calls
+        // in `calls_span_and_id` are not replaceable judging by the `sugg_map`.
+        let mut appl = Applicability::MachineApplicable;
+        let mut suggs = vec![(self.ty_span_no_args, "std::sync::LazyLock".to_string())];
+
+        for (span, def_id) in &self.calls_span_and_id {
+            let maybe_sugg = sugg_map.get(def_id).cloned().flatten();
+            if let Some(sugg) = maybe_sugg {
+                suggs.push((*span, sugg));
+            } else {
+                // If NO suggested replacement, not machine applicable
+                appl = Applicability::Unspecified;
+            }
+        }
+
+        span_lint_and_then(
+            cx,
+            NON_STD_LAZY_STATICS,
+            self.ty_span_no_args,
+            "this type has been superceded by `LazyLock` in the standard library",
+            |diag| {
+                diag.multipart_suggestion("use `std::sync::LazyLock` instead", suggs, appl);
+            },
+        );
+    }
+}
+
+/// Return the span of a given `Path` without including any of its args.
+///
+/// NB: Re-write of a private function `rustc_lint::non_local_def::path_span_without_args`.
+fn path_span_without_args(path: &hir::Path<'_>) -> Span {
+    path.segments
+        .last()
+        .and_then(|seg| seg.args)
+        .map_or(path.span, |args| path.span.until(args.span_ext))
+}
+
+/// Returns the `DefId` and `Span` of the callee if the given expression is a function call.
+///
+/// NB: Modified from [`clippy_utils::fn_def_id`], to support calling in an static `Item`'s body.
+fn fn_def_id_and_span_from_body(cx: &LateContext<'_>, expr: &Expr<'_>, body_id: BodyId) -> Option<(DefId, Span)> {
+    // FIXME: find a way to cache the result.
+    let typeck = cx.tcx.typeck_body(body_id);
+    match &expr.kind {
+        ExprKind::Call(
+            Expr {
+                kind: ExprKind::Path(qpath),
+                hir_id: path_hir_id,
+                span,
+                ..
+            },
+            ..,
+        ) => {
+            // Only return Fn-like DefIds, not the DefIds of statics/consts/etc that contain or
+            // deref to fn pointers, dyn Fn, impl Fn - #8850
+            if let Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) =
+                typeck.qpath_res(qpath, *path_hir_id)
+            {
+                Some((id, *span))
+            } else {
+                None
+            }
+        },
+        _ => None,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
index 2eae9b23746..6e7ee727965 100644
--- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs
+++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
@@ -4,7 +4,6 @@ use rustc_ast::token::LitKind;
 use rustc_ast::{Expr, ExprKind};
 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::{BytePos, Pos, SpanData};
 
@@ -59,7 +58,7 @@ impl EarlyLintPass for OctalEscapes {
                 LitKind::ByteStr | LitKind::CStr => 2,
                 _ => return,
             })
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
         {
             let s = lit.symbol.as_str();
             let mut iter = s.as_bytes().iter();
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index 0eca788c787..9d07a14718d 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -104,7 +104,7 @@ impl ArithmeticSideEffects {
 
             if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
                 return false;
-            };
+            }
 
             let int_type = substs.type_at(0);
             let unsigned_int_types = [
@@ -214,13 +214,13 @@ impl ArithmeticSideEffects {
                 | hir::BinOpKind::Sub
         ) {
             return;
-        };
+        }
         let (mut actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs);
         let (mut actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs);
         actual_lhs = expr_or_init(cx, actual_lhs);
         actual_rhs = expr_or_init(cx, actual_rhs);
         let lhs_ty = cx.typeck_results().expr_ty(actual_lhs).peel_refs();
-        let rhs_ty = cx.typeck_results().expr_ty(actual_rhs).peel_refs();
+        let rhs_ty = cx.typeck_results().expr_ty_adjusted(actual_rhs).peel_refs();
         if self.has_allowed_binary(lhs_ty, rhs_ty) {
             return;
         }
@@ -283,7 +283,7 @@ impl ArithmeticSideEffects {
         if ConstEvalCtxt::new(cx).eval_simple(receiver).is_some() {
             return;
         }
-        let instance_ty = cx.typeck_results().expr_ty(receiver);
+        let instance_ty = cx.typeck_results().expr_ty_adjusted(receiver);
         if !Self::is_integral(instance_ty) {
             return;
         }
@@ -311,7 +311,7 @@ impl ArithmeticSideEffects {
         if ConstEvalCtxt::new(cx).eval(un_expr).is_some() {
             return;
         }
-        let ty = cx.typeck_results().expr_ty(expr).peel_refs();
+        let ty = cx.typeck_results().expr_ty_adjusted(expr).peel_refs();
         if self.has_allowed_unary(ty) {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
index b0d872e98fd..cf6b8992973 100644
--- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs
@@ -104,7 +104,7 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool)
             } else {
                 expr_snip = arg_snip.to_string();
                 eq_impl = without_deref;
-            };
+            }
 
             let span;
             let hint;
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 1a0bfd8b997..10455d3b93a 100644
--- a/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
@@ -127,7 +127,7 @@ pub(super) fn check<'tcx>(
                 None,
                 note,
             );
-        };
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/operators/double_comparison.rs b/src/tools/clippy/clippy_lints/src/operators/double_comparison.rs
index d72a2fc3b1a..54f50f11e03 100644
--- a/src/tools/clippy/clippy_lints/src/operators/double_comparison.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/double_comparison.rs
@@ -49,5 +49,5 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, op: BinOpKind, lhs: &'tcx Expr
             lint_double_comparison!(==);
         },
         _ => (),
-    };
+    }
 }
diff --git a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
index 8272d3643d4..01dc6a27c33 100644
--- a/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/float_cmp.rs
@@ -120,7 +120,7 @@ fn is_float(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 
     if let ty::Array(arr_ty, _) = value {
         return matches!(arr_ty.kind(), ty::Float(_));
-    };
+    }
 
     matches!(value, ty::Float(_))
 }
diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs
index 9e8a821c3f4..9ad32c2bd39 100644
--- a/src/tools/clippy/clippy_lints/src/operators/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs
@@ -262,12 +262,9 @@ declare_clippy_lint! {
     /// to `trailing_zeros`
     ///
     /// ### Why is this bad?
-    /// `x.trailing_zeros() > 4` is much clearer than `x & 15
+    /// `x.trailing_zeros() >= 4` is much clearer than `x & 15
     /// == 0`
     ///
-    /// ### Known problems
-    /// llvm generates better code for `x & 15 == 0` on x86
-    ///
     /// ### Example
     /// ```no_run
     /// # let x = 1;
@@ -278,7 +275,7 @@ declare_clippy_lint! {
     ///
     /// ```no_run
     /// # let x: i32 = 1;
-    /// if x.trailing_zeros() > 4 { }
+    /// if x.trailing_zeros() >= 4 { }
     /// ```
     #[clippy::version = "pre 1.29.0"]
     pub VERBOSE_BIT_MASK,
diff --git a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
index c83bdda347a..691d7b904ef 100644
--- a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
@@ -30,7 +30,7 @@ pub(super) fn check<'tcx>(
         } else {
             check_non_const_operands(cx, e, lhs);
         }
-    };
+    }
 }
 
 fn used_in_comparison_with_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/operators/modulo_one.rs b/src/tools/clippy/clippy_lints/src/operators/modulo_one.rs
index 54eea14833f..fc5565e821e 100644
--- a/src/tools/clippy/clippy_lints/src/operators/modulo_one.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/modulo_one.rs
@@ -21,6 +21,6 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, op: BinOpKind, right:
                     "any number modulo -1 will panic/overflow or result in 0",
                 );
             }
-        };
+        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
index 82b9d10fbeb..c3c09946c27 100644
--- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
@@ -190,7 +190,8 @@ fn in_impl<'tcx>(
         && let Some(generic_args) = seg.args
         && let Some(GenericArg::Type(other_ty)) = generic_args.args.last()
     {
-        Some((item.self_ty, other_ty))
+        // `_` is not permitted in impl headers
+        Some((item.self_ty, other_ty.as_unambig_ty()))
     } else {
         None
     }
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 6d9e75f51d6..de9f055863c 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
@@ -7,7 +7,9 @@ use clippy_utils::{
 use rustc_errors::Applicability;
 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_hir::{
+    Arm, BindingMode, Expr, ExprKind, MatchSource, Mutability, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, UnOp,
+};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::SyntaxContext;
@@ -281,7 +283,11 @@ fn try_convert_match<'tcx>(
 
 fn is_none_or_err_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
     match arm.pat.kind {
-        PatKind::Path(ref qpath) => is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone),
+        PatKind::Expr(PatExpr {
+            kind: PatExprKind::Path(qpath),
+            hir_id,
+            ..
+        }) => is_res_lang_ctor(cx, cx.qpath_res(qpath, *hir_id), OptionNone),
         PatKind::TupleStruct(ref qpath, [first_pat], _) => {
             is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), ResultErr)
                 && matches!(first_pat.kind, PatKind::Wild)
diff --git a/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs b/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs
index 7f100a746d5..bc1821a48a3 100644
--- a/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs
+++ b/src/tools/clippy/clippy_lints/src/panicking_overflow_checks.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::eq_expr_value;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 
@@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for PanickingOverflowChecks {
             && matches!(ty.kind(), ty::Uint(_))
             && ty == typeck.expr_ty(op_rhs)
             && ty == typeck.expr_ty(other)
-            && !in_external_macro(cx.tcx.sess, expr.span)
+            && !expr.span.in_external_macro(cx.tcx.sess.source_map())
             && (eq_expr_value(cx, op_lhs, other) || (commutative && eq_expr_value(cx, op_rhs, other)))
         {
             span_lint(
diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
index 794bef7b321..55676522419 100644
--- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
@@ -53,6 +53,6 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
                     );
                 }
             }
-        };
+        }
     }
 }
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 b2089487a9f..a3e89671eec 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
@@ -19,7 +19,7 @@ use rustc_middle::ty::{self, RegionKind, TyCtxt};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{Span, sym};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -277,7 +277,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
         let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
         match kind {
             FnKind::ItemFn(.., header) => {
-                if header.abi != Abi::Rust {
+                if header.abi != ExternAbi::Rust {
                     return;
                 }
                 let attrs = cx.tcx.hir().attrs(hir_id);
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 668f09bbfd5..b653b459b04 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
@@ -7,7 +7,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, Symbol, sym};
 
@@ -136,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for PathbufThenPush<'tcx> {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && let ty = cx.typeck_results().pat_ty(local.pat)
             && is_type_diagnostic_item(cx, ty, sym::PathBuf)
         {
@@ -157,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for PathbufThenPush<'tcx> {
             && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
             && let [name] = &path.segments
             && let Res::Local(id) = path.res
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && let ty = cx.typeck_results().expr_ty(left)
             && is_type_diagnostic_item(cx, ty, sym::PathBuf)
         {
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 42fbba8ef6d..8f1a1ee76c6 100644
--- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
@@ -3,7 +3,6 @@ use rustc_hir::{
     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::Span;
@@ -84,7 +83,7 @@ declare_lint_pass!(PatternTypeMismatch => [PATTERN_TYPE_MISMATCH]);
 impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
         if let StmtKind::Let(local) = stmt.kind {
-            if in_external_macro(cx.sess(), local.pat.span) {
+            if local.pat.span.in_external_macro(cx.sess().source_map()) {
                 return;
             }
             let deref_possible = match local.source {
@@ -171,7 +170,7 @@ fn find_first_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(Span, Mut
         if result.is_some() {
             return false;
         }
-        if in_external_macro(cx.sess(), p.span) {
+        if p.span.in_external_macro(cx.sess().source_map()) {
             return true;
         }
         let adjust_pat = match p.kind {
diff --git a/src/tools/clippy/clippy_lints/src/precedence.rs b/src/tools/clippy/clippy_lints/src/precedence.rs
index 031f0931059..ec6835db897 100644
--- a/src/tools/clippy/clippy_lints/src/precedence.rs
+++ b/src/tools/clippy/clippy_lints/src/precedence.rs
@@ -3,17 +3,14 @@ use clippy_utils::source::snippet_with_applicability;
 use rustc_ast::ast::BinOpKind::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
 use rustc_ast::ast::{BinOpKind, Expr, ExprKind};
 use rustc_errors::Applicability;
-use rustc_lint::{EarlyContext, EarlyLintPass};
+use rustc_lint::{EarlyContext, EarlyLintPass, Lint};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for operations where precedence may be unclear
-    /// and suggests to add parentheses. Currently it catches the following:
-    /// * mixed usage of arithmetic and bit shifting/combining operators without
-    /// parentheses
-    /// * mixed usage of bitmasking and bit shifting operators without parentheses
+    /// Checks for operations where precedence may be unclear and suggests to add parentheses.
+    /// It catches a mixed usage of arithmetic and bit shifting/combining operators without parentheses
     ///
     /// ### Why is this bad?
     /// Not everyone knows the precedence of those operators by
@@ -21,15 +18,32 @@ declare_clippy_lint! {
     /// code.
     ///
     /// ### Example
-    /// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
-    /// * `0x2345 & 0xF000 >> 12` equals 5, while `(0x2345 & 0xF000) >> 12` equals 2
+    /// `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
     #[clippy::version = "pre 1.29.0"]
     pub PRECEDENCE,
     complexity,
     "operations where precedence may be unclear"
 }
 
-declare_lint_pass!(Precedence => [PRECEDENCE]);
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for bit shifting operations combined with bit masking/combining operators
+    /// and suggest using parentheses.
+    ///
+    /// ### Why restrict this?
+    /// Not everyone knows the precedence of those operators by
+    /// heart, so expressions like these may trip others trying to reason about the
+    /// code.
+    ///
+    /// ### Example
+    /// `0x2345 & 0xF000 >> 12` equals 5, while `(0x2345 & 0xF000) >> 12` equals 2
+    #[clippy::version = "1.86.0"]
+    pub PRECEDENCE_BITS,
+    restriction,
+    "operations mixing bit shifting with bit combining/masking"
+}
+
+declare_lint_pass!(Precedence => [PRECEDENCE, PRECEDENCE_BITS]);
 
 impl EarlyLintPass for Precedence {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
@@ -38,12 +52,12 @@ impl EarlyLintPass for Precedence {
         }
 
         if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.kind {
-            let span_sugg = |expr: &Expr, sugg, appl| {
+            let span_sugg = |lint: &'static Lint, expr: &Expr, sugg, appl| {
                 span_lint_and_sugg(
                     cx,
-                    PRECEDENCE,
+                    lint,
                     expr.span,
-                    "operator precedence can trip the unwary",
+                    "operator precedence might not be obvious",
                     "consider parenthesizing your expression",
                     sugg,
                     appl,
@@ -57,37 +71,41 @@ impl EarlyLintPass for Precedence {
             match (op, get_bin_opt(left), get_bin_opt(right)) {
                 (
                     BitAnd | BitOr | BitXor,
-                    Some(Shl | Shr | Add | Div | Mul | Rem | Sub),
-                    Some(Shl | Shr | Add | Div | Mul | Rem | Sub),
+                    Some(left_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)),
+                    Some(right_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)),
                 )
-                | (Shl | Shr, Some(Add | Div | Mul | Rem | Sub), Some(Add | Div | Mul | Rem | Sub)) => {
+                | (
+                    Shl | Shr,
+                    Some(left_op @ (Add | Div | Mul | Rem | Sub)),
+                    Some(right_op @ (Add | Div | Mul | Rem | Sub)),
+                ) => {
                     let sugg = format!(
                         "({}) {} ({})",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
                         op.as_str(),
                         snippet_with_applicability(cx, right.span, "..", &mut applicability)
                     );
-                    span_sugg(expr, sugg, applicability);
+                    span_sugg(lint_for(&[op, left_op, right_op]), expr, sugg, applicability);
                 },
-                (BitAnd | BitOr | BitXor, Some(Shl | Shr | Add | Div | Mul | Rem | Sub), _)
-                | (Shl | Shr, Some(Add | Div | Mul | Rem | Sub), _) => {
+                (BitAnd | BitOr | BitXor, Some(side_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)), _)
+                | (Shl | Shr, Some(side_op @ (Add | Div | Mul | Rem | Sub)), _) => {
                     let sugg = format!(
                         "({}) {} {}",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
                         op.as_str(),
                         snippet_with_applicability(cx, right.span, "..", &mut applicability)
                     );
-                    span_sugg(expr, sugg, applicability);
+                    span_sugg(lint_for(&[op, side_op]), expr, sugg, applicability);
                 },
-                (BitAnd | BitOr | BitXor, _, Some(Shl | Shr | Add | Div | Mul | Rem | Sub))
-                | (Shl | Shr, _, Some(Add | Div | Mul | Rem | Sub)) => {
+                (BitAnd | BitOr | BitXor, _, Some(side_op @ (Shl | Shr | Add | Div | Mul | Rem | Sub)))
+                | (Shl | Shr, _, Some(side_op @ (Add | Div | Mul | Rem | Sub))) => {
                     let sugg = format!(
                         "{} {} ({})",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
                         op.as_str(),
                         snippet_with_applicability(cx, right.span, "..", &mut applicability)
                     );
-                    span_sugg(expr, sugg, applicability);
+                    span_sugg(lint_for(&[op, side_op]), expr, sugg, applicability);
                 },
                 _ => (),
             }
@@ -106,3 +124,11 @@ fn get_bin_opt(expr: &Expr) -> Option<BinOpKind> {
 fn is_bit_op(op: BinOpKind) -> bool {
     matches!(op, BitXor | BitAnd | BitOr | Shl | Shr)
 }
+
+fn lint_for(ops: &[BinOpKind]) -> &'static Lint {
+    if ops.iter().all(|op| is_bit_op(*op)) {
+        PRECEDENCE_BITS
+    } else {
+        PRECEDENCE
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 506adf0f2cc..7fba4b6a6c8 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -1,5 +1,6 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::source::SpanRangeExt;
+use clippy_utils::sugg::Sugg;
 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, std_or_core};
 use hir::LifetimeName;
@@ -18,7 +19,7 @@ use rustc_middle::ty::{self, Binder, ClauseKind, ExistentialPredicate, List, Pre
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, sym};
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use std::{fmt, iter};
@@ -159,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
             check_mut_from_ref(cx, sig, None);
 
-            if !matches!(sig.header.abi, Abi::Rust) {
+            if !matches!(sig.header.abi, ExternAbi::Rust) {
                 // Ignore `extern` functions with non-Rust calling conventions
                 return;
             }
@@ -219,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
         check_mut_from_ref(cx, sig, Some(body));
 
-        if !matches!(sig.header.abi, Abi::Rust) {
+        if !matches!(sig.header.abi, ExternAbi::Rust) {
             // Ignore `extern` functions with non-Rust calling conventions
             return;
         }
@@ -250,15 +251,24 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if let ExprKind::Binary(ref op, l, r) = expr.kind {
-            if (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne) && (is_null_path(cx, l) || is_null_path(cx, r)) {
-                span_lint(
-                    cx,
-                    CMP_NULL,
-                    expr.span,
-                    "comparing with null is better expressed by the `.is_null()` method",
-                );
-            }
+        if let ExprKind::Binary(op, l, r) = expr.kind
+            && (op.node == BinOpKind::Eq || op.node == BinOpKind::Ne)
+        {
+            let non_null_path_snippet = match (is_null_path(cx, l), is_null_path(cx, r)) {
+                (true, false) if let Some(sugg) = Sugg::hir_opt(cx, r) => sugg.maybe_par(),
+                (false, true) if let Some(sugg) = Sugg::hir_opt(cx, l) => sugg.maybe_par(),
+                _ => return,
+            };
+
+            span_lint_and_sugg(
+                cx,
+                CMP_NULL,
+                expr.span,
+                "comparing with null is better expressed by the `.is_null()` method",
+                "try",
+                format!("{non_null_path_snippet}.is_null()"),
+                Applicability::MachineApplicable,
+            );
         } else {
             check_invalid_ptr_usage(cx, expr);
         }
diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs
index 23d0e768c2f..c6e6e782f9d 100644
--- a/src/tools/clippy/clippy_lints/src/raw_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs
@@ -5,7 +5,6 @@ use rustc_ast::ast::{Expr, ExprKind};
 use rustc_ast::token::LitKind;
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, Span};
 use std::iter::once;
@@ -72,7 +71,7 @@ impl RawStrings {
 impl EarlyLintPass for RawStrings {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
         if let ExprKind::FormatArgs(format_args) = &expr.kind
-            && !in_external_macro(cx.sess(), format_args.span)
+            && !format_args.span.in_external_macro(cx.sess().source_map())
             && format_args.span.check_source_text(cx, |src| src.starts_with('r'))
             && let Some(str) = snippet_opt(cx.sess(), format_args.span)
             && let count_hash = str.bytes().skip(1).take_while(|b| *b == b'#').count()
@@ -95,7 +94,7 @@ impl EarlyLintPass for RawStrings {
                 LitKind::CStrRaw(max) => ("cr", max),
                 _ => return,
             }
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && expr.span.check_source_text(cx, |src| src.starts_with(prefix))
         {
             self.check_raw_string(cx, lit.symbol.as_str(), expr.span, prefix, max, lit.kind.descr());
diff --git a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
index 3ade6bcee84..65fd312b3a0 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_async_block.rs
@@ -10,7 +10,6 @@ use rustc_hir::{
     Closure, ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, ExprKind, MatchSource,
 };
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::UpvarCapture;
 use rustc_session::declare_lint_pass;
 
@@ -47,7 +46,7 @@ declare_lint_pass!(RedundantAsyncBlock => [REDUNDANT_ASYNC_BLOCK]);
 impl<'tcx> LateLintPass<'tcx> for RedundantAsyncBlock {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let span = expr.span;
-        if !in_external_macro(cx.tcx.sess, span) &&
+        if !span.in_external_macro(cx.tcx.sess.source_map()) &&
             let Some(body_expr) = desugar_async_block(cx, expr) &&
             let Some(expr) = desugar_await(peel_blocks(body_expr)) &&
             // The await prefix must not come from a macro as its content could change in the future.
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index b9e0106fc86..fb1bc494bd9 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -349,10 +349,14 @@ 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 41a44de536b..91d023500ca 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -10,7 +10,6 @@ use rustc_hir::{
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::ExpnKind;
@@ -138,7 +137,7 @@ fn get_parent_call_exprs<'tcx>(
 
 impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
@@ -208,7 +207,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                         // avoid clippy::double_parens
                         if !is_in_fn_call_arg {
                             hint = hint.maybe_par();
-                        };
+                        }
 
                         diag.span_suggestion(full_expr.span, "try doing something like", hint, applicability);
                     }
diff --git a/src/tools/clippy/clippy_lints/src/redundant_else.rs b/src/tools/clippy/clippy_lints/src/redundant_else.rs
index a27f9b63114..a1b5a3aff32 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_else.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_else.rs
@@ -1,9 +1,12 @@
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::{indent_of, reindent_multiline, snippet};
 use rustc_ast::ast::{Block, Expr, ExprKind, Stmt, StmtKind};
 use rustc_ast::visit::{Visitor, walk_expr};
+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::Span;
+use std::borrow::Cow;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -46,7 +49,7 @@ declare_lint_pass!(RedundantElse => [REDUNDANT_ELSE]);
 
 impl EarlyLintPass for RedundantElse {
     fn check_stmt(&mut self, cx: &EarlyContext<'_>, stmt: &Stmt) {
-        if in_external_macro(cx.sess(), stmt.span) {
+        if stmt.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         // Only look at expressions that are a whole statement
@@ -76,13 +79,27 @@ impl EarlyLintPass for RedundantElse {
                 _ => break,
             }
         }
-        span_lint_and_help(
+
+        let mut app = Applicability::MachineApplicable;
+        if let ExprKind::Block(block, _) = &els.kind {
+            for stmt in &block.stmts {
+                // If the `else` block contains a local binding or a macro invocation, Clippy shouldn't auto-fix it
+                if matches!(&stmt.kind, StmtKind::Let(_) | StmtKind::MacCall(_)) {
+                    app = Applicability::Unspecified;
+                    break;
+                }
+            }
+        }
+
+        // FIXME: The indentation of the suggestion would be the same as the one of the macro invocation in this implementation, see https://github.com/rust-lang/rust-clippy/pull/13936#issuecomment-2569548202
+        span_lint_and_sugg(
             cx,
             REDUNDANT_ELSE,
-            els.span,
+            els.span.with_lo(then.span.hi()),
             "redundant else block",
-            None,
             "remove the `else` block and move the contents out",
+            make_sugg(cx, els.span, "..", Some(expr.span)).to_string(),
+            app,
         );
     }
 }
@@ -137,3 +154,23 @@ impl BreakVisitor {
         self.check(stmt, Self::visit_stmt)
     }
 }
+
+// Extract the inner contents of an `else` block str
+// e.g. `{ foo(); bar(); }` -> `foo(); bar();`
+fn extract_else_block(mut block: &str) -> String {
+    block = block.strip_prefix("{").unwrap_or(block);
+    block = block.strip_suffix("}").unwrap_or(block);
+    block.trim_end().to_string()
+}
+
+fn make_sugg<'a>(
+    cx: &EarlyContext<'_>,
+    els_span: Span,
+    default: &'a str,
+    indent_relative_to: Option<Span>,
+) -> Cow<'a, str> {
+    let extracted = extract_else_block(&snippet(cx, els_span, default));
+    let indent = indent_relative_to.and_then(|s| indent_of(cx, s));
+
+    reindent_multiline(extracted.into(), false, indent)
+}
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 347540e7344..707abc008a8 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -4,7 +4,6 @@ use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::ast::{Expr, ExprKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
@@ -56,7 +55,7 @@ impl EarlyLintPass for RedundantFieldNames {
             return;
         }
 
-        if in_external_macro(cx.sess(), expr.span) {
+        if expr.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         if let ExprKind::Struct(ref se) = expr.kind {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 658d93e634c..ebe3e7c2019 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -6,7 +6,6 @@ use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, ByRef, ExprKind, HirId, LetStmt, Node, Pat, PatKind, QPath};
 use rustc_hir_typeck::expr_use_visitor::PlaceBase;
 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::DesugaringKind;
@@ -69,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
             // the local does not affect the code's drop behavior
             && !needs_ordered_drop(cx, cx.typeck_results().expr_ty(expr))
             // the local is user-controlled
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, expr)
             && !is_by_value_closure_capture(cx, local.hir_id, binding_id)
         {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
index 1b557730eca..6a17b83b3d0 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::HasSession;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Item, ItemKind};
@@ -49,6 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
             && !cx.effective_visibilities.is_exported(item.owner_id.def_id)
             && self.is_exported.last() == Some(&false)
             && is_not_macro_export(item)
+            && !item.span.in_external_macro(cx.sess().source_map())
         {
             let span = item.span.with_hi(item.ident.span.hi());
             let descr = cx.tcx.def_kind(item.owner_id).descr(item.owner_id.to_def_id());
diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
index 81556f39614..7bd4d6e993b 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
@@ -215,6 +215,6 @@ impl LateLintPass<'_> for RedundantTypeAnnotations {
                 },
                 _ => (),
             }
-        };
+        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
index 7d59bf24d93..074345e7532 100644
--- a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::last_path_segment;
 use clippy_utils::source::snippet;
 use rustc_errors::Applicability;
-use rustc_hir::{GenericArg, GenericArgsParentheses, Mutability, Ty, TyKind};
+use rustc_hir::{AmbigArg, GenericArg, GenericArgsParentheses, Mutability, Ty, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
@@ -36,7 +36,7 @@ declare_clippy_lint! {
 declare_lint_pass!(RefOptionRef => [REF_OPTION_REF]);
 
 impl<'tcx> LateLintPass<'tcx> for RefOptionRef {
-    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) {
         if let TyKind::Ref(_, ref mut_ty) = ty.kind
             && mut_ty.mutbl == Mutability::Not
             && let TyKind::Path(qpath) = &mut_ty.ty.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 f54cafffb83..5dddf9263a3 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
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::VecArgs;
 use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::source::snippet;
-use clippy_utils::{expr_or_init, fn_def_id};
+use clippy_utils::{expr_or_init, fn_def_id, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -93,6 +93,7 @@ fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) {
         && let ExprKind::Call(_, [repeat_expr]) = expr.kind
         && fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did))
         && !repeat_expr.span.from_expansion()
+        && let Some(exec_context) = std_or_core(cx)
     {
         emit_lint(
             cx,
@@ -100,7 +101,10 @@ fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) {
             "iter::repeat",
             "none of the yielded `Vec`s will have the requested capacity",
             "if you intended to create an iterator that yields `Vec`s with an initial capacity, try",
-            format!("std::iter::repeat_with(|| {})", snippet(cx, repeat_expr.span, "..")),
+            format!(
+                "{exec_context}::iter::repeat_with(|| {})",
+                snippet(cx, repeat_expr.span, "..")
+            ),
         );
     }
 }
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 6157adad059..152d7450f5f 100644
--- a/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/reserve_after_initialization.rs
@@ -6,7 +6,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
@@ -72,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingMode::MUT, id, _, None) = local.pat.kind
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, init_expr)
             && !matches!(
                 init,
@@ -101,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
             && let ExprKind::Assign(left, right, _) = expr.kind
             && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
             && let Res::Local(id) = path.res
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, right)
             && !matches!(
                 init,
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 42d9cf2c88c..5a25483c397 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
@@ -5,7 +5,6 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::FnKind;
 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::{Span, sym};
 
@@ -69,7 +68,7 @@ declare_clippy_lint! {
 declare_lint_pass!(ReturnSelfNotMustUse => [RETURN_SELF_NOT_MUST_USE]);
 
 fn check_method(cx: &LateContext<'_>, decl: &FnDecl<'_>, fn_def: LocalDefId, span: Span, owner_id: OwnerId) {
-    if !in_external_macro(cx.sess(), span)
+    if !span.in_external_macro(cx.sess().source_map())
         // If it comes from an external macro, better ignore it.
         && decl.implicit_self.has_implicit_self()
         // We only show this warning for public exported methods.
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index dfaee8cc305..a1cf16e6ce9 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -1,10 +1,11 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::source::{SpanRangeExt, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::visitors::{Descend, for_each_expr, for_each_unconsumed_temporary};
+use clippy_utils::visitors::{Descend, for_each_expr};
 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,
+    binary_expr_needs_parentheses, fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor,
+    leaks_droppable_temporary_with_limited_lifetime, path_res, path_to_local_id, span_contains_cfg,
+    span_find_starting_semi,
 };
 use core::ops::ControlFlow;
 use rustc_ast::MetaItemInner;
@@ -16,7 +17,6 @@ use rustc_hir::{
     StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass, Level, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::{self, GenericArgKind, Ty};
 use rustc_session::declare_lint_pass;
@@ -190,7 +190,7 @@ fn stmt_needs_never_type(cx: &LateContext<'_>, stmt_hir_id: HirId) -> bool {
 
 impl<'tcx> LateLintPass<'tcx> for Return {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
-        if !in_external_macro(cx.sess(), stmt.span)
+        if !stmt.span.in_external_macro(cx.sess().source_map())
             && let StmtKind::Semi(expr) = stmt.kind
             && let ExprKind::Ret(Some(ret)) = expr.kind
             // return Err(...)? desugars to a match
@@ -236,8 +236,8 @@ impl<'tcx> LateLintPass<'tcx> for Return {
             && let PatKind::Binding(_, local_id, _, _) = local.pat.kind
             && path_to_local_id(retexpr, local_id)
             && !last_statement_borrows(cx, initexpr)
-            && !in_external_macro(cx.sess(), initexpr.span)
-            && !in_external_macro(cx.sess(), retexpr.span)
+            && !initexpr.span.in_external_macro(cx.sess().source_map())
+            && !retexpr.span.in_external_macro(cx.sess().source_map())
             && !local.span.from_expansion()
             && !span_contains_cfg(cx, stmt.span.between(retexpr.span))
         {
@@ -389,22 +389,8 @@ fn check_final_expr<'tcx>(
                 }
             };
 
-            if let Some(inner) = inner {
-                if for_each_unconsumed_temporary(cx, inner, |temporary_ty| {
-                    if temporary_ty.has_significant_drop(cx.tcx, cx.typing_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 inner.is_some_and(|inner| leaks_droppable_temporary_with_limited_lifetime(cx, inner)) {
+                return;
             }
 
             if ret_span.from_expansion() || is_from_proc_macro(cx, expr) {
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 8d31641d483..29914d4379f 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -62,10 +62,13 @@ 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/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
index 0176077c70e..fdbccbaa8a5 100644
--- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
@@ -6,7 +6,6 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{Expr, ExprKind, HirId, Node};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
@@ -88,7 +87,7 @@ impl SingleCallFn {
         fn_span: Span,
     ) -> bool {
         (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(fn_def_id))
-            || in_external_macro(cx.sess(), fn_span)
+            || fn_span.in_external_macro(cx.sess().source_map())
             || cx
                 .tcx
                 .hir()
diff --git a/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs b/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs
index d92b890950a..50a6ee316c8 100644
--- a/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs
+++ b/src/tools/clippy/clippy_lints/src/single_char_lifetime_names.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::ast::{GenericParam, GenericParamKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -42,7 +41,7 @@ declare_lint_pass!(SingleCharLifetimeNames => [SINGLE_CHAR_LIFETIME_NAMES]);
 
 impl EarlyLintPass for SingleCharLifetimeNames {
     fn check_generic_param(&mut self, ctx: &EarlyContext<'_>, param: &GenericParam) {
-        if in_external_macro(ctx.sess(), param.ident.span) {
+        if param.ident.span.in_external_macro(ctx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs b/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
index 9737b84cdb9..2d989b1cf0b 100644
--- a/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
+++ b/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
@@ -1,9 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::get_trait_def_id;
 use clippy_utils::higher::VecArgs;
 use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
+use clippy_utils::{get_trait_def_id, is_no_std_crate};
 use rustc_ast::{LitIntType, LitKind, UintTy};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, LangItem, QPath, StructTailExpr};
@@ -125,7 +125,7 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
                     span,
                     format!("{suggested_type} of `Range` that is only one element"),
                     |diag| {
-                        if should_emit_every_value {
+                        if should_emit_every_value && !is_no_std_crate(cx) {
                             diag.span_suggestion(
                                 span,
                                 "if you wanted a `Vec` that contains the entire range, try",
diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
index db1c75fc3de..b22c638fc36 100644
--- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
+++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs
@@ -63,8 +63,7 @@ fn get_pointee_ty_and_count_expr<'tcx>(
     cx: &LateContext<'tcx>,
     expr: &'tcx Expr<'_>,
 ) -> Option<(Ty<'tcx>, &'tcx Expr<'tcx>)> {
-    const METHODS: [&str; 11] = [
-        "write_bytes",
+    const METHODS: [&str; 10] = [
         "copy_to",
         "copy_from",
         "copy_to_nonoverlapping",
@@ -79,7 +78,7 @@ fn get_pointee_ty_and_count_expr<'tcx>(
 
     if let ExprKind::Call(func, [.., count]) = expr.kind
         // Find calls to ptr::{copy, copy_nonoverlapping}
-        // and ptr::{swap_nonoverlapping, write_bytes},
+        // and ptr::swap_nonoverlapping,
         && let ExprKind::Path(ref func_qpath) = func.kind
         && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id()
         && matches!(cx.tcx.get_diagnostic_name(def_id), Some(
@@ -88,7 +87,6 @@ fn get_pointee_ty_and_count_expr<'tcx>(
             | sym::ptr_slice_from_raw_parts
             | sym::ptr_slice_from_raw_parts_mut
             | sym::ptr_swap_nonoverlapping
-            | sym::ptr_write_bytes
             | sym::slice_from_raw_parts
             | sym::slice_from_raw_parts_mut
         ))
@@ -97,9 +95,9 @@ fn get_pointee_ty_and_count_expr<'tcx>(
         && let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).types().next()
     {
         return Some((pointee_ty, count));
-    };
+    }
     if let ExprKind::MethodCall(method_path, ptr_self, [.., count], _) = expr.kind
-        // Find calls to copy_{from,to}{,_nonoverlapping} and write_bytes methods
+        // Find calls to copy_{from,to}{,_nonoverlapping}
         && let method_ident = method_path.ident.as_str()
         && METHODS.iter().any(|m| *m == method_ident)
 
@@ -108,7 +106,7 @@ fn get_pointee_ty_and_count_expr<'tcx>(
             cx.typeck_results().expr_ty(ptr_self).kind()
     {
         return Some((*pointee_ty, count));
-    };
+    }
     None
 }
 
@@ -121,6 +119,8 @@ impl<'tcx> LateLintPass<'tcx> for SizeOfInElementCount {
              instead of a count of elements of `T`";
 
         if let Some((pointee_ty, count_expr)) = get_pointee_ty_and_count_expr(cx, expr)
+            // Using a number of bytes for a byte type isn't suspicious
+            && pointee_ty != cx.tcx.types.u8
             // Find calls to functions with an element count parameter and get
             // the pointee type and count parameter expression
 
@@ -130,6 +130,6 @@ impl<'tcx> LateLintPass<'tcx> for SizeOfInElementCount {
             && pointee_ty == ty_used_for_size_of
         {
             span_lint_and_help(cx, SIZE_OF_IN_ELEMENT_COUNT, count_expr.span, LINT_MSG, None, HELP_MSG);
-        };
+        }
     }
 }
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 d2d693eaa1f..d26288adb39 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -3,6 +3,7 @@ use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
     SpanlessEq, get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local, path_to_local_id,
+    span_contains_comment,
 };
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_stmt};
@@ -190,7 +191,7 @@ impl SlowVectorInit {
             InitializationType::Extend(e) | InitializationType::Resize(e) => {
                 Self::emit_lint(cx, e, vec_alloc, "slow zero-filling initialization");
             },
-        };
+        }
     }
 
     fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &'static str) {
@@ -206,6 +207,14 @@ impl SlowVectorInit {
         let span_to_replace = slow_fill
             .span
             .with_lo(vec_alloc.allocation_expr.span.source_callsite().lo());
+
+        // If there is no comment in `span_to_replace`, Clippy can automatically fix the code.
+        let app = if span_contains_comment(cx.tcx.sess.source_map(), span_to_replace) {
+            Applicability::Unspecified
+        } else {
+            Applicability::MachineApplicable
+        };
+
         span_lint_and_sugg(
             cx,
             SLOW_VECTOR_INITIALIZATION,
@@ -213,7 +222,7 @@ impl SlowVectorInit {
             msg,
             "consider replacing this with",
             format!("vec![0; {len_expr}]"),
-            Applicability::Unspecified,
+            app,
         );
     }
 }
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 8ec7bfe9edd..59c13a1e2c5 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
@@ -8,7 +8,6 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{HirId, Path, PathSegment};
 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::{Span, sym};
@@ -112,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
         if let Res::Def(_, def_id) = path.res
             && let Some(first_segment) = get_first_segment(path)
             && is_stable(cx, def_id, &self.msrv)
-            && !in_external_macro(cx.sess(), path.span)
+            && !path.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, &first_segment.ident)
         {
             let (lint, used_mod, replace_with) = match first_segment.ident.name {
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 2925f355d0b..6164a6191db 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -9,7 +9,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, LangItem, Node, QPath};
 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::source_map::Spanned;
@@ -147,7 +146,7 @@ declare_lint_pass!(StringAdd => [STRING_ADD, STRING_ADD_ASSIGN, STRING_SLICE]);
 
 impl<'tcx> LateLintPass<'tcx> for StringAdd {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), e.span) {
+        if e.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
         match e.kind {
@@ -284,7 +283,7 @@ impl<'tcx> LateLintPass<'tcx> for StringLitAsBytes {
             );
         }
 
-        if !in_external_macro(cx.sess(), e.span)
+        if !e.span.in_external_macro(cx.sess().source_map())
             && let ExprKind::MethodCall(path, receiver, ..) = &e.kind
             && path.ident.name.as_str() == "as_bytes"
             && let ExprKind::Lit(lit) = &receiver.kind
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
index d1d822a5532..e55d17818e4 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_xor_used_as_pow.rs
@@ -5,7 +5,6 @@ use rustc_ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -32,7 +31,7 @@ declare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR_USED_AS_POW]);
 
 impl LateLintPass<'_> for ConfusingXorAndPow {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
-        if !in_external_macro(cx.sess(), expr.span)
+        if !expr.span.in_external_macro(cx.sess().source_map())
             && let ExprKind::Binary(op, left, right) = &expr.kind
             && op.node == BinOpKind::BitXor
             && left.span.eq_ctxt(right.span)
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index ff116800512..7176d533b61 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -12,7 +12,6 @@ use rustc_hir::intravisit::{Visitor, walk_expr};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
 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::source_map::Spanned;
@@ -212,7 +211,7 @@ fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) {
         if let Some((lhs0, rhs0)) = parse(first)
             && let Some((lhs1, rhs1)) = parse(second)
             && first.span.eq_ctxt(second.span)
-			&& !in_external_macro(cx.sess(), first.span)
+			&& !first.span.in_external_macro(cx.sess().source_map())
             && is_same(cx, lhs0, rhs1)
             && is_same(cx, lhs1, rhs0)
 			&& !is_same(cx, lhs1, rhs1) // Ignore a = b; a = a (#10421)
@@ -296,7 +295,7 @@ fn check_xor_swap<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         {
             let span = s1.span.to(s3.span);
             generate_swap_warning(block, cx, lhs0, rhs0, rhs1, rhs2, span, true);
-        };
+        }
     }
 }
 
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 569812d8106..9993e6ae18b 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
@@ -55,13 +55,11 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
                     if 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 99844beb8f0..790e0965198 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -10,8 +10,8 @@ use rustc_data_structures::unhash::UnhashMap;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{
-    BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment, PredicateOrigin, QPath,
-    TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicateKind,
+    AmbigArg, BoundPolarity, GenericBound, Generics, Item, ItemKind, LangItem, Node, Path, PathSegment,
+    PredicateOrigin, QPath, TraitBoundModifiers, TraitItem, TraitRef, Ty, TyKind, WherePredicateKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
@@ -171,7 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx>) {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, ty: &'tcx Ty<'tcx, AmbigArg>) {
         if let TyKind::Ref(.., mut_ty) = &ty.kind
             && let TyKind::TraitObject(bounds, ..) = mut_ty.ty.kind
             && bounds.len() > 2
diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
index b2892d136fa..4961dd6b280 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_errors::Applicability;
 use rustc_hir::{GenericArg, HirId, LetStmt, Node, Path, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
 
 use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
@@ -44,17 +43,13 @@ pub(super) fn check<'tcx>(
     expr_hir_id: HirId,
 ) -> bool {
     let last = path.segments.last().unwrap();
-    if in_external_macro(cx.tcx.sess, last.ident.span) {
+    if last.ident.span.in_external_macro(cx.tcx.sess.source_map()) {
         // If it comes from a non-local macro, we ignore it.
         return false;
     }
     let args = last.args;
     let missing_generic = match args {
-        Some(args) if !args.args.is_empty() => args.args.iter().any(|arg| match arg {
-            GenericArg::Infer(_) => true,
-            GenericArg::Type(ty) => matches!(ty.kind, TyKind::Infer),
-            _ => false,
-        }),
+        Some(args) if !args.args.is_empty() => args.args.iter().any(|arg| matches!(arg, GenericArg::Infer(_))),
         _ => true,
     };
     if !missing_generic {
@@ -65,7 +60,7 @@ pub(super) fn check<'tcx>(
         // ... which does have type annotations.
         if let Some(ty) = local.ty
             // If this is a `let x: _ =`, we should lint.
-            && !matches!(ty.kind, TyKind::Infer)
+            && !matches!(ty.kind, TyKind::Infer(()))
         {
             return false;
         }
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
index 3729dfd3e86..f27aaa2fa77 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
@@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(
 
     if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) {
         return false;
-    };
+    }
 
     let int_ty = substs.type_at(0);
     if from_ty != int_ty {
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 99a55f9fc35..c7aefc65f70 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -7,7 +7,6 @@ use itertools::Itertools;
 use rustc_ast::LitKind;
 use rustc_hir::{Expr, ExprKind, Node, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
 use std::iter::once;
@@ -56,7 +55,7 @@ impl TupleArrayConversions {
 
 impl LateLintPass<'_> for TupleArrayConversions {
     fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if in_external_macro(cx.sess(), expr.span) || !self.msrv.meets(msrvs::TUPLE_ARRAY_CONVERSIONS) {
+        if expr.span.in_external_macro(cx.sess().source_map()) || !self.msrv.meets(msrvs::TUPLE_ARRAY_CONVERSIONS) {
             return;
         }
 
@@ -119,7 +118,7 @@ fn check_tuple<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, elements: &
                         && let LitKind::Int(val, _) = lit.node
                     {
                         return (val == i as u128).then_some(lhs);
-                    };
+                    }
 
                     None
                 })
diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
index bde88ab61ad..2e97772407f 100644
--- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs
@@ -25,7 +25,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
                     _ => None,
                 })
             {
-                if is_any_trait(cx, inner) {
+                if is_any_trait(cx, inner.as_unambig_ty()) {
                     // Ignore `Box<Any>` types; see issue #1884 for details.
                     return false;
                 }
@@ -47,7 +47,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
                 // Originally reported as the issue #3128.
                 let inner_snippet = snippet(cx, inner.span, "..");
                 let suggestion = match &inner.kind {
-                    TyKind::TraitObject(bounds, lt_bound, _) if bounds.len() > 1 || !lt_bound.is_elided() => {
+                    TyKind::TraitObject(bounds, lt_bound) if bounds.len() > 1 || !lt_bound.is_elided() => {
                         format!("&{ltopt}({inner_snippet})")
                     },
                     TyKind::Path(qpath)
@@ -71,7 +71,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
                     Applicability::Unspecified,
                 );
                 return true;
-            };
+            }
             false
         },
         _ => false,
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 43cce625c64..579cbf447a2 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -386,22 +386,30 @@ 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,
-            in_body: matches!(fn_kind, FnKind::Closure),
-            is_exported,
-            ..CheckTyContext::default()
-        });
+        self.check_fn_decl(
+            cx,
+            decl,
+            CheckTyContext {
+                is_in_trait_impl,
+                in_body: matches!(fn_kind, FnKind::Closure),
+                is_exported,
+                ..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
             _ => (),
         }
@@ -419,10 +427,14 @@ 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
@@ -438,10 +450,14 @@ 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>) {
@@ -469,10 +485,14 @@ 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()
+                },
+            );
         }
     }
 }
@@ -560,7 +580,7 @@ impl Types {
                                     _ => None,
                                 })
                         }) {
-                            self.check_ty(cx, ty, context);
+                            self.check_ty(cx, ty.as_unambig_ty(), context);
                         }
                     },
                     QPath::Resolved(None, p) => {
@@ -574,7 +594,7 @@ impl Types {
                                     _ => None,
                                 })
                         }) {
-                            self.check_ty(cx, ty, context);
+                            self.check_ty(cx, ty.as_unambig_ty(), context);
                         }
                     },
                     QPath::TypeRelative(ty, seg) => {
@@ -585,7 +605,7 @@ impl Types {
                                 GenericArg::Type(ty) => Some(ty),
                                 _ => None,
                             }) {
-                                self.check_ty(cx, ty, context);
+                                self.check_ty(cx, ty.as_unambig_ty(), context);
                             }
                         }
                     },
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 b89bd6a8d05..0704653385f 100644
--- a/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/types/type_complexity.rs
@@ -1,16 +1,16 @@
 use clippy_utils::diagnostics::span_lint;
-use rustc_hir as hir;
-use rustc_hir::intravisit::{Visitor, walk_inf, walk_ty};
-use rustc_hir::{GenericParamKind, TyKind};
+use rustc_abi::ExternAbi;
+use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_ty};
+use rustc_hir::{self as hir, AmbigArg, GenericParamKind, TyKind};
 use rustc_lint::LateContext;
-use rustc_target::spec::abi::Abi;
+use rustc_span::Span;
 
 use super::TYPE_COMPLEXITY;
 
 pub(super) fn check(cx: &LateContext<'_>, ty: &hir::Ty<'_>, type_complexity_threshold: u64) -> bool {
     let score = {
         let mut visitor = TypeComplexityVisitor { score: 0, nest: 1 };
-        visitor.visit_ty(ty);
+        visitor.visit_ty_unambig(ty);
         visitor.score
     };
 
@@ -36,23 +36,23 @@ struct TypeComplexityVisitor {
 }
 
 impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
-    fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
+    fn visit_infer(&mut self, inf_id: hir::HirId, _inf_span: Span, _kind: InferKind<'tcx>) -> Self::Result {
         self.score += 1;
-        walk_inf(self, inf);
+        self.visit_id(inf_id);
     }
 
-    fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_>) {
+    fn visit_ty(&mut self, ty: &'tcx hir::Ty<'_, AmbigArg>) {
         let (add_score, sub_nest) = match ty.kind {
-            // _, &x and *x have only small overhead; don't mess with nesting level
-            TyKind::Infer | TyKind::Ptr(..) | TyKind::Ref(..) => (1, 0),
+            // &x and *x have only small overhead; don't mess with nesting level
+            TyKind::Ptr(..) | TyKind::Ref(..) => (1, 0),
 
             // the "normal" components of a type: named types, arrays/tuples
             TyKind::Path(..) | TyKind::Slice(..) | TyKind::Tup(..) | TyKind::Array(..) => (10 * self.nest, 1),
 
             // function types bring a lot of overhead
-            TyKind::BareFn(bare) if bare.abi == Abi::Rust => (50 * self.nest, 1),
+            TyKind::BareFn(bare) if bare.abi == ExternAbi::Rust => (50 * self.nest, 1),
 
-            TyKind::TraitObject(param_bounds, _, _) => {
+            TyKind::TraitObject(param_bounds, _) => {
                 let has_lifetime_parameters = param_bounds.iter().any(|bound| {
                     bound
                         .bound_generic_params
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 9b236d3bda5..769244c675e 100644
--- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
@@ -35,7 +35,8 @@ pub(super) fn check<'tcx>(
             && let Some(GenericArg::Type(boxed_ty)) = last.args.first()
             // extract allocator from the Box for later
             && let boxed_alloc_ty = last.args.get(1)
-            && let ty_ty = lower_ty(cx.tcx, boxed_ty)
+            // we don't expect to encounter `_` here so ignore `GenericArg::Infer` is okay
+            && let ty_ty = lower_ty(cx.tcx, boxed_ty.as_unambig_ty())
             && !ty_ty.has_escaping_bound_vars()
             && ty_ty.is_sized(cx.tcx, cx.typing_env())
             && let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes())
@@ -55,7 +56,8 @@ pub(super) fn check<'tcx>(
                     }
                 },
                 (Some(GenericArg::Type(l)), Some(GenericArg::Type(r))) =>
-                    lower_ty(cx.tcx, l) == lower_ty(cx.tcx, r),
+                    // we don't expect to encounter `_` here so ignore `GenericArg::Infer` is okay
+                    lower_ty(cx.tcx, l.as_unambig_ty()) == lower_ty(cx.tcx, r.as_unambig_ty()),
                 _ => false
             }
         {
diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
index 3fc08e8192d..207f2ef4563 100644
--- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
@@ -257,10 +257,13 @@ 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 45d730985bb..b3d26908093 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -1,3 +1,4 @@
+use std::sync::Arc;
 use std::ops::ControlFlow;
 
 use clippy_config::Conf;
@@ -6,12 +7,10 @@ use clippy_utils::is_lint_allowed;
 use clippy_utils::source::walk_span_to_context;
 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::{TokenKind, tokenize};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext};
 
@@ -111,7 +110,7 @@ impl_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECES
 impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
-            && !in_external_macro(cx.tcx.sess, block.span)
+            && !block.span.in_external_macro(cx.tcx.sess.source_map())
             && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
             && !is_unsafe_from_proc_macro(cx, block.span)
             && !block_has_safety_comment(cx, block.span)
@@ -143,7 +142,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
 
         if let Some(tail) = block.expr
             && !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, tail.hir_id)
-            && !in_external_macro(cx.tcx.sess, tail.span)
+            && !tail.span.in_external_macro(cx.tcx.sess.source_map())
             && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, tail.span, tail.hir_id)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, tail, pos)
         {
@@ -167,7 +166,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
             return;
         };
         if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, stmt.hir_id)
-            && !in_external_macro(cx.tcx.sess, stmt.span)
+            && !stmt.span.in_external_macro(cx.tcx.sess.source_map())
             && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, stmt.span, stmt.hir_id)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, expr, pos)
         {
@@ -184,7 +183,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
     }
 
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
-        if in_external_macro(cx.tcx.sess, item.span) {
+        if item.span.in_external_macro(cx.tcx.sess.source_map()) {
             return;
         }
 
@@ -481,7 +480,7 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
     if let Some(comment_start) = comment_start
         && let Ok(unsafe_line) = source_map.lookup_line(item.span.lo())
         && let Ok(comment_start_line) = source_map.lookup_line(comment_start)
-        && Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
+        && Arc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
         && let Some(src) = unsafe_line.sf.src.as_deref()
     {
         return if comment_start_line.line >= unsafe_line.line {
@@ -521,7 +520,7 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H
     if let Some(comment_start) = comment_start
         && let Ok(unsafe_line) = source_map.lookup_line(span.lo())
         && let Ok(comment_start_line) = source_map.lookup_line(comment_start)
-        && Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
+        && Arc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
         && let Some(src) = unsafe_line.sf.src.as_deref()
     {
         return if comment_start_line.line >= unsafe_line.line {
@@ -581,7 +580,7 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
         //     ^--------------------------------------------^
         if let Ok(unsafe_line) = source_map.lookup_line(span.lo())
             && let Ok(macro_line) = source_map.lookup_line(ctxt.outer_expn_data().def_site.lo())
-            && Lrc::ptr_eq(&unsafe_line.sf, &macro_line.sf)
+            && Arc::ptr_eq(&unsafe_line.sf, &macro_line.sf)
             && let Some(src) = unsafe_line.sf.src.as_deref()
         {
             if macro_line.line < unsafe_line.line {
@@ -642,7 +641,7 @@ fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
         if let Ok(unsafe_line) = source_map.lookup_line(span.lo())
             && let Some(body_span) = walk_span_to_context(search_span, SyntaxContext::root())
             && let Ok(body_line) = source_map.lookup_line(body_span.lo())
-            && Lrc::ptr_eq(&unsafe_line.sf, &body_line.sf)
+            && Arc::ptr_eq(&unsafe_line.sf, &body_line.sf)
             && let Some(src) = unsafe_line.sf.src.as_deref()
         {
             // Get the text from the start of function body to the unsafe block.
diff --git a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
index ee9ef017253..b342f37f0c5 100644
--- a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
+++ b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
@@ -3,7 +3,6 @@ use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};
 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::Span;
 use rustc_span::def_id::LocalDefId;
@@ -40,7 +39,7 @@ declare_lint_pass!(UninhabitedReferences => [UNINHABITED_REFERENCES]);
 
 impl LateLintPass<'_> for UninhabitedReferences {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
-        if in_external_macro(cx.tcx.sess, expr.span) {
+        if expr.span.in_external_macro(cx.tcx.sess.source_map()) {
             return;
         }
 
@@ -66,7 +65,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
         span: Span,
         _: LocalDefId,
     ) {
-        if in_external_macro(cx.tcx.sess, span) || matches!(kind, FnKind::Closure) {
+        if span.in_external_macro(cx.tcx.sess.source_map()) || matches!(kind, FnKind::Closure) {
             return;
         }
         if let FnRetTy::Return(hir_ty) = fndecl.output
diff --git a/src/tools/clippy/clippy_lints/src/uninit_vec.rs b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
index 93ed15777e0..7803d5115c9 100644
--- a/src/tools/clippy/clippy_lints/src/uninit_vec.rs
+++ b/src/tools/clippy/clippy_lints/src/uninit_vec.rs
@@ -4,7 +4,6 @@ use clippy_utils::ty::{is_type_diagnostic_item, is_uninit_value_valid_for_ty};
 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::{Span, sym};
@@ -64,7 +63,7 @@ declare_lint_pass!(UninitVec => [UNINIT_VEC]);
 // Threads: https://github.com/rust-lang/rust-clippy/pull/7682#discussion_r710998368
 impl<'tcx> LateLintPass<'tcx> for UninitVec {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) {
-        if !in_external_macro(cx.tcx.sess, block.span) {
+        if !block.span.in_external_macro(cx.tcx.sess.source_map()) {
             for w in block.stmts.windows(2) {
                 if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = w[1].kind {
                     handle_uninit_vec_pair(cx, &w[0], expr);
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 d2727968c0c..00b80e827d8 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -7,7 +7,6 @@ use rustc_hir::def::{DefKind, Res};
 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};
 use rustc_middle::ty;
 
 use super::LET_UNIT_VALUE;
@@ -22,8 +21,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
 
     if let Some(init) = local.init
         && !local.pat.span.from_expansion()
-        && !in_external_macro(cx.sess(), local.span)
-        && !is_from_async_await(local.span)
+        && !local.span.in_external_macro(cx.sess().source_map())
+        && !local.span.is_from_async_await()
         && cx.typeck_results().pat_ty(local.pat).is_unit()
     {
         // skip `let awa = ()`
@@ -38,7 +37,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
             return;
         }
 
-        if (local.ty.is_some_and(|ty| !matches!(ty.kind, TyKind::Infer))
+        if (local.ty.is_some_and(|ty| !matches!(ty.kind, TyKind::Infer(())))
             || matches!(local.pat.kind, PatKind::Tuple([], ddpos) if ddpos.as_opt_usize().is_none()))
             && expr_needs_inferred_result(cx, init)
         {
@@ -158,7 +157,7 @@ fn expr_needs_inferred_result<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -
     }
     while let Some(id) = locals_to_check.pop() {
         if let Node::LetStmt(l) = cx.tcx.parent_hir_node(id) {
-            if !l.ty.is_none_or(|ty| matches!(ty.kind, TyKind::Infer)) {
+            if !l.ty.is_none_or(|ty| matches!(ty.kind, TyKind::Infer(()))) {
                 return false;
             }
             if let Some(e) = l.init {
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs b/src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs
new file mode 100644
index 00000000000..e5267620c4f
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_semicolon.rs
@@ -0,0 +1,121 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::leaks_droppable_temporary_with_limited_lifetime;
+use rustc_errors::Applicability;
+use rustc_hir::{Block, ExprKind, HirId, MatchSource, Stmt, StmtKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::impl_lint_pass;
+use rustc_span::edition::Edition::Edition2021;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for the presence of a semicolon at the end of
+    /// a `match` or `if` statement evaluating to `()`.
+    ///
+    /// ### Why is this bad?
+    /// The semicolon is not needed, and may be removed to
+    /// avoid confusion and visual clutter.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// # let a: u32 = 42;
+    /// if a > 10 {
+    ///     println!("a is greater than 10");
+    /// };
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// # let a: u32 = 42;
+    /// if a > 10 {
+    ///    println!("a is greater than 10");
+    /// }
+    /// ```
+    #[clippy::version = "1.86.0"]
+    pub UNNECESSARY_SEMICOLON,
+    pedantic,
+    "unnecessary semicolon after expression returning `()`"
+}
+
+#[derive(Default)]
+pub struct UnnecessarySemicolon {
+    last_statements: Vec<(HirId, bool)>,
+}
+
+impl_lint_pass!(UnnecessarySemicolon => [UNNECESSARY_SEMICOLON]);
+
+impl UnnecessarySemicolon {
+    /// Enter or leave a block, remembering the last statement of the block.
+    fn handle_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>, enter: bool) {
+        // The last statement of an expressionless block deserves a special treatment.
+        if block.expr.is_none()
+            && let Some(last_stmt) = block.stmts.last()
+        {
+            if enter {
+                let block_ty = cx.typeck_results().node_type(block.hir_id);
+                self.last_statements.push((last_stmt.hir_id, block_ty.is_unit()));
+            } else {
+                self.last_statements.pop();
+            }
+        }
+    }
+
+    /// Checks if `stmt` is the last statement in an expressionless block. In this case,
+    /// return `Some` with a boolean which is `true` if the block type is `()`.
+    fn is_last_in_block(&self, stmt: &Stmt<'_>) -> Option<bool> {
+        self.last_statements
+            .last()
+            .and_then(|&(stmt_id, is_unit)| (stmt_id == stmt.hir_id).then_some(is_unit))
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for UnnecessarySemicolon {
+    fn check_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {
+        self.handle_block(cx, block, true);
+    }
+
+    fn check_block_post(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {
+        self.handle_block(cx, block, false);
+    }
+
+    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'tcx>) {
+        // rustfmt already takes care of removing semicolons at the end
+        // of loops.
+        if let StmtKind::Semi(expr) = stmt.kind
+            && !stmt.span.from_expansion()
+            && !expr.span.from_expansion()
+            && matches!(
+                expr.kind,
+                ExprKind::If(..) | ExprKind::Match(_, _, MatchSource::Normal | MatchSource::Postfix)
+            )
+            && cx.typeck_results().expr_ty(expr) == cx.tcx.types.unit
+        {
+            if let Some(block_is_unit) = self.is_last_in_block(stmt) {
+                if cx.tcx.sess.edition() <= Edition2021 && leaks_droppable_temporary_with_limited_lifetime(cx, expr) {
+                    // The expression contains temporaries with limited lifetimes in edition lower than 2024. Those may
+                    // survive until after the end of the current scope instead of until the end of the statement, so do
+                    // not lint this situation.
+                    return;
+                }
+
+                if !block_is_unit {
+                    // Although the expression returns `()`, the block doesn't. This may happen if the expression
+                    // returns early in all code paths, such as a `return value` in the condition of an `if` statement,
+                    // in which case the block type would be `!`. Do not lint in this case, as the statement would
+                    // become the block expression; the block type would become `()` and this may not type correctly
+                    // if the expected type for the block is not `()`.
+                    return;
+                }
+            }
+
+            let semi_span = expr.span.shrink_to_hi().to(stmt.span.shrink_to_hi());
+            span_lint_and_sugg(
+                cx,
+                UNNECESSARY_SEMICOLON,
+                semi_span,
+                "unnecessary semicolon",
+                "remove",
+                String::new(),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs b/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs
new file mode 100644
index 00000000000..a74eab8b6ae
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/unneeded_struct_pattern.rs
@@ -0,0 +1,76 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_from_proc_macro;
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{Pat, PatKind, QPath};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::declare_lint_pass;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for struct patterns that match against unit variant.
+    ///
+    /// ### Why is this bad?
+    /// Struct pattern `{ }` or `{ .. }` is not needed for unit variant.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// match Some(42) {
+    ///     Some(v) => v,
+    ///     None { .. } => 0,
+    /// };
+    /// // Or
+    /// match Some(42) {
+    ///     Some(v) => v,
+    ///     None { } => 0,
+    /// };
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// match Some(42) {
+    ///     Some(v) => v,
+    ///     None => 0,
+    /// };
+    /// ```
+    #[clippy::version = "1.86.0"]
+    pub UNNEEDED_STRUCT_PATTERN,
+    style,
+    "using struct pattern to match against unit variant"
+}
+
+declare_lint_pass!(UnneededStructPattern => [UNNEEDED_STRUCT_PATTERN]);
+
+impl LateLintPass<'_> for UnneededStructPattern {
+    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
+        if !pat.span.from_expansion()
+            && let PatKind::Struct(path, [], _) = &pat.kind
+            && let QPath::Resolved(_, path) = path
+            && let Res::Def(DefKind::Variant, did) = path.res
+        {
+            let enum_did = cx.tcx.parent(did);
+            let variant = cx.tcx.adt_def(enum_did).variant_with_id(did);
+
+            let has_only_fields_brackets = variant.ctor.is_some() && variant.fields.is_empty();
+            let non_exhaustive_activated = !variant.def_id.is_local() && variant.is_field_list_non_exhaustive();
+            if !has_only_fields_brackets || non_exhaustive_activated {
+                return;
+            }
+
+            if is_from_proc_macro(cx, *path) {
+                return;
+            }
+
+            if let Some(brackets_span) = pat.span.trim_start(path.span) {
+                span_lint_and_sugg(
+                    cx,
+                    UNNEEDED_STRUCT_PATTERN,
+                    brackets_span,
+                    "struct pattern is not needed for a unit variant",
+                    "remove the struct pattern",
+                    String::new(),
+                    Applicability::MachineApplicable,
+                );
+            }
+        }
+    }
+}
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 7c9455bf8ab..e65123b8a94 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -182,7 +182,7 @@ fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
             emit_lint(cx, expr.span, expr.hir_id, op, &[]);
         },
         _ => {},
-    };
+    }
 }
 
 fn should_lint<'a>(cx: &LateContext<'a>, mut inner: &'a hir::Expr<'a>) -> Option<IoOp> {
diff --git a/src/tools/clippy/clippy_lints/src/unused_result_ok.rs b/src/tools/clippy/clippy_lints/src/unused_result_ok.rs
index 0c0d10eac5b..958f19d1833 100644
--- a/src/tools/clippy/clippy_lints/src/unused_result_ok.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_result_ok.rs
@@ -4,7 +4,6 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_errors::Applicability;
 use rustc_hir::{ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
@@ -39,7 +38,7 @@ impl LateLintPass<'_> for UnusedResultOk {
             && let ExprKind::MethodCall(ok_path, recv, [], ..) = expr.kind //check is expr.ok() has type Result<T,E>.ok(, _)
             && ok_path.ident.as_str() == "ok"
             && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result)
-            && !in_external_macro(cx.sess(), stmt.span)
+            && !stmt.span.in_external_macro(cx.sess().source_map())
         {
             let ctxt = expr.span.ctxt();
             let mut applicability = Applicability::MaybeIncorrect;
diff --git a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
index 17ee5fc20ca..f8341583435 100644
--- a/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_trait_names.rs
@@ -7,7 +7,6 @@ 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;
@@ -63,7 +62,7 @@ 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)
+            && !item.span.in_external_macro(cx.sess().source_map())
             && let ItemKind::Use(path, UseKind::Single) = item.kind
             // Ignore imports that already use Underscore
             && item.ident.name != kw::Underscore
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index eaa119b045f..6a952c0d97a 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -8,7 +8,6 @@ use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, HirId, Node, PathSegmen
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceWithHirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
@@ -292,7 +291,7 @@ impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> {
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         // Shouldn't lint when `expr` is in macro.
-        if in_external_macro(self.cx.tcx.sess, expr.span) {
+        if expr.span.in_external_macro(self.cx.tcx.sess.source_map()) {
             return;
         }
         if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr) {
diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
index c3843279ba2..3449468ef48 100644
--- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
+++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
@@ -4,7 +4,6 @@ use core::mem::replace;
 use rustc_errors::Applicability;
 use rustc_hir::{HirId, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::Ident;
 
@@ -126,7 +125,7 @@ fn check_ident(cx: &LateContext<'_>, ident: &Ident, hir_id: HirId, be_aggressive
 impl LateLintPass<'_> for UpperCaseAcronyms {
     fn check_item(&mut self, cx: &LateContext<'_>, it: &Item<'_>) {
         // do not lint public items or in macros
-        if in_external_macro(cx.sess(), it.span)
+        if it.span.in_external_macro(cx.sess().source_map())
             || (self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(it.owner_id.def_id))
         {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index 05c5be03002..47ce2243aa0 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -7,10 +7,10 @@ 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::{Visitor, walk_inf, walk_ty};
+use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt, 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,
+    self as hir, AmbigArg, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind,
+    HirId, Impl, ImplItemKind, Item, ItemKind, Pat, PatExpr, PatExprKind, PatKind, Path, QPath, Ty, TyKind,
 };
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
@@ -179,7 +179,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             for (impl_hir_ty, trait_sem_ty) in impl_inputs_outputs.zip(trait_method_sig.inputs_and_output) {
                 if trait_sem_ty.walk().any(|inner| inner == self_ty.into()) {
                     let mut visitor = SkipTyCollector::default();
-                    visitor.visit_ty(impl_hir_ty);
+                    visitor.visit_ty_unambig(impl_hir_ty);
                     types_to_skip.extend(visitor.types_to_skip);
                 }
             }
@@ -201,7 +201,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx>) {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx, AmbigArg>) {
         if !hir_ty.span.from_expansion()
             && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS)
             && let Some(&StackItem::Check {
@@ -218,7 +218,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             && let ty = if in_body > 0 {
                 cx.typeck_results().node_type(hir_ty.hir_id)
             } else {
-                lower_ty(cx.tcx, hir_ty)
+                // We don't care about ignoring infer vars here
+                lower_ty(cx.tcx, hir_ty.as_unambig_ty())
             }
             && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()
             && same_type_and_consts(ty, impl_ty)
@@ -257,7 +258,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS)
             && let Some(&StackItem::Check { impl_id, .. }) = self.stack.last()
             // get the path from the pattern
-            && let PatKind::Path(QPath::Resolved(_, path))
+            && let PatKind::Expr(&PatExpr { kind: PatExprKind::Path(QPath::Resolved(_, path)), .. })
                  | PatKind::TupleStruct(QPath::Resolved(_, path), _, _)
                  | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind
             && cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity()
@@ -275,12 +276,14 @@ struct SkipTyCollector {
 }
 
 impl Visitor<'_> for SkipTyCollector {
-    fn visit_infer(&mut self, inf: &hir::InferArg) {
-        self.types_to_skip.push(inf.hir_id);
-
-        walk_inf(self, inf);
+    fn visit_infer(&mut self, inf_id: HirId, _inf_span: Span, kind: InferKind<'_>) -> Self::Result {
+        // Conservatively assume ambiguously kinded inferred arguments are type arguments
+        if let InferKind::Ambig(_) | InferKind::Ty(_) = kind {
+            self.types_to_skip.push(inf_id);
+        }
+        self.visit_id(inf_id);
     }
-    fn visit_ty(&mut self, hir_ty: &Ty<'_>) {
+    fn visit_ty(&mut self, hir_ty: &Ty<'_, AmbigArg>) {
         self.types_to_skip.push(hir_ty.hir_id);
 
         walk_ty(self, hir_ty);
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 7ffab81a544..5e452c6d2ac 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::{snippet, snippet_with_applicability, snippet_with_context};
+use clippy_utils::source::{snippet, snippet_with_context};
 use clippy_utils::sugg::{DiagExt as _, Sugg};
 use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts};
 use clippy_utils::{
@@ -12,6 +12,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::Obligation;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability};
 use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
@@ -251,26 +252,25 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                             //  ^^^
                             let (into_iter_recv, depth) = into_iter_deep_call(cx, into_iter_recv);
 
-                            let plural = if depth == 0 { "" } else { "s" };
-                            let mut applicability = Applicability::MachineApplicable;
-                            let sugg = snippet_with_applicability(
-                                cx,
-                                into_iter_recv.span.source_callsite(),
-                                "<expr>",
-                                &mut applicability,
-                            )
-                            .into_owned();
                             span_lint_and_then(
                                 cx,
                                 USELESS_CONVERSION,
                                 e.span,
                                 "explicit call to `.into_iter()` in function argument accepting `IntoIterator`",
                                 |diag| {
-                                    diag.span_suggestion(
-                                        e.span,
+                                    let receiver_span = into_iter_recv.span.source_callsite();
+                                    let adjustments = adjustments(cx, into_iter_recv);
+                                    let mut sugg = if adjustments.is_empty() {
+                                        vec![]
+                                    } else {
+                                        vec![(receiver_span.shrink_to_lo(), adjustments)]
+                                    };
+                                    let plural = if depth == 0 { "" } else { "s" };
+                                    sugg.push((e.span.with_lo(receiver_span.hi()), String::new()));
+                                    diag.multipart_suggestion(
                                         format!("consider removing the `.into_iter()`{plural}"),
                                         sugg,
-                                        applicability,
+                                        Applicability::MachineApplicable,
                                     );
                                     diag.span_note(span, "this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`");
                                 },
@@ -431,3 +431,16 @@ fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>)
     }
     false
 }
+
+fn adjustments(cx: &LateContext<'_>, expr: &Expr<'_>) -> String {
+    let mut prefix = String::new();
+    for adj in cx.typeck_results().expr_adjustments(expr) {
+        match adj.kind {
+            Adjust::Deref(_) => prefix = format!("*{prefix}"),
+            Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })) => prefix = format!("&mut {prefix}"),
+            Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)) => prefix = format!("&{prefix}"),
+            _ => {},
+        }
+    }
+    prefix
+}
diff --git a/src/tools/clippy/clippy_lints/src/utils/attr_collector.rs b/src/tools/clippy/clippy_lints/src/utils/attr_collector.rs
index 1522553bbf5..169429811d3 100644
--- a/src/tools/clippy/clippy_lints/src/utils/attr_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/attr_collector.rs
@@ -1,14 +1,13 @@
 use std::mem;
-use std::sync::OnceLock;
+use std::sync::{Arc, OnceLock};
 
 use rustc_ast::{Attribute, Crate};
-use rustc_data_structures::sync::Lrc;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
 
 #[derive(Clone, Default)]
-pub struct AttrStorage(pub Lrc<OnceLock<Vec<Span>>>);
+pub struct AttrStorage(pub Arc<OnceLock<Vec<Span>>>);
 
 pub struct AttrCollector {
     storage: AttrStorage,
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 4dcc8ac7fb0..6bad78cf871 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -708,11 +708,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 self.qpath(qpath);
                 self.slice(fields, |pat| self.pat(pat));
             },
-            PatKind::Path(ref qpath) => {
-                bind!(self, qpath);
-                kind!("Path(ref {qpath})");
-                self.qpath(qpath);
-            },
             PatKind::Tuple(fields, skip_pos) => {
                 bind!(self, fields);
                 kind!("Tuple({fields}, {skip_pos:?})");
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
index 49aad881994..b8bcb9b3756 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
@@ -69,6 +69,6 @@ impl<'tcx> LateLintPass<'tcx> for SlowSymbolComparisons {
                 ),
                 applicability,
             );
-        };
+        }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index 0730b561bc2..03c667846b6 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
         };
         if self.allow_in_test && is_in_test(cx.tcx, expr.hir_id) {
             return;
-        };
+        }
         // the parent callsite of this `vec!` expression, or span to the borrowed one such as `&vec!`
         let callsite = expr.span.parent_callsite().unwrap_or(expr.span);
 
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 d87d554eb07..3c23662e9d1 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
@@ -8,7 +8,6 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{BindingMode, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, Symbol};
 
@@ -158,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingMode::MUT, id, name, None) = local.pat.kind
-            && !in_external_macro(cx.sess(), local.span)
+            && !local.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, init_expr)
             && !matches!(init, VecInitKind::WithExprCapacity(_))
         {
@@ -181,7 +180,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
             && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
             && let [name] = &path.segments
             && let Res::Local(id) = path.res
-            && !in_external_macro(cx.sess(), expr.span)
+            && !expr.span.in_external_macro(cx.sess().source_map())
             && let Some(init) = get_vec_init_kind(cx, right)
             && !matches!(init, VecInitKind::WithExprCapacity(_))
         {
diff --git a/src/tools/clippy/clippy_lints/src/visibility.rs b/src/tools/clippy/clippy_lints/src/visibility.rs
index 2e5fc5834e2..d17b3df9921 100644
--- a/src/tools/clippy/clippy_lints/src/visibility.rs
+++ b/src/tools/clippy/clippy_lints/src/visibility.rs
@@ -3,7 +3,6 @@ use clippy_utils::source::SpanRangeExt;
 use rustc_ast::ast::{Item, VisibilityKind};
 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::Span;
 use rustc_span::symbol::kw;
@@ -79,7 +78,7 @@ declare_lint_pass!(Visibility => [NEEDLESS_PUB_SELF, PUB_WITH_SHORTHAND, PUB_WIT
 
 impl EarlyLintPass for Visibility {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if !in_external_macro(cx.sess(), item.span)
+        if !item.span.in_external_macro(cx.sess().source_map())
             && let VisibilityKind::Restricted { path, shorthand, .. } = &item.vis.kind
         {
             if **path == kw::SelfLower && !is_from_proc_macro(cx, item.vis.span) {
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index 31ae002e47d..11c14c14777 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -522,7 +522,7 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
 
             let replacement = match (format_string_is_raw, replace_raw) {
                 (false, false) => Some(replacement),
-                (false, true) => Some(replacement.replace('"', "\\\"").replace('\\', "\\\\")),
+                (false, true) => Some(replacement.replace('\\', "\\\\").replace('"', "\\\"")),
                 (true, false) => match conservative_unescape(&replacement) {
                     Ok(unescaped) => Some(unescaped),
                     Err(UnescapeErr::Lint) => None,
diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
index e14480b8655..1221abec1ab 100644
--- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
+++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item};
-use rustc_hir::{self as hir, HirId, ItemKind, Node};
+use rustc_hir::{self as hir, AmbigArg, HirId, ItemKind, Node};
 use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf as _;
@@ -44,10 +44,11 @@ declare_clippy_lint! {
 declare_lint_pass!(ZeroSizedMapValues => [ZERO_SIZED_MAP_VALUES]);
 
 impl LateLintPass<'_> for ZeroSizedMapValues {
-    fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) {
+    fn check_ty<'tcx>(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx, AmbigArg>) {
         if !hir_ty.span.from_expansion()
             && !in_trait_impl(cx, hir_ty.hir_id)
-            && let ty = ty_from_hir_ty(cx, hir_ty)
+            // We don't care about infer vars
+            && let ty = ty_from_hir_ty(cx, hir_ty.as_unambig_ty())
             && (is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap))
             && let ty::Adt(_, args) = ty.kind()
             && let ty = args.type_at(1)
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 7fa070cd226..68b7e1592e2 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -3,7 +3,7 @@ name = "clippy_utils"
 # begin autogenerated version
 version = "0.1.86"
 # end autogenerated version
-edition = "2021"
+edition = "2024"
 description = "Helpful tools for writing lints, provided as they are used in Clippy"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
index c267b804124..41f3b1cbd50 100644
--- a/src/tools/clippy/clippy_utils/README.md
+++ b/src/tools/clippy/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2025-01-09
+nightly-2025-02-06
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 2eb09bac8d8..ab5f97199ce 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -362,18 +362,21 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 defaultness: ld,
                 sig: lf,
                 generics: lg,
+                contract: lc,
                 body: lb,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
                 generics: rg,
+                contract: rc,
                 body: rb,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
                 && eq_generics(lg, rg)
+                && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (Mod(lu, lmk), Mod(ru, rmk)) => {
@@ -497,18 +500,21 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 defaultness: ld,
                 sig: lf,
                 generics: lg,
+                contract: lc,
                 body: lb,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
                 generics: rg,
+                contract: rc,
                 body: rb,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
                 && eq_generics(lg, rg)
+                && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
@@ -559,18 +565,21 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 defaultness: ld,
                 sig: lf,
                 generics: lg,
+                contract: lc,
                 body: lb,
             }),
             Fn(box ast::Fn {
                 defaultness: rd,
                 sig: rf,
                 generics: rg,
+                contract: rc,
                 body: rb,
             }),
         ) => {
             eq_defaultness(*ld, *rd)
                 && eq_fn_sig(lf, rf)
                 && eq_generics(lg, rg)
+                && eq_opt_fn_contract(lc, rc)
                 && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
@@ -653,6 +662,17 @@ pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
         && eq_ext(&l.ext, &r.ext)
 }
 
+#[expect(clippy::ref_option, reason = "This is the type how it is stored in the AST")]
+pub fn eq_opt_fn_contract(l: &Option<P<FnContract>>, r: &Option<P<FnContract>>) -> bool {
+    match (l, r) {
+        (Some(l), Some(r)) => {
+            eq_expr_opt(l.requires.as_ref(), r.requires.as_ref()) && eq_expr_opt(l.ensures.as_ref(), r.ensures.as_ref())
+        },
+        (None, None) => true,
+        (Some(_), None) | (None, Some(_)) => false,
+    }
+}
+
 pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
     over(&l.params, &r.params, eq_generic_param)
         && over(&l.where_clause.predicates, &r.where_clause.predicates, |l, r| {
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 68e7f807bf5..59aaaa3d9fb 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -12,6 +12,7 @@
 //! 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_abi::ExternAbi;
 use rustc_ast::AttrStyle;
 use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy};
 use rustc_ast::token::CommentKind;
@@ -26,7 +27,6 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
 use rustc_span::symbol::{Ident, kw};
 use rustc_span::{Span, Symbol};
-use rustc_target::spec::abi::Abi;
 
 /// The search pattern to look for. Used by `span_matches_pat`
 #[derive(Clone)]
@@ -233,7 +233,7 @@ fn fn_header_search_pat(header: FnHeader) -> Pat {
         Pat::Str("const")
     } else if header.is_unsafe() {
         Pat::Str("unsafe")
-    } else if header.abi != Abi::Rust {
+    } else if header.abi != ExternAbi::Rust {
         Pat::Str("extern")
     } else {
         Pat::MultiStr(&["fn", "extern"])
@@ -375,7 +375,7 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
         TyKind::BareFn(bare_fn) => (
             if bare_fn.safety.is_unsafe() {
                 Pat::Str("unsafe")
-            } else if bare_fn.abi != Abi::Rust {
+            } else if bare_fn.abi != ExternAbi::Rust {
                 Pat::Str("extern")
             } else {
                 Pat::MultiStr(&["fn", "extern"])
@@ -399,8 +399,10 @@ fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
         TyKind::Tup([head, .., tail]) => (ty_search_pat(head).0, ty_search_pat(tail).1),
         TyKind::OpaqueDef(..) => (Pat::Str("impl"), Pat::Str("")),
         TyKind::Path(qpath) => qpath_search_pat(&qpath),
-        TyKind::Infer => (Pat::Str("_"), Pat::Str("_")),
-        TyKind::TraitObject(_, _, TraitObjectSyntax::Dyn) => (Pat::Str("dyn"), Pat::Str("")),
+        TyKind::Infer(()) => (Pat::Str("_"), Pat::Str("_")),
+        TyKind::TraitObject(_, tagged_ptr) if let TraitObjectSyntax::Dyn = tagged_ptr.tag() => {
+            (Pat::Str("dyn"), Pat::Str(""))
+        },
         // NOTE: `TraitObject` is incomplete. It will always return true then.
         _ => (Pat::Str(""), Pat::Str("")),
     }
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index d46beddf731..db82c458f70 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -4,15 +4,19 @@
 //! executable MIR bodies, so we have to do this instead.
 #![allow(clippy::float_cmp)]
 
+use std::sync::Arc;
+
 use crate::source::{SpanRangeExt, walk_span_to_context};
 use crate::{clip, is_direct_expn_of, sext, unsext};
 
+use rustc_abi::Size;
 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, PatExpr, PatExprKind};
+use rustc_hir::{
+    BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp,
+};
 use rustc_lexer::tokenize;
 use rustc_lint::LateContext;
 use rustc_middle::mir::ConstValue;
@@ -22,7 +26,6 @@ use rustc_middle::{bug, mir, span_bug};
 use rustc_span::def_id::DefId;
 use rustc_span::symbol::Ident;
 use rustc_span::{SyntaxContext, sym};
-use rustc_target::abi::Size;
 use std::cell::Cell;
 use std::cmp::Ordering;
 use std::hash::{Hash, Hasher};
@@ -35,7 +38,7 @@ pub enum Constant<'tcx> {
     /// A `String` (e.g., "abc").
     Str(String),
     /// A binary string (e.g., `b"abc"`).
-    Binary(Lrc<[u8]>),
+    Binary(Arc<[u8]>),
     /// A single `char` (e.g., `'a'`).
     Char(char),
     /// An integer's bit representation.
@@ -303,7 +306,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
     match *lit {
         LitKind::Str(ref is, _) => Constant::Str(is.to_string()),
         LitKind::Byte(b) => Constant::Int(u128::from(b)),
-        LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Lrc::clone(s)),
+        LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(Arc::clone(s)),
         LitKind::Char(c) => Constant::Char(c),
         LitKind::Int(n, _) => Constant::Int(n.get()),
         LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
@@ -451,8 +454,8 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 } else {
                     Some(val)
                 }
-            }
-            PatExprKind::ConstBlock(ConstBlock { body, ..}) => self.expr(self.tcx.hir().body(*body).value),
+            },
+            PatExprKind::ConstBlock(ConstBlock { body, .. }) => self.expr(self.tcx.hir().body(*body).value),
             PatExprKind::Path(qpath) => self.qpath(qpath, pat_expr.hir_id),
         }
     }
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index 60be7e4a4d3..6bb876322f2 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -475,7 +475,7 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -
                         Some(Constant::Int(num)) => Some(VecInitKind::WithConstCapacity(num)),
                         _ => Some(VecInitKind::WithExprCapacity(arg.hir_id)),
                     };
-                };
+                }
             },
             ExprKind::Path(QPath::Resolved(_, path))
                 if cx.tcx.is_diagnostic_item(sym::default_fn, path.res.opt_def_id()?)
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index a1c48d5c36c..4bbf28115a6 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -10,7 +10,7 @@ use rustc_hir::{
     AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
     ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName,
     Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
-    TraitBoundModifiers, Ty, TyKind,
+    TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
 };
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::LateContext;
@@ -459,9 +459,9 @@ impl HirEqInterExpr<'_, '_, '_> {
 
     fn eq_generic_arg(&mut self, left: &GenericArg<'_>, right: &GenericArg<'_>) -> bool {
         match (left, right) {
-            (GenericArg::Const(l), GenericArg::Const(r)) => self.eq_const_arg(l, r),
+            (GenericArg::Const(l), GenericArg::Const(r)) => self.eq_const_arg(l.as_unambig_ct(), r.as_unambig_ct()),
             (GenericArg::Lifetime(l_lt), GenericArg::Lifetime(r_lt)) => Self::eq_lifetime(l_lt, r_lt),
-            (GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty, r_ty),
+            (GenericArg::Type(l_ty), GenericArg::Type(r_ty)) => self.eq_ty(l_ty.as_unambig_ty(), r_ty.as_unambig_ty()),
             (GenericArg::Infer(l_inf), GenericArg::Infer(r_inf)) => self.eq_ty(&l_inf.to_ty(), &r_inf.to_ty()),
             _ => false,
         }
@@ -524,7 +524,6 @@ impl HirEqInterExpr<'_, '_, '_> {
                 }
                 eq
             },
-            (PatKind::Path(l), PatKind::Path(r)) => self.eq_qpath(l, r),
             (&PatKind::Expr(l), &PatKind::Expr(r)) => self.eq_pat_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)) => {
@@ -618,7 +617,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             },
             (TyKind::Path(l), TyKind::Path(r)) => self.eq_qpath(l, r),
             (&TyKind::Tup(l), &TyKind::Tup(r)) => over(l, r, |l, r| self.eq_ty(l, r)),
-            (&TyKind::Infer, &TyKind::Infer) => true,
+            (&TyKind::Infer(()), &TyKind::Infer(())) => true,
             _ => false,
         }
     }
@@ -1103,6 +1102,22 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
         }
     }
 
+    pub fn hash_ty_pat(&mut self, pat: &TyPat<'_>) {
+        std::mem::discriminant(&pat.kind).hash(&mut self.s);
+        match pat.kind {
+            TyPatKind::Range(s, e, i) => {
+                if let Some(s) = s {
+                    self.hash_const_arg(s);
+                }
+                if let Some(e) = e {
+                    self.hash_const_arg(e);
+                }
+                std::mem::discriminant(&i).hash(&mut self.s);
+            },
+            TyPatKind::Err(_) => {},
+        }
+    }
+
     pub fn hash_pat(&mut self, pat: &Pat<'_>) {
         std::mem::discriminant(&pat.kind).hash(&mut self.s);
         match pat.kind {
@@ -1120,7 +1135,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     self.hash_pat(pat);
                 }
             },
-            PatKind::Path(ref qpath) => self.hash_qpath(qpath),
             PatKind::Range(s, e, i) => {
                 if let Some(s) = s {
                     self.hash_pat_expr(s);
@@ -1249,7 +1263,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             },
             TyKind::Pat(ty, pat) => {
                 self.hash_ty(ty);
-                self.hash_pat(pat);
+                self.hash_ty_pat(pat);
             },
             TyKind::Ptr(mut_ty) => {
                 self.hash_ty(mut_ty.ty);
@@ -1281,7 +1295,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 }
             },
             TyKind::Path(qpath) => self.hash_qpath(qpath),
-            TyKind::TraitObject(_, lifetime, _) => {
+            TyKind::TraitObject(_, lifetime) => {
                 self.hash_lifetime(lifetime);
             },
             TyKind::Typeof(anon_const) => {
@@ -1291,7 +1305,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 self.hash_ty(binder.inner_ty);
             },
             TyKind::Err(_)
-            | TyKind::Infer
+            | TyKind::Infer(())
             | TyKind::Never
             | TyKind::InferDelegation(..)
             | TyKind::OpaqueDef(_)
@@ -1318,8 +1332,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
         for arg in arg_list {
             match *arg {
                 GenericArg::Lifetime(l) => self.hash_lifetime(l),
-                GenericArg::Type(ty) => self.hash_ty(ty),
-                GenericArg::Const(ca) => self.hash_const_arg(ca),
+                GenericArg::Type(ty) => self.hash_ty(ty.as_unambig_ty()),
+                GenericArg::Const(ca) => self.hash_const_arg(ca.as_unambig_ct()),
                 GenericArg::Infer(ref inf) => self.hash_ty(&inf.to_ty()),
             }
         }
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index eecfc3fb13f..79cc5066580 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -29,6 +29,7 @@
 
 // FIXME: switch to something more ergonomic here, once available.
 // (Currently there is no way to opt into sysroot crates without `extern crate`.)
+extern crate rustc_abi;
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
 extern crate rustc_attr_parsing;
@@ -48,7 +49,6 @@ extern crate rustc_middle;
 extern crate rustc_mir_dataflow;
 extern crate rustc_session;
 extern crate rustc_span;
-extern crate rustc_target;
 extern crate rustc_trait_selection;
 extern crate smallvec;
 
@@ -88,7 +88,7 @@ use core::mem;
 use core::ops::ControlFlow;
 use std::collections::hash_map::Entry;
 use std::hash::BuildHasherDefault;
-use std::iter::{once, repeat};
+use std::iter::{once, repeat_n};
 use std::sync::{Mutex, MutexGuard, OnceLock};
 
 use itertools::Itertools;
@@ -106,26 +106,25 @@ use rustc_hir::{
     self as hir, Arm, 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,
+    PatExpr, PatExprKind, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
+    TraitItemRef, TraitRef, TyKind, UnOp, def,
 };
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::place::PlaceBase;
-use rustc_middle::mir::Const;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{
-    self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, Ty, TyCtxt,
-    TypeVisitableExt, UintTy, UpvarCapture,
+    self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgKind, GenericArgsRef, IntTy, Ty,
+    TyCtxt, TypeVisitableExt, UintTy, UpvarCapture,
 };
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{Ident, Symbol, kw};
 use rustc_span::{InnerSpan, Span, sym};
-use rustc_target::abi::Integer;
-use visitors::Visitable;
+use rustc_abi::Integer;
+use visitors::{Visitable, for_each_unconsumed_temporary};
 
 use crate::consts::{ConstEvalCtxt, Constant, mir_to_const};
 use crate::higher::Range;
@@ -342,6 +341,15 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
     matches!(pat.kind, PatKind::Wild)
 }
 
+// Checks if arm has the form `None => None`
+pub fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
+    matches!(
+        arm.pat.kind,
+        PatKind::Expr(PatExpr { kind: PatExprKind::Path(qpath), .. })
+            if is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), OptionNone)
+    )
+}
+
 /// Checks if the given `QPath` belongs to a type alias.
 pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
     match *qpath {
@@ -437,7 +445,7 @@ pub fn qpath_generic_tys<'tcx>(qpath: &QPath<'tcx>) -> impl Iterator<Item = &'tc
         .map_or(&[][..], |a| a.args)
         .iter()
         .filter_map(|a| match a {
-            hir::GenericArg::Type(ty) => Some(*ty),
+            hir::GenericArg::Type(ty) => Some(ty.as_unambig_ty()),
             _ => None,
         })
 }
@@ -561,7 +569,20 @@ macro_rules! maybe_path {
     };
 }
 maybe_path!(Expr, ExprKind);
-maybe_path!(Pat, PatKind);
+impl<'hir> MaybePath<'hir> for Pat<'hir> {
+    fn hir_id(&self) -> HirId {
+        self.hir_id
+    }
+    fn qpath_opt(&self) -> Option<&QPath<'hir>> {
+        match &self.kind {
+            PatKind::Expr(PatExpr {
+                kind: PatExprKind::Path(qpath),
+                ..
+            }) => Some(qpath),
+            _ => None,
+        }
+    }
+}
 maybe_path!(Ty, TyKind);
 
 /// If `maybe_path` is a path node, resolves it, otherwise returns `Res::Err`
@@ -815,7 +836,7 @@ fn projection_stack<'a, 'hir>(mut e: &'a Expr<'hir>) -> (Vec<&'a Expr<'hir>>, &'
                 e = ep;
             },
             _ => break e,
-        };
+        }
     };
     result.reverse();
     (result, root)
@@ -1584,8 +1605,8 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
         let start_is_none_or_min = start.is_none_or(|start| {
             if let rustc_ty::Adt(_, subst) = ty.kind()
                 && let bnd_ty = subst.type_at(0)
-                && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx)
-                && let Some(min_const) = mir_to_const(cx.tcx, Const::from_ty_const(min_val, bnd_ty, cx.tcx))
+                && let Some(min_const) = bnd_ty.numeric_min_val(cx.tcx)
+                && let Some(min_const) = mir_to_const(cx.tcx, min_const)
                 && let Some(start_const) = ConstEvalCtxt::new(cx).eval(start)
             {
                 start_const == min_const
@@ -1597,8 +1618,8 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
             RangeLimits::Closed => {
                 if let rustc_ty::Adt(_, subst) = ty.kind()
                     && let bnd_ty = subst.type_at(0)
-                    && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx)
-                    && let Some(max_const) = mir_to_const(cx.tcx, Const::from_ty_const(max_val, bnd_ty, cx.tcx))
+                    && let Some(max_const) = bnd_ty.numeric_max_val(cx.tcx)
+                    && let Some(max_const) = mir_to_const(cx.tcx, max_const)
                     && let Some(end_const) = ConstEvalCtxt::new(cx).eval(end)
                 {
                     end_const == max_const
@@ -1754,7 +1775,11 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
         PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
         PatKind::Binding(_, _, _, pat) => pat.is_some_and(|pat| is_refutable(cx, pat)),
         PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
-        PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
+        PatKind::Expr(PatExpr {
+            kind: PatExprKind::Path(qpath),
+            hir_id,
+            ..
+        }) => is_enum_variant(cx, qpath, *hir_id),
         PatKind::Or(pats) => {
             // TODO: should be the honest check, that pats is exhaustive set
             are_refutable(cx, pats)
@@ -2046,7 +2071,7 @@ pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'t
         {
             return Some(expr);
         }
-    };
+    }
     None
 }
 
@@ -2148,7 +2173,7 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
 pub fn is_expr_untyped_identity_function(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match expr.kind {
         ExprKind::Closure(&Closure { body, fn_decl, .. })
-            if fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer)) =>
+            if fn_decl.inputs.iter().all(|ty| matches!(ty.kind, TyKind::Infer(()))) =>
         {
             is_body_identity_function(cx, cx.tcx.hir().body(body))
         },
@@ -3421,7 +3446,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
             }))
             .join("::")
     } else {
-        repeat(String::from("super")).take(go_up_by).chain(path).join("::")
+        repeat_n(String::from("super"), go_up_by).chain(path).join("::")
     }
 }
 
@@ -3466,3 +3491,20 @@ pub fn is_receiver_of_method_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool
     }
     false
 }
+
+/// Returns true if `expr` creates any temporary whose type references a non-static lifetime and has
+/// a significant drop and does not consume it.
+pub fn leaks_droppable_temporary_with_limited_lifetime<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
+    for_each_unconsumed_temporary(cx, expr, |temporary_ty| {
+        if temporary_ty.has_significant_drop(cx.tcx, cx.typing_env())
+            && temporary_ty
+                .walk()
+                .any(|arg| matches!(arg.unpack(), GenericArgKind::Lifetime(re) if !re.is_static()))
+        {
+            ControlFlow::Break(())
+        } else {
+            ControlFlow::Continue(())
+        }
+    })
+    .is_break()
+}
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 45beb146eb6..30fd48fc060 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -1,12 +1,14 @@
 #![allow(clippy::similar_names)] // `expr` and `expn`
 
+use std::sync::Arc;
+
 use crate::get_unique_attr;
 use crate::visitors::{Descend, for_each_expr_without_closures};
 
 use arrayvec::ArrayVec;
 use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::{Lrc, OnceLock};
+use rustc_data_structures::sync::OnceLock;
 use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
 use rustc_lint::{LateContext, LintContext};
 use rustc_span::def_id::DefId;
@@ -251,7 +253,7 @@ impl<'a> PanicExpn<'a> {
         // This has no argument
         if name == "panic_cold_explicit" {
             return Some(Self::Empty);
-        };
+        }
 
         let [arg, rest @ ..] = args else {
             return None;
@@ -393,7 +395,7 @@ fn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) ->
 /// Stores AST [`FormatArgs`] nodes for use in late lint passes, as they are in a desugared form in
 /// the HIR
 #[derive(Default, Clone)]
-pub struct FormatArgsStorage(Lrc<OnceLock<FxHashMap<Span, FormatArgs>>>);
+pub struct FormatArgsStorage(Arc<OnceLock<FxHashMap<Span, FormatArgs>>>);
 
 impl FormatArgsStorage {
     /// Returns an AST [`FormatArgs`] node if a `format_args` expansion is found as a descendant of
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index ccbbccd0dbf..85250f81dc4 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -112,10 +112,14 @@ 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 5eb9b3b8f22..605764cef89 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
@@ -184,9 +184,10 @@ impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
             vis.visit_body(mir);
             vis.into_map(cx)
         };
-        let maybe_storage_live_result = MaybeStorageLive::new(Cow::Owned(DenseBitSet::new_empty(mir.local_decls.len())))
-            .iterate_to_fixpoint(cx.tcx, mir, Some("redundant_clone"))
-            .into_results_cursor(mir);
+        let maybe_storage_live_result =
+            MaybeStorageLive::new(Cow::Owned(DenseBitSet::new_empty(mir.local_decls.len())))
+                .iterate_to_fixpoint(cx.tcx, mir, Some("redundant_clone"))
+                .into_results_cursor(mir);
         let mut vis = PossibleBorrowerVisitor::new(cx, mir, possible_origin);
         vis.visit_body(mir);
         vis.into_map(cx, maybe_storage_live_result)
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 2169a5fdd63..24f73b9df26 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -1,4 +1,5 @@
 use rustc_ast::attr::AttributeExt;
+
 use rustc_attr_parsing::{RustcVersion, parse_version};
 use rustc_session::Session;
 use rustc_span::{Symbol, sym};
@@ -18,12 +19,14 @@ macro_rules! msrv_aliases {
 
 // names may refer to stabilized feature flags or library items
 msrv_aliases! {
-    1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY }
+    1,84,0 { CONST_OPTION_AS_SLICE }
+    1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP }
     1,82,0 { IS_NONE_OR, REPEAT_N, RAW_REF_OP }
-    1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE }
-    1,80,0 { BOX_INTO_ITER }
+    1,81,0 { LINT_REASONS_STABILIZATION, ERROR_IN_CORE, EXPLICIT_SELF_TYPE_ELISION }
+    1,80,0 { BOX_INTO_ITER, LAZY_CELL }
     1,77,0 { C_STR_LITERALS }
     1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
+    1,75,0 { OPTION_AS_SLICE }
     1,74,0 { REPR_RUST }
     1,73,0 { MANUAL_DIV_CEIL }
     1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
@@ -40,7 +43,7 @@ msrv_aliases! {
     1,53,0 { OR_PATTERNS, MANUAL_BITS, BTREE_MAP_RETAIN, BTREE_SET_RETAIN, ARRAY_INTO_ITERATOR }
     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,50,0 { BOOL_THEN, CLAMP, SLICE_FILL }
     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 }
diff --git a/src/tools/clippy/clippy_utils/src/numeric_literal.rs b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
index 2c49df9d807..bb2a6282110 100644
--- a/src/tools/clippy/clippy_utils/src/numeric_literal.rs
+++ b/src/tools/clippy/clippy_utils/src/numeric_literal.rs
@@ -125,7 +125,7 @@ impl<'a> NumericLiteral<'a> {
                             integer = &digits[..exp_start];
                         } else {
                             fraction = Some(&digits[integer.len() + 1..exp_start]);
-                        };
+                        }
                         exponent = Some((&digits[exp_start..=i], &digits[i + 1..]));
                         break;
                     },
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 104ae154e36..c7890f33f27 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
@@ -29,13 +29,14 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv)
     let def_id = body.source.def_id();
 
     for local in &body.local_decls {
-        check_ty(tcx, local.ty, local.source_info.span)?;
+        check_ty(tcx, local.ty, local.source_info.span, msrv)?;
     }
     // impl trait is gone in MIR, so check the return type manually
     check_ty(
         tcx,
         tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(),
         body.local_decls.iter().next().unwrap().source_info.span,
+        msrv,
     )?;
 
     for bb in &*body.basic_blocks {
@@ -51,7 +52,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv)
     Ok(())
 }
 
-fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
+fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, msrv: &Msrv) -> McfResult {
     for arg in ty.walk() {
         let ty = match arg.unpack() {
             GenericArgKind::Type(ty) => ty,
@@ -62,7 +63,7 @@ fn check_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
         };
 
         match ty.kind() {
-            ty::Ref(_, _, hir::Mutability::Mut) => {
+            ty::Ref(_, _, hir::Mutability::Mut) if !msrv.meets(msrvs::CONST_MUT_REFS) => {
                 return Err((span, "mutable references in const fn are unstable".into()));
             },
             ty::Alias(ty::Opaque, ..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
@@ -115,6 +116,7 @@ fn check_rvalue<'tcx>(
         Rvalue::CopyForDeref(place) => check_place(tcx, *place, span, body, msrv),
         Rvalue::Repeat(operand, _)
         | Rvalue::Use(operand)
+        | Rvalue::WrapUnsafeBinder(operand, _)
         | Rvalue::Cast(
             CastKind::PointerWithExposedProvenance
             | CastKind::IntToInt
@@ -177,7 +179,10 @@ fn check_rvalue<'tcx>(
                 ))
             }
         },
-        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks, _)
+        Rvalue::NullaryOp(
+            NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks | NullOp::ContractChecks,
+            _,
+        )
         | Rvalue::ShallowInitBox(_, _) => Ok(()),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
@@ -288,7 +293,8 @@ fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &B
             | ProjectionElem::Downcast(..)
             | ProjectionElem::Subslice { .. }
             | ProjectionElem::Subtype(_)
-            | ProjectionElem::Index(_) => {},
+            | ProjectionElem::Index(_)
+            | ProjectionElem::UnwrapUnsafeBinder(_) => {},
         }
     }
 
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index eecbfb3936a..c6a038f7e0c 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -2,8 +2,9 @@
 
 #![allow(clippy::module_name_repetitions)]
 
+use std::sync::Arc;
+
 use rustc_ast::{LitKind, StrStyle};
-use rustc_data_structures::sync::Lrc;
 use rustc_errors::Applicability;
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
 use rustc_lint::{EarlyContext, LateContext};
@@ -204,7 +205,7 @@ impl fmt::Display for SourceText {
 fn get_source_range(sm: &SourceMap, sp: Range<BytePos>) -> Option<SourceFileRange> {
     let start = sm.lookup_byte_offset(sp.start);
     let end = sm.lookup_byte_offset(sp.end);
-    if !Lrc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos {
+    if !Arc::ptr_eq(&start.sf, &end.sf) || start.pos > end.pos {
         return None;
     }
     sm.ensure_source_file_source_present(&start.sf);
@@ -277,7 +278,7 @@ fn trim_start(sm: &SourceMap, sp: Range<BytePos>) -> Range<BytePos> {
 }
 
 pub struct SourceFileRange {
-    pub sf: Lrc<SourceFile>,
+    pub sf: Arc<SourceFile>,
     pub range: Range<usize>,
 }
 impl SourceFileRange {
@@ -726,12 +727,15 @@ 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 {
diff --git a/src/tools/clippy/clippy_utils/src/str_utils.rs b/src/tools/clippy/clippy_utils/src/str_utils.rs
index 1588ee452da..421b25a77fe 100644
--- a/src/tools/clippy/clippy_utils/src/str_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/str_utils.rs
@@ -370,11 +370,9 @@ 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/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index 32e7c2bbf7c..a5374f6904e 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -4,6 +4,7 @@
 
 use core::ops::ControlFlow;
 use itertools::Itertools;
+use rustc_abi::VariantIdx;
 use rustc_ast::ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
@@ -23,7 +24,6 @@ use rustc_middle::ty::{
 };
 use rustc_span::symbol::Ident;
 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;
 use rustc_trait_selection::traits::{Obligation, ObligationCause};
@@ -96,7 +96,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
                         return false;
                     }
 
-                    for (predicate, _span) in cx.tcx.explicit_item_super_predicates(def_id).iter_identity_copied() {
+                    for (predicate, _span) in cx.tcx.explicit_item_self_bounds(def_id).iter_identity_copied() {
                         match predicate.kind().skip_binder() {
                             // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through
                             // and check substitutions to find `U`.
@@ -118,7 +118,7 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
                                     if contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen) {
                                         return true;
                                     }
-                                };
+                                }
                             },
                             _ => (),
                         }
@@ -322,7 +322,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
         },
         ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),
         ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
-            for (predicate, _) in cx.tcx.explicit_item_super_predicates(def_id).skip_binder() {
+            for (predicate, _) in cx.tcx.explicit_item_self_bounds(def_id).skip_binder() {
                 if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
                     if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
                         return true;
@@ -712,7 +712,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
         ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) => sig_from_bounds(
             cx,
             ty,
-            cx.tcx.item_super_predicates(def_id).iter_instantiated(cx.tcx, args),
+            cx.tcx.item_self_bounds(def_id).iter_instantiated(cx.tcx, args),
             cx.tcx.opt_parent(def_id),
         ),
         ty::FnPtr(sig_tys, hdr) => Some(ExprFnSig::Sig(sig_tys.with(hdr), None)),
@@ -1341,3 +1341,14 @@ pub fn get_field_by_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, name: Symbol) ->
         _ => None,
     }
 }
+
+/// Check if `ty` is an `Option` and return its argument type if it is.
+pub fn option_arg_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
+    match ty.kind() {
+        ty::Adt(adt, args) => cx
+            .tcx
+            .is_diagnostic_item(sym::Option, adt.did())
+            .then(|| args.type_at(0)),
+        _ => None,
+    }
+}
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 d7640ebfb00..3398ff8af2f 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,8 +14,8 @@
 use crate::def_path_res;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
-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_hir::intravisit::{InferKind, Visitor, VisitorExt, walk_qpath, walk_ty};
+use rustc_hir::{self as hir, AmbigArg, 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};
@@ -55,7 +55,7 @@ fn expr_type_certainty(cx: &LateContext<'_>, expr: &Expr<'_>) -> Certainty {
                 && let Some(self_ty_def_id) = adt_def_id(self_ty(cx, method_def_id))
             {
                 receiver_type_certainty = receiver_type_certainty.with_def_id(self_ty_def_id);
-            };
+            }
             let lhs = path_segment_certainty(cx, receiver_type_certainty, method, false);
             let rhs = if type_is_inferable_from_arguments(cx, expr) {
                 meet(
@@ -116,14 +116,15 @@ impl<'cx> Visitor<'cx> for CertaintyVisitor<'cx, '_> {
         }
     }
 
-    fn visit_ty(&mut self, ty: &'cx hir::Ty<'_>) {
-        if matches!(ty.kind, TyKind::Infer) {
-            self.certainty = Certainty::Uncertain;
-        }
+    fn visit_ty(&mut self, ty: &'cx hir::Ty<'_, AmbigArg>) {
         if self.certainty != Certainty::Uncertain {
             walk_ty(self, ty);
         }
     }
+
+    fn visit_infer(&mut self, _inf_id: HirId, _inf_span: Span, _kind: InferKind<'cx>) -> Self::Result {
+        self.certainty = Certainty::Uncertain;
+    }
 }
 
 fn type_certainty(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Certainty {
@@ -139,7 +140,7 @@ fn type_certainty(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> Certainty {
     }
 
     let mut visitor = CertaintyVisitor::new(cx);
-    visitor.visit_ty(ty);
+    visitor.visit_ty_unambig(ty);
     visitor.certainty
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 7a3a861a9ca..99984c41714 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -2,12 +2,11 @@ use crate::ty::needs_ordered_drop;
 use crate::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
 use rustc_ast::visit::{VisitorResult, try_visit};
-use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 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,
-    Stmt, StructTailExpr, UnOp, UnsafeSource,
+    self as hir, AmbigArg, AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId,
+    ItemKind, LetExpr, Pat, QPath, Stmt, StructTailExpr, UnOp, UnsafeSource,
 };
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
@@ -122,7 +121,7 @@ pub fn for_each_expr_without_closures<'tcx, B, C: Continue>(
         }
 
         // Avoid unnecessary `walk_*` calls.
-        fn visit_ty(&mut self, _: &'tcx hir::Ty<'tcx>) -> Self::Result {
+        fn visit_ty(&mut self, _: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
             ControlFlow::Continue(())
         }
         fn visit_pat(&mut self, _: &'tcx Pat<'tcx>) -> Self::Result {
@@ -172,7 +171,7 @@ pub fn for_each_expr<'tcx, B, C: Continue>(
             ControlFlow::Continue(())
         }
         // Avoid unnecessary `walk_*` calls.
-        fn visit_ty(&mut self, _: &'tcx hir::Ty<'tcx>) -> Self::Result {
+        fn visit_ty(&mut self, _: &'tcx hir::Ty<'tcx, AmbigArg>) -> Self::Result {
             ControlFlow::Continue(())
         }
         fn visit_pat(&mut self, _: &'tcx Pat<'tcx>) -> Self::Result {
diff --git a/src/tools/clippy/lintcheck/Cargo.toml b/src/tools/clippy/lintcheck/Cargo.toml
index b0e4e3e3e57..55e588f5ec7 100644
--- a/src/tools/clippy/lintcheck/Cargo.toml
+++ b/src/tools/clippy/lintcheck/Cargo.toml
@@ -6,7 +6,7 @@ readme = "README.md"
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust-clippy"
 categories = ["development-tools"]
-edition = "2021"
+edition = "2024"
 publish = false
 default-run = "lintcheck"
 
diff --git a/src/tools/clippy/lintcheck/src/config.rs b/src/tools/clippy/lintcheck/src/config.rs
index bd4fcc5e337..83c3d7aba02 100644
--- a/src/tools/clippy/lintcheck/src/config.rs
+++ b/src/tools/clippy/lintcheck/src/config.rs
@@ -2,6 +2,7 @@ use clap::{Parser, Subcommand, ValueEnum};
 use std::num::NonZero;
 use std::path::PathBuf;
 
+#[allow(clippy::struct_excessive_bools)]
 #[derive(Parser, Clone, Debug)]
 #[command(args_conflicts_with_subcommands = true)]
 pub(crate) struct LintcheckConfig {
@@ -11,6 +12,9 @@ pub(crate) struct LintcheckConfig {
         short = 'j',
         value_name = "N",
         default_value_t = 0,
+        default_value_if("perf", "true", Some("1")), // Limit jobs to 1 when benchmarking
+        conflicts_with("perf"),
+        required = false,
         hide_default_value = true
     )]
     pub max_jobs: usize,
@@ -46,6 +50,11 @@ pub(crate) struct LintcheckConfig {
     /// Run clippy on the dependencies of crates specified in crates-toml
     #[clap(long, conflicts_with("max_jobs"))]
     pub recursive: bool,
+    /// Also produce a `perf.data` file, implies --jobs=1,
+    /// the `perf.data` file can be found at
+    /// `target/lintcheck/sources/<package>-<version>/perf.data`
+    #[clap(long)]
+    pub perf: bool,
     #[command(subcommand)]
     pub subcommand: Option<Commands>,
 }
@@ -107,7 +116,7 @@ impl LintcheckConfig {
             } else {
                 std::thread::available_parallelism().map_or(1, NonZero::get)
             };
-        };
+        }
 
         for lint_name in &mut config.lint_filter {
             *lint_name = format!(
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index 03e2a24f6f9..8d0d41ab945 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -116,7 +116,25 @@ impl Crate {
 
         clippy_args.extend(lint_levels_args.iter().map(String::as_str));
 
-        let mut cmd = Command::new("cargo");
+        let mut cmd;
+
+        if config.perf {
+            cmd = Command::new("perf");
+            cmd.args(&[
+                "record",
+                "-e",
+                "instructions", // Only count instructions
+                "-g",           // Enable call-graph, useful for flamegraphs and produces richer reports
+                "--quiet",      // Do not tamper with lintcheck's normal output
+                "-o",
+                "perf.data",
+                "--",
+                "cargo",
+            ]);
+        } else {
+            cmd = Command::new("cargo");
+        }
+
         cmd.arg(if config.fix { "fix" } else { "check" })
             .arg("--quiet")
             .current_dir(&self.path)
@@ -145,7 +163,7 @@ impl Crate {
             assert_eq!(status.code(), Some(0));
 
             return Vec::new();
-        };
+        }
 
         if !config.fix {
             cmd.arg("--message-format=json");
@@ -234,12 +252,22 @@ fn normalize_diag(
 }
 
 /// Builds clippy inside the repo to make sure we have a clippy executable we can use.
-fn build_clippy() -> String {
-    let output = Command::new("cargo")
-        .args(["run", "--bin=clippy-driver", "--", "--version"])
-        .stderr(Stdio::inherit())
-        .output()
-        .unwrap();
+fn build_clippy(release_build: bool) -> String {
+    let mut build_cmd = Command::new("cargo");
+    build_cmd.args([
+        "run",
+        "--bin=clippy-driver",
+        if release_build { "-r" } else { "" },
+        "--",
+        "--version",
+    ]);
+
+    if release_build {
+        build_cmd.env("CARGO_PROFILE_RELEASE_DEBUG", "true");
+    }
+
+    let output = build_cmd.stderr(Stdio::inherit()).output().unwrap();
+
     if !output.status.success() {
         eprintln!("Error: Failed to compile Clippy!");
         std::process::exit(1);
@@ -270,13 +298,18 @@ fn main() {
 
 #[allow(clippy::too_many_lines)]
 fn lintcheck(config: LintcheckConfig) {
-    let clippy_ver = build_clippy();
-    let clippy_driver_path = fs::canonicalize(format!("target/debug/clippy-driver{EXE_SUFFIX}")).unwrap();
+    let clippy_ver = build_clippy(config.perf);
+    let clippy_driver_path = fs::canonicalize(format!(
+        "target/{}/clippy-driver{EXE_SUFFIX}",
+        if config.perf { "release" } else { "debug" }
+    ))
+    .unwrap();
 
     // assert that clippy is found
     assert!(
         clippy_driver_path.is_file(),
-        "target/debug/clippy-driver binary not found! {}",
+        "target/{}/clippy-driver binary not found! {}",
+        if config.perf { "release" } else { "debug" },
         clippy_driver_path.display()
     );
 
@@ -313,7 +346,7 @@ fn lintcheck(config: LintcheckConfig) {
                 filter
             })
             .collect_into(&mut lint_level_args);
-    };
+    }
 
     let crates: Vec<Crate> = crates
         .into_iter()
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index b1f0a82b1f4..ab760287e83 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2025-01-09"
+channel = "nightly-2025-02-06"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/rustc_tools_util/Cargo.toml b/src/tools/clippy/rustc_tools_util/Cargo.toml
index b63632916ba..cba02563948 100644
--- a/src/tools/clippy/rustc_tools_util/Cargo.toml
+++ b/src/tools/clippy/rustc_tools_util/Cargo.toml
@@ -7,6 +7,6 @@ readme = "README.md"
 license = "MIT OR Apache-2.0"
 keywords = ["rustc", "tool", "git", "version", "hash"]
 categories = ["development-tools"]
-edition = "2018"
+edition = "2024"
 
 [dependencies]
diff --git a/src/tools/clippy/rustfmt.toml b/src/tools/clippy/rustfmt.toml
index 4248f42f654..0dc6adce7bf 100644
--- a/src/tools/clippy/rustfmt.toml
+++ b/src/tools/clippy/rustfmt.toml
@@ -2,8 +2,8 @@ max_width = 120
 comment_width = 100
 match_block_trailing_comma = true
 wrap_comments = true
-edition = "2021"
+edition = "2024"
 error_on_line_overflow = true
 imports_granularity = "Module"
-version = "Two"
+style_edition = "2024"
 ignore = ["tests/ui/crashes/ice-10912.rs"]
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 75ef60a5dc8..e4092bcd105 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -166,6 +166,8 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
         // MIR passes can be enabled / disabled separately, we should figure out, what passes to
         // use for Clippy.
         config.opts.unstable_opts.mir_opt_level = Some(0);
+        config.opts.unstable_opts.mir_enable_passes =
+            vec![("CheckNull".to_owned(), false), ("CheckAlignment".to_owned(), false)];
 
         // Disable flattening and inlining of format_args!(), so the HIR matches with the AST.
         config.opts.unstable_opts.flatten_format_args = false;
@@ -186,7 +188,7 @@ pub fn main() {
 
     rustc_driver::init_rustc_env_logger(&early_dcx);
 
-    let using_internal_features = rustc_driver::install_ice_hook(BUG_REPORT_URL, |dcx| {
+    rustc_driver::install_ice_hook(BUG_REPORT_URL, |dcx| {
         // FIXME: this macro calls unwrap internally but is called in a panicking context!  It's not
         // as simple as moving the call from the hook to main, because `install_ice_hook` doesn't
         // accept a generic closure.
@@ -195,7 +197,7 @@ pub fn main() {
     });
 
     exit(rustc_driver::catch_with_exit_code(move || {
-        let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?;
+        let mut orig_args = rustc_driver::args::raw_args(&early_dcx);
 
         let has_sysroot_arg = |args: &mut [String]| -> bool {
             if has_arg(args, "--sysroot") {
@@ -223,7 +225,7 @@ pub fn main() {
                 if !has_sysroot_arg(args) {
                     args.extend(vec!["--sysroot".into(), sys_root]);
                 }
-            };
+            }
         };
 
         // make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc"
@@ -236,8 +238,8 @@ pub fn main() {
             let mut args: Vec<String> = orig_args.clone();
             pass_sysroot_env_if_given(&mut args, sys_root_env);
 
-            rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run();
-            return Ok(());
+            rustc_driver::run_compiler(&args, &mut DefaultCallbacks);
+            return;
         }
 
         if orig_args.iter().any(|a| a == "--version" || a == "-V") {
@@ -295,15 +297,10 @@ pub fn main() {
         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 })
-                .set_using_internal_features(using_internal_features)
-                .run();
+            rustc_driver::run_compiler(&args, &mut ClippyCallbacks { clippy_args_var });
         } else {
-            rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var })
-                .set_using_internal_features(using_internal_features)
-                .run();
+            rustc_driver::run_compiler(&args, &mut RustcCallbacks { clippy_args_var });
         }
-        Ok(())
     }))
 }
 
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index e2e4d92df79..d1b1a1d2323 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -300,7 +300,9 @@ fn run_ui_cargo(cx: &TestContext) {
 }
 
 fn main() {
-    set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
+    unsafe {
+        set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
+    }
 
     let cx = TestContext::new();
 
diff --git a/src/tools/clippy/tests/missing-test-files.rs b/src/tools/clippy/tests/missing-test-files.rs
index 64eba5e0888..565dcd73f58 100644
--- a/src/tools/clippy/tests/missing-test-files.rs
+++ b/src/tools/clippy/tests/missing-test-files.rs
@@ -60,7 +60,7 @@ fn explore_directory(dir: &Path) -> Vec<String> {
                         }
                     },
                     _ => {},
-                };
+                }
             }
         }
     }
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
index ff178924bd1..ae5d8ef1d0b 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
@@ -13,5 +13,9 @@ note: rustc <version> running on <target>
 
 note: compiler flags: -Z ui-testing -Z deduplicate-diagnostics=no
 
+query stack during panic:
+#0 [early_lint_checks] perform lints prior to macro expansion
+#1 [hir_crate] getting the crate HIR
+... and 3 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
 note: Clippy version: foo
 
diff --git a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr
index 129fab5ff97..f0d7104a57d 100644
--- a/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr
+++ b/src/tools/clippy/tests/ui-toml/dbg_macro/dbg_macro.stderr
@@ -8,8 +8,9 @@ LL |     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
    = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`
 help: remove the invocation before committing it to a version control system
    |
-LL |     if let Some(n) = n.checked_sub(4) { n } else { n }
-   |                      ~~~~~~~~~~~~~~~~
+LL -     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
+LL +     if let Some(n) = n.checked_sub(4) { n } else { n }
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui-toml/dbg_macro/dbg_macro.rs:10:8
@@ -19,8 +20,9 @@ LL |     if dbg!(n <= 1) {
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     if n <= 1 {
-   |        ~~~~~~
+LL -     if dbg!(n <= 1) {
+LL +     if n <= 1 {
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui-toml/dbg_macro/dbg_macro.rs:11:9
@@ -30,7 +32,8 @@ LL |         dbg!(1)
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         1
+LL -         dbg!(1)
+LL +         1
    |
 
 error: the `dbg!` macro is intended as a debugging tool
@@ -41,7 +44,8 @@ LL |         dbg!(n * factorial(n - 1))
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         n * factorial(n - 1)
+LL -         dbg!(n * factorial(n - 1))
+LL +         n * factorial(n - 1)
    |
 
 error: the `dbg!` macro is intended as a debugging tool
@@ -52,8 +56,9 @@ LL |     dbg!(42);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     42;
-   |     ~~
+LL -     dbg!(42);
+LL +     42;
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui-toml/dbg_macro/dbg_macro.rs:19:14
@@ -63,8 +68,9 @@ LL |     foo(3) + dbg!(factorial(4));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     foo(3) + factorial(4);
-   |              ~~~~~~~~~~~~
+LL -     foo(3) + dbg!(factorial(4));
+LL +     foo(3) + factorial(4);
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui-toml/dbg_macro/dbg_macro.rs:20:5
@@ -74,8 +80,9 @@ LL |     dbg!(1, 2, 3, 4, 5);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     (1, 2, 3, 4, 5);
-   |     ~~~~~~~~~~~~~~~
+LL -     dbg!(1, 2, 3, 4, 5);
+LL +     (1, 2, 3, 4, 5);
+   |
 
 error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr
index a6e0ad0f804..8ba237ee75c 100644
--- a/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr
+++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_append/doc_markdown.stderr
@@ -8,8 +8,9 @@ LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and sh
    = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
 help: try
    |
-LL | /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.
+LL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr
index d4d8a579798..9f2d7cf54e0 100644
--- a/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr
+++ b/src/tools/clippy/tests/ui-toml/doc_valid_idents_replace/doc_markdown.stderr
@@ -8,8 +8,9 @@ LL | /// OAuth and LaTeX are inside Clippy's default list.
    = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
 help: try
    |
-LL | /// `OAuth` and LaTeX are inside Clippy's default list.
-   |     ~~~~~~~
+LL - /// OAuth and LaTeX are inside Clippy's default list.
+LL + /// `OAuth` and LaTeX are inside Clippy's default list.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:6:15
@@ -19,8 +20,9 @@ LL | /// OAuth and LaTeX are inside Clippy's default list.
    |
 help: try
    |
-LL | /// OAuth and `LaTeX` are inside Clippy's default list.
-   |               ~~~~~~~
+LL - /// OAuth and LaTeX are inside Clippy's default list.
+LL + /// OAuth and `LaTeX` are inside Clippy's default list.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui-toml/doc_valid_idents_replace/doc_markdown.rs:9:5
@@ -30,8 +32,9 @@ LL | /// TestItemThingyOfCoolness might sound cool but is not on the list and sh
    |
 help: try
    |
-LL | /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// TestItemThingyOfCoolness might sound cool but is not on the list and should be linted.
+LL + /// `TestItemThingyOfCoolness` might sound cool but is not on the list and should be linted.
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
index 8f7ebbd9546..020b3cc7878 100644
--- a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
@@ -14,8 +14,9 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     B(Box<[u8; 501]>),
-   |       ~~~~~~~~~~~~~~
+LL -     B([u8; 501]),
+LL +     B(Box<[u8; 501]>),
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr
index 2d700f60759..de9f17520ff 100644
--- a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr
+++ b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.default.stderr
@@ -33,8 +33,9 @@ LL |     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {
    |
 help: consider using the default names
    |
-LL |     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) {
-   |                              ~~~~           ~~~~~
+LL -     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {
+LL +     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) {
+   |
 
 error: renamed function parameter of trait impl
   --> tests/ui-toml/renamed_function_params/renamed_function_params.rs:80:18
diff --git a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr
index e57554fa613..bdc4eeaad80 100644
--- a/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr
+++ b/src/tools/clippy/tests/ui-toml/renamed_function_params/renamed_function_params.extend.stderr
@@ -27,8 +27,9 @@ LL |     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {
    |
 help: consider using the default names
    |
-LL |     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) {
-   |                              ~~~~           ~~~~~
+LL -     fn hash_slice<H: Hasher>(date: &[Self], states: &mut H) {
+LL +     fn hash_slice<H: Hasher>(data: &[Self], state: &mut H) {
+   |
 
 error: aborting due to 4 previous errors
 
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 b58ce9b8af3..2aff276a4a1 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
@@ -8,8 +8,9 @@ LL |         let _ = boxed_slice.get(1).unwrap();
    = help: to override `-D warnings` add `#[allow(clippy::get_unwrap)]`
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &boxed_slice[1];
-   |                 ~~~~~~~~~~~~~~~
+LL -         let _ = boxed_slice.get(1).unwrap();
+LL +         let _ = &boxed_slice[1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:38:17
@@ -30,8 +31,9 @@ LL |         let _ = some_slice.get(0).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_slice[0];
-   |                 ~~~~~~~~~~~~~~
+LL -         let _ = some_slice.get(0).unwrap();
+LL +         let _ = &some_slice[0];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:39:17
@@ -50,8 +52,9 @@ LL |         let _ = some_vec.get(0).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_vec[0];
-   |                 ~~~~~~~~~~~~
+LL -         let _ = some_vec.get(0).unwrap();
+LL +         let _ = &some_vec[0];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:40:17
@@ -70,8 +73,9 @@ LL |         let _ = some_vecdeque.get(0).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_vecdeque[0];
-   |                 ~~~~~~~~~~~~~~~~~
+LL -         let _ = some_vecdeque.get(0).unwrap();
+LL +         let _ = &some_vecdeque[0];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:41:17
@@ -90,8 +94,9 @@ LL |         let _ = some_hashmap.get(&1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_hashmap[&1];
-   |                 ~~~~~~~~~~~~~~~~~
+LL -         let _ = some_hashmap.get(&1).unwrap();
+LL +         let _ = &some_hashmap[&1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:42:17
@@ -110,8 +115,9 @@ LL |         let _ = some_btreemap.get(&1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_btreemap[&1];
-   |                 ~~~~~~~~~~~~~~~~~~
+LL -         let _ = some_btreemap.get(&1).unwrap();
+LL +         let _ = &some_btreemap[&1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:43:17
@@ -130,8 +136,9 @@ LL |         let _: u8 = *boxed_slice.get(1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _: u8 = boxed_slice[1];
-   |                     ~~~~~~~~~~~~~~
+LL -         let _: u8 = *boxed_slice.get(1).unwrap();
+LL +         let _: u8 = boxed_slice[1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:47:22
@@ -150,8 +157,9 @@ LL |         *boxed_slice.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         boxed_slice[0] = 1;
-   |         ~~~~~~~~~~~~~~
+LL -         *boxed_slice.get_mut(0).unwrap() = 1;
+LL +         boxed_slice[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:52:10
@@ -170,8 +178,9 @@ LL |         *some_slice.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         some_slice[0] = 1;
-   |         ~~~~~~~~~~~~~
+LL -         *some_slice.get_mut(0).unwrap() = 1;
+LL +         some_slice[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:53:10
@@ -190,8 +199,9 @@ LL |         *some_vec.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         some_vec[0] = 1;
-   |         ~~~~~~~~~~~
+LL -         *some_vec.get_mut(0).unwrap() = 1;
+LL +         some_vec[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:54:10
@@ -210,8 +220,9 @@ LL |         *some_vecdeque.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         some_vecdeque[0] = 1;
-   |         ~~~~~~~~~~~~~~~~
+LL -         *some_vecdeque.get_mut(0).unwrap() = 1;
+LL +         some_vecdeque[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:55:10
@@ -230,8 +241,9 @@ LL |         let _ = some_vec.get(0..1).unwrap().to_vec();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = some_vec[0..1].to_vec();
-   |                 ~~~~~~~~~~~~~~
+LL -         let _ = some_vec.get(0..1).unwrap().to_vec();
+LL +         let _ = some_vec[0..1].to_vec();
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:67:17
@@ -250,8 +262,9 @@ LL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = some_vec[0..1].to_vec();
-   |                 ~~~~~~~~~~~~~~
+LL -         let _ = some_vec.get_mut(0..1).unwrap().to_vec();
+LL +         let _ = some_vec[0..1].to_vec();
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:68:17
@@ -270,8 +283,9 @@ LL |     let _ = boxed_slice.get(1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |     let _ = &boxed_slice[1];
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = boxed_slice.get(1).unwrap();
+LL +     let _ = &boxed_slice[1];
+   |
 
 error: called `.get().unwrap()` on a slice
   --> tests/ui-toml/unwrap_used/unwrap_used.rs:94:17
@@ -281,8 +295,9 @@ LL |         let _ = Box::new([0]).get(1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &Box::new([0])[1];
-   |                 ~~~~~~~~~~~~~~~~~
+LL -         let _ = Box::new([0]).get(1).unwrap();
+LL +         let _ = &Box::new([0])[1];
+   |
 
 error: aborting due to 28 previous errors
 
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
index 3f204073085..f09106773c7 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.rs
@@ -170,6 +170,7 @@ pub fn hard_coded_allowed() {
 
     let _ = Saturating(0u32) + Saturating(0u32);
     let _ = String::new() + "";
+    let _ = String::new() + &String::new();
     let _ = Wrapping(0u32) + Wrapping(0u32);
 
     let saturating: Saturating<u32> = Saturating(0u32);
@@ -408,11 +409,14 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() {
     _n.wrapping_rem(_n);
     _n.wrapping_rem_euclid(_n);
 
+    _n.saturating_div(*Box::new(_n));
+
     // Unary
     _n = -_n;
     _n = -&_n;
     _custom = -_custom;
     _custom = -&_custom;
+    _ = -*Box::new(_n);
 }
 
 // Copied and pasted from the `integer_arithmetic` lint for comparison.
@@ -534,4 +538,11 @@ pub fn issue_12318() {
     one.sub_assign(1);
 }
 
+pub fn explicit_methods() {
+    use core::ops::Add;
+    let one: i32 = 1;
+    one.add(&one);
+    Box::new(one).add(one);
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
index 78b1aca4b8a..9b4cfb83fbb 100644
--- a/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
+++ b/src/tools/clippy/tests/ui/arithmetic_side_effects.stderr
@@ -14,730 +14,760 @@ LL |     let _ = 1f128 + 1f128;
    |             ^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:307:5
+  --> tests/ui/arithmetic_side_effects.rs:173:13
+   |
+LL |     let _ = String::new() + &String::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> 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:308: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:309: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:310:5
+  --> tests/ui/arithmetic_side_effects.rs:311: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:312:5
    |
 LL |     _n /= 0;
    |     ^^^^^^^
 
 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:313: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:314: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:315: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:316:5
    |
 LL |     _n *= 2;
    |     ^^^^^^^
 
 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:317: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:318:5
    |
 LL |     _n += -1;
    |     ^^^^^^^^
 
 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:319: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:320: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:321: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:322:5
    |
 LL |     _n /= -0;
    |     ^^^^^^^^
 
 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:323: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:324: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:325: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:326:5
    |
 LL |     _n *= -2;
    |     ^^^^^^^^
 
 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:327: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:328:5
    |
 LL |     _custom += Custom;
    |     ^^^^^^^^^^^^^^^^^
 
 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:329: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:330: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:331: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:332: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:333: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:334: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:335: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:336: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:337: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:338: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:339: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:340: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:341: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:342: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:343: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:344: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:345: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:346: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:347: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:348: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:349: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:350: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:351: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:352: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:353: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:354: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:355:5
    |
 LL |     _custom <<= &-Custom;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:357: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:358:10
+  --> tests/ui/arithmetic_side_effects.rs:359: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:360:10
    |
 LL |     _n = 1 + _n;
    |          ^^^^^^
 
 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:361: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:362:10
    |
 LL |     _n = _n - 1;
    |          ^^^^^^
 
 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:363: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:364:10
    |
 LL |     _n = 1 - _n;
    |          ^^^^^^
 
 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:365: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:366:10
    |
 LL |     _n = _n / 0;
    |          ^^^^^^
 
 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:367: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:368: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:369: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:370:10
    |
 LL |     _n = _n * 2;
    |          ^^^^^^
 
 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:371: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:372:10
    |
 LL |     _n = 2 * _n;
    |          ^^^^^^
 
 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:373: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:374:10
    |
 LL |     _n = 23 + &85;
    |          ^^^^^^^^
 
 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:375: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:376:10
    |
 LL |     _n = &23 + &85;
    |          ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:376: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:377: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:378: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:379: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:380: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:381: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:382: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:383: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:384: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:385: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:386: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:387: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:388: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:389: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:390: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:391: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:392: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:393: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:394: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:395: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:396: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:397: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:398:15
+  --> tests/ui/arithmetic_side_effects.rs:399:15
    |
 LL |     _custom = &Custom << _custom;
    |               ^^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:401:23
+  --> tests/ui/arithmetic_side_effects.rs:402:23
    |
 LL |     _n.saturating_div(0);
    |                       ^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:402:21
+  --> tests/ui/arithmetic_side_effects.rs:403:21
    |
 LL |     _n.wrapping_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:404:21
    |
 LL |     _n.wrapping_rem(0);
    |                     ^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:404:28
+  --> tests/ui/arithmetic_side_effects.rs:405:28
    |
 LL |     _n.wrapping_rem_euclid(0);
    |                            ^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:406:23
+  --> tests/ui/arithmetic_side_effects.rs:407:23
    |
 LL |     _n.saturating_div(_n);
    |                       ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:407:21
+  --> tests/ui/arithmetic_side_effects.rs:408:21
    |
 LL |     _n.wrapping_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:409:21
    |
 LL |     _n.wrapping_rem(_n);
    |                     ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:409:28
+  --> tests/ui/arithmetic_side_effects.rs:410:28
    |
 LL |     _n.wrapping_rem_euclid(_n);
    |                            ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:412:10
+  --> tests/ui/arithmetic_side_effects.rs:412:23
+   |
+LL |     _n.saturating_div(*Box::new(_n));
+   |                       ^^^^^^^^^^^^^
+
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> tests/ui/arithmetic_side_effects.rs:415:10
    |
 LL |     _n = -_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:416:10
    |
 LL |     _n = -&_n;
    |          ^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:414:15
+  --> tests/ui/arithmetic_side_effects.rs:417:15
    |
 LL |     _custom = -_custom;
    |               ^^^^^^^^
 
 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:418:15
    |
 LL |     _custom = -&_custom;
    |               ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:424:5
+  --> tests/ui/arithmetic_side_effects.rs:419:9
+   |
+LL |     _ = -*Box::new(_n);
+   |         ^^^^^^^^^^^^^^
+
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> tests/ui/arithmetic_side_effects.rs:428:5
    |
 LL |     1 + i;
    |     ^^^^^
 
 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:429:5
    |
 LL |     i * 2;
    |     ^^^^^
 
 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:430:5
    |
 LL |     1 % 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:431:5
    |
 LL |     i - 2 + 2 - i;
    |     ^^^^^^^^^^^^^
 
 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:432:5
    |
 LL |     -i;
    |     ^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:439:5
+  --> tests/ui/arithmetic_side_effects.rs:443:5
    |
 LL |     i += 1;
    |     ^^^^^^
 
 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:444: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:445:5
    |
 LL |     i *= 2;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:443:5
+  --> tests/ui/arithmetic_side_effects.rs:447:5
    |
 LL |     i /= 0;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:445:5
+  --> tests/ui/arithmetic_side_effects.rs:449:5
    |
 LL |     i /= var1;
    |     ^^^^^^^^^
 
 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:450:5
    |
 LL |     i /= var2;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:448:5
+  --> tests/ui/arithmetic_side_effects.rs:452:5
    |
 LL |     i %= 0;
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:450:5
+  --> tests/ui/arithmetic_side_effects.rs:454:5
    |
 LL |     i %= var1;
    |     ^^^^^^^^^
 
 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:455:5
    |
 LL |     i %= var2;
    |     ^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:461:5
+  --> tests/ui/arithmetic_side_effects.rs:465:5
    |
 LL |     10 / a
    |     ^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:515: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:519:9
+  --> tests/ui/arithmetic_side_effects.rs:523:9
    |
 LL |         x % maybe_zero
    |         ^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:530:5
+  --> tests/ui/arithmetic_side_effects.rs:534:5
    |
 LL |     one.add_assign(1);
    |     ^^^^^^^^^^^^^^^^^
 
 error: arithmetic operation that can potentially result in unexpected side-effects
-  --> tests/ui/arithmetic_side_effects.rs:534:5
+  --> tests/ui/arithmetic_side_effects.rs:538:5
    |
 LL |     one.sub_assign(1);
    |     ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 123 previous errors
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> tests/ui/arithmetic_side_effects.rs:544:5
+   |
+LL |     one.add(&one);
+   |     ^^^^^^^^^^^^^
+
+error: arithmetic operation that can potentially result in unexpected side-effects
+  --> tests/ui/arithmetic_side_effects.rs:545:5
+   |
+LL |     Box::new(one).add(one);
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 128 previous errors
 
diff --git a/src/tools/clippy/tests/ui/assign_ops2.stderr b/src/tools/clippy/tests/ui/assign_ops2.stderr
index ddeba2b2ff8..09b101b216a 100644
--- a/src/tools/clippy/tests/ui/assign_ops2.stderr
+++ b/src/tools/clippy/tests/ui/assign_ops2.stderr
@@ -8,12 +8,14 @@ LL |     a += a + 1;
    = help: to override `-D warnings` add `#[allow(clippy::misrefactored_assign_op)]`
 help: did you mean `a = a + 1` or `a = a + a + 1`? Consider replacing it with
    |
-LL |     a += 1;
-   |     ~~~~~~
+LL -     a += a + 1;
+LL +     a += 1;
+   |
 help: or
    |
-LL |     a = a + a + 1;
-   |     ~~~~~~~~~~~~~
+LL -     a += a + 1;
+LL +     a = a + a + 1;
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:11:5
@@ -23,12 +25,14 @@ LL |     a += 1 + a;
    |
 help: did you mean `a = a + 1` or `a = a + 1 + a`? Consider replacing it with
    |
-LL |     a += 1;
-   |     ~~~~~~
+LL -     a += 1 + a;
+LL +     a += 1;
+   |
 help: or
    |
-LL |     a = a + 1 + a;
-   |     ~~~~~~~~~~~~~
+LL -     a += 1 + a;
+LL +     a = a + 1 + a;
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:13:5
@@ -38,12 +42,14 @@ LL |     a -= a - 1;
    |
 help: did you mean `a = a - 1` or `a = a - (a - 1)`? Consider replacing it with
    |
-LL |     a -= 1;
-   |     ~~~~~~
+LL -     a -= a - 1;
+LL +     a -= 1;
+   |
 help: or
    |
-LL |     a = a - (a - 1);
-   |     ~~~~~~~~~~~~~~~
+LL -     a -= a - 1;
+LL +     a = a - (a - 1);
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:15:5
@@ -53,12 +59,14 @@ LL |     a *= a * 99;
    |
 help: did you mean `a = a * 99` or `a = a * a * 99`? Consider replacing it with
    |
-LL |     a *= 99;
-   |     ~~~~~~~
+LL -     a *= a * 99;
+LL +     a *= 99;
+   |
 help: or
    |
-LL |     a = a * a * 99;
-   |     ~~~~~~~~~~~~~~
+LL -     a *= a * 99;
+LL +     a = a * a * 99;
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:17:5
@@ -68,12 +76,14 @@ LL |     a *= 42 * a;
    |
 help: did you mean `a = a * 42` or `a = a * 42 * a`? Consider replacing it with
    |
-LL |     a *= 42;
-   |     ~~~~~~~
+LL -     a *= 42 * a;
+LL +     a *= 42;
+   |
 help: or
    |
-LL |     a = a * 42 * a;
-   |     ~~~~~~~~~~~~~~
+LL -     a *= 42 * a;
+LL +     a = a * 42 * a;
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:19:5
@@ -83,12 +93,14 @@ LL |     a /= a / 2;
    |
 help: did you mean `a = a / 2` or `a = a / (a / 2)`? Consider replacing it with
    |
-LL |     a /= 2;
-   |     ~~~~~~
+LL -     a /= a / 2;
+LL +     a /= 2;
+   |
 help: or
    |
-LL |     a = a / (a / 2);
-   |     ~~~~~~~~~~~~~~~
+LL -     a /= a / 2;
+LL +     a = a / (a / 2);
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:21:5
@@ -98,12 +110,14 @@ LL |     a %= a % 5;
    |
 help: did you mean `a = a % 5` or `a = a % (a % 5)`? Consider replacing it with
    |
-LL |     a %= 5;
-   |     ~~~~~~
+LL -     a %= a % 5;
+LL +     a %= 5;
+   |
 help: or
    |
-LL |     a = a % (a % 5);
-   |     ~~~~~~~~~~~~~~~
+LL -     a %= a % 5;
+LL +     a = a % (a % 5);
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:23:5
@@ -113,12 +127,14 @@ LL |     a &= a & 1;
    |
 help: did you mean `a = a & 1` or `a = a & a & 1`? Consider replacing it with
    |
-LL |     a &= 1;
-   |     ~~~~~~
+LL -     a &= a & 1;
+LL +     a &= 1;
+   |
 help: or
    |
-LL |     a = a & a & 1;
-   |     ~~~~~~~~~~~~~
+LL -     a &= a & 1;
+LL +     a = a & a & 1;
+   |
 
 error: variable appears on both sides of an assignment operation
   --> tests/ui/assign_ops2.rs:25:5
@@ -128,12 +144,14 @@ LL |     a *= a * a;
    |
 help: did you mean `a = a * a` or `a = a * a * a`? Consider replacing it with
    |
-LL |     a *= a;
-   |     ~~~~~~
+LL -     a *= a * a;
+LL +     a *= a;
+   |
 help: or
    |
-LL |     a = a * a * a;
-   |     ~~~~~~~~~~~~~
+LL -     a *= a * a;
+LL +     a = a * a * a;
+   |
 
 error: manual implementation of an assign operation
   --> tests/ui/assign_ops2.rs:63:5
diff --git a/src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs b/src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs
index 420232f9f8d..e3205193cce 100644
--- a/src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/non-exhaustive-enum.rs
@@ -6,3 +6,24 @@ pub enum ErrorKind {
     #[doc(hidden)]
     Uncategorized,
 }
+
+#[non_exhaustive]
+pub enum ExtNonExhaustiveEnum {
+    Unit,
+    Tuple(i32),
+    Struct { field: i32 },
+}
+
+pub enum ExtNonExhaustiveVariant {
+    ExhaustiveUnit,
+    #[non_exhaustive]
+    Unit,
+    #[non_exhaustive]
+    Tuple(i32),
+    #[non_exhaustive]
+    StructNoField {},
+    #[non_exhaustive]
+    Struct {
+        field: i32,
+    },
+}
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
index d271381adea..7c5882d4296 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.stderr
@@ -11,8 +11,9 @@ LL | #![deny(clippy::bind_instead_of_map)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: use `map` instead
    |
-LL |     let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
-   |                        ~~~                       ~          ~~~~~~~
+LL -     let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });
+LL +     let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
+   |
 
 error: using `Result.and_then(|x| Ok(y))`, which is more succinctly expressed as `map(|x| y)`
   --> tests/ui/bind_instead_of_map_multipart.rs:8:13
@@ -22,8 +23,9 @@ LL |     let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else {
    |
 help: use `map` instead
    |
-LL |     let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
-   |                               ~~~                       ~          ~~~~~~~
+LL -     let _ = Ok::<_, ()>("42").and_then(|s| if s.len() < 42 { Ok(0) } else { Ok(s.len()) });
+LL +     let _ = Ok::<_, ()>("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
+   |
 
 error: using `Result.or_else(|x| Err(y))`, which is more succinctly expressed as `map_err(|x| y)`
   --> tests/ui/bind_instead_of_map_multipart.rs:11:13
@@ -33,8 +35,9 @@ LL |     let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() +
    |
 help: use `map_err` instead
    |
-LL |     let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() });
-   |                                ~~~~~~~                       ~~~~~~~~~~~~          ~~~~~~~
+LL -     let _ = Err::<(), _>("42").or_else(|s| if s.len() < 42 { Err(s.len() + 20) } else { Err(s.len()) });
+LL +     let _ = Err::<(), _>("42").map_err(|s| if s.len() < 42 { s.len() + 20 } else { s.len() });
+   |
 
 error: using `Option.and_then(|x| Some(y))`, which is more succinctly expressed as `map(|x| y)`
   --> tests/ui/bind_instead_of_map_multipart.rs:19:5
@@ -83,8 +86,9 @@ LL |     let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { So
    |
 help: use `map` instead
    |
-LL |     let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) });
-   |                      ~~~                        ~~~~          ~~~~~~~~
+LL -     let _ = Some("").and_then(|s| if s.len() == 20 { Some(m!()) } else { Some(Some(20)) });
+LL +     let _ = Some("").map(|s| if s.len() == 20 { m!() } else { Some(20) });
+   |
 
 error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr
index 7d3a5c84a82..71f43af46c2 100644
--- a/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/borrow_deref_ref_unfixable.stderr
@@ -8,12 +8,14 @@ LL |         let x: &str = &*s;
    = help: to override `-D warnings` add `#[allow(clippy::borrow_deref_ref)]`
 help: if you would like to reborrow, try removing `&*`
    |
-LL |         let x: &str = s;
-   |                       ~
+LL -         let x: &str = &*s;
+LL +         let x: &str = s;
+   |
 help: if you would like to deref, try using `&**`
    |
-LL |         let x: &str = &**s;
-   |                       ~~~~
+LL -         let x: &str = &*s;
+LL +         let x: &str = &**s;
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/bytes_nth.fixed b/src/tools/clippy/tests/ui/bytes_nth.fixed
index 11deb2390fd..da35fcb55e5 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.fixed
+++ b/src/tools/clippy/tests/ui/bytes_nth.fixed
@@ -1,4 +1,5 @@
 #![allow(clippy::unnecessary_operation)]
+#![allow(clippy::sliced_string_as_bytes)]
 #![warn(clippy::bytes_nth)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/bytes_nth.rs b/src/tools/clippy/tests/ui/bytes_nth.rs
index 62d9c7a5ea7..5dbe84ecec8 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.rs
+++ b/src/tools/clippy/tests/ui/bytes_nth.rs
@@ -1,4 +1,5 @@
 #![allow(clippy::unnecessary_operation)]
+#![allow(clippy::sliced_string_as_bytes)]
 #![warn(clippy::bytes_nth)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/bytes_nth.stderr b/src/tools/clippy/tests/ui/bytes_nth.stderr
index c6f21576c3d..c5f341cb37f 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.stderr
+++ b/src/tools/clippy/tests/ui/bytes_nth.stderr
@@ -1,5 +1,5 @@
 error: called `.bytes().nth()` on a `String`
-  --> tests/ui/bytes_nth.rs:6:13
+  --> tests/ui/bytes_nth.rs:7:13
    |
 LL |     let _ = s.bytes().nth(3);
    |             ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3).copied()`
@@ -8,13 +8,13 @@ LL |     let _ = s.bytes().nth(3);
    = help: to override `-D warnings` add `#[allow(clippy::bytes_nth)]`
 
 error: called `.bytes().nth().unwrap()` on a `String`
-  --> tests/ui/bytes_nth.rs:7:14
+  --> tests/ui/bytes_nth.rs:8:14
    |
 LL |     let _ = &s.bytes().nth(3).unwrap();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.as_bytes()[3]`
 
 error: called `.bytes().nth()` on a `str`
-  --> tests/ui/bytes_nth.rs:8:13
+  --> tests/ui/bytes_nth.rs:9:13
    |
 LL |     let _ = s[..].bytes().nth(3);
    |             ^^^^^^^^^^^^^^^^^^^^ help: try: `s[..].as_bytes().get(3).copied()`
diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr
index 452482fc88e..901447c738e 100644
--- a/src/tools/clippy/tests/ui/cast.stderr
+++ b/src/tools/clippy/tests/ui/cast.stderr
@@ -81,8 +81,9 @@ LL |     1i32 as i8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i8::try_from(1i32);
-   |     ~~~~~~~~~~~~~~~~~~
+LL -     1i32 as i8;
+LL +     i8::try_from(1i32);
+   |
 
 error: casting `i32` to `u8` may truncate the value
   --> tests/ui/cast.rs:52:5
@@ -93,8 +94,9 @@ LL |     1i32 as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     u8::try_from(1i32);
-   |     ~~~~~~~~~~~~~~~~~~
+LL -     1i32 as u8;
+LL +     u8::try_from(1i32);
+   |
 
 error: casting `f64` to `isize` may truncate the value
   --> tests/ui/cast.rs:54:5
@@ -127,8 +129,9 @@ LL |     1f32 as u32 as u16;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     u16::try_from(1f32 as u32);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     1f32 as u32 as u16;
+LL +     u16::try_from(1f32 as u32);
+   |
 
 error: casting `f32` to `u32` may truncate the value
   --> tests/ui/cast.rs:59:5
@@ -153,8 +156,9 @@ LL |         let _x: i8 = 1i32 as _;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |         let _x: i8 = 1i32.try_into();
-   |                      ~~~~~~~~~~~~~~~
+LL -         let _x: i8 = 1i32 as _;
+LL +         let _x: i8 = 1i32.try_into();
+   |
 
 error: casting `f32` to `i32` may truncate the value
   --> tests/ui/cast.rs:66:9
@@ -228,8 +232,9 @@ LL |     1usize as i8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i8::try_from(1usize);
-   |     ~~~~~~~~~~~~~~~~~~~~
+LL -     1usize as i8;
+LL +     i8::try_from(1usize);
+   |
 
 error: casting `usize` to `i16` may truncate the value
   --> tests/ui/cast.rs:90:5
@@ -240,8 +245,9 @@ LL |     1usize as i16;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i16::try_from(1usize);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1usize as i16;
+LL +     i16::try_from(1usize);
+   |
 
 error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers
   --> tests/ui/cast.rs:90:5
@@ -261,8 +267,9 @@ LL |     1usize as i32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i32::try_from(1usize);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1usize as i32;
+LL +     i32::try_from(1usize);
+   |
 
 error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
   --> tests/ui/cast.rs:95:5
@@ -300,8 +307,9 @@ LL |     1u64 as isize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     isize::try_from(1u64);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1u64 as isize;
+LL +     isize::try_from(1u64);
+   |
 
 error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
   --> tests/ui/cast.rs:111:5
@@ -360,8 +368,9 @@ LL |     (-99999999999i64).min(1) as i8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i8::try_from((-99999999999i64).min(1));
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     (-99999999999i64).min(1) as i8;
+LL +     i8::try_from((-99999999999i64).min(1));
+   |
 
 error: casting `u64` to `u8` may truncate the value
   --> tests/ui/cast.rs:222:5
@@ -372,8 +381,9 @@ LL |     999999u64.clamp(0, 256) as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     u8::try_from(999999u64.clamp(0, 256));
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     999999u64.clamp(0, 256) as u8;
+LL +     u8::try_from(999999u64.clamp(0, 256));
+   |
 
 error: casting `main::E2` to `u8` may truncate the value
   --> tests/ui/cast.rs:245:21
@@ -384,8 +394,9 @@ LL |             let _ = self as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |             let _ = u8::try_from(self);
-   |                     ~~~~~~~~~~~~~~~~~~
+LL -             let _ = self as u8;
+LL +             let _ = u8::try_from(self);
+   |
 
 error: casting `main::E2::B` to `u8` will truncate the value
   --> tests/ui/cast.rs:247:21
@@ -405,8 +416,9 @@ LL |             let _ = self as i8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |             let _ = i8::try_from(self);
-   |                     ~~~~~~~~~~~~~~~~~~
+LL -             let _ = self as i8;
+LL +             let _ = i8::try_from(self);
+   |
 
 error: casting `main::E5::A` to `i8` will truncate the value
   --> tests/ui/cast.rs:291:21
@@ -423,8 +435,9 @@ LL |             let _ = self as i16;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |             let _ = i16::try_from(self);
-   |                     ~~~~~~~~~~~~~~~~~~~
+LL -             let _ = self as i16;
+LL +             let _ = i16::try_from(self);
+   |
 
 error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers
   --> tests/ui/cast.rs:327:21
@@ -435,8 +448,9 @@ LL |             let _ = self as usize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |             let _ = usize::try_from(self);
-   |                     ~~~~~~~~~~~~~~~~~~~~~
+LL -             let _ = self as usize;
+LL +             let _ = usize::try_from(self);
+   |
 
 error: casting `main::E10` to `u16` may truncate the value
   --> tests/ui/cast.rs:374:21
@@ -447,8 +461,9 @@ LL |             let _ = self as u16;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |             let _ = u16::try_from(self);
-   |                     ~~~~~~~~~~~~~~~~~~~
+LL -             let _ = self as u16;
+LL +             let _ = u16::try_from(self);
+   |
 
 error: casting `u32` to `u8` may truncate the value
   --> tests/ui/cast.rs:385:13
@@ -459,8 +474,9 @@ LL |     let c = (q >> 16) as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     let c = u8::try_from(q >> 16);
-   |             ~~~~~~~~~~~~~~~~~~~~~
+LL -     let c = (q >> 16) as u8;
+LL +     let c = u8::try_from(q >> 16);
+   |
 
 error: casting `u32` to `u8` may truncate the value
   --> tests/ui/cast.rs:389:13
@@ -471,8 +487,9 @@ LL |     let c = (q / 1000) as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     let c = u8::try_from(q / 1000);
-   |             ~~~~~~~~~~~~~~~~~~~~~~
+LL -     let c = (q / 1000) as u8;
+LL +     let c = u8::try_from(q / 1000);
+   |
 
 error: casting `i32` to `u32` may lose the sign of the value
   --> tests/ui/cast.rs:401:9
@@ -674,8 +691,9 @@ LL |     m!();
    = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |             let _ = u8::try_from(u32::MAX); // cast_possible_truncation
-   |                     ~~~~~~~~~~~~~~~~~~~~~~
+LL -             let _ = u32::MAX as u8; // cast_possible_truncation
+LL +             let _ = u8::try_from(u32::MAX); // cast_possible_truncation
+   |
 
 error: casting `f64` to `f32` may truncate the value
   --> tests/ui/cast.rs:474:21
@@ -698,7 +716,8 @@ LL |     bar.unwrap().unwrap() as usize
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     usize::try_from(bar.unwrap().unwrap())
+LL -     bar.unwrap().unwrap() as usize
+LL +     usize::try_from(bar.unwrap().unwrap())
    |
 
 error: casting `i64` to `usize` may lose the sign of the value
@@ -716,8 +735,9 @@ LL |     (256 & 999999u64) as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     u8::try_from(256 & 999999u64);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     (256 & 999999u64) as u8;
+LL +     u8::try_from(256 & 999999u64);
+   |
 
 error: casting `u64` to `u8` may truncate the value
   --> tests/ui/cast.rs:500:5
@@ -728,8 +748,9 @@ LL |     (255 % 999999u64) as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     u8::try_from(255 % 999999u64);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     (255 % 999999u64) as u8;
+LL +     u8::try_from(255 % 999999u64);
+   |
 
 error: aborting due to 92 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
index 82d6b2e4b8e..68992271762 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_bool.stderr
@@ -9,8 +9,9 @@ LL |     let _ = true as u8;
    = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
 help: use `u8::from` instead
    |
-LL |     let _ = u8::from(true);
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = true as u8;
+LL +     let _ = u8::from(true);
+   |
 
 error: casts from `bool` to `u16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:9:13
@@ -21,8 +22,9 @@ LL |     let _ = true as u16;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u16::from` instead
    |
-LL |     let _ = u16::from(true);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = true as u16;
+LL +     let _ = u16::from(true);
+   |
 
 error: casts from `bool` to `u32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:10:13
@@ -33,8 +35,9 @@ LL |     let _ = true as u32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u32::from` instead
    |
-LL |     let _ = u32::from(true);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = true as u32;
+LL +     let _ = u32::from(true);
+   |
 
 error: casts from `bool` to `u64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:11:13
@@ -45,8 +48,9 @@ LL |     let _ = true as u64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u64::from` instead
    |
-LL |     let _ = u64::from(true);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = true as u64;
+LL +     let _ = u64::from(true);
+   |
 
 error: casts from `bool` to `u128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:12:13
@@ -57,8 +61,9 @@ LL |     let _ = true as u128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u128::from` instead
    |
-LL |     let _ = u128::from(true);
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = true as u128;
+LL +     let _ = u128::from(true);
+   |
 
 error: casts from `bool` to `usize` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:13:13
@@ -69,8 +74,9 @@ LL |     let _ = true as usize;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `usize::from` instead
    |
-LL |     let _ = usize::from(true);
-   |             ~~~~~~~~~~~~~~~~~
+LL -     let _ = true as usize;
+LL +     let _ = usize::from(true);
+   |
 
 error: casts from `bool` to `i8` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:15:13
@@ -81,8 +87,9 @@ LL |     let _ = true as i8;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i8::from` instead
    |
-LL |     let _ = i8::from(true);
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = true as i8;
+LL +     let _ = i8::from(true);
+   |
 
 error: casts from `bool` to `i16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:16:13
@@ -93,8 +100,9 @@ LL |     let _ = true as i16;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i16::from` instead
    |
-LL |     let _ = i16::from(true);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = true as i16;
+LL +     let _ = i16::from(true);
+   |
 
 error: casts from `bool` to `i32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:17:13
@@ -105,8 +113,9 @@ LL |     let _ = true as i32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i32::from` instead
    |
-LL |     let _ = i32::from(true);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = true as i32;
+LL +     let _ = i32::from(true);
+   |
 
 error: casts from `bool` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:18:13
@@ -117,8 +126,9 @@ LL |     let _ = true as i64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i64::from` instead
    |
-LL |     let _ = i64::from(true);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = true as i64;
+LL +     let _ = i64::from(true);
+   |
 
 error: casts from `bool` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:19:13
@@ -129,8 +139,9 @@ LL |     let _ = true as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     let _ = i128::from(true);
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = true as i128;
+LL +     let _ = i128::from(true);
+   |
 
 error: casts from `bool` to `isize` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:20:13
@@ -141,8 +152,9 @@ LL |     let _ = true as isize;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `isize::from` instead
    |
-LL |     let _ = isize::from(true);
-   |             ~~~~~~~~~~~~~~~~~
+LL -     let _ = true as isize;
+LL +     let _ = isize::from(true);
+   |
 
 error: casts from `bool` to `u16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:23:13
@@ -153,8 +165,9 @@ LL |     let _ = (true | false) as u16;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u16::from` instead
    |
-LL |     let _ = u16::from(true | false);
-   |             ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = (true | false) as u16;
+LL +     let _ = u16::from(true | false);
+   |
 
 error: casts from `bool` to `u8` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:25:13
@@ -165,8 +178,9 @@ LL |     let _ = true as U8;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `U8::from` instead
    |
-LL |     let _ = U8::from(true);
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = true as U8;
+LL +     let _ = U8::from(true);
+   |
 
 error: casts from `bool` to `u8` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_bool.rs:53:13
@@ -177,8 +191,9 @@ LL |     let _ = true as u8;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u8::from` instead
    |
-LL |     let _ = u8::from(true);
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = true as u8;
+LL +     let _ = u8::from(true);
+   |
 
 error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_lossless_float.stderr b/src/tools/clippy/tests/ui/cast_lossless_float.stderr
index b36f8bcecf5..3f405e3f402 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_float.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_float.stderr
@@ -9,8 +9,9 @@ LL |     let _ = x0 as f32;
    = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
 help: use `f32::from` instead
    |
-LL |     let _ = f32::from(x0);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x0 as f32;
+LL +     let _ = f32::from(x0);
+   |
 
 error: casts from `i8` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:13:13
@@ -21,8 +22,9 @@ LL |     let _ = x0 as f64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f64::from` instead
    |
-LL |     let _ = f64::from(x0);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x0 as f64;
+LL +     let _ = f64::from(x0);
+   |
 
 error: casts from `i8` to `f32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:14:13
@@ -33,8 +35,9 @@ LL |     let _ = x0 as F32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `F32::from` instead
    |
-LL |     let _ = F32::from(x0);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x0 as F32;
+LL +     let _ = F32::from(x0);
+   |
 
 error: casts from `i8` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:15:13
@@ -45,8 +48,9 @@ LL |     let _ = x0 as F64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `F64::from` instead
    |
-LL |     let _ = F64::from(x0);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x0 as F64;
+LL +     let _ = F64::from(x0);
+   |
 
 error: casts from `u8` to `f32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:17:13
@@ -57,8 +61,9 @@ LL |     let _ = x1 as f32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f32::from` instead
    |
-LL |     let _ = f32::from(x1);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x1 as f32;
+LL +     let _ = f32::from(x1);
+   |
 
 error: casts from `u8` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:18:13
@@ -69,8 +74,9 @@ LL |     let _ = x1 as f64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f64::from` instead
    |
-LL |     let _ = f64::from(x1);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x1 as f64;
+LL +     let _ = f64::from(x1);
+   |
 
 error: casts from `i16` to `f32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:20:13
@@ -81,8 +87,9 @@ LL |     let _ = x2 as f32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f32::from` instead
    |
-LL |     let _ = f32::from(x2);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x2 as f32;
+LL +     let _ = f32::from(x2);
+   |
 
 error: casts from `i16` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:21:13
@@ -93,8 +100,9 @@ LL |     let _ = x2 as f64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f64::from` instead
    |
-LL |     let _ = f64::from(x2);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x2 as f64;
+LL +     let _ = f64::from(x2);
+   |
 
 error: casts from `u16` to `f32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:23:13
@@ -105,8 +113,9 @@ LL |     let _ = x3 as f32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f32::from` instead
    |
-LL |     let _ = f32::from(x3);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x3 as f32;
+LL +     let _ = f32::from(x3);
+   |
 
 error: casts from `u16` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:24:13
@@ -117,8 +126,9 @@ LL |     let _ = x3 as f64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f64::from` instead
    |
-LL |     let _ = f64::from(x3);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x3 as f64;
+LL +     let _ = f64::from(x3);
+   |
 
 error: casts from `i32` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:26:13
@@ -129,8 +139,9 @@ LL |     let _ = x4 as f64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f64::from` instead
    |
-LL |     let _ = f64::from(x4);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x4 as f64;
+LL +     let _ = f64::from(x4);
+   |
 
 error: casts from `u32` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:28:13
@@ -141,8 +152,9 @@ LL |     let _ = x5 as f64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f64::from` instead
    |
-LL |     let _ = f64::from(x5);
-   |             ~~~~~~~~~~~~~
+LL -     let _ = x5 as f64;
+LL +     let _ = f64::from(x5);
+   |
 
 error: casts from `f32` to `f64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_float.rs:31:13
@@ -153,8 +165,9 @@ LL |     let _ = 1.0f32 as f64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `f64::from` instead
    |
-LL |     let _ = f64::from(1.0f32);
-   |             ~~~~~~~~~~~~~~~~~
+LL -     let _ = 1.0f32 as f64;
+LL +     let _ = f64::from(1.0f32);
+   |
 
 error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
index c93ecb8fb56..d2580913bb5 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
@@ -9,8 +9,9 @@ LL |     0u8 as u16;
    = help: to override `-D warnings` add `#[allow(clippy::cast_lossless)]`
 help: use `u16::from` instead
    |
-LL |     u16::from(0u8);
-   |     ~~~~~~~~~~~~~~
+LL -     0u8 as u16;
+LL +     u16::from(0u8);
+   |
 
 error: casts from `u8` to `i16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:10:5
@@ -21,8 +22,9 @@ LL |     0u8 as i16;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i16::from` instead
    |
-LL |     i16::from(0u8);
-   |     ~~~~~~~~~~~~~~
+LL -     0u8 as i16;
+LL +     i16::from(0u8);
+   |
 
 error: casts from `u8` to `u32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:12:5
@@ -33,8 +35,9 @@ LL |     0u8 as u32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u32::from` instead
    |
-LL |     u32::from(0u8);
-   |     ~~~~~~~~~~~~~~
+LL -     0u8 as u32;
+LL +     u32::from(0u8);
+   |
 
 error: casts from `u8` to `i32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:14:5
@@ -45,8 +48,9 @@ LL |     0u8 as i32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i32::from` instead
    |
-LL |     i32::from(0u8);
-   |     ~~~~~~~~~~~~~~
+LL -     0u8 as i32;
+LL +     i32::from(0u8);
+   |
 
 error: casts from `u8` to `u64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:16:5
@@ -57,8 +61,9 @@ LL |     0u8 as u64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u64::from` instead
    |
-LL |     u64::from(0u8);
-   |     ~~~~~~~~~~~~~~
+LL -     0u8 as u64;
+LL +     u64::from(0u8);
+   |
 
 error: casts from `u8` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:18:5
@@ -69,8 +74,9 @@ LL |     0u8 as i64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i64::from` instead
    |
-LL |     i64::from(0u8);
-   |     ~~~~~~~~~~~~~~
+LL -     0u8 as i64;
+LL +     i64::from(0u8);
+   |
 
 error: casts from `u8` to `u128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:20:5
@@ -81,8 +87,9 @@ LL |     0u8 as u128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u128::from` instead
    |
-LL |     u128::from(0u8);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u8 as u128;
+LL +     u128::from(0u8);
+   |
 
 error: casts from `u8` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:22:5
@@ -93,8 +100,9 @@ LL |     0u8 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0u8);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u8 as i128;
+LL +     i128::from(0u8);
+   |
 
 error: casts from `u16` to `u32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:25:5
@@ -105,8 +113,9 @@ LL |     0u16 as u32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u32::from` instead
    |
-LL |     u32::from(0u16);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u16 as u32;
+LL +     u32::from(0u16);
+   |
 
 error: casts from `u16` to `i32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:27:5
@@ -117,8 +126,9 @@ LL |     0u16 as i32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i32::from` instead
    |
-LL |     i32::from(0u16);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u16 as i32;
+LL +     i32::from(0u16);
+   |
 
 error: casts from `u16` to `u64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:29:5
@@ -129,8 +139,9 @@ LL |     0u16 as u64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u64::from` instead
    |
-LL |     u64::from(0u16);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u16 as u64;
+LL +     u64::from(0u16);
+   |
 
 error: casts from `u16` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:31:5
@@ -141,8 +152,9 @@ LL |     0u16 as i64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i64::from` instead
    |
-LL |     i64::from(0u16);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u16 as i64;
+LL +     i64::from(0u16);
+   |
 
 error: casts from `u16` to `u128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:33:5
@@ -153,8 +165,9 @@ LL |     0u16 as u128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u128::from` instead
    |
-LL |     u128::from(0u16);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0u16 as u128;
+LL +     u128::from(0u16);
+   |
 
 error: casts from `u16` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:35:5
@@ -165,8 +178,9 @@ LL |     0u16 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0u16);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0u16 as i128;
+LL +     i128::from(0u16);
+   |
 
 error: casts from `u32` to `u64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:38:5
@@ -177,8 +191,9 @@ LL |     0u32 as u64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u64::from` instead
    |
-LL |     u64::from(0u32);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u32 as u64;
+LL +     u64::from(0u32);
+   |
 
 error: casts from `u32` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:40:5
@@ -189,8 +204,9 @@ LL |     0u32 as i64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i64::from` instead
    |
-LL |     i64::from(0u32);
-   |     ~~~~~~~~~~~~~~~
+LL -     0u32 as i64;
+LL +     i64::from(0u32);
+   |
 
 error: casts from `u32` to `u128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:42:5
@@ -201,8 +217,9 @@ LL |     0u32 as u128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u128::from` instead
    |
-LL |     u128::from(0u32);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0u32 as u128;
+LL +     u128::from(0u32);
+   |
 
 error: casts from `u32` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:44:5
@@ -213,8 +230,9 @@ LL |     0u32 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0u32);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0u32 as i128;
+LL +     i128::from(0u32);
+   |
 
 error: casts from `u64` to `u128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:47:5
@@ -225,8 +243,9 @@ LL |     0u64 as u128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u128::from` instead
    |
-LL |     u128::from(0u64);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0u64 as u128;
+LL +     u128::from(0u64);
+   |
 
 error: casts from `u64` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:49:5
@@ -237,8 +256,9 @@ LL |     0u64 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0u64);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0u64 as i128;
+LL +     i128::from(0u64);
+   |
 
 error: casts from `i8` to `i16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:52:5
@@ -249,8 +269,9 @@ LL |     0i8 as i16;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i16::from` instead
    |
-LL |     i16::from(0i8);
-   |     ~~~~~~~~~~~~~~
+LL -     0i8 as i16;
+LL +     i16::from(0i8);
+   |
 
 error: casts from `i8` to `i32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:54:5
@@ -261,8 +282,9 @@ LL |     0i8 as i32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i32::from` instead
    |
-LL |     i32::from(0i8);
-   |     ~~~~~~~~~~~~~~
+LL -     0i8 as i32;
+LL +     i32::from(0i8);
+   |
 
 error: casts from `i8` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:56:5
@@ -273,8 +295,9 @@ LL |     0i8 as i64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i64::from` instead
    |
-LL |     i64::from(0i8);
-   |     ~~~~~~~~~~~~~~
+LL -     0i8 as i64;
+LL +     i64::from(0i8);
+   |
 
 error: casts from `i8` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:58:5
@@ -285,8 +308,9 @@ LL |     0i8 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0i8);
-   |     ~~~~~~~~~~~~~~~
+LL -     0i8 as i128;
+LL +     i128::from(0i8);
+   |
 
 error: casts from `i16` to `i32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:61:5
@@ -297,8 +321,9 @@ LL |     0i16 as i32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i32::from` instead
    |
-LL |     i32::from(0i16);
-   |     ~~~~~~~~~~~~~~~
+LL -     0i16 as i32;
+LL +     i32::from(0i16);
+   |
 
 error: casts from `i16` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:63:5
@@ -309,8 +334,9 @@ LL |     0i16 as i64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i64::from` instead
    |
-LL |     i64::from(0i16);
-   |     ~~~~~~~~~~~~~~~
+LL -     0i16 as i64;
+LL +     i64::from(0i16);
+   |
 
 error: casts from `i16` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:65:5
@@ -321,8 +347,9 @@ LL |     0i16 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0i16);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0i16 as i128;
+LL +     i128::from(0i16);
+   |
 
 error: casts from `i32` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:68:5
@@ -333,8 +360,9 @@ LL |     0i32 as i64;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i64::from` instead
    |
-LL |     i64::from(0i32);
-   |     ~~~~~~~~~~~~~~~
+LL -     0i32 as i64;
+LL +     i64::from(0i32);
+   |
 
 error: casts from `i32` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:70:5
@@ -345,8 +373,9 @@ LL |     0i32 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0i32);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0i32 as i128;
+LL +     i128::from(0i32);
+   |
 
 error: casts from `i64` to `i128` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:73:5
@@ -357,8 +386,9 @@ LL |     0i64 as i128;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i128::from` instead
    |
-LL |     i128::from(0i64);
-   |     ~~~~~~~~~~~~~~~~
+LL -     0i64 as i128;
+LL +     i128::from(0i64);
+   |
 
 error: casts from `u8` to `u16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:77:13
@@ -369,8 +399,9 @@ LL |     let _ = (1u8 + 1u8) as u16;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `u16::from` instead
    |
-LL |     let _ = u16::from(1u8 + 1u8);
-   |             ~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = (1u8 + 1u8) as u16;
+LL +     let _ = u16::from(1u8 + 1u8);
+   |
 
 error: casts from `i8` to `i64` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:80:13
@@ -381,8 +412,9 @@ LL |     let _ = 1i8 as I64Alias;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `I64Alias::from` instead
    |
-LL |     let _ = I64Alias::from(1i8);
-   |             ~~~~~~~~~~~~~~~~~~~
+LL -     let _ = 1i8 as I64Alias;
+LL +     let _ = I64Alias::from(1i8);
+   |
 
 error: casts from `u8` to `u16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:83:18
@@ -393,8 +425,9 @@ LL |     let _: u16 = 0u8 as _;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `Into::into` instead
    |
-LL |     let _: u16 = 0u8.into();
-   |                  ~~~~~~~~~~
+LL -     let _: u16 = 0u8 as _;
+LL +     let _: u16 = 0u8.into();
+   |
 
 error: casts from `i8` to `i16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:85:18
@@ -405,8 +438,9 @@ LL |     let _: i16 = -1i8 as _;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `Into::into` instead
    |
-LL |     let _: i16 = (-1i8).into();
-   |                  ~~~~~~~~~~~~~
+LL -     let _: i16 = -1i8 as _;
+LL +     let _: i16 = (-1i8).into();
+   |
 
 error: casts from `u8` to `u16` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:87:18
@@ -417,8 +451,9 @@ LL |     let _: u16 = (1u8 + 2) as _;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `Into::into` instead
    |
-LL |     let _: u16 = (1u8 + 2).into();
-   |                  ~~~~~~~~~~~~~~~~
+LL -     let _: u16 = (1u8 + 2) as _;
+LL +     let _: u16 = (1u8 + 2).into();
+   |
 
 error: casts from `u16` to `u32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:89:18
@@ -429,8 +464,9 @@ LL |     let _: u32 = 1i8 as u16 as _;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `Into::into` instead
    |
-LL |     let _: u32 = (1i8 as u16).into();
-   |                  ~~~~~~~~~~~~~~~~~~~
+LL -     let _: u32 = 1i8 as u16 as _;
+LL +     let _: u32 = (1i8 as u16).into();
+   |
 
 error: casts from `i8` to `i32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:124:13
@@ -441,8 +477,9 @@ LL |     let _ = sign_cast!(x, u8, i8) as i32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i32::from` instead
    |
-LL |     let _ = i32::from(sign_cast!(x, u8, i8));
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = sign_cast!(x, u8, i8) as i32;
+LL +     let _ = i32::from(sign_cast!(x, u8, i8));
+   |
 
 error: casts from `i8` to `i32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:126:13
@@ -453,8 +490,9 @@ LL |     let _ = (sign_cast!(x, u8, i8) + 1) as i32;
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `i32::from` instead
    |
-LL |     let _ = i32::from(sign_cast!(x, u8, i8) + 1);
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = (sign_cast!(x, u8, i8) + 1) as i32;
+LL +     let _ = i32::from(sign_cast!(x, u8, i8) + 1);
+   |
 
 error: casts from `u8` to `u32` can be expressed infallibly using `From`
   --> tests/ui/cast_lossless_integer.rs:133:13
@@ -469,7 +507,8 @@ LL |     let _ = in_macro!();
    = note: this error originates in the macro `in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: use `u32::from` instead
    |
-LL |             u32::from(1u8)
+LL -             1u8 as u32
+LL +             u32::from(1u8)
    |
 
 error: casts from `u8` to `u32` can be expressed infallibly using `From`
@@ -481,8 +520,9 @@ LL |     let _ = 0u8 as ty!();
    = help: an `as` cast can become silently lossy if the types change in the future
 help: use `<ty!()>::from` instead
    |
-LL |     let _ = <ty!()>::from(0u8);
-   |             ~~~~~~~~~~~~~~~~~~
+LL -     let _ = 0u8 as ty!();
+LL +     let _ = <ty!()>::from(0u8);
+   |
 
 error: aborting due to 40 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_size.64bit.stderr b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
index bc37107d80e..6b9919f8a10 100644
--- a/src/tools/clippy/tests/ui/cast_size.64bit.stderr
+++ b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
@@ -9,8 +9,9 @@ LL |     1isize as i8;
    = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i8::try_from(1isize);
-   |     ~~~~~~~~~~~~~~~~~~~~
+LL -     1isize as i8;
+LL +     i8::try_from(1isize);
+   |
 
 error: casting `isize` to `f32` causes a loss of precision (`isize` is 32 or 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
   --> tests/ui/cast_size.rs:21:5
@@ -48,8 +49,9 @@ LL |     1isize as i32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i32::try_from(1isize);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1isize as i32;
+LL +     i32::try_from(1isize);
+   |
 
 error: casting `isize` to `u32` may truncate the value on targets with 64-bit wide pointers
   --> tests/ui/cast_size.rs:29:5
@@ -60,8 +62,9 @@ LL |     1isize as u32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     u32::try_from(1isize);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1isize as u32;
+LL +     u32::try_from(1isize);
+   |
 
 error: casting `usize` to `u32` may truncate the value on targets with 64-bit wide pointers
   --> tests/ui/cast_size.rs:30:5
@@ -72,8 +75,9 @@ LL |     1usize as u32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     u32::try_from(1usize);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1usize as u32;
+LL +     u32::try_from(1usize);
+   |
 
 error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
   --> tests/ui/cast_size.rs:31:5
@@ -84,8 +88,9 @@ LL |     1usize as i32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     i32::try_from(1usize);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1usize as i32;
+LL +     i32::try_from(1usize);
+   |
 
 error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
   --> tests/ui/cast_size.rs:31:5
@@ -105,8 +110,9 @@ LL |     1i64 as isize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     isize::try_from(1i64);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1i64 as isize;
+LL +     isize::try_from(1i64);
+   |
 
 error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
   --> tests/ui/cast_size.rs:33:5
@@ -117,8 +123,9 @@ LL |     1i64 as usize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     usize::try_from(1i64);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1i64 as usize;
+LL +     usize::try_from(1i64);
+   |
 
 error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
   --> tests/ui/cast_size.rs:34:5
@@ -129,8 +136,9 @@ LL |     1u64 as isize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     isize::try_from(1u64);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1u64 as isize;
+LL +     isize::try_from(1u64);
+   |
 
 error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
   --> tests/ui/cast_size.rs:34:5
@@ -147,8 +155,9 @@ LL |     1u64 as usize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 help: ... or use `try_from` and handle the error accordingly
    |
-LL |     usize::try_from(1u64);
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     1u64 as usize;
+LL +     usize::try_from(1u64);
+   |
 
 error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
   --> tests/ui/cast_size.rs:36:5
diff --git a/src/tools/clippy/tests/ui/cmp_null.fixed b/src/tools/clippy/tests/ui/cmp_null.fixed
new file mode 100644
index 00000000000..e5ab765bc86
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cmp_null.fixed
@@ -0,0 +1,32 @@
+#![warn(clippy::cmp_null)]
+#![allow(unused_mut)]
+
+use std::ptr;
+
+fn main() {
+    let x = 0;
+    let p: *const usize = &x;
+    if p.is_null() {
+        //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+        //~| NOTE: `-D clippy::cmp-null` implied by `-D warnings`
+        println!("This is surprising!");
+    }
+    if p.is_null() {
+        //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+        println!("This is surprising!");
+    }
+
+    let mut y = 0;
+    let mut m: *mut usize = &mut y;
+    if m.is_null() {
+        //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+        println!("This is surprising, too!");
+    }
+    if m.is_null() {
+        //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+        println!("This is surprising, too!");
+    }
+
+    let _ = (x as *const ()).is_null();
+    //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+}
diff --git a/src/tools/clippy/tests/ui/cmp_null.rs b/src/tools/clippy/tests/ui/cmp_null.rs
index ef1d93940aa..257f7ba2662 100644
--- a/src/tools/clippy/tests/ui/cmp_null.rs
+++ b/src/tools/clippy/tests/ui/cmp_null.rs
@@ -11,10 +11,22 @@ fn main() {
         //~| NOTE: `-D clippy::cmp-null` implied by `-D warnings`
         println!("This is surprising!");
     }
+    if ptr::null() == p {
+        //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+        println!("This is surprising!");
+    }
+
     let mut y = 0;
     let mut m: *mut usize = &mut y;
     if m == ptr::null_mut() {
         //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
         println!("This is surprising, too!");
     }
+    if ptr::null_mut() == m {
+        //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
+        println!("This is surprising, too!");
+    }
+
+    let _ = x as *const () == ptr::null();
+    //~^ ERROR: comparing with null is better expressed by the `.is_null()` method
 }
diff --git a/src/tools/clippy/tests/ui/cmp_null.stderr b/src/tools/clippy/tests/ui/cmp_null.stderr
index 8362904a5ba..f3b35f3afba 100644
--- a/src/tools/clippy/tests/ui/cmp_null.stderr
+++ b/src/tools/clippy/tests/ui/cmp_null.stderr
@@ -2,16 +2,34 @@ error: comparing with null is better expressed by the `.is_null()` method
   --> tests/ui/cmp_null.rs:9:8
    |
 LL |     if p == ptr::null() {
-   |        ^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^ help: try: `p.is_null()`
    |
    = note: `-D clippy::cmp-null` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::cmp_null)]`
 
 error: comparing with null is better expressed by the `.is_null()` method
-  --> tests/ui/cmp_null.rs:16:8
+  --> tests/ui/cmp_null.rs:14:8
+   |
+LL |     if ptr::null() == p {
+   |        ^^^^^^^^^^^^^^^^ help: try: `p.is_null()`
+
+error: comparing with null is better expressed by the `.is_null()` method
+  --> tests/ui/cmp_null.rs:21:8
    |
 LL |     if m == ptr::null_mut() {
-   |        ^^^^^^^^^^^^^^^^^^^^
+   |        ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()`
+
+error: comparing with null is better expressed by the `.is_null()` method
+  --> tests/ui/cmp_null.rs:25:8
+   |
+LL |     if ptr::null_mut() == m {
+   |        ^^^^^^^^^^^^^^^^^^^^ help: try: `m.is_null()`
+
+error: comparing with null is better expressed by the `.is_null()` method
+  --> tests/ui/cmp_null.rs:30:13
+   |
+LL |     let _ = x as *const () == ptr::null();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(x as *const ()).is_null()`
 
-error: aborting due to 2 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11230.fixed b/src/tools/clippy/tests/ui/crashes/ice-11230.fixed
new file mode 100644
index 00000000000..1d4c3dd9dcc
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-11230.fixed
@@ -0,0 +1,16 @@
+// Test for https://github.com/rust-lang/rust-clippy/issues/11230
+#![warn(clippy::explicit_iter_loop)]
+#![warn(clippy::needless_collect)]
+
+// explicit_iter_loop
+fn main() {
+    const A: &[for<'a> fn(&'a ())] = &[];
+    for v in A {}
+}
+
+// needless_collect
+trait Helper<'a>: Iterator<Item = fn()> {}
+
+fn x(w: &mut dyn for<'a> Helper<'a>) {
+    w.next().is_none();
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11230.rs b/src/tools/clippy/tests/ui/crashes/ice-11230.rs
index 94044e9435e..a16fb271497 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-11230.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-11230.rs
@@ -1,6 +1,16 @@
 // Test for https://github.com/rust-lang/rust-clippy/issues/11230
+#![warn(clippy::explicit_iter_loop)]
+#![warn(clippy::needless_collect)]
 
+// explicit_iter_loop
 fn main() {
     const A: &[for<'a> fn(&'a ())] = &[];
     for v in A.iter() {}
 }
+
+// needless_collect
+trait Helper<'a>: Iterator<Item = fn()> {}
+
+fn x(w: &mut dyn for<'a> Helper<'a>) {
+    w.collect::<Vec<_>>().is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11230.stderr b/src/tools/clippy/tests/ui/crashes/ice-11230.stderr
new file mode 100644
index 00000000000..7167d90e456
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-11230.stderr
@@ -0,0 +1,20 @@
+error: it is more concise to loop over references to containers instead of using explicit iteration methods
+  --> tests/ui/crashes/ice-11230.rs:8:14
+   |
+LL |     for v in A.iter() {}
+   |              ^^^^^^^^ help: to write this more concisely, try: `A`
+   |
+   = note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::explicit_iter_loop)]`
+
+error: avoid using `collect()` when not needed
+  --> tests/ui/crashes/ice-11230.rs:15:7
+   |
+LL |     w.collect::<Vec<_>>().is_empty();
+   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
+   |
+   = note: `-D clippy::needless-collect` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_collect)]`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11422.fixed b/src/tools/clippy/tests/ui/crashes/ice-11422.fixed
index ca5721cbb2b..d996b1db08a 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-11422.fixed
+++ b/src/tools/clippy/tests/ui/crashes/ice-11422.fixed
@@ -3,7 +3,7 @@
 use std::fmt::Debug;
 use std::ops::*;
 
-fn gen() -> impl PartialOrd + Debug {}
+fn r#gen() -> impl PartialOrd + Debug {}
 
 struct Bar {}
 trait Foo<T = Self> {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11422.rs b/src/tools/clippy/tests/ui/crashes/ice-11422.rs
index 355ec2480bb..eb89b7c38f4 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-11422.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-11422.rs
@@ -3,7 +3,7 @@
 use std::fmt::Debug;
 use std::ops::*;
 
-fn gen() -> impl PartialOrd + PartialEq + Debug {}
+fn r#gen() -> impl PartialOrd + PartialEq + Debug {}
 
 struct Bar {}
 trait Foo<T = Self> {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-11422.stderr b/src/tools/clippy/tests/ui/crashes/ice-11422.stderr
index a340977f469..67944e4e6e8 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-11422.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-11422.stderr
@@ -1,15 +1,15 @@
 error: this bound is already specified as the supertrait of `PartialOrd`
-  --> tests/ui/crashes/ice-11422.rs:6:31
+  --> tests/ui/crashes/ice-11422.rs:6:33
    |
-LL | fn gen() -> impl PartialOrd + PartialEq + Debug {}
-   |                               ^^^^^^^^^
+LL | fn r#gen() -> impl PartialOrd + PartialEq + Debug {}
+   |                                 ^^^^^^^^^
    |
    = note: `-D clippy::implied-bounds-in-impls` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::implied_bounds_in_impls)]`
 help: try removing this bound
    |
-LL - fn gen() -> impl PartialOrd + PartialEq + Debug {}
-LL + fn gen() -> impl PartialOrd + Debug {}
+LL - fn r#gen() -> impl PartialOrd + PartialEq + Debug {}
+LL + fn r#gen() -> impl PartialOrd + Debug {}
    |
 
 error: aborting due to 1 previous error
diff --git a/src/tools/clippy/tests/ui/create_dir.stderr b/src/tools/clippy/tests/ui/create_dir.stderr
index ab51705bb55..9bb98a2606d 100644
--- a/src/tools/clippy/tests/ui/create_dir.stderr
+++ b/src/tools/clippy/tests/ui/create_dir.stderr
@@ -8,8 +8,9 @@ LL |     std::fs::create_dir("foo");
    = help: to override `-D warnings` add `#[allow(clippy::create_dir)]`
 help: consider calling `std::fs::create_dir_all` instead
    |
-LL |     create_dir_all("foo");
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     std::fs::create_dir("foo");
+LL +     create_dir_all("foo");
+   |
 
 error: calling `std::fs::create_dir` where there may be a better way
   --> tests/ui/create_dir.rs:11:5
@@ -19,8 +20,9 @@ LL |     std::fs::create_dir("bar").unwrap();
    |
 help: consider calling `std::fs::create_dir_all` instead
    |
-LL |     create_dir_all("bar").unwrap();
-   |     ~~~~~~~~~~~~~~~~~~~~~
+LL -     std::fs::create_dir("bar").unwrap();
+LL +     create_dir_all("bar").unwrap();
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr
index b3d74b9ff61..f218614fdd6 100644
--- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr
+++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro.stderr
@@ -8,8 +8,9 @@ LL |     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
    = help: to override `-D warnings` add `#[allow(clippy::dbg_macro)]`
 help: remove the invocation before committing it to a version control system
    |
-LL |     if let Some(n) = n.checked_sub(4) { n } else { n }
-   |                      ~~~~~~~~~~~~~~~~
+LL -     if let Some(n) = dbg!(n.checked_sub(4)) { n } else { n }
+LL +     if let Some(n) = n.checked_sub(4) { n } else { n }
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:11:8
@@ -19,8 +20,9 @@ LL |     if dbg!(n <= 1) {
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     if n <= 1 {
-   |        ~~~~~~
+LL -     if dbg!(n <= 1) {
+LL +     if n <= 1 {
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:13:9
@@ -30,7 +32,8 @@ LL |         dbg!(1)
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         1
+LL -         dbg!(1)
+LL +         1
    |
 
 error: the `dbg!` macro is intended as a debugging tool
@@ -41,7 +44,8 @@ LL |         dbg!(n * factorial(n - 1))
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         n * factorial(n - 1)
+LL -         dbg!(n * factorial(n - 1))
+LL +         n * factorial(n - 1)
    |
 
 error: the `dbg!` macro is intended as a debugging tool
@@ -52,8 +56,9 @@ LL |     dbg!(42);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     42;
-   |     ~~
+LL -     dbg!(42);
+LL +     42;
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:24:14
@@ -63,8 +68,9 @@ LL |     foo(3) + dbg!(factorial(4));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     foo(3) + factorial(4);
-   |              ~~~~~~~~~~~~
+LL -     foo(3) + dbg!(factorial(4));
+LL +     foo(3) + factorial(4);
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:26:5
@@ -74,8 +80,9 @@ LL |     dbg!(1, 2, 3, 4, 5);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     (1, 2, 3, 4, 5);
-   |     ~~~~~~~~~~~~~~~
+LL -     dbg!(1, 2, 3, 4, 5);
+LL +     (1, 2, 3, 4, 5);
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:48:5
@@ -96,8 +103,9 @@ LL |     let _ = dbg!();
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     let _ = ();
-   |             ~~
+LL -     let _ = dbg!();
+LL +     let _ = ();
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:53:9
@@ -107,8 +115,9 @@ LL |     bar(dbg!());
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     bar(());
-   |         ~~
+LL -     bar(dbg!());
+LL +     bar(());
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:55:10
@@ -118,8 +127,9 @@ LL |     foo!(dbg!());
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     foo!(());
-   |          ~~
+LL -     foo!(dbg!());
+LL +     foo!(());
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:57:16
@@ -129,8 +139,9 @@ LL |     foo2!(foo!(dbg!()));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     foo2!(foo!(()));
-   |                ~~
+LL -     foo2!(foo!(dbg!()));
+LL +     foo2!(foo!(()));
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:43:13
@@ -155,8 +166,9 @@ LL |         dbg!(2);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         2;
-   |         ~
+LL -         dbg!(2);
+LL +         2;
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:86:5
@@ -166,8 +178,9 @@ LL |     dbg!(1);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     1;
-   |     ~
+LL -     dbg!(1);
+LL +     1;
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:92:5
@@ -177,8 +190,9 @@ LL |     dbg!(1);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     1;
-   |     ~
+LL -     dbg!(1);
+LL +     1;
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:99:9
@@ -188,8 +202,9 @@ LL |         dbg!(1);
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         1;
-   |         ~
+LL -         dbg!(1);
+LL +         1;
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:106:31
@@ -199,8 +214,9 @@ LL |         println!("dbg: {:?}", dbg!(s));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         println!("dbg: {:?}", s);
-   |                               ~
+LL -         println!("dbg: {:?}", dbg!(s));
+LL +         println!("dbg: {:?}", s);
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro.rs:108:22
@@ -210,8 +226,9 @@ LL |         print!("{}", dbg!(s));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |         print!("{}", s);
-   |                      ~
+LL -         print!("{}", dbg!(s));
+LL +         print!("{}", s);
+   |
 
 error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr
index b8e91906b93..e8d5f9f2f46 100644
--- a/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/dbg_macro/dbg_macro_unfixable.stderr
@@ -19,8 +19,9 @@ LL |     dbg!(dbg!(dbg!(42)));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     dbg!(dbg!(42));
-   |     ~~~~~~~~~~~~~~
+LL -     dbg!(dbg!(dbg!(42)));
+LL +     dbg!(dbg!(42));
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:10
@@ -30,8 +31,9 @@ LL |     dbg!(dbg!(dbg!(42)));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     dbg!(dbg!(42));
-   |          ~~~~~~~~
+LL -     dbg!(dbg!(dbg!(42)));
+LL +     dbg!(dbg!(42));
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:8:15
@@ -41,8 +43,9 @@ LL |     dbg!(dbg!(dbg!(42)));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     dbg!(dbg!(42));
-   |               ~~
+LL -     dbg!(dbg!(dbg!(42)));
+LL +     dbg!(dbg!(42));
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:5
@@ -52,8 +55,9 @@ LL |     dbg!(1, 2, dbg!(3, 4));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     (1, 2, dbg!(3, 4));
-   |     ~~~~~~~~~~~~~~~~~~
+LL -     dbg!(1, 2, dbg!(3, 4));
+LL +     (1, 2, dbg!(3, 4));
+   |
 
 error: the `dbg!` macro is intended as a debugging tool
   --> tests/ui/dbg_macro/dbg_macro_unfixable.rs:10:16
@@ -63,8 +67,9 @@ LL |     dbg!(1, 2, dbg!(3, 4));
    |
 help: remove the invocation before committing it to a version control system
    |
-LL |     dbg!(1, 2, (3, 4));
-   |                ~~~~~~
+LL -     dbg!(1, 2, dbg!(3, 4));
+LL +     dbg!(1, 2, (3, 4));
+   |
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
index 27a04e4b558..54d73581485 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
@@ -8,8 +8,9 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t
    = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
 help: try
    |
-LL | /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there)
-   |         ~~~~~~~~~
+LL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
+LL + /// The `foo_bar` function does _nothing_. See also foo::bar. (note the dot there)
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:9:51
@@ -19,8 +20,9 @@ LL | /// The foo_bar function does _nothing_. See also foo::bar. (note the dot t
    |
 help: try
    |
-LL | /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot there)
-   |                                                   ~~~~~~~~~~
+LL - /// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
+LL + /// The foo_bar function does _nothing_. See also `foo::bar`. (note the dot there)
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:10:83
@@ -30,8 +32,9 @@ LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. B
    |
 help: try
    |
-LL | /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun`
-   |                                                                                   ~~~~~~~~~~~~~~~
+LL - /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not Foo::some_fun
+LL + /// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:12:13
@@ -41,8 +44,9 @@ LL | /// Here be ::a::global:path, and _::another::global::path_.  :: is not a p
    |
 help: try
    |
-LL | /// Here be `::a::global:path`, and _::another::global::path_.  :: is not a path though.
-   |             ~~~~~~~~~~~~~~~~~~
+LL - /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.
+LL + /// Here be `::a::global:path`, and _::another::global::path_.  :: is not a path though.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:12:36
@@ -52,8 +56,9 @@ LL | /// Here be ::a::global:path, and _::another::global::path_.  :: is not a p
    |
 help: try
    |
-LL | /// Here be ::a::global:path, and _`::another::global::path`_.  :: is not a path though.
-   |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// Here be ::a::global:path, and _::another::global::path_.  :: is not a path though.
+LL + /// Here be ::a::global:path, and _`::another::global::path`_.  :: is not a path though.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:13:25
@@ -63,8 +68,9 @@ LL | /// Import an item from ::awesome::global::blob:: (Intended postfix)
    |
 help: try
    |
-LL | /// Import an item from `::awesome::global::blob::` (Intended postfix)
-   |                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// Import an item from ::awesome::global::blob:: (Intended postfix)
+LL + /// Import an item from `::awesome::global::blob::` (Intended postfix)
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:14:31
@@ -74,8 +80,9 @@ LL | /// These are the options for ::Cat: (Intended trailing single colon, shoul
    |
 help: try
    |
-LL | /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted)
-   |                               ~~~~~~~
+LL - /// These are the options for ::Cat: (Intended trailing single colon, shouldn't be linted)
+LL + /// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted)
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:15:22
@@ -85,8 +92,9 @@ LL | /// That's not code ~NotInCodeBlock~.
    |
 help: try
    |
-LL | /// That's not code ~`NotInCodeBlock`~.
-   |                      ~~~~~~~~~~~~~~~~
+LL - /// That's not code ~NotInCodeBlock~.
+LL + /// That's not code ~`NotInCodeBlock`~.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:16:5
@@ -96,8 +104,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:30:5
@@ -107,8 +116,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:37:5
@@ -118,8 +128,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:51:5
@@ -129,8 +140,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:79:5
@@ -140,8 +152,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:96:5
@@ -151,8 +164,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:104:8
@@ -162,8 +176,9 @@ LL | /// ## CamelCaseThing
    |
 help: try
    |
-LL | /// ## `CamelCaseThing`
-   |        ~~~~~~~~~~~~~~~~
+LL - /// ## CamelCaseThing
+LL + /// ## `CamelCaseThing`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:107:7
@@ -173,8 +188,9 @@ LL | /// # CamelCaseThing
    |
 help: try
    |
-LL | /// # `CamelCaseThing`
-   |       ~~~~~~~~~~~~~~~~
+LL - /// # CamelCaseThing
+LL + /// # `CamelCaseThing`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:109:22
@@ -184,8 +200,9 @@ LL | /// Not a title #897 CamelCaseThing
    |
 help: try
    |
-LL | /// Not a title #897 `CamelCaseThing`
-   |                      ~~~~~~~~~~~~~~~~
+LL - /// Not a title #897 CamelCaseThing
+LL + /// Not a title #897 `CamelCaseThing`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:110:5
@@ -195,8 +212,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:117:5
@@ -206,8 +224,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:130:5
@@ -217,8 +236,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:141:43
@@ -228,8 +248,9 @@ LL | /** E.g., serialization of an empty list: FooBar
    |
 help: try
    |
-LL | /** E.g., serialization of an empty list: `FooBar`
-   |                                           ~~~~~~~~
+LL - /** E.g., serialization of an empty list: FooBar
+LL + /** E.g., serialization of an empty list: `FooBar`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:146:5
@@ -239,8 +260,9 @@ LL | And BarQuz too.
    |
 help: try
    |
-LL | And `BarQuz` too.
-   |     ~~~~~~~~
+LL - And BarQuz too.
+LL + And `BarQuz` too.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:147:1
@@ -250,7 +272,8 @@ LL | be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | `be_sure_we_got_to_the_end_of_it`
+LL - be_sure_we_got_to_the_end_of_it
+LL + `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
@@ -261,8 +284,9 @@ LL | /** E.g., serialization of an empty list: FooBar
    |
 help: try
    |
-LL | /** E.g., serialization of an empty list: `FooBar`
-   |                                           ~~~~~~~~
+LL - /** E.g., serialization of an empty list: FooBar
+LL + /** E.g., serialization of an empty list: `FooBar`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:157:5
@@ -272,8 +296,9 @@ LL | And BarQuz too.
    |
 help: try
    |
-LL | And `BarQuz` too.
-   |     ~~~~~~~~
+LL - And BarQuz too.
+LL + And `BarQuz` too.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:158:1
@@ -283,7 +308,8 @@ LL | be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | `be_sure_we_got_to_the_end_of_it`
+LL - be_sure_we_got_to_the_end_of_it
+LL + `be_sure_we_got_to_the_end_of_it`
    |
 
 error: item in documentation is missing backticks
@@ -294,8 +320,9 @@ LL | /// be_sure_we_got_to_the_end_of_it
    |
 help: try
    |
-LL | /// `be_sure_we_got_to_the_end_of_it`
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL - /// be_sure_we_got_to_the_end_of_it
+LL + /// `be_sure_we_got_to_the_end_of_it`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:188:22
@@ -305,8 +332,9 @@ LL | /// An iterator over mycrate::Collection's values.
    |
 help: try
    |
-LL | /// An iterator over `mycrate::Collection`'s values.
-   |                      ~~~~~~~~~~~~~~~~~~~~~
+LL - /// An iterator over mycrate::Collection's values.
+LL + /// An iterator over `mycrate::Collection`'s values.
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:212:34
@@ -316,8 +344,9 @@ LL | /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint
    |
 help: try
    |
-LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
-   |                                  ~~~~~~~~~~~~~~~~~
+LL - /// Foo \[bar\] \[baz\] \[qux\]. DocMarkdownLint
+LL + /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:235:22
@@ -327,8 +356,9 @@ LL | /// There is no try (do() or do_not()).
    |
 help: try
    |
-LL | /// There is no try (`do()` or do_not()).
-   |                      ~~~~~~
+LL - /// There is no try (do() or do_not()).
+LL + /// There is no try (`do()` or do_not()).
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:235:30
@@ -338,8 +368,9 @@ LL | /// There is no try (do() or do_not()).
    |
 help: try
    |
-LL | /// There is no try (do() or `do_not()`).
-   |                              ~~~~~~~~~~
+LL - /// There is no try (do() or do_not()).
+LL + /// There is no try (do() or `do_not()`).
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:238:5
@@ -349,8 +380,9 @@ LL | /// ABes
    |
 help: try
    |
-LL | /// `ABes`
-   |     ~~~~~~
+LL - /// ABes
+LL + /// `ABes`
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/doc-fixable.rs:244:9
@@ -360,8 +392,9 @@ LL |     /// foo()
    |
 help: try
    |
-LL |     /// `foo()`
-   |         ~~~~~~~
+LL -     /// foo()
+LL +     /// `foo()`
+   |
 
 error: you should put bare URLs between `<`/`>` or make a proper Markdown link
   --> tests/ui/doc/doc-fixable.rs:248:5
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 0822cc7c635..8e2ed1bbd18 100644
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc_lazy_list.fixed
@@ -1,4 +1,5 @@
 #![warn(clippy::doc_lazy_continuation)]
+#![allow(clippy::doc_overindented_list_items)]
 
 /// 1. nest here
 ///    lazy continuation
diff --git a/src/tools/clippy/tests/ui/doc/doc_lazy_list.rs b/src/tools/clippy/tests/ui/doc/doc_lazy_list.rs
index 068de140e00..1da11d8fae2 100644
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_list.rs
+++ b/src/tools/clippy/tests/ui/doc/doc_lazy_list.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::doc_lazy_continuation)]
+#![allow(clippy::doc_overindented_list_items)]
 
 /// 1. nest here
 /// lazy continuation
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 b38f43b7555..cea6157119f 100644
--- a/src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc_lazy_list.stderr
@@ -1,5 +1,5 @@
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:4:5
+  --> tests/ui/doc/doc_lazy_list.rs:5:5
    |
 LL | /// lazy continuation
    |     ^
@@ -13,7 +13,7 @@ LL | ///    lazy continuation
    |     +++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:9:5
+  --> tests/ui/doc/doc_lazy_list.rs:10:5
    |
 LL | /// lazy list continuations don't make warnings with this lint
    |     ^
@@ -25,7 +25,7 @@ LL | ///    lazy list continuations don't make warnings with this lint
    |     +++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:11:5
+  --> tests/ui/doc/doc_lazy_list.rs:12:5
    |
 LL | /// because they don't have the
    |     ^
@@ -37,7 +37,7 @@ LL | ///    because they don't have the
    |     +++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:16:5
+  --> tests/ui/doc/doc_lazy_list.rs:17:5
    |
 LL | /// lazy continuation
    |     ^
@@ -49,7 +49,7 @@ LL | ///     lazy continuation
    |     ++++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:21:5
+  --> tests/ui/doc/doc_lazy_list.rs:22:5
    |
 LL | /// lazy list continuations don't make warnings with this lint
    |     ^
@@ -61,7 +61,7 @@ LL | ///     lazy list continuations don't make warnings with this lint
    |     ++++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:23:5
+  --> tests/ui/doc/doc_lazy_list.rs:24:5
    |
 LL | /// because they don't have the
    |     ^
@@ -73,7 +73,7 @@ LL | ///     because they don't have the
    |     ++++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:28:5
+  --> tests/ui/doc/doc_lazy_list.rs:29:5
    |
 LL | /// lazy continuation
    |     ^
@@ -85,7 +85,7 @@ LL | ///     lazy continuation
    |     ++++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:33:5
+  --> tests/ui/doc/doc_lazy_list.rs:34:5
    |
 LL | /// this will warn on the lazy continuation
    |     ^
@@ -97,7 +97,7 @@ LL | ///       this will warn on the lazy continuation
    |     ++++++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:35:5
+  --> tests/ui/doc/doc_lazy_list.rs:36:5
    |
 LL | ///     and so should this
    |     ^^^^
@@ -109,7 +109,7 @@ LL | ///       and so should this
    |         ++
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:56:5
+  --> tests/ui/doc/doc_lazy_list.rs:57:5
    |
 LL | ///  'protocol_descriptors': [
    |     ^
@@ -121,7 +121,7 @@ LL | ///   'protocol_descriptors': [
    |      +
 
 error: doc list item without indentation
-  --> tests/ui/doc/doc_lazy_list.rs:75:5
+  --> tests/ui/doc/doc_lazy_list.rs:76:5
    |
 LL | ///  ]
    |     ^
diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr
index ae68a767ec9..65b8f2ed80b 100644
--- a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr
@@ -11,8 +11,9 @@ LL | #![deny(clippy::doc_markdown)]
    |         ^^^^^^^^^^^^^^^^^^^^
 help: try
    |
-LL |     /// `HumaNified`
-   |         ~~~~~~~~~~~~
+LL -     /// HumaNified
+LL +     /// `HumaNified`
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.fixed b/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.fixed
new file mode 100644
index 00000000000..940cff48c1e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.fixed
@@ -0,0 +1,28 @@
+#![warn(clippy::doc_overindented_list_items)]
+
+#[rustfmt::skip]
+/// - first list item
+///   overindented line
+//~^ ERROR: doc list item overindented
+///   this is overindented line too
+//~^ ERROR: doc list item overindented
+/// - second list item
+fn foo() {}
+
+#[rustfmt::skip]
+///   - first list item
+///     overindented line
+//~^ ERROR: doc list item overindented
+///     this is overindented line too
+//~^ ERROR: doc list item overindented
+///   - second list item
+fn bar() {}
+
+#[rustfmt::skip]
+/// * first list item
+///   overindented line
+//~^ ERROR: doc list item overindented
+///   this is overindented line too
+//~^ ERROR: doc list item overindented
+/// * second list item
+fn baz() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.rs b/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.rs
new file mode 100644
index 00000000000..77f3ee8a64d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.rs
@@ -0,0 +1,28 @@
+#![warn(clippy::doc_overindented_list_items)]
+
+#[rustfmt::skip]
+/// - first list item
+///        overindented line
+//~^ ERROR: doc list item overindented
+///      this is overindented line too
+//~^ ERROR: doc list item overindented
+/// - second list item
+fn foo() {}
+
+#[rustfmt::skip]
+///   - first list item
+///        overindented line
+//~^ ERROR: doc list item overindented
+///      this is overindented line too
+//~^ ERROR: doc list item overindented
+///   - second list item
+fn bar() {}
+
+#[rustfmt::skip]
+/// * first list item
+///        overindented line
+//~^ ERROR: doc list item overindented
+///      this is overindented line too
+//~^ ERROR: doc list item overindented
+/// * second list item
+fn baz() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.stderr b/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.stderr
new file mode 100644
index 00000000000..ff201ba5eb9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_overindented_list_items.stderr
@@ -0,0 +1,41 @@
+error: doc list item overindented
+  --> tests/ui/doc/doc_overindented_list_items.rs:5:5
+   |
+LL | ///        overindented line
+   |     ^^^^^^^ help: try using `  ` (2 spaces)
+   |
+   = note: `-D clippy::doc-overindented-list-items` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_overindented_list_items)]`
+
+error: doc list item overindented
+  --> tests/ui/doc/doc_overindented_list_items.rs:7:5
+   |
+LL | ///      this is overindented line too
+   |     ^^^^^ help: try using `  ` (2 spaces)
+
+error: doc list item overindented
+  --> tests/ui/doc/doc_overindented_list_items.rs:14:7
+   |
+LL | ///        overindented line
+   |       ^^^^^ help: try using `  ` (2 spaces)
+
+error: doc list item overindented
+  --> tests/ui/doc/doc_overindented_list_items.rs:16:7
+   |
+LL | ///      this is overindented line too
+   |       ^^^ help: try using `  ` (2 spaces)
+
+error: doc list item overindented
+  --> tests/ui/doc/doc_overindented_list_items.rs:23:5
+   |
+LL | ///        overindented line
+   |     ^^^^^^^ help: try using `  ` (2 spaces)
+
+error: doc list item overindented
+  --> tests/ui/doc/doc_overindented_list_items.rs:25:5
+   |
+LL | ///      this is overindented line too
+   |     ^^^^^ help: try using `  ` (2 spaces)
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/doc/issue_10262.stderr b/src/tools/clippy/tests/ui/doc/issue_10262.stderr
index f43d9551e94..f9ecb3de219 100644
--- a/src/tools/clippy/tests/ui/doc/issue_10262.stderr
+++ b/src/tools/clippy/tests/ui/doc/issue_10262.stderr
@@ -8,8 +8,9 @@ LL | /// AviSynth documentation:
    = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
 help: try
    |
-LL | /// `AviSynth` documentation:
-   |     ~~~~~~~~~~
+LL - /// AviSynth documentation:
+LL + /// `AviSynth` documentation:
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/doc/issue_12795.stderr b/src/tools/clippy/tests/ui/doc/issue_12795.stderr
index 5700145ec8f..047de915ed4 100644
--- a/src/tools/clippy/tests/ui/doc/issue_12795.stderr
+++ b/src/tools/clippy/tests/ui/doc/issue_12795.stderr
@@ -8,8 +8,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b(
    = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
 help: try
    |
-LL | //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
-   |                    ~~~~~~~~
+LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
+LL + //! A comment with `a_b(x)` and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/issue_12795.rs:3:31
@@ -19,8 +20,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b(
    |
 help: try
    |
-LL | //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c)))
-   |                               ~~~~~
+LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
+LL + //! A comment with a_b(x) and `a_c` in it and (a_b((c)) ) too and (maybe a_b((c)))
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/issue_12795.rs:3:46
@@ -30,8 +32,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b(
    |
 help: try
    |
-LL | //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c)))
-   |                                              ~~~~~~~~~~
+LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
+LL + //! A comment with a_b(x) and a_c in it and (`a_b((c))` ) too and (maybe a_b((c)))
+   |
 
 error: item in documentation is missing backticks
   --> tests/ui/doc/issue_12795.rs:3:72
@@ -41,8 +44,9 @@ LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b(
    |
 help: try
    |
-LL | //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`)
-   |                                                                        ~~~~~~~~~~
+LL - //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe a_b((c)))
+LL + //! A comment with a_b(x) and a_c in it and (a_b((c)) ) too and (maybe `a_b((c))`)
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.stderr b/src/tools/clippy/tests/ui/doc/issue_9473.stderr
index 35aa2884cc1..744c8dc8c83 100644
--- a/src/tools/clippy/tests/ui/doc/issue_9473.stderr
+++ b/src/tools/clippy/tests/ui/doc/issue_9473.stderr
@@ -8,8 +8,9 @@ LL | /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].
    = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
 help: try
    |
-LL | /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].
-   |                                                          ~~~~~~~~
+LL - /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].
+LL + /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
index 04446787b6c..a065654e319 100644
--- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.rs
@@ -66,3 +66,19 @@ fn escape_3() {}
 
 /// Backslashes ` \` within code blocks don't count.
 fn escape_4() {}
+
+trait Foo {
+    fn bar();
+}
+
+struct Bar;
+impl Foo for Bar {
+    // NOTE: false positive
+    /// Returns an `Option<Month>` from a i64, assuming a 1-index, January = 1.
+    ///
+    /// `Month::from_i64(n: i64)`: | `1`                  | `2`                   | ... | `12`
+    /// ---------------------------| -------------------- | --------------------- | ... | -----
+    /// ``:                        | Some(Month::January) | Some(Month::February) | ... |
+    /// Some(Month::December)
+    fn bar() {}
+}
diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
index 50324010e97..4114a823822 100644
--- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
+++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr
@@ -29,8 +29,9 @@ LL | /// This paragraph is fine and should_be linted normally.
    |
 help: try
    |
-LL | /// This paragraph is fine and `should_be` linted normally.
-   |                                ~~~~~~~~~~~
+LL - /// This paragraph is fine and should_be linted normally.
+LL + /// This paragraph is fine and `should_be` linted normally.
+   |
 
 error: backticks are unbalanced
   --> tests/ui/doc/unbalanced_ticks.rs:20:5
@@ -48,8 +49,9 @@ LL | /// ## not_fine
    |
 help: try
    |
-LL | /// ## `not_fine`
-   |        ~~~~~~~~~~
+LL - /// ## not_fine
+LL + /// ## `not_fine`
+   |
 
 error: backticks are unbalanced
   --> tests/ui/doc/unbalanced_ticks.rs:37:5
@@ -75,8 +77,9 @@ LL | /// - This item needs backticks_here
    |
 help: try
    |
-LL | /// - This item needs `backticks_here`
-   |                       ~~~~~~~~~~~~~~~~
+LL - /// - This item needs backticks_here
+LL + /// - This item needs `backticks_here`
+   |
 
 error: backticks are unbalanced
   --> tests/ui/doc/unbalanced_ticks.rs:53:5
@@ -94,5 +97,17 @@ LL | /// Escaped \` ` backticks don't count, but unescaped backticks do.
    |
    = help: a backtick may be missing a pair
 
-error: aborting due to 10 previous errors
+error: backticks are unbalanced
+  --> tests/ui/doc/unbalanced_ticks.rs:79:9
+   |
+LL |       /// `Month::from_i64(n: i64)`: | `1`                  | `2`                   | ... | `12`
+   |  _________^
+LL | |     /// ---------------------------| -------------------- | --------------------- | ... | -----
+LL | |     /// ``:                        | Some(Month::January) | Some(Month::February) | ... |
+LL | |     /// Some(Month::December)
+   | |_____________________________^
+   |
+   = help: a backtick may be missing a pair
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/double_neg.rs b/src/tools/clippy/tests/ui/double_neg.rs
deleted file mode 100644
index 3be8c628873..00000000000
--- a/src/tools/clippy/tests/ui/double_neg.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#[warn(clippy::double_neg)]
-#[allow(clippy::no_effect)]
-fn main() {
-    let x = 1;
-    -x;
-    -(-x);
-    --x;
-    //~^ ERROR: `--x` could be misinterpreted as pre-decrement by C programmers, is usually
-    //~| NOTE: `-D clippy::double-neg` implied by `-D warnings`
-}
diff --git a/src/tools/clippy/tests/ui/double_neg.stderr b/src/tools/clippy/tests/ui/double_neg.stderr
deleted file mode 100644
index 9a902d1323c..00000000000
--- a/src/tools/clippy/tests/ui/double_neg.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error: `--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op
-  --> tests/ui/double_neg.rs:7:5
-   |
-LL |     --x;
-   |     ^^^
-   |
-   = note: `-D clippy::double-neg` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::double_neg)]`
-
-error: aborting due to 1 previous error
-
diff --git a/src/tools/clippy/tests/ui/drain_collect_nostd.fixed b/src/tools/clippy/tests/ui/drain_collect_nostd.fixed
new file mode 100644
index 00000000000..a4ab2956f2a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/drain_collect_nostd.fixed
@@ -0,0 +1,8 @@
+#![warn(clippy::drain_collect)]
+#![no_std]
+extern crate alloc;
+use alloc::vec::Vec;
+
+fn remove_all(v: &mut Vec<i32>) -> Vec<i32> {
+    core::mem::take(v)
+}
diff --git a/src/tools/clippy/tests/ui/drain_collect_nostd.rs b/src/tools/clippy/tests/ui/drain_collect_nostd.rs
new file mode 100644
index 00000000000..a8be1ce6bbd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/drain_collect_nostd.rs
@@ -0,0 +1,8 @@
+#![warn(clippy::drain_collect)]
+#![no_std]
+extern crate alloc;
+use alloc::vec::Vec;
+
+fn remove_all(v: &mut Vec<i32>) -> Vec<i32> {
+    v.drain(..).collect()
+}
diff --git a/src/tools/clippy/tests/ui/drain_collect_nostd.stderr b/src/tools/clippy/tests/ui/drain_collect_nostd.stderr
new file mode 100644
index 00000000000..91b38932fee
--- /dev/null
+++ b/src/tools/clippy/tests/ui/drain_collect_nostd.stderr
@@ -0,0 +1,11 @@
+error: you seem to be trying to move all elements into a new `Vec`
+  --> tests/ui/drain_collect_nostd.rs:7:5
+   |
+LL |     v.drain(..).collect()
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using `mem::take`: `core::mem::take(v)`
+   |
+   = note: `-D clippy::drain-collect` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::drain_collect)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/eager_transmute.stderr b/src/tools/clippy/tests/ui/eager_transmute.stderr
index 5cf7bd49a92..68690c3730d 100644
--- a/src/tools/clippy/tests/ui/eager_transmute.stderr
+++ b/src/tools/clippy/tests/ui/eager_transmute.stderr
@@ -8,8 +8,9 @@ LL |     (op < 4).then_some(unsafe { std::mem::transmute(op) })
    = help: to override `-D warnings` add `#[allow(clippy::eager_transmute)]`
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     (op < 4).then(|| unsafe { std::mem::transmute(op) })
-   |              ~~~~ ++
+LL -     (op < 4).then_some(unsafe { std::mem::transmute(op) })
+LL +     (op < 4).then(|| unsafe { std::mem::transmute(op) })
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:27:33
@@ -19,8 +20,9 @@ LL |     (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });
-   |              ~~~~ ++
+LL -     (op < 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });
+LL +     (op < 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:28:33
@@ -30,8 +32,9 @@ LL |     (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });
-   |              ~~~~ ++
+LL -     (op > 4).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });
+LL +     (op > 4).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:29:34
@@ -41,8 +44,9 @@ LL |     (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });
-   |               ~~~~ ++
+LL -     (op == 0).then_some(unsafe { std::mem::transmute::<_, Opcode>(op) });
+LL +     (op == 0).then(|| unsafe { std::mem::transmute::<_, Opcode>(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:31:68
@@ -52,8 +56,9 @@ LL |     let _: Option<Opcode> = (op > 0 && op < 10).then_some(unsafe { std::mem
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) });
-   |                                                 ~~~~ ++
+LL -     let _: Option<Opcode> = (op > 0 && op < 10).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = (op > 0 && op < 10).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:32:86
@@ -63,8 +68,9 @@ LL |     let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then_some
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) });
-   |                                                                   ~~~~ ++
+LL -     let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = (op > 0 && op < 10 && unrelated == 0).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:35:84
@@ -74,8 +80,9 @@ LL |     let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(u
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) });
-   |                                                                 ~~~~ ++
+LL -     let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then_some(unsafe { std::mem::transmute(op2.foo[0]) });
+LL +     let _: Option<Opcode> = (op2.foo[0] > 0 && op2.foo[0] < 10).then(|| unsafe { std::mem::transmute(op2.foo[0]) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:47:70
@@ -85,8 +92,9 @@ LL |     let _: Option<Opcode> = (1..=3).contains(&op).then_some(unsafe { std::m
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
-   |                                                   ~~~~ ++
+LL -     let _: Option<Opcode> = (1..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = (1..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:48:83
@@ -96,8 +104,9 @@ LL |     let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then_some(un
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) });
-   |                                                                ~~~~ ++
+LL -     let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = ((1..=3).contains(&op) || op == 4).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:49:69
@@ -107,8 +116,9 @@ LL |     let _: Option<Opcode> = (1..3).contains(&op).then_some(unsafe { std::me
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
-   |                                                  ~~~~ ++
+LL -     let _: Option<Opcode> = (1..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = (1..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:50:68
@@ -118,8 +128,9 @@ LL |     let _: Option<Opcode> = (1..).contains(&op).then_some(unsafe { std::mem
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) });
-   |                                                 ~~~~ ++
+LL -     let _: Option<Opcode> = (1..).contains(&op).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = (1..).contains(&op).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:51:68
@@ -129,8 +140,9 @@ LL |     let _: Option<Opcode> = (..3).contains(&op).then_some(unsafe { std::mem
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
-   |                                                 ~~~~ ++
+LL -     let _: Option<Opcode> = (..3).contains(&op).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = (..3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:52:69
@@ -140,8 +152,9 @@ LL |     let _: Option<Opcode> = (..=3).contains(&op).then_some(unsafe { std::me
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<Opcode> = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
-   |                                                  ~~~~ ++
+LL -     let _: Option<Opcode> = (..=3).contains(&op).then_some(unsafe { std::mem::transmute(op) });
+LL +     let _: Option<Opcode> = (..=3).contains(&op).then(|| unsafe { std::mem::transmute(op) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:61:24
@@ -151,8 +164,9 @@ LL |     (op < 4).then_some(std::mem::transmute::<_, Opcode>(op));
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     (op < 4).then(|| std::mem::transmute::<_, Opcode>(op));
-   |              ~~~~ ++
+LL -     (op < 4).then_some(std::mem::transmute::<_, Opcode>(op));
+LL +     (op < 4).then(|| std::mem::transmute::<_, Opcode>(op));
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:90:62
@@ -162,8 +176,9 @@ LL |     let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::tran
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });
-   |                                           ~~~~ ++
+LL -     let _: Option<NonZero<u8>> = (v1 > 0).then_some(unsafe { std::mem::transmute(v1) });
+LL +     let _: Option<NonZero<u8>> = (v1 > 0).then(|| unsafe { std::mem::transmute(v1) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:96:86
@@ -173,8 +188,9 @@ LL |     let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
-   |                                                                   ~~~~ ++
+LL -     let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
+LL +     let _: Option<NonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
+   |
 
 error: this transmute is always evaluated eagerly, even if the condition is false
   --> tests/ui/eager_transmute.rs:102:93
@@ -184,8 +200,9 @@ LL |     let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).th
    |
 help: consider using `bool::then` to only transmute if the condition holds
    |
-LL |     let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
-   |                                                                          ~~~~ ++
+LL -     let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then_some(unsafe { std::mem::transmute(v2) });
+LL +     let _: Option<NonZeroNonMaxU8> = (v2 < NonZero::new(255u8).unwrap()).then(|| unsafe { std::mem::transmute(v2) });
+   |
 
 error: aborting due to 17 previous errors
 
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
index fd6a94b6a80..3772b465fdb 100644
--- 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
@@ -132,4 +132,13 @@ pub struct BlockComment;
 ))]
 fn empty_line_in_cfg_attr() {}
 
+trait Foo {
+    fn bar();
+}
+
+impl Foo for LineComment {
+    /// comment on assoc item
+    fn bar() {}
+}
+
 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
index 7a57dcd9233..3028d03b669 100644
--- 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
@@ -141,4 +141,13 @@ pub struct BlockComment;
 ))]
 fn empty_line_in_cfg_attr() {}
 
+trait Foo {
+    fn bar();
+}
+
+impl Foo for LineComment {
+    /// comment on assoc item
+    fn bar() {}
+}
+
 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
index 1da761a5c3d..ae4ebc271fa 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.rs
@@ -144,4 +144,14 @@ pub struct BlockComment;
 ))]
 fn empty_line_in_cfg_attr() {}
 
+trait Foo {
+    fn bar();
+}
+
+impl Foo for LineComment {
+    /// comment on assoc item
+
+    fn bar() {}
+}
+
 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
index c5d5f3d3759..ca05a1b03eb 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr
@@ -5,11 +5,11 @@ LL | / /// for the crate
 LL | |
    | |_^
 LL |   fn first_in_crate() {}
-   |   ------------------- the comment documents this function
+   |   ----------------- 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 empty line is unintentional, remove it
 help: if the comment should document the crate use an inner doc comment
    |
 LL ~ //! Meant to be an
@@ -24,9 +24,9 @@ LL | /     /// for the module
 LL | |
    | |_^
 LL |       fn first_in_module() {}
-   |       -------------------- the comment documents this function
+   |       ------------------ the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -42,9 +42,9 @@ LL | |
    | |_^
 LL |       /// Blank line
 LL |       fn indented() {}
-   |       ------------- the comment documents this function
+   |       ----------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the documentation should include the empty line include it in the comment
    |
 LL |     ///
@@ -57,9 +57,9 @@ LL | / /// This should produce a warning
 LL | |
    | |_^
 LL |   fn with_doc_and_newline() {}
-   |   ------------------------- the comment documents this function
+   |   ----------------------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -72,9 +72,9 @@ LL | |
    | |_^
 ...
 LL |   fn three_attributes() {}
-   |   --------------------- the comment documents this function
+   |   ------------------- the comment documents this function
    |
-   = help: if the empty lines are unintentional remove them
+   = 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
@@ -84,9 +84,9 @@ LL | |     // fn old_code() {}
 LL | |
    | |_^
 LL |       fn new_code() {}
-   |       ------------- the comment documents this function
+   |       ----------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = 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`
@@ -106,7 +106,7 @@ LL | |
 LL |       struct Multiple;
    |       --------------- the comment documents this struct
    |
-   = help: if the empty lines are unintentional remove them
+   = help: if the empty lines are unintentional, remove them
 help: if the doc comment should not document `Multiple` comment it out
    |
 LL ~     // /// Docs
@@ -126,13 +126,14 @@ LL | |      */
 LL | |
    | |_^
 LL |       fn first_in_module() {}
-   |       -------------------- the comment documents this function
+   |       ------------------ the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the comment should document the parent module use an inner doc comment
    |
-LL |     /*!
-   |       ~
+LL -     /**
+LL +     /*!
+   |
 
 error: empty line after doc comment
   --> tests/ui/empty_line_after/doc_comments.rs:85:5
@@ -145,9 +146,9 @@ LL | |
    | |_^
 ...
 LL |       fn new_code() {}
-   |       ------------- the comment documents this function
+   |       ----------- the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = help: if the empty line is unintentional, remove it
 help: if the doc comment should not document `new_code` comment it out
    |
 LL -     /**
@@ -163,13 +164,24 @@ LL | |
    | |_^
 LL |       /// Docs for `new_code2`
 LL |       fn new_code2() {}
-   |       -------------- the comment documents this function
+   |       ------------ the comment documents this function
    |
-   = help: if the empty line is unintentional remove it
+   = 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
+error: empty line after doc comment
+  --> tests/ui/empty_line_after/doc_comments.rs:152:5
+   |
+LL | /     /// comment on assoc item
+LL | |
+   | |_^
+LL |       fn bar() {}
+   |       ------ the comment documents this function
+   |
+   = help: if the empty line is unintentional, remove it
+
+error: aborting due to 11 previous errors
 
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
index a95306e2fa3..519ba6e6761 100644
--- a/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
+++ b/src/tools/clippy/tests/ui/empty_line_after/outer_attribute.stderr
@@ -5,11 +5,11 @@ LL | / #[crate_type = "lib"]
 LL | |
    | |_^
 LL |   fn first_in_crate() {}
-   |   ------------------- the attribute applies to this function
+   |   ----------------- 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 empty line is unintentional, remove it
 help: if the attribute should apply to the crate use an inner attribute
    |
 LL | #![crate_type = "lib"]
@@ -23,9 +23,9 @@ LL | |
    | |_^
 LL |   /// some comment
 LL |   fn with_one_newline_and_comment() {}
-   |   --------------------------------- the attribute applies to this function
+   |   ------------------------------- the attribute applies to this function
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -34,9 +34,9 @@ LL | / #[inline]
 LL | |
    | |_^
 LL |   fn with_one_newline() {}
-   |   --------------------- the attribute applies to this function
+   |   ------------------- the attribute applies to this function
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -46,9 +46,9 @@ LL | |
 LL | |
    | |_^
 LL |       fn with_two_newlines() {}
-   |       ---------------------- the attribute applies to this function
+   |       -------------------- the attribute applies to this function
    |
-   = help: if the empty lines are unintentional remove them
+   = 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"]
@@ -63,7 +63,7 @@ LL | |
 LL |   enum Baz {
    |   -------- the attribute applies to this enum
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -74,7 +74,7 @@ LL | |
 LL |   struct Foo {
    |   ---------- the attribute applies to this struct
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -85,7 +85,7 @@ LL | |
 LL |   mod foo {}
    |   ------- the attribute applies to this module
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -95,9 +95,9 @@ LL | | // Still lint cases where the empty line does not immediately follow the
 LL | |
    | |_^
 LL |   fn comment_before_empty_line() {}
-   |   ------------------------------ the attribute applies to this function
+   |   ---------------------------- the attribute applies to this function
    |
-   = help: if the empty line is unintentional remove it
+   = 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
@@ -107,9 +107,9 @@ LL | / #[allow(unused)]
 LL | |
    | |_^
 LL |   pub fn isolated_comment() {}
-   |   ------------------------- the attribute applies to this function
+   |   ----------------------- the attribute applies to this function
    |
-   = help: if the empty lines are unintentional remove them
+   = help: if the empty lines are unintentional, remove them
 
 error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index f1baf28200e..abccc30ef87 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -116,6 +116,11 @@ fn test_redundant_closures_containing_method_calls() {
         t.iter().filter(|x| x.trait_foo_ref());
         t.iter().map(|x| x.trait_foo_ref());
     }
+
+    fn issue14096() {
+        let x = Some("42");
+        let _ = x.map(str::parse::<i16>);
+    }
 }
 
 struct Thunk<T>(Box<dyn FnMut() -> T>);
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index c52a51880bf..9bcee4eba34 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -116,6 +116,11 @@ fn test_redundant_closures_containing_method_calls() {
         t.iter().filter(|x| x.trait_foo_ref());
         t.iter().map(|x| x.trait_foo_ref());
     }
+
+    fn issue14096() {
+        let x = Some("42");
+        let _ = x.map(|x| x.parse::<i16>());
+    }
 }
 
 struct Thunk<T>(Box<dyn FnMut() -> T>);
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index 1731a4377f5..ac58e87bc5e 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -71,142 +71,148 @@ LL |     let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_as
    |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
 
 error: redundant closure
-  --> tests/ui/eta.rs:169:22
+  --> tests/ui/eta.rs:122:23
+   |
+LL |         let _ = x.map(|x| x.parse::<i16>());
+   |                       ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `str::parse::<i16>`
+
+error: redundant closure
+  --> tests/ui/eta.rs:174:22
    |
 LL |     requires_fn_once(|| x());
    |                      ^^^^^^ help: replace the closure with the function itself: `x`
 
 error: redundant closure
-  --> tests/ui/eta.rs:176:27
+  --> tests/ui/eta.rs:181: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:181:27
+  --> tests/ui/eta.rs:186: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:213:28
+  --> tests/ui/eta.rs:218: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:214:28
+  --> tests/ui/eta.rs:219: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:215:28
+  --> tests/ui/eta.rs:220: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:222:21
+  --> tests/ui/eta.rs:227: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:226:21
+  --> tests/ui/eta.rs:231: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:319:18
+  --> tests/ui/eta.rs:324:18
    |
 LL |     takes_fn_mut(|| f());
    |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:322:19
+  --> tests/ui/eta.rs:327:19
    |
 LL |     takes_fn_once(|| f());
    |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:326:26
+  --> tests/ui/eta.rs:331: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:338:19
+  --> tests/ui/eta.rs:343: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:341:19
+  --> tests/ui/eta.rs:346: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:344:17
+  --> tests/ui/eta.rs:349: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:348:17
+  --> tests/ui/eta.rs:353: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:408:19
+  --> tests/ui/eta.rs:413: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:436:22
+  --> tests/ui/eta.rs:441:22
    |
 LL |             test.map(|t| t.method())
    |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:440:22
+  --> tests/ui/eta.rs:445: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:453:18
+  --> tests/ui/eta.rs:458: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:460:30
+  --> tests/ui/eta.rs:465: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:479:38
+  --> tests/ui/eta.rs:484: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:483:38
+  --> tests/ui/eta.rs:488: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:500:35
+  --> tests/ui/eta.rs:505:35
    |
 LL |         let _field = bind.or_else(|| get_default()).unwrap();
    |                                   ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default`
 
-error: aborting due to 34 previous errors
+error: aborting due to 35 previous errors
 
diff --git a/src/tools/clippy/tests/ui/eta_nostd.fixed b/src/tools/clippy/tests/ui/eta_nostd.fixed
new file mode 100644
index 00000000000..23059c52b67
--- /dev/null
+++ b/src/tools/clippy/tests/ui/eta_nostd.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::redundant_closure)]
+#![no_std]
+
+extern crate alloc;
+use alloc::vec;
+use alloc::vec::Vec;
+
+fn issue_13895() {
+    let _: Option<Vec<u8>> = true.then(alloc::vec::Vec::new);
+}
diff --git a/src/tools/clippy/tests/ui/eta_nostd.rs b/src/tools/clippy/tests/ui/eta_nostd.rs
new file mode 100644
index 00000000000..ae44ac348c6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/eta_nostd.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::redundant_closure)]
+#![no_std]
+
+extern crate alloc;
+use alloc::vec;
+use alloc::vec::Vec;
+
+fn issue_13895() {
+    let _: Option<Vec<u8>> = true.then(|| vec![]);
+}
diff --git a/src/tools/clippy/tests/ui/eta_nostd.stderr b/src/tools/clippy/tests/ui/eta_nostd.stderr
new file mode 100644
index 00000000000..4dfef43efa4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/eta_nostd.stderr
@@ -0,0 +1,11 @@
+error: redundant closure
+  --> tests/ui/eta_nostd.rs:9:40
+   |
+LL |     let _: Option<Vec<u8>> = true.then(|| vec![]);
+   |                                        ^^^^^^^^^ help: replace the closure with `Vec::new`: `alloc::vec::Vec::new`
+   |
+   = note: `-D clippy::redundant-closure` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/excessive_precision.stderr b/src/tools/clippy/tests/ui/excessive_precision.stderr
index 81e4fb6765d..b1f12eed420 100644
--- a/src/tools/clippy/tests/ui/excessive_precision.stderr
+++ b/src/tools/clippy/tests/ui/excessive_precision.stderr
@@ -8,8 +8,9 @@ LL |     const BAD32_1: f32 = 0.123_456_789_f32;
    = help: to override `-D warnings` add `#[allow(clippy::excessive_precision)]`
 help: consider changing the type or truncating it to
    |
-LL |     const BAD32_1: f32 = 0.123_456_79_f32;
-   |                          ~~~~~~~~~~~~~~~~
+LL -     const BAD32_1: f32 = 0.123_456_789_f32;
+LL +     const BAD32_1: f32 = 0.123_456_79_f32;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:21:26
@@ -19,8 +20,9 @@ LL |     const BAD32_2: f32 = 0.123_456_789;
    |
 help: consider changing the type or truncating it to
    |
-LL |     const BAD32_2: f32 = 0.123_456_79;
-   |                          ~~~~~~~~~~~~
+LL -     const BAD32_2: f32 = 0.123_456_789;
+LL +     const BAD32_2: f32 = 0.123_456_79;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:22:26
@@ -30,8 +32,9 @@ LL |     const BAD32_3: f32 = 0.100_000_000_000_1;
    |
 help: consider changing the type or truncating it to
    |
-LL |     const BAD32_3: f32 = 0.1;
-   |                          ~~~
+LL -     const BAD32_3: f32 = 0.100_000_000_000_1;
+LL +     const BAD32_3: f32 = 0.1;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:23:29
@@ -41,8 +44,9 @@ LL |     const BAD32_EDGE: f32 = 1.000_000_9;
    |
 help: consider changing the type or truncating it to
    |
-LL |     const BAD32_EDGE: f32 = 1.000_001;
-   |                             ~~~~~~~~~
+LL -     const BAD32_EDGE: f32 = 1.000_000_9;
+LL +     const BAD32_EDGE: f32 = 1.000_001;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:27:26
@@ -52,8 +56,9 @@ LL |     const BAD64_3: f64 = 0.100_000_000_000_000_000_1;
    |
 help: consider changing the type or truncating it to
    |
-LL |     const BAD64_3: f64 = 0.1;
-   |                          ~~~
+LL -     const BAD64_3: f64 = 0.100_000_000_000_000_000_1;
+LL +     const BAD64_3: f64 = 0.1;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:30:22
@@ -63,8 +68,9 @@ LL |     println!("{:?}", 8.888_888_888_888_888_888_888);
    |
 help: consider changing the type or truncating it to
    |
-LL |     println!("{:?}", 8.888_888_888_888_89);
-   |                      ~~~~~~~~~~~~~~~~~~~~
+LL -     println!("{:?}", 8.888_888_888_888_888_888_888);
+LL +     println!("{:?}", 8.888_888_888_888_89);
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:41:22
@@ -74,8 +80,9 @@ LL |     let bad32: f32 = 1.123_456_789;
    |
 help: consider changing the type or truncating it to
    |
-LL |     let bad32: f32 = 1.123_456_8;
-   |                      ~~~~~~~~~~~
+LL -     let bad32: f32 = 1.123_456_789;
+LL +     let bad32: f32 = 1.123_456_8;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:42:26
@@ -85,8 +92,9 @@ LL |     let bad32_suf: f32 = 1.123_456_789_f32;
    |
 help: consider changing the type or truncating it to
    |
-LL |     let bad32_suf: f32 = 1.123_456_8_f32;
-   |                          ~~~~~~~~~~~~~~~
+LL -     let bad32_suf: f32 = 1.123_456_789_f32;
+LL +     let bad32_suf: f32 = 1.123_456_8_f32;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:43:21
@@ -96,8 +104,9 @@ LL |     let bad32_inf = 1.123_456_789_f32;
    |
 help: consider changing the type or truncating it to
    |
-LL |     let bad32_inf = 1.123_456_8_f32;
-   |                     ~~~~~~~~~~~~~~~
+LL -     let bad32_inf = 1.123_456_789_f32;
+LL +     let bad32_inf = 1.123_456_8_f32;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:53:36
@@ -107,8 +116,9 @@ LL |     let bad_vec32: Vec<f32> = vec![0.123_456_789];
    |
 help: consider changing the type or truncating it to
    |
-LL |     let bad_vec32: Vec<f32> = vec![0.123_456_79];
-   |                                    ~~~~~~~~~~~~
+LL -     let bad_vec32: Vec<f32> = vec![0.123_456_789];
+LL +     let bad_vec32: Vec<f32> = vec![0.123_456_79];
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:54:36
@@ -118,8 +128,9 @@ LL |     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
    |
 help: consider changing the type or truncating it to
    |
-LL |     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_78];
-   |                                    ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_789];
+LL +     let bad_vec64: Vec<f64> = vec![0.123_456_789_123_456_78];
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:58:24
@@ -129,8 +140,9 @@ LL |     let bad_e32: f32 = 1.123_456_788_888e-10;
    |
 help: consider changing the type or truncating it to
    |
-LL |     let bad_e32: f32 = 1.123_456_8e-10;
-   |                        ~~~~~~~~~~~~~~~
+LL -     let bad_e32: f32 = 1.123_456_788_888e-10;
+LL +     let bad_e32: f32 = 1.123_456_8e-10;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:61:27
@@ -140,8 +152,9 @@ LL |     let bad_bige32: f32 = 1.123_456_788_888E-10;
    |
 help: consider changing the type or truncating it to
    |
-LL |     let bad_bige32: f32 = 1.123_456_8E-10;
-   |                           ~~~~~~~~~~~~~~~
+LL -     let bad_bige32: f32 = 1.123_456_788_888E-10;
+LL +     let bad_bige32: f32 = 1.123_456_8E-10;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:70:13
@@ -151,8 +164,9 @@ LL |     let _ = 2.225_073_858_507_201_1e-308_f64;
    |
 help: consider changing the type or truncating it to
    |
-LL |     let _ = 2.225_073_858_507_201e-308_f64;
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = 2.225_073_858_507_201_1e-308_f64;
+LL +     let _ = 2.225_073_858_507_201e-308_f64;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:73:13
@@ -162,8 +176,9 @@ LL |     let _ = 1.000_000_000_000_001e-324_f64;
    |
 help: consider changing the type or truncating it to
    |
-LL |     let _ = 0_f64;
-   |             ~~~~~
+LL -     let _ = 1.000_000_000_000_001e-324_f64;
+LL +     let _ = 0_f64;
+   |
 
 error: float has excessive precision
   --> tests/ui/excessive_precision.rs:83:20
@@ -173,8 +188,9 @@ LL |     const _: f64 = 3.0000000000000000e+00;
    |
 help: consider changing the type or truncating it to
    |
-LL |     const _: f64 = 3.0;
-   |                    ~~~
+LL -     const _: f64 = 3.0000000000000000e+00;
+LL +     const _: f64 = 3.0;
+   |
 
 error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr
index a05b7138bc9..c069c9d1672 100644
--- a/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr
+++ b/src/tools/clippy/tests/ui/fn_to_numeric_cast_any.stderr
@@ -8,8 +8,9 @@ LL |     let _ = foo as i8;
    = help: to override `-D warnings` add `#[allow(clippy::fn_to_numeric_cast_any)]`
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as i8;
-   |             ~~~~~~~~~~~
+LL -     let _ = foo as i8;
+LL +     let _ = foo() as i8;
+   |
 
 error: casting function pointer `foo` to `i16`
   --> tests/ui/fn_to_numeric_cast_any.rs:26:13
@@ -19,8 +20,9 @@ LL |     let _ = foo as i16;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as i16;
-   |             ~~~~~~~~~~~~
+LL -     let _ = foo as i16;
+LL +     let _ = foo() as i16;
+   |
 
 error: casting function pointer `foo` to `i32`
   --> tests/ui/fn_to_numeric_cast_any.rs:28:13
@@ -30,8 +32,9 @@ LL |     let _ = foo as i32;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as i32;
-   |             ~~~~~~~~~~~~
+LL -     let _ = foo as i32;
+LL +     let _ = foo() as i32;
+   |
 
 error: casting function pointer `foo` to `i64`
   --> tests/ui/fn_to_numeric_cast_any.rs:30:13
@@ -41,8 +44,9 @@ LL |     let _ = foo as i64;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as i64;
-   |             ~~~~~~~~~~~~
+LL -     let _ = foo as i64;
+LL +     let _ = foo() as i64;
+   |
 
 error: casting function pointer `foo` to `i128`
   --> tests/ui/fn_to_numeric_cast_any.rs:32:13
@@ -52,8 +56,9 @@ LL |     let _ = foo as i128;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as i128;
-   |             ~~~~~~~~~~~~~
+LL -     let _ = foo as i128;
+LL +     let _ = foo() as i128;
+   |
 
 error: casting function pointer `foo` to `isize`
   --> tests/ui/fn_to_numeric_cast_any.rs:34:13
@@ -63,8 +68,9 @@ LL |     let _ = foo as isize;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as isize;
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = foo as isize;
+LL +     let _ = foo() as isize;
+   |
 
 error: casting function pointer `foo` to `u8`
   --> tests/ui/fn_to_numeric_cast_any.rs:37:13
@@ -74,8 +80,9 @@ LL |     let _ = foo as u8;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as u8;
-   |             ~~~~~~~~~~~
+LL -     let _ = foo as u8;
+LL +     let _ = foo() as u8;
+   |
 
 error: casting function pointer `foo` to `u16`
   --> tests/ui/fn_to_numeric_cast_any.rs:39:13
@@ -85,8 +92,9 @@ LL |     let _ = foo as u16;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as u16;
-   |             ~~~~~~~~~~~~
+LL -     let _ = foo as u16;
+LL +     let _ = foo() as u16;
+   |
 
 error: casting function pointer `foo` to `u32`
   --> tests/ui/fn_to_numeric_cast_any.rs:41:13
@@ -96,8 +104,9 @@ LL |     let _ = foo as u32;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as u32;
-   |             ~~~~~~~~~~~~
+LL -     let _ = foo as u32;
+LL +     let _ = foo() as u32;
+   |
 
 error: casting function pointer `foo` to `u64`
   --> tests/ui/fn_to_numeric_cast_any.rs:43:13
@@ -107,8 +116,9 @@ LL |     let _ = foo as u64;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as u64;
-   |             ~~~~~~~~~~~~
+LL -     let _ = foo as u64;
+LL +     let _ = foo() as u64;
+   |
 
 error: casting function pointer `foo` to `u128`
   --> tests/ui/fn_to_numeric_cast_any.rs:45:13
@@ -118,8 +128,9 @@ LL |     let _ = foo as u128;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as u128;
-   |             ~~~~~~~~~~~~~
+LL -     let _ = foo as u128;
+LL +     let _ = foo() as u128;
+   |
 
 error: casting function pointer `foo` to `usize`
   --> tests/ui/fn_to_numeric_cast_any.rs:47:13
@@ -129,8 +140,9 @@ LL |     let _ = foo as usize;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as usize;
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = foo as usize;
+LL +     let _ = foo() as usize;
+   |
 
 error: casting function pointer `Struct::static_method` to `usize`
   --> tests/ui/fn_to_numeric_cast_any.rs:52:13
@@ -140,8 +152,9 @@ LL |     let _ = Struct::static_method as usize;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = Struct::static_method() as usize;
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = Struct::static_method as usize;
+LL +     let _ = Struct::static_method() as usize;
+   |
 
 error: casting function pointer `f` to `usize`
   --> tests/ui/fn_to_numeric_cast_any.rs:57:5
@@ -151,7 +164,8 @@ LL |     f as usize
    |
 help: did you mean to invoke the function?
    |
-LL |     f() as usize
+LL -     f as usize
+LL +     f() as usize
    |
 
 error: casting function pointer `T::static_method` to `usize`
@@ -162,7 +176,8 @@ LL |     T::static_method as usize
    |
 help: did you mean to invoke the function?
    |
-LL |     T::static_method() as usize
+LL -     T::static_method as usize
+LL +     T::static_method() as usize
    |
 
 error: casting function pointer `(clos as fn(u32) -> u32)` to `usize`
@@ -173,8 +188,9 @@ LL |     let _ = (clos as fn(u32) -> u32) as usize;
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = (clos as fn(u32) -> u32)() as usize;
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = (clos as fn(u32) -> u32) as usize;
+LL +     let _ = (clos as fn(u32) -> u32)() as usize;
+   |
 
 error: casting function pointer `foo` to `*const ()`
   --> tests/ui/fn_to_numeric_cast_any.rs:74:13
@@ -184,8 +200,9 @@ LL |     let _ = foo as *const ();
    |
 help: did you mean to invoke the function?
    |
-LL |     let _ = foo() as *const ();
-   |             ~~~~~~~~~~~~~~~~~~
+LL -     let _ = foo as *const ();
+LL +     let _ = foo() as *const ();
+   |
 
 error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/for_kv_map.stderr b/src/tools/clippy/tests/ui/for_kv_map.stderr
index adcc3ab8fdb..11b61c8cbc6 100644
--- a/src/tools/clippy/tests/ui/for_kv_map.stderr
+++ b/src/tools/clippy/tests/ui/for_kv_map.stderr
@@ -8,8 +8,9 @@ LL |     for (_, v) in &m {
    = help: to override `-D warnings` add `#[allow(clippy::for_kv_map)]`
 help: use the corresponding method
    |
-LL |     for v in m.values() {
-   |         ~    ~~~~~~~~~~
+LL -     for (_, v) in &m {
+LL +     for v in m.values() {
+   |
 
 error: you seem to want to iterate on a map's values
   --> tests/ui/for_kv_map.rs:16:19
@@ -19,8 +20,9 @@ LL |     for (_, v) in &*m {
    |
 help: use the corresponding method
    |
-LL |     for v in (*m).values() {
-   |         ~    ~~~~~~~~~~~~~
+LL -     for (_, v) in &*m {
+LL +     for v in (*m).values() {
+   |
 
 error: you seem to want to iterate on a map's values
   --> tests/ui/for_kv_map.rs:25:19
@@ -30,8 +32,9 @@ LL |     for (_, v) in &mut m {
    |
 help: use the corresponding method
    |
-LL |     for v in m.values_mut() {
-   |         ~    ~~~~~~~~~~~~~~
+LL -     for (_, v) in &mut m {
+LL +     for v in m.values_mut() {
+   |
 
 error: you seem to want to iterate on a map's values
   --> tests/ui/for_kv_map.rs:31:19
@@ -41,8 +44,9 @@ LL |     for (_, v) in &mut *m {
    |
 help: use the corresponding method
    |
-LL |     for v in (*m).values_mut() {
-   |         ~    ~~~~~~~~~~~~~~~~~
+LL -     for (_, v) in &mut *m {
+LL +     for v in (*m).values_mut() {
+   |
 
 error: you seem to want to iterate on a map's keys
   --> tests/ui/for_kv_map.rs:38:24
@@ -52,8 +56,9 @@ LL |     for (k, _value) in rm {
    |
 help: use the corresponding method
    |
-LL |     for k in rm.keys() {
-   |         ~    ~~~~~~~~~
+LL -     for (k, _value) in rm {
+LL +     for k in rm.keys() {
+   |
 
 error: you seem to want to iterate on a map's keys
   --> tests/ui/for_kv_map.rs:45:32
@@ -63,8 +68,9 @@ LL |     'label: for (k, _value) in rm {
    |
 help: use the corresponding method
    |
-LL |     'label: for k in rm.keys() {
-   |                 ~    ~~~~~~~~~
+LL -     'label: for (k, _value) in rm {
+LL +     'label: for k in rm.keys() {
+   |
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes.stderr b/src/tools/clippy/tests/ui/four_forward_slashes.stderr
index 3606a2227a0..d5bf71fadc7 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes.stderr
+++ b/src/tools/clippy/tests/ui/four_forward_slashes.stderr
@@ -9,6 +9,8 @@ LL | | fn a() {}
    = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`
 help: make this a doc comment by removing one `/`
    |
+LL - //// whoops
+LL - fn a() {}
 LL + /// whoops
    |
 
@@ -22,6 +24,8 @@ LL | | fn b() {}
    |
 help: make this a doc comment by removing one `/`
    |
+LL - //// whoops
+LL - #[allow(dead_code)]
 LL + /// whoops
    |
 
@@ -50,6 +54,8 @@ LL | | fn g() {}
    |
 help: make this a doc comment by removing one `/`
    |
+LL - //// between attributes
+LL - #[allow(dead_code)]
 LL + /// between attributes
    |
 
@@ -62,6 +68,8 @@ LL | | fn h() {}
    |
 help: make this a doc comment by removing one `/`
    |
+LL -     //// not very start of contents
+LL - fn h() {}
 LL + /// not very start of contents
    |
 
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
index 81732346412..83bfb60eb16 100644
--- a/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
+++ b/src/tools/clippy/tests/ui/four_forward_slashes_first_line.stderr
@@ -9,6 +9,8 @@ LL | | fn a() {}
    = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`
 help: make this a doc comment by removing one `/`
    |
+LL - //// borked doc comment on the first line. doesn't combust!
+LL - fn a() {}
 LL + /// borked doc comment on the first line. doesn't combust!
    |
 
diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
index c250162dfb8..67da45a348f 100644
--- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
+++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.fixed
@@ -1,6 +1,6 @@
 #![warn(clippy::from_iter_instead_of_collect)]
 #![allow(unused_imports)]
-#![allow(clippy::useless_vec)]
+#![allow(clippy::useless_vec, clippy::manual_repeat_n)]
 
 use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
 
diff --git a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
index 8adbb841c8b..423a7454bed 100644
--- a/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
+++ b/src/tools/clippy/tests/ui/from_iter_instead_of_collect.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::from_iter_instead_of_collect)]
 #![allow(unused_imports)]
-#![allow(clippy::useless_vec)]
+#![allow(clippy::useless_vec, clippy::manual_repeat_n)]
 
 use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque};
 
diff --git a/src/tools/clippy/tests/ui/get_unwrap.stderr b/src/tools/clippy/tests/ui/get_unwrap.stderr
index 8eacb249c60..fc6c0b9299c 100644
--- a/src/tools/clippy/tests/ui/get_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/get_unwrap.stderr
@@ -11,8 +11,9 @@ LL | #![deny(clippy::get_unwrap)]
    |         ^^^^^^^^^^^^^^^^^^
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &boxed_slice[1];
-   |                 ~~~~~~~~~~~~~~~
+LL -         let _ = boxed_slice.get(1).unwrap();
+LL +         let _ = &boxed_slice[1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:37:17
@@ -33,8 +34,9 @@ LL |         let _ = some_slice.get(0).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_slice[0];
-   |                 ~~~~~~~~~~~~~~
+LL -         let _ = some_slice.get(0).unwrap();
+LL +         let _ = &some_slice[0];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:38:17
@@ -53,8 +55,9 @@ LL |         let _ = some_vec.get(0).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_vec[0];
-   |                 ~~~~~~~~~~~~
+LL -         let _ = some_vec.get(0).unwrap();
+LL +         let _ = &some_vec[0];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:39:17
@@ -73,8 +76,9 @@ LL |         let _ = some_vecdeque.get(0).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_vecdeque[0];
-   |                 ~~~~~~~~~~~~~~~~~
+LL -         let _ = some_vecdeque.get(0).unwrap();
+LL +         let _ = &some_vecdeque[0];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:40:17
@@ -93,8 +97,9 @@ LL |         let _ = some_hashmap.get(&1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_hashmap[&1];
-   |                 ~~~~~~~~~~~~~~~~~
+LL -         let _ = some_hashmap.get(&1).unwrap();
+LL +         let _ = &some_hashmap[&1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:41:17
@@ -113,8 +118,9 @@ LL |         let _ = some_btreemap.get(&1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = &some_btreemap[&1];
-   |                 ~~~~~~~~~~~~~~~~~~
+LL -         let _ = some_btreemap.get(&1).unwrap();
+LL +         let _ = &some_btreemap[&1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:42:17
@@ -133,8 +139,9 @@ LL |         let _: u8 = *boxed_slice.get(1).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _: u8 = boxed_slice[1];
-   |                     ~~~~~~~~~~~~~~
+LL -         let _: u8 = *boxed_slice.get(1).unwrap();
+LL +         let _: u8 = boxed_slice[1];
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:46:22
@@ -153,8 +160,9 @@ LL |         *boxed_slice.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         boxed_slice[0] = 1;
-   |         ~~~~~~~~~~~~~~
+LL -         *boxed_slice.get_mut(0).unwrap() = 1;
+LL +         boxed_slice[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:51:10
@@ -173,8 +181,9 @@ LL |         *some_slice.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         some_slice[0] = 1;
-   |         ~~~~~~~~~~~~~
+LL -         *some_slice.get_mut(0).unwrap() = 1;
+LL +         some_slice[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:52:10
@@ -193,8 +202,9 @@ LL |         *some_vec.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         some_vec[0] = 1;
-   |         ~~~~~~~~~~~
+LL -         *some_vec.get_mut(0).unwrap() = 1;
+LL +         some_vec[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:53:10
@@ -213,8 +223,9 @@ LL |         *some_vecdeque.get_mut(0).unwrap() = 1;
    |
 help: using `[]` is clearer and more concise
    |
-LL |         some_vecdeque[0] = 1;
-   |         ~~~~~~~~~~~~~~~~
+LL -         *some_vecdeque.get_mut(0).unwrap() = 1;
+LL +         some_vecdeque[0] = 1;
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:54:10
@@ -233,8 +244,9 @@ LL |         let _ = some_vec.get(0..1).unwrap().to_vec();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = some_vec[0..1].to_vec();
-   |                 ~~~~~~~~~~~~~~
+LL -         let _ = some_vec.get(0..1).unwrap().to_vec();
+LL +         let _ = some_vec[0..1].to_vec();
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:66:17
@@ -253,8 +265,9 @@ LL |         let _ = some_vec.get_mut(0..1).unwrap().to_vec();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _ = some_vec[0..1].to_vec();
-   |                 ~~~~~~~~~~~~~~
+LL -         let _ = some_vec.get_mut(0..1).unwrap().to_vec();
+LL +         let _ = some_vec[0..1].to_vec();
+   |
 
 error: used `unwrap()` on an `Option` value
   --> tests/ui/get_unwrap.rs:67:17
@@ -273,8 +286,9 @@ LL |         let _x: &i32 = f.get(1 + 2).unwrap();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _x: &i32 = &f[1 + 2];
-   |                        ~~~~~~~~~
+LL -         let _x: &i32 = f.get(1 + 2).unwrap();
+LL +         let _x: &i32 = &f[1 + 2];
+   |
 
 error: called `.get().unwrap()` on a slice
   --> tests/ui/get_unwrap.rs:81:18
@@ -284,8 +298,9 @@ LL |         let _x = f.get(1 + 2).unwrap().to_string();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _x = f[1 + 2].to_string();
-   |                  ~~~~~~~~
+LL -         let _x = f.get(1 + 2).unwrap().to_string();
+LL +         let _x = f[1 + 2].to_string();
+   |
 
 error: called `.get().unwrap()` on a slice
   --> tests/ui/get_unwrap.rs:84:18
@@ -295,8 +310,9 @@ LL |         let _x = f.get(1 + 2).unwrap().abs();
    |
 help: using `[]` is clearer and more concise
    |
-LL |         let _x = f[1 + 2].abs();
-   |                  ~~~~~~~~
+LL -         let _x = f.get(1 + 2).unwrap().abs();
+LL +         let _x = f[1 + 2].abs();
+   |
 
 error: called `.get_mut().unwrap()` on a slice
   --> tests/ui/get_unwrap.rs:101:33
@@ -306,8 +322,9 @@ LL |                         let b = rest.get_mut(linidx(j, k) - linidx(i, k) -
    |
 help: using `[]` is clearer and more concise
    |
-LL |                         let b = &mut rest[linidx(j, k) - linidx(i, k) - 1];
-   |                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -                         let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
+LL +                         let b = &mut rest[linidx(j, k) - linidx(i, k) - 1];
+   |
 
 error: aborting due to 30 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 fde40437309..118f0b48895 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
@@ -21,12 +21,15 @@ 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 528844d76e0..92feb9e6c28 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
@@ -21,12 +21,15 @@ 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 54ff4454d6b..00a254e3919 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:25:12
+  --> tests/ui/ignored_unit_patterns.rs:27:16
    |
-LL |         Ok(_) => {},
-   |            ^ help: use `()` instead of `_`: `()`
+LL |             Ok(_) => {},
+   |                ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:27:13
+  --> tests/ui/ignored_unit_patterns.rs:29:17
    |
-LL |         Err(_) => {},
-   |             ^ help: use `()` instead of `_`: `()`
+LL |             Err(_) => {},
+   |                 ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:38:9
+  --> tests/ui/ignored_unit_patterns.rs:41:9
    |
 LL |     let _ = foo().unwrap();
    |         ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:47:13
+  --> tests/ui/ignored_unit_patterns.rs:50:13
    |
 LL |         (1, _) => unimplemented!(),
    |             ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> tests/ui/ignored_unit_patterns.rs:54:13
+  --> tests/ui/ignored_unit_patterns.rs:57:13
    |
 LL |     for (x, _) in v {
    |             ^ help: use `()` instead of `_`: `()`
diff --git a/src/tools/clippy/tests/ui/implicit_hasher.fixed b/src/tools/clippy/tests/ui/implicit_hasher.fixed
index 2d6dc0274cf..971746ae95d 100644
--- a/src/tools/clippy/tests/ui/implicit_hasher.fixed
+++ b/src/tools/clippy/tests/ui/implicit_hasher.fixed
@@ -70,7 +70,7 @@ pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {}
 pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {}
 
 #[inline_macros]
-pub mod gen {
+pub mod gen_ {
     use super::*;
     inline! {
         impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {
diff --git a/src/tools/clippy/tests/ui/implicit_hasher.rs b/src/tools/clippy/tests/ui/implicit_hasher.rs
index 0a334357bd1..b34aa1f8137 100644
--- a/src/tools/clippy/tests/ui/implicit_hasher.rs
+++ b/src/tools/clippy/tests/ui/implicit_hasher.rs
@@ -70,7 +70,7 @@ pub fn map(map: &mut HashMap<i32, i32>) {}
 pub fn set(set: &mut HashSet<i32>) {}
 
 #[inline_macros]
-pub mod gen {
+pub mod gen_ {
     use super::*;
     inline! {
         impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
diff --git a/src/tools/clippy/tests/ui/implicit_hasher.stderr b/src/tools/clippy/tests/ui/implicit_hasher.stderr
index 48c6ebc209c..6e964c65a2e 100644
--- a/src/tools/clippy/tests/ui/implicit_hasher.stderr
+++ b/src/tools/clippy/tests/ui/implicit_hasher.stderr
@@ -78,8 +78,9 @@ LL | pub fn map(map: &mut HashMap<i32, i32>) {}
    |
 help: add a type parameter for `BuildHasher`
    |
-LL | pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {}
-   |           +++++++++++++++++++++++++++++           ~~~~~~~~~~~~~~~~~~~~
+LL - pub fn map(map: &mut HashMap<i32, i32>) {}
+LL + pub fn map<S: ::std::hash::BuildHasher>(map: &mut HashMap<i32, i32, S>) {}
+   |
 
 error: parameter of type `HashSet` should be generalized over different hashers
   --> tests/ui/implicit_hasher.rs:70:22
@@ -89,8 +90,9 @@ LL | pub fn set(set: &mut HashSet<i32>) {}
    |
 help: add a type parameter for `BuildHasher`
    |
-LL | pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {}
-   |           +++++++++++++++++++++++++++++           ~~~~~~~~~~~~~~~
+LL - pub fn set(set: &mut HashSet<i32>) {}
+LL + pub fn set<S: ::std::hash::BuildHasher>(set: &mut HashSet<i32, S>) {}
+   |
 
 error: impl for `HashMap` should be generalized over different hashers
   --> tests/ui/implicit_hasher.rs:76:43
@@ -98,7 +100,7 @@ error: impl for `HashMap` should be generalized over different hashers
 LL |         impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
    |                                           ^^^^^^^^^^^^^
    |
-   = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info)
+   = note: this error originates in the macro `__inline_mac_mod_gen_` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: add a type parameter for `BuildHasher`
    |
 LL ~         impl<K: Hash + Eq, V, S: ::std::hash::BuildHasher + Default> Foo<u8> for HashMap<K, V, S> {
@@ -114,8 +116,9 @@ LL | pub async fn election_vote(_data: HashMap<i32, i32>) {}
    |
 help: add a type parameter for `BuildHasher`
    |
-LL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
-   |                           +++++++++++++++++++++++++++++        ~~~~~~~~~~~~~~~~~~~~
+LL - pub async fn election_vote(_data: HashMap<i32, i32>) {}
+LL + pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
+   |
 
 error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/implicit_return.stderr b/src/tools/clippy/tests/ui/implicit_return.stderr
index 3b06f26f5a0..0d2faa5e067 100644
--- a/src/tools/clippy/tests/ui/implicit_return.stderr
+++ b/src/tools/clippy/tests/ui/implicit_return.stderr
@@ -8,7 +8,8 @@ LL |     true
    = help: to override `-D warnings` add `#[allow(clippy::implicit_return)]`
 help: add `return` as shown
    |
-LL |     return true
+LL -     true
+LL +     return true
    |
 
 error: missing `return` statement
@@ -19,8 +20,9 @@ LL |     if true { true } else { false }
    |
 help: add `return` as shown
    |
-LL |     if true { return true } else { false }
-   |               ~~~~~~~~~~~
+LL -     if true { true } else { false }
+LL +     if true { return true } else { false }
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:19:29
@@ -30,8 +32,9 @@ LL |     if true { true } else { false }
    |
 help: add `return` as shown
    |
-LL |     if true { true } else { return false }
-   |                             ~~~~~~~~~~~~
+LL -     if true { true } else { false }
+LL +     if true { true } else { return false }
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:25:17
@@ -41,8 +44,9 @@ LL |         true => false,
    |
 help: add `return` as shown
    |
-LL |         true => return false,
-   |                 ~~~~~~~~~~~~
+LL -         true => false,
+LL +         true => return false,
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:26:20
@@ -52,8 +56,9 @@ LL |         false => { true },
    |
 help: add `return` as shown
    |
-LL |         false => { return true },
-   |                    ~~~~~~~~~~~
+LL -         false => { true },
+LL +         false => { return true },
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:39:9
@@ -63,8 +68,9 @@ LL |         break true;
    |
 help: change `break` to `return` as shown
    |
-LL |         return true;
-   |         ~~~~~~~~~~~
+LL -         break true;
+LL +         return true;
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:46:13
@@ -74,8 +80,9 @@ LL |             break true;
    |
 help: change `break` to `return` as shown
    |
-LL |             return true;
-   |             ~~~~~~~~~~~
+LL -             break true;
+LL +             return true;
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:54:13
@@ -85,8 +92,9 @@ LL |             break true;
    |
 help: change `break` to `return` as shown
    |
-LL |             return true;
-   |             ~~~~~~~~~~~
+LL -             break true;
+LL +             return true;
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:72:18
@@ -96,8 +104,9 @@ LL |     let _ = || { true };
    |
 help: add `return` as shown
    |
-LL |     let _ = || { return true };
-   |                  ~~~~~~~~~~~
+LL -     let _ = || { true };
+LL +     let _ = || { return true };
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:73:16
@@ -107,8 +116,9 @@ LL |     let _ = || true;
    |
 help: add `return` as shown
    |
-LL |     let _ = || return true;
-   |                ~~~~~~~~~~~
+LL -     let _ = || true;
+LL +     let _ = || return true;
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:81:5
@@ -118,7 +128,8 @@ LL |     format!("test {}", "test")
    |
 help: add `return` as shown
    |
-LL |     return format!("test {}", "test")
+LL -     format!("test {}", "test")
+LL +     return format!("test {}", "test")
    |
 
 error: missing `return` statement
@@ -129,7 +140,8 @@ LL |     m!(true, false)
    |
 help: add `return` as shown
    |
-LL |     return m!(true, false)
+LL -     m!(true, false)
+LL +     return m!(true, false)
    |
 
 error: missing `return` statement
@@ -140,8 +152,9 @@ LL |             break true;
    |
 help: change `break` to `return` as shown
    |
-LL |             return true;
-   |             ~~~~~~~~~~~
+LL -             break true;
+LL +             return true;
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:101:17
@@ -151,8 +164,9 @@ LL |                 break 'outer false;
    |
 help: change `break` to `return` as shown
    |
-LL |                 return false;
-   |                 ~~~~~~~~~~~~
+LL -                 break 'outer false;
+LL +                 return false;
+   |
 
 error: missing `return` statement
   --> tests/ui/implicit_return.rs:116:5
@@ -177,7 +191,8 @@ LL |     true
    |
 help: add `return` as shown
    |
-LL |     return true
+LL -     true
+LL +     return true
    |
 
 error: aborting due to 16 previous errors
diff --git a/src/tools/clippy/tests/ui/iter_nth.stderr b/src/tools/clippy/tests/ui/iter_nth.stderr
index 178463f5347..1167a604ecd 100644
--- a/src/tools/clippy/tests/ui/iter_nth.stderr
+++ b/src/tools/clippy/tests/ui/iter_nth.stderr
@@ -8,8 +8,9 @@ LL |         let bad_vec = some_vec.iter().nth(3);
    = help: to override `-D warnings` add `#[allow(clippy::iter_nth)]`
 help: `get` is equivalent but more concise
    |
-LL |         let bad_vec = some_vec.get(3);
-   |                                ~~~
+LL -         let bad_vec = some_vec.iter().nth(3);
+LL +         let bad_vec = some_vec.get(3);
+   |
 
 error: called `.iter().nth()` on a slice
   --> tests/ui/iter_nth.rs:35:26
@@ -19,8 +20,9 @@ LL |         let bad_slice = &some_vec[..].iter().nth(3);
    |
 help: `get` is equivalent but more concise
    |
-LL |         let bad_slice = &some_vec[..].get(3);
-   |                                       ~~~
+LL -         let bad_slice = &some_vec[..].iter().nth(3);
+LL +         let bad_slice = &some_vec[..].get(3);
+   |
 
 error: called `.iter().nth()` on a slice
   --> tests/ui/iter_nth.rs:36:31
@@ -30,8 +32,9 @@ LL |         let bad_boxed_slice = boxed_slice.iter().nth(3);
    |
 help: `get` is equivalent but more concise
    |
-LL |         let bad_boxed_slice = boxed_slice.get(3);
-   |                                           ~~~
+LL -         let bad_boxed_slice = boxed_slice.iter().nth(3);
+LL +         let bad_boxed_slice = boxed_slice.get(3);
+   |
 
 error: called `.iter().nth()` on a `VecDeque`
   --> tests/ui/iter_nth.rs:37:29
@@ -41,8 +44,9 @@ LL |         let bad_vec_deque = some_vec_deque.iter().nth(3);
    |
 help: `get` is equivalent but more concise
    |
-LL |         let bad_vec_deque = some_vec_deque.get(3);
-   |                                            ~~~
+LL -         let bad_vec_deque = some_vec_deque.iter().nth(3);
+LL +         let bad_vec_deque = some_vec_deque.get(3);
+   |
 
 error: called `.iter_mut().nth()` on a `Vec`
   --> tests/ui/iter_nth.rs:42:23
@@ -52,8 +56,9 @@ LL |         let bad_vec = some_vec.iter_mut().nth(3);
    |
 help: `get_mut` is equivalent but more concise
    |
-LL |         let bad_vec = some_vec.get_mut(3);
-   |                                ~~~~~~~
+LL -         let bad_vec = some_vec.iter_mut().nth(3);
+LL +         let bad_vec = some_vec.get_mut(3);
+   |
 
 error: called `.iter_mut().nth()` on a slice
   --> tests/ui/iter_nth.rs:45:26
@@ -63,8 +68,9 @@ LL |         let bad_slice = &some_vec[..].iter_mut().nth(3);
    |
 help: `get_mut` is equivalent but more concise
    |
-LL |         let bad_slice = &some_vec[..].get_mut(3);
-   |                                       ~~~~~~~
+LL -         let bad_slice = &some_vec[..].iter_mut().nth(3);
+LL +         let bad_slice = &some_vec[..].get_mut(3);
+   |
 
 error: called `.iter_mut().nth()` on a `VecDeque`
   --> tests/ui/iter_nth.rs:48:29
@@ -74,8 +80,9 @@ LL |         let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
    |
 help: `get_mut` is equivalent but more concise
    |
-LL |         let bad_vec_deque = some_vec_deque.get_mut(3);
-   |                                            ~~~~~~~
+LL -         let bad_vec_deque = some_vec_deque.iter_mut().nth(3);
+LL +         let bad_vec_deque = some_vec_deque.get_mut(3);
+   |
 
 error: called `.iter().nth()` on a `Vec`
   --> tests/ui/iter_nth.rs:52:5
@@ -85,8 +92,9 @@ LL |     vec_ref.iter().nth(3);
    |
 help: `get` is equivalent but more concise
    |
-LL |     vec_ref.get(3);
-   |             ~~~
+LL -     vec_ref.iter().nth(3);
+LL +     vec_ref.get(3);
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/join_absolute_paths.stderr b/src/tools/clippy/tests/ui/join_absolute_paths.stderr
index e7fd5508823..300946bf3b5 100644
--- a/src/tools/clippy/tests/ui/join_absolute_paths.stderr
+++ b/src/tools/clippy/tests/ui/join_absolute_paths.stderr
@@ -9,12 +9,14 @@ LL |     path.join("/sh");
    = help: to override `-D warnings` add `#[allow(clippy::join_absolute_paths)]`
 help: if this is unintentional, try removing the starting separator
    |
-LL |     path.join("sh");
-   |               ~~~~
+LL -     path.join("/sh");
+LL +     path.join("sh");
+   |
 help: if this is intentional, consider using `Path::new`
    |
-LL |     PathBuf::from("/sh");
-   |     ~~~~~~~~~~~~~~~~~~~~
+LL -     path.join("/sh");
+LL +     PathBuf::from("/sh");
+   |
 
 error: argument to `Path::join` starts with a path separator
   --> tests/ui/join_absolute_paths.rs:14:15
@@ -25,12 +27,14 @@ LL |     path.join("\\user");
    = note: joining a path starting with separator will replace the path instead
 help: if this is unintentional, try removing the starting separator
    |
-LL |     path.join("\user");
-   |               ~~~~~~~
+LL -     path.join("\\user");
+LL +     path.join("\user");
+   |
 help: if this is intentional, consider using `Path::new`
    |
-LL |     PathBuf::from("\\user");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     path.join("\\user");
+LL +     PathBuf::from("\\user");
+   |
 
 error: argument to `Path::join` starts with a path separator
   --> tests/ui/join_absolute_paths.rs:18:15
@@ -41,12 +45,14 @@ LL |     path.join("/sh");
    = note: joining a path starting with separator will replace the path instead
 help: if this is unintentional, try removing the starting separator
    |
-LL |     path.join("sh");
-   |               ~~~~
+LL -     path.join("/sh");
+LL +     path.join("sh");
+   |
 help: if this is intentional, consider using `Path::new`
    |
-LL |     PathBuf::from("/sh");
-   |     ~~~~~~~~~~~~~~~~~~~~
+LL -     path.join("/sh");
+LL +     PathBuf::from("/sh");
+   |
 
 error: argument to `Path::join` starts with a path separator
   --> tests/ui/join_absolute_paths.rs:22:15
@@ -57,12 +63,14 @@ LL |     path.join(r#"/sh"#);
    = note: joining a path starting with separator will replace the path instead
 help: if this is unintentional, try removing the starting separator
    |
-LL |     path.join(r#"sh"#);
-   |               ~~~~~~~
+LL -     path.join(r#"/sh"#);
+LL +     path.join(r#"sh"#);
+   |
 help: if this is intentional, consider using `Path::new`
    |
-LL |     PathBuf::from(r#"/sh"#);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     path.join(r#"/sh"#);
+LL +     PathBuf::from(r#"/sh"#);
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
index 805cb406f83..60653b4abfb 100644
--- a/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
+++ b/src/tools/clippy/tests/ui/large_enum_variant.64bit.stderr
@@ -13,8 +13,9 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     B(Box<[i32; 8000]>),
-   |       ~~~~~~~~~~~~~~~~
+LL -     B([i32; 8000]),
+LL +     B(Box<[i32; 8000]>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:35:1
@@ -29,8 +30,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     ContainingLargeEnum(Box<LargeEnum>),
-   |                         ~~~~~~~~~~~~~~
+LL -     ContainingLargeEnum(LargeEnum),
+LL +     ContainingLargeEnum(Box<LargeEnum>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:40:1
@@ -46,8 +48,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
-   |                                     ~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~
+LL -     ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
+LL +     ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:46:1
@@ -62,8 +65,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
-   |                          ~~~~~~~~~~~~~~~~
+LL -     StructLikeLarge { x: [i32; 8000], y: i32 },
+LL +     StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:51:1
@@ -78,8 +82,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     StructLikeLarge2 { x: Box<[i32; 8000]> },
-   |                           ~~~~~~~~~~~~~~~~
+LL -     StructLikeLarge2 { x: [i32; 8000] },
+LL +     StructLikeLarge2 { x: Box<[i32; 8000]> },
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:67:1
@@ -95,8 +100,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     B(Box<[u8; 1255]>),
-   |       ~~~~~~~~~~~~~~~
+LL -     B([u8; 1255]),
+LL +     B(Box<[u8; 1255]>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:73:1
@@ -111,8 +117,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
-   |                                ~~~~~~~~~~~~~~~~            ~~~~~~~~~~~~~~~~
+LL -     ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
+LL +     ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:78:1
@@ -127,8 +134,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     B(Box<Struct2>),
-   |       ~~~~~~~~~~~~
+LL -     B(Struct2),
+LL +     B(Box<Struct2>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:83:1
@@ -143,8 +151,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     B(Box<Struct2>),
-   |       ~~~~~~~~~~~~
+LL -     B(Struct2),
+LL +     B(Box<Struct2>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:88:1
@@ -159,8 +168,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     B(Box<Struct2>),
-   |       ~~~~~~~~~~~~
+LL -     B(Struct2),
+LL +     B(Box<Struct2>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:103:1
@@ -241,8 +251,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     Large(Box<(T, [u8; 512])>),
-   |           ~~~~~~~~~~~~~~~~~~~
+LL -     Large((T, [u8; 512])),
+LL +     Large(Box<(T, [u8; 512])>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:143:1
@@ -257,8 +268,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     Large(Box<[Foo<u64>; 64]>),
-   |           ~~~~~~~~~~~~~~~~~~~
+LL -     Large([Foo<u64>; 64]),
+LL +     Large(Box<[Foo<u64>; 64]>),
+   |
 
 error: large size difference between variants
   --> tests/ui/large_enum_variant.rs:153:1
@@ -273,8 +285,9 @@ LL | | }
    |
 help: consider boxing the large fields to reduce the total size of the enum
    |
-LL |     Error(Box<PossiblyLargeEnumWithConst<256>>),
-   |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     Error(PossiblyLargeEnumWithConst<256>),
+LL +     Error(Box<PossiblyLargeEnumWithConst<256>>),
+   |
 
 error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
index 267b9ac8e4d..74fe09e0f5c 100644
--- a/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
@@ -8,8 +8,9 @@ LL |     std::f32::EPSILON;
    = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]`
 help: use the associated constant instead
    |
-LL |     f32::EPSILON;
-   |     ~~~~~~~~~~~~
+LL -     std::f32::EPSILON;
+LL +     f32::EPSILON;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:34:5
@@ -19,8 +20,9 @@ LL |     std::u8::MIN;
    |
 help: use the associated constant instead
    |
-LL |     u8::MIN;
-   |     ~~~~~~~
+LL -     std::u8::MIN;
+LL +     u8::MIN;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:37:5
@@ -30,8 +32,9 @@ LL |     std::usize::MIN;
    |
 help: use the associated constant instead
    |
-LL |     usize::MIN;
-   |     ~~~~~~~~~~
+LL -     std::usize::MIN;
+LL +     usize::MIN;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:40:5
@@ -41,8 +44,9 @@ LL |     std::u32::MAX;
    |
 help: use the associated constant instead
    |
-LL |     u32::MAX;
-   |     ~~~~~~~~
+LL -     std::u32::MAX;
+LL +     u32::MAX;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:43:5
@@ -52,8 +56,9 @@ LL |     core::u32::MAX;
    |
 help: use the associated constant instead
    |
-LL |     u32::MAX;
-   |     ~~~~~~~~
+LL -     core::u32::MAX;
+LL +     u32::MAX;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:46:5
@@ -63,8 +68,9 @@ LL |     MAX;
    |
 help: use the associated constant instead
    |
-LL |     u32::MAX;
-   |     ~~~~~~~~
+LL -     MAX;
+LL +     u32::MAX;
+   |
 
 error: usage of a legacy numeric method
   --> tests/ui/legacy_numeric_constants.rs:49:10
@@ -74,8 +80,9 @@ LL |     i32::max_value();
    |
 help: use the associated constant instead
    |
-LL |     i32::MAX;
-   |          ~~~
+LL -     i32::max_value();
+LL +     i32::MAX;
+   |
 
 error: usage of a legacy numeric method
   --> tests/ui/legacy_numeric_constants.rs:52:9
@@ -85,8 +92,9 @@ LL |     u8::max_value();
    |
 help: use the associated constant instead
    |
-LL |     u8::MAX;
-   |         ~~~
+LL -     u8::max_value();
+LL +     u8::MAX;
+   |
 
 error: usage of a legacy numeric method
   --> tests/ui/legacy_numeric_constants.rs:55:9
@@ -96,8 +104,9 @@ LL |     u8::min_value();
    |
 help: use the associated constant instead
    |
-LL |     u8::MIN;
-   |         ~~~
+LL -     u8::min_value();
+LL +     u8::MIN;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:58:5
@@ -107,8 +116,9 @@ LL |     ::std::u8::MIN;
    |
 help: use the associated constant instead
    |
-LL |     u8::MIN;
-   |     ~~~~~~~
+LL -     ::std::u8::MIN;
+LL +     u8::MIN;
+   |
 
 error: usage of a legacy numeric method
   --> tests/ui/legacy_numeric_constants.rs:61:27
@@ -118,8 +128,9 @@ LL |     ::std::primitive::u8::min_value();
    |
 help: use the associated constant instead
    |
-LL |     ::std::primitive::u8::MIN;
-   |                           ~~~
+LL -     ::std::primitive::u8::min_value();
+LL +     ::std::primitive::u8::MIN;
+   |
 
 error: usage of a legacy numeric method
   --> tests/ui/legacy_numeric_constants.rs:64:26
@@ -129,8 +140,9 @@ LL |     std::primitive::i32::max_value();
    |
 help: use the associated constant instead
    |
-LL |     std::primitive::i32::MAX;
-   |                          ~~~
+LL -     std::primitive::i32::max_value();
+LL +     std::primitive::i32::MAX;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:67:5
@@ -140,8 +152,9 @@ LL |     self::a::u128::MAX;
    |
 help: use the associated constant instead
    |
-LL |     u128::MAX;
-   |     ~~~~~~~~~
+LL -     self::a::u128::MAX;
+LL +     u128::MAX;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:17:25
@@ -155,8 +168,9 @@ LL |     b!();
    = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: use the associated constant instead
    |
-LL |                 let x = u64::MAX;
-   |                         ~~~~~~~~
+LL -                 let x = std::u64::MAX;
+LL +                 let x = u64::MAX;
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:81:14
@@ -166,8 +180,9 @@ LL |     [(0, "", std::i128::MAX)];
    |
 help: use the associated constant instead
    |
-LL |     [(0, "", i128::MAX)];
-   |              ~~~~~~~~~
+LL -     [(0, "", std::i128::MAX)];
+LL +     [(0, "", i128::MAX)];
+   |
 
 error: usage of a legacy numeric constant
   --> tests/ui/legacy_numeric_constants.rs:115:5
@@ -177,8 +192,9 @@ LL |     std::u32::MAX;
    |
 help: use the associated constant instead
    |
-LL |     u32::MAX;
-   |     ~~~~~~~~
+LL -     std::u32::MAX;
+LL +     u32::MAX;
+   |
 
 error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr
index 564e0bc4f74..a9192825b35 100644
--- a/src/tools/clippy/tests/ui/literals.stderr
+++ b/src/tools/clippy/tests/ui/literals.stderr
@@ -71,12 +71,14 @@ LL |     let fail_multi_zero = 000_123usize;
    = help: to override `-D warnings` add `#[allow(clippy::zero_prefixed_literal)]`
 help: if you mean to use a decimal constant, remove the `0` to avoid confusion
    |
-LL |     let fail_multi_zero = 123usize;
-   |                           ~~~~~~~~
+LL -     let fail_multi_zero = 000_123usize;
+LL +     let fail_multi_zero = 123usize;
+   |
 help: if you mean to use an octal constant, use `0o`
    |
-LL |     let fail_multi_zero = 0o123usize;
-   |                           ~~~~~~~~~~
+LL -     let fail_multi_zero = 000_123usize;
+LL +     let fail_multi_zero = 0o123usize;
+   |
 
 error: integer type suffix should not be separated by an underscore
   --> tests/ui/literals.rs:36:16
@@ -92,12 +94,14 @@ LL |     let fail8 = 0123;
    |
 help: if you mean to use a decimal constant, remove the `0` to avoid confusion
    |
-LL |     let fail8 = 123;
-   |                 ~~~
+LL -     let fail8 = 0123;
+LL +     let fail8 = 123;
+   |
 help: if you mean to use an octal constant, use `0o`
    |
-LL |     let fail8 = 0o123;
-   |                 ~~~~~
+LL -     let fail8 = 0123;
+LL +     let fail8 = 0o123;
+   |
 
 error: integer type suffix should not be separated by an underscore
   --> tests/ui/literals.rs:48:16
@@ -143,8 +147,9 @@ LL |     let _ = 08;
    |
 help: if you mean to use a decimal constant, remove the `0` to avoid confusion
    |
-LL |     let _ = 8;
-   |             ~
+LL -     let _ = 08;
+LL +     let _ = 8;
+   |
 
 error: this is a decimal constant
   --> tests/ui/literals.rs:72:13
@@ -154,8 +159,9 @@ LL |     let _ = 09;
    |
 help: if you mean to use a decimal constant, remove the `0` to avoid confusion
    |
-LL |     let _ = 9;
-   |             ~
+LL -     let _ = 09;
+LL +     let _ = 9;
+   |
 
 error: this is a decimal constant
   --> tests/ui/literals.rs:74:13
@@ -165,8 +171,9 @@ LL |     let _ = 089;
    |
 help: if you mean to use a decimal constant, remove the `0` to avoid confusion
    |
-LL |     let _ = 89;
-   |             ~~
+LL -     let _ = 089;
+LL +     let _ = 89;
+   |
 
 error: aborting due to 20 previous errors
 
diff --git a/src/tools/clippy/tests/ui/lossy_float_literal.stderr b/src/tools/clippy/tests/ui/lossy_float_literal.stderr
index 3026854e317..118351a62d0 100644
--- a/src/tools/clippy/tests/ui/lossy_float_literal.stderr
+++ b/src/tools/clippy/tests/ui/lossy_float_literal.stderr
@@ -8,8 +8,9 @@ LL |     let _: f32 = 16_777_217.0;
    = help: to override `-D warnings` add `#[allow(clippy::lossy_float_literal)]`
 help: consider changing the type or replacing it with
    |
-LL |     let _: f32 = 16_777_216.0;
-   |                  ~~~~~~~~~~~~
+LL -     let _: f32 = 16_777_217.0;
+LL +     let _: f32 = 16_777_216.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:15:18
@@ -19,8 +20,9 @@ LL |     let _: f32 = 16_777_219.0;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f32 = 16_777_220.0;
-   |                  ~~~~~~~~~~~~
+LL -     let _: f32 = 16_777_219.0;
+LL +     let _: f32 = 16_777_220.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:16:18
@@ -30,8 +32,9 @@ LL |     let _: f32 = 16_777_219.;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f32 = 16_777_220.0;
-   |                  ~~~~~~~~~~~~
+LL -     let _: f32 = 16_777_219.;
+LL +     let _: f32 = 16_777_220.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:17:18
@@ -41,8 +44,9 @@ LL |     let _: f32 = 16_777_219.000;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f32 = 16_777_220.0;
-   |                  ~~~~~~~~~~~~
+LL -     let _: f32 = 16_777_219.000;
+LL +     let _: f32 = 16_777_220.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:18:13
@@ -52,8 +56,9 @@ LL |     let _ = 16_777_219f32;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _ = 16_777_220_f32;
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = 16_777_219f32;
+LL +     let _ = 16_777_220_f32;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:19:19
@@ -63,8 +68,9 @@ LL |     let _: f32 = -16_777_219.0;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f32 = -16_777_220.0;
-   |                   ~~~~~~~~~~~~
+LL -     let _: f32 = -16_777_219.0;
+LL +     let _: f32 = -16_777_220.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:21:18
@@ -74,8 +80,9 @@ LL |     let _: f64 = 9_007_199_254_740_993.0;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f64 = 9_007_199_254_740_992.0;
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: f64 = 9_007_199_254_740_993.0;
+LL +     let _: f64 = 9_007_199_254_740_992.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:22:18
@@ -85,8 +92,9 @@ LL |     let _: f64 = 9_007_199_254_740_993.;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f64 = 9_007_199_254_740_992.0;
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: f64 = 9_007_199_254_740_993.;
+LL +     let _: f64 = 9_007_199_254_740_992.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:23:18
@@ -96,8 +104,9 @@ LL |     let _: f64 = 9_007_199_254_740_993.00;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f64 = 9_007_199_254_740_992.0;
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: f64 = 9_007_199_254_740_993.00;
+LL +     let _: f64 = 9_007_199_254_740_992.0;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:24:13
@@ -107,8 +116,9 @@ LL |     let _ = 9_007_199_254_740_993f64;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _ = 9_007_199_254_740_992_f64;
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = 9_007_199_254_740_993f64;
+LL +     let _ = 9_007_199_254_740_992_f64;
+   |
 
 error: literal cannot be represented as the underlying type without loss of precision
   --> tests/ui/lossy_float_literal.rs:25:19
@@ -118,8 +128,9 @@ LL |     let _: f64 = -9_007_199_254_740_993.0;
    |
 help: consider changing the type or replacing it with
    |
-LL |     let _: f64 = -9_007_199_254_740_992.0;
-   |                   ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: f64 = -9_007_199_254_740_993.0;
+LL +     let _: f64 = -9_007_199_254_740_992.0;
+   |
 
 error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
index 004463720e2..dfccf7e9939 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
@@ -79,7 +79,15 @@ LL | |     }
    |
 help: try instead
    |
-LL |     assert!(!(a > 2), "panic with comment");
+LL -     if a > 2 {
+LL -         // comment
+LL -         /* this is a
+LL -         multiline
+LL -         comment */
+LL -         /// Doc comment
+LL -         panic!("panic with comment") // comment after `panic!`
+LL -     }
+LL +     assert!(!(a > 2), "panic with comment");
    |
 
 error: only a `panic!` in `if`-then statement
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
index 004463720e2..dfccf7e9939 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
@@ -79,7 +79,15 @@ LL | |     }
    |
 help: try instead
    |
-LL |     assert!(!(a > 2), "panic with comment");
+LL -     if a > 2 {
+LL -         // comment
+LL -         /* this is a
+LL -         multiline
+LL -         comment */
+LL -         /// Doc comment
+LL -         panic!("panic with comment") // comment after `panic!`
+LL -     }
+LL +     assert!(!(a > 2), "panic with comment");
    |
 
 error: only a `panic!` in `if`-then statement
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.stderr b/src/tools/clippy/tests/ui/manual_async_fn.stderr
index 68a97243436..a7cfc30fb69 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.stderr
+++ b/src/tools/clippy/tests/ui/manual_async_fn.stderr
@@ -8,8 +8,9 @@ LL | fn fut() -> impl Future<Output = i32> {
    = help: to override `-D warnings` add `#[allow(clippy::manual_async_fn)]`
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn fut() -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - fn fut() -> impl Future<Output = i32> {
+LL + async fn fut() -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:11:1
@@ -19,8 +20,9 @@ LL | fn fut2() ->impl Future<Output = i32> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn fut2() -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - fn fut2() ->impl Future<Output = i32> {
+LL + async fn fut2() -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:16:1
@@ -30,8 +32,9 @@ LL | fn fut3()-> impl Future<Output = i32> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn fut3() -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - fn fut3()-> impl Future<Output = i32> {
+LL + async fn fut3() -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:20:1
@@ -41,8 +44,9 @@ LL | fn empty_fut() -> impl Future<Output = ()> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn empty_fut() {}
-   | ~~~~~~~~~~~~~~~~~~~~ ~~
+LL - fn empty_fut() -> impl Future<Output = ()> {
+LL + async fn empty_fut() {}
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:25:1
@@ -52,8 +56,9 @@ LL | fn empty_fut2() ->impl Future<Output = ()> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn empty_fut2() {}
-   | ~~~~~~~~~~~~~~~~~~~~~ ~~
+LL - fn empty_fut2() ->impl Future<Output = ()> {
+LL + async fn empty_fut2() {}
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:30:1
@@ -63,8 +68,9 @@ LL | fn empty_fut3()-> impl Future<Output = ()> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn empty_fut3() {}
-   | ~~~~~~~~~~~~~~~~~~~~~ ~~
+LL - fn empty_fut3()-> impl Future<Output = ()> {
+LL + async fn empty_fut3() {}
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:34:1
@@ -74,8 +80,9 @@ LL | fn core_fut() -> impl core::future::Future<Output = i32> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn core_fut() -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - fn core_fut() -> impl core::future::Future<Output = i32> {
+LL + async fn core_fut() -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:56:5
@@ -108,8 +115,9 @@ LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn elided(_: &i32) -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - fn elided(_: &i32) -> impl Future<Output = i32> + '_ {
+LL + async fn elided(_: &i32) -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:101:1
@@ -119,8 +127,9 @@ LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> +
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
+LL + async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:130:1
@@ -130,8 +139,9 @@ LL | pub fn issue_10450() -> impl Future<Output = i32> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | pub async fn issue_10450() -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - pub fn issue_10450() -> impl Future<Output = i32> {
+LL + pub async fn issue_10450() -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:134:1
@@ -141,8 +151,9 @@ LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | pub(crate) async fn issue_10450_2() -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - pub(crate) fn issue_10450_2() -> impl Future<Output = i32> {
+LL + pub(crate) async fn issue_10450_2() -> i32 { 42 }
+   |
 
 error: this function can be simplified using the `async fn` syntax
   --> tests/ui/manual_async_fn.rs:138:1
@@ -152,8 +163,9 @@ LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> {
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | pub(self) async fn issue_10450_3() -> i32 { 42 }
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
+LL - pub(self) fn issue_10450_3() -> impl Future<Output = i32> {
+LL + pub(self) async fn issue_10450_3() -> i32 { 42 }
+   |
 
 error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil.fixed b/src/tools/clippy/tests/ui/manual_div_ceil.fixed
index 1fb1df5b442..f6eb5a9784a 100644
--- a/src/tools/clippy/tests/ui/manual_div_ceil.fixed
+++ b/src/tools/clippy/tests/ui/manual_div_ceil.fixed
@@ -50,3 +50,14 @@ fn issue_13843() {
 
     let _ = 1_000_000_u32.div_ceil(6u32);
 }
+
+fn issue_13950() {
+    let x = 33u32;
+    let _ = x.div_ceil(8);
+    let _ = x.div_ceil(8);
+
+    let y = -33i32;
+    let _ = (y + -8) / -7;
+    let _ = (-8 + y) / -7;
+    let _ = (y - 8) / -7;
+}
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil.rs b/src/tools/clippy/tests/ui/manual_div_ceil.rs
index 4f6d38f0d14..2f063afe787 100644
--- a/src/tools/clippy/tests/ui/manual_div_ceil.rs
+++ b/src/tools/clippy/tests/ui/manual_div_ceil.rs
@@ -50,3 +50,14 @@ fn issue_13843() {
 
     let _ = (1_000_000 + 6u32 - 1) / 6u32;
 }
+
+fn issue_13950() {
+    let x = 33u32;
+    let _ = (x + 7) / 8;
+    let _ = (7 + x) / 8;
+
+    let y = -33i32;
+    let _ = (y + -8) / -7;
+    let _ = (-8 + y) / -7;
+    let _ = (y - 8) / -7;
+}
diff --git a/src/tools/clippy/tests/ui/manual_div_ceil.stderr b/src/tools/clippy/tests/ui/manual_div_ceil.stderr
index 3d87fe8e040..0bac5d8ef1c 100644
--- a/src/tools/clippy/tests/ui/manual_div_ceil.stderr
+++ b/src/tools/clippy/tests/ui/manual_div_ceil.stderr
@@ -85,5 +85,17 @@ error: manually reimplementing `div_ceil`
 LL |     let _ = (1_000_000 + 6u32 - 1) / 6u32;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)`
 
-error: aborting due to 14 previous errors
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil.rs:56:13
+   |
+LL |     let _ = (x + 7) / 8;
+   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil.rs:57:13
+   |
+LL |     let _ = (7 + x) / 8;
+   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`
+
+error: aborting due to 16 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
index f32b78aa14d..01c58151bc9 100644
--- a/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.fixed
+++ b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.fixed
@@ -50,3 +50,14 @@ fn issue_13843() {
 
     let _ = 1_000_000_u32.div_ceil(6u32);
 }
+
+fn issue_13950() {
+    let x = 33u32;
+    let _ = x.div_ceil(8);
+    let _ = x.div_ceil(8);
+
+    let y = -33i32;
+    let _ = y.div_ceil(-7);
+    let _ = y.div_ceil(-7);
+    let _ = y.div_ceil(-7);
+}
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
index 54d89fcbd46..048ff401581 100644
--- a/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.rs
+++ b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.rs
@@ -50,3 +50,14 @@ fn issue_13843() {
 
     let _ = (1_000_000 + 6u32 - 1) / 6u32;
 }
+
+fn issue_13950() {
+    let x = 33u32;
+    let _ = (x + 7) / 8;
+    let _ = (7 + x) / 8;
+
+    let y = -33i32;
+    let _ = (y + -8) / -7;
+    let _ = (-8 + y) / -7;
+    let _ = (y - 8) / -7;
+}
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
index c5e8c1a687c..807cfd82724 100644
--- a/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.stderr
+++ b/src/tools/clippy/tests/ui/manual_div_ceil_with_feature.stderr
@@ -109,5 +109,35 @@ error: manually reimplementing `div_ceil`
 LL |     let _ = (1_000_000 + 6u32 - 1) / 6u32;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)`
 
-error: aborting due to 18 previous errors
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:56:13
+   |
+LL |     let _ = (x + 7) / 8;
+   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:57:13
+   |
+LL |     let _ = (7 + x) / 8;
+   |             ^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(8)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:60:13
+   |
+LL |     let _ = (y + -8) / -7;
+   |             ^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:61:13
+   |
+LL |     let _ = (-8 + y) / -7;
+   |             ^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)`
+
+error: manually reimplementing `div_ceil`
+  --> tests/ui/manual_div_ceil_with_feature.rs:62:13
+   |
+LL |     let _ = (y - 8) / -7;
+   |             ^^^^^^^^^^^^ help: consider using `.div_ceil()`: `y.div_ceil(-7)`
+
+error: aborting due to 23 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_float_methods.stderr b/src/tools/clippy/tests/ui/manual_float_methods.stderr
index 676a4485ab4..1352c5e73ca 100644
--- a/src/tools/clippy/tests/ui/manual_float_methods.stderr
+++ b/src/tools/clippy/tests/ui/manual_float_methods.stderr
@@ -17,16 +17,19 @@ LL |     if x != f32::INFINITY && x != f32::NEG_INFINITY {}
    = help: to override `-D warnings` add `#[allow(clippy::manual_is_finite)]`
 help: use the dedicated method instead
    |
-LL |     if x.is_finite() {}
-   |        ~~~~~~~~~~~~~
+LL -     if x != f32::INFINITY && x != f32::NEG_INFINITY {}
+LL +     if x.is_finite() {}
+   |
 help: this will alter how it handles NaN; if that is a problem, use instead
    |
-LL |     if x.is_finite() || x.is_nan() {}
-   |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if x != f32::INFINITY && x != f32::NEG_INFINITY {}
+LL +     if x.is_finite() || x.is_nan() {}
+   |
 help: or, for conciseness
    |
-LL |     if !x.is_infinite() {}
-   |        ~~~~~~~~~~~~~~~~
+LL -     if x != f32::INFINITY && x != f32::NEG_INFINITY {}
+LL +     if !x.is_infinite() {}
+   |
 
 error: manually checking if a float is infinite
   --> tests/ui/manual_float_methods.rs:26:8
@@ -42,16 +45,19 @@ LL |     if x != INFINITE && x != NEG_INFINITE {}
    |
 help: use the dedicated method instead
    |
-LL |     if x.is_finite() {}
-   |        ~~~~~~~~~~~~~
+LL -     if x != INFINITE && x != NEG_INFINITE {}
+LL +     if x.is_finite() {}
+   |
 help: this will alter how it handles NaN; if that is a problem, use instead
    |
-LL |     if x.is_finite() || x.is_nan() {}
-   |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if x != INFINITE && x != NEG_INFINITE {}
+LL +     if x.is_finite() || x.is_nan() {}
+   |
 help: or, for conciseness
    |
-LL |     if !x.is_infinite() {}
-   |        ~~~~~~~~~~~~~~~~
+LL -     if x != INFINITE && x != NEG_INFINITE {}
+LL +     if !x.is_infinite() {}
+   |
 
 error: manually checking if a float is infinite
   --> tests/ui/manual_float_methods.rs:29:8
@@ -67,16 +73,19 @@ LL |     if x != f64::INFINITY && x != f64::NEG_INFINITY {}
    |
 help: use the dedicated method instead
    |
-LL |     if x.is_finite() {}
-   |        ~~~~~~~~~~~~~
+LL -     if x != f64::INFINITY && x != f64::NEG_INFINITY {}
+LL +     if x.is_finite() {}
+   |
 help: this will alter how it handles NaN; if that is a problem, use instead
    |
-LL |     if x.is_finite() || x.is_nan() {}
-   |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if x != f64::INFINITY && x != f64::NEG_INFINITY {}
+LL +     if x.is_finite() || x.is_nan() {}
+   |
 help: or, for conciseness
    |
-LL |     if !x.is_infinite() {}
-   |        ~~~~~~~~~~~~~~~~
+LL -     if x != f64::INFINITY && x != f64::NEG_INFINITY {}
+LL +     if !x.is_infinite() {}
+   |
 
 error: manually checking if a float is infinite
   --> tests/ui/manual_float_methods.rs:44:12
diff --git a/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr b/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr
index 11e8b8aebb5..bc6393b66d5 100644
--- a/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr
+++ b/src/tools/clippy/tests/ui/manual_ignore_case_cmp.stderr
@@ -11,8 +11,9 @@ LL | #![deny(clippy::manual_ignore_case_cmp)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     if a.eq_ignore_ascii_case(b) {
-   |        ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if a.to_ascii_lowercase() == b.to_ascii_lowercase() {
+LL +     if a.eq_ignore_ascii_case(b) {
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:12:8
@@ -22,8 +23,9 @@ LL |     if a.to_ascii_uppercase() == b.to_ascii_uppercase() {
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     if a.eq_ignore_ascii_case(b) {
-   |        ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if a.to_ascii_uppercase() == b.to_ascii_uppercase() {
+LL +     if a.eq_ignore_ascii_case(b) {
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:15:13
@@ -33,8 +35,9 @@ LL |     let r = a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     let r = a.eq_ignore_ascii_case(b);
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let r = a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     let r = a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:16:18
@@ -44,8 +47,9 @@ LL |     let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     let r = r || a.eq_ignore_ascii_case(b);
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let r = r || a.to_ascii_uppercase() == b.to_ascii_uppercase();
+LL +     let r = r || a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:17:10
@@ -55,8 +59,9 @@ LL |     r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     r && a.eq_ignore_ascii_case(&b.to_uppercase());
-   |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     r && a.to_ascii_lowercase() == b.to_uppercase().to_ascii_lowercase();
+LL +     r && a.eq_ignore_ascii_case(&b.to_uppercase());
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:19:8
@@ -66,8 +71,9 @@ LL |     if a.to_ascii_lowercase() != b.to_ascii_lowercase() {
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     if !a.eq_ignore_ascii_case(b) {
-   |        ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if a.to_ascii_lowercase() != b.to_ascii_lowercase() {
+LL +     if !a.eq_ignore_ascii_case(b) {
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:22:8
@@ -77,8 +83,9 @@ LL |     if a.to_ascii_uppercase() != b.to_ascii_uppercase() {
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     if !a.eq_ignore_ascii_case(b) {
-   |        ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if a.to_ascii_uppercase() != b.to_ascii_uppercase() {
+LL +     if !a.eq_ignore_ascii_case(b) {
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:25:13
@@ -88,8 +95,9 @@ LL |     let r = a.to_ascii_lowercase() != b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     let r = !a.eq_ignore_ascii_case(b);
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let r = a.to_ascii_lowercase() != b.to_ascii_lowercase();
+LL +     let r = !a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:26:18
@@ -99,8 +107,9 @@ LL |     let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     let r = r || !a.eq_ignore_ascii_case(b);
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let r = r || a.to_ascii_uppercase() != b.to_ascii_uppercase();
+LL +     let r = r || !a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:27:10
@@ -110,8 +119,9 @@ LL |     r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     r && !a.eq_ignore_ascii_case(&b.to_uppercase());
-   |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     r && a.to_ascii_lowercase() != b.to_uppercase().to_ascii_lowercase();
+LL +     r && !a.eq_ignore_ascii_case(&b.to_uppercase());
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:38:5
@@ -121,8 +131,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:41:5
@@ -132,8 +143,9 @@ LL |     a.to_ascii_lowercase() == 'a';
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(&'a');
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == 'a';
+LL +     a.eq_ignore_ascii_case(&'a');
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:42:5
@@ -143,8 +155,9 @@ LL |     'a' == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     'a'.eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     'a' == b.to_ascii_lowercase();
+LL +     'a'.eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:45:5
@@ -154,8 +167,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:46:5
@@ -165,8 +179,9 @@ LL |     a.to_ascii_lowercase() == b'a';
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(&b'a');
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b'a';
+LL +     a.eq_ignore_ascii_case(&b'a');
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:47:5
@@ -176,8 +191,9 @@ LL |     b'a' == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     b'a'.eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     b'a' == b.to_ascii_lowercase();
+LL +     b'a'.eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:50:5
@@ -187,8 +203,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:51:5
@@ -198,8 +215,9 @@ LL |     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.to_uppercase().eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.to_uppercase().eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:52:5
@@ -209,8 +227,9 @@ LL |     a.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == "a";
+LL +     a.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:53:5
@@ -220,8 +239,9 @@ LL |     "a" == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == b.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:56:5
@@ -231,8 +251,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:57:5
@@ -242,8 +263,9 @@ LL |     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.to_uppercase().eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_uppercase().to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.to_uppercase().eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:58:5
@@ -253,8 +275,9 @@ LL |     a.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == "a";
+LL +     a.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:59:5
@@ -264,8 +287,9 @@ LL |     "a" == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == b.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:62:5
@@ -275,8 +299,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:63:5
@@ -286,8 +311,9 @@ LL |     a.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == "a";
+LL +     a.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:64:5
@@ -297,8 +323,9 @@ LL |     "a" == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == b.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:67:5
@@ -308,8 +335,9 @@ LL |     a.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == "a";
+LL +     a.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:68:5
@@ -319,8 +347,9 @@ LL |     "a" == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == b.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:71:5
@@ -330,8 +359,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:72:5
@@ -341,8 +371,9 @@ LL |     a.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == "a";
+LL +     a.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:73:5
@@ -352,8 +383,9 @@ LL |     "a" == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == b.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:75:5
@@ -363,8 +395,9 @@ LL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     b.eq_ignore_ascii_case(&a);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();
+LL +     b.eq_ignore_ascii_case(&a);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:76:5
@@ -374,8 +407,9 @@ LL |     b.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     b.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     b.to_ascii_lowercase() == "a";
+LL +     b.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:77:5
@@ -385,8 +419,9 @@ LL |     "a" == a.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(&a);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == a.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(&a);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:80:5
@@ -396,8 +431,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:81:5
@@ -407,8 +443,9 @@ LL |     a.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == "a";
+LL +     a.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:82:5
@@ -418,8 +455,9 @@ LL |     "a" == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == b.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:84:5
@@ -429,8 +467,9 @@ LL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     b.eq_ignore_ascii_case(&a);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();
+LL +     b.eq_ignore_ascii_case(&a);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:85:5
@@ -440,8 +479,9 @@ LL |     b.to_ascii_lowercase() == "a";
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     b.eq_ignore_ascii_case("a");
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     b.to_ascii_lowercase() == "a";
+LL +     b.eq_ignore_ascii_case("a");
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:86:5
@@ -451,8 +491,9 @@ LL |     "a" == a.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     "a".eq_ignore_ascii_case(&a);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "a" == a.to_ascii_lowercase();
+LL +     "a".eq_ignore_ascii_case(&a);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:89:5
@@ -462,8 +503,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:92:5
@@ -473,8 +515,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(&b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(&b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:95:5
@@ -484,8 +527,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:96:5
@@ -495,8 +539,9 @@ LL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     b.eq_ignore_ascii_case(&a);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();
+LL +     b.eq_ignore_ascii_case(&a);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:99:5
@@ -506,8 +551,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:102:5
@@ -517,8 +563,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:105:5
@@ -528,8 +575,9 @@ LL |     a.to_ascii_lowercase() == b.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     a.eq_ignore_ascii_case(b);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     a.to_ascii_lowercase() == b.to_ascii_lowercase();
+LL +     a.eq_ignore_ascii_case(b);
+   |
 
 error: manual case-insensitive ASCII comparison
   --> tests/ui/manual_ignore_case_cmp.rs:106:5
@@ -539,8 +587,9 @@ LL |     b.to_ascii_lowercase() == a.to_ascii_lowercase();
    |
 help: consider using `.eq_ignore_ascii_case()` instead
    |
-LL |     b.eq_ignore_ascii_case(a);
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     b.to_ascii_lowercase() == a.to_ascii_lowercase();
+LL +     b.eq_ignore_ascii_case(a);
+   |
 
 error: aborting due to 49 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
index 92d93208006..7b3f0c938b0 100644
--- a/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
+++ b/src/tools/clippy/tests/ui/manual_is_ascii_check.stderr
@@ -153,8 +153,9 @@ LL |     take_while(|c| ('A'..='Z').contains(&c));
    |
 help: try
    |
-LL |     take_while(|c: char| c.is_ascii_uppercase());
-   |                 ~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~
+LL -     take_while(|c| ('A'..='Z').contains(&c));
+LL +     take_while(|c: char| c.is_ascii_uppercase());
+   |
 
 error: manual check for common ascii range
   --> tests/ui/manual_is_ascii_check.rs:82:20
@@ -164,8 +165,9 @@ LL |     take_while(|c| (b'A'..=b'Z').contains(&c));
    |
 help: try
    |
-LL |     take_while(|c: u8| c.is_ascii_uppercase());
-   |                 ~~~~~  ~~~~~~~~~~~~~~~~~~~~~~
+LL -     take_while(|c| (b'A'..=b'Z').contains(&c));
+LL +     take_while(|c: u8| c.is_ascii_uppercase());
+   |
 
 error: manual check for common ascii range
   --> tests/ui/manual_is_ascii_check.rs:83:26
@@ -181,8 +183,9 @@ LL |     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').c
    |
 help: try
    |
-LL |     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect();
-   |                                                            ~~~~~~~~~  ~~~~~~~~~~~~~~~~~~
+LL -     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c| ('0'..='9').contains(c)).collect();
+LL +     let digits: Vec<&char> = ['1', 'A'].iter().take_while(|c: &&char| c.is_ascii_digit()).collect();
+   |
 
 error: manual check for common ascii range
   --> tests/ui/manual_is_ascii_check.rs:88:71
@@ -192,8 +195,9 @@ LL |     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'.
    |
 help: try
    |
-LL |     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
-   |                                                                    ~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~
+LL -     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c| ('0'..='9').contains(c)).collect();
+LL +     let digits: Vec<&mut char> = ['1', 'A'].iter_mut().take_while(|c: &&mut char| c.is_ascii_digit()).collect();
+   |
 
 error: aborting due to 29 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
index c917fa7f2d0..2f8640cd3f5 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
@@ -1,5 +1,10 @@
 #![warn(clippy::manual_memcpy)]
-#![allow(clippy::assigning_clones, clippy::useless_vec, clippy::needless_range_loop)]
+#![allow(
+    clippy::assigning_clones,
+    clippy::useless_vec,
+    clippy::needless_range_loop,
+    clippy::manual_slice_fill
+)]
 
 //@no-rustfix
 const LOOP_OFFSET: usize = 5000;
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
index 803053b2db2..c881e3fac76 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
@@ -1,5 +1,5 @@
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:9:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:14:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -12,7 +12,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:16:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:21:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -21,7 +21,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:22:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:27:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -30,7 +30,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:28:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:33:5
    |
 LL | /     for i in 11..src.len() {
 LL | |
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:34:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:39:5
    |
 LL | /     for i in 0..dst.len() {
 LL | |
@@ -48,7 +48,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:48:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:53:5
    |
 LL | /     for i in 10..256 {
 LL | |
@@ -64,7 +64,7 @@ LL +     dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]);
    |
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:61:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:66:5
    |
 LL | /     for i in 10..LOOP_OFFSET {
 LL | |
@@ -73,7 +73,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:75:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:80:5
    |
 LL | /     for i in 0..src_vec.len() {
 LL | |
@@ -82,7 +82,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:105:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:110:5
    |
 LL | /     for i in from..from + src.len() {
 LL | |
@@ -91,7 +91,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:110:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:115:5
    |
 LL | /     for i in from..from + 3 {
 LL | |
@@ -100,7 +100,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:116:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:121:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -109,7 +109,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:122:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:127:5
    |
 LL | /     for i in 0..0 {
 LL | |
@@ -118,7 +118,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:146:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:151:5
    |
 LL | /     for i in 0..4 {
 LL | |
@@ -127,7 +127,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:152:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:157:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -136,7 +136,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:158:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:163:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -145,7 +145,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:205:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:210:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -154,7 +154,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:211:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:216:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -163,7 +163,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:219:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:224:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
diff --git a/src/tools/clippy/tests/ui/manual_ok_err.fixed b/src/tools/clippy/tests/ui/manual_ok_err.fixed
new file mode 100644
index 00000000000..e7e0464c478
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_ok_err.fixed
@@ -0,0 +1,91 @@
+#![warn(clippy::manual_ok_err)]
+
+fn funcall() -> Result<u32, &'static str> {
+    todo!()
+}
+
+fn main() {
+    let _ = funcall().ok();
+
+    let _ = funcall().ok();
+
+    let _ = funcall().err();
+
+    let _ = funcall().err();
+
+    let _ = funcall().ok();
+
+    let _ = funcall().err();
+
+    #[allow(clippy::redundant_pattern)]
+    let _ = funcall().ok();
+
+    struct S;
+
+    impl std::ops::Neg for S {
+        type Output = Result<u32, &'static str>;
+
+        fn neg(self) -> Self::Output {
+            funcall()
+        }
+    }
+
+    // Suggestion should be properly parenthesized
+    let _ = (-S).ok();
+
+    no_lint();
+}
+
+fn no_lint() {
+    let _ = match funcall() {
+        Ok(v) if v > 3 => Some(v),
+        _ => None,
+    };
+
+    let _ = match funcall() {
+        Err(_) => None,
+        Ok(3) => None,
+        Ok(v) => Some(v),
+    };
+
+    let _ = match funcall() {
+        _ => None,
+        Ok(v) => Some(v),
+    };
+
+    let _ = match funcall() {
+        Err(_) | Ok(3) => None,
+        Ok(v) => Some(v),
+    };
+
+    #[expect(clippy::redundant_pattern)]
+    let _ = match funcall() {
+        _v @ _ => None,
+        Ok(v) => Some(v),
+    };
+
+    // Content of `Option` and matching content of `Result` do
+    // not have the same type.
+    let _: Option<&dyn std::any::Any> = match Ok::<_, ()>(&1) {
+        Ok(v) => Some(v),
+        _ => None,
+    };
+
+    let _ = match Ok::<_, ()>(&1) {
+        _x => None,
+        Ok(v) => Some(v),
+    };
+
+    let _ = match Ok::<_, std::convert::Infallible>(1) {
+        Ok(3) => None,
+        Ok(v) => Some(v),
+    };
+}
+
+const fn cf(x: Result<u32, &'static str>) -> Option<u32> {
+    // Do not lint in const code
+    match x {
+        Ok(v) => Some(v),
+        Err(_) => None,
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_ok_err.rs b/src/tools/clippy/tests/ui/manual_ok_err.rs
new file mode 100644
index 00000000000..03ad773f47c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_ok_err.rs
@@ -0,0 +1,125 @@
+#![warn(clippy::manual_ok_err)]
+
+fn funcall() -> Result<u32, &'static str> {
+    todo!()
+}
+
+fn main() {
+    let _ = match funcall() {
+        //~^ manual_ok_err
+        Ok(v) => Some(v),
+        Err(_) => None,
+    };
+
+    let _ = match funcall() {
+        //~^ manual_ok_err
+        Ok(v) => Some(v),
+        _v => None,
+    };
+
+    let _ = match funcall() {
+        //~^ manual_ok_err
+        Err(v) => Some(v),
+        Ok(_) => None,
+    };
+
+    let _ = match funcall() {
+        //~^ manual_ok_err
+        Err(v) => Some(v),
+        _v => None,
+    };
+
+    let _ = if let Ok(v) = funcall() {
+        //~^ manual_ok_err
+        Some(v)
+    } else {
+        None
+    };
+
+    let _ = if let Err(v) = funcall() {
+        //~^ manual_ok_err
+        Some(v)
+    } else {
+        None
+    };
+
+    #[allow(clippy::redundant_pattern)]
+    let _ = match funcall() {
+        //~^ manual_ok_err
+        Ok(v) => Some(v),
+        _v @ _ => None,
+    };
+
+    struct S;
+
+    impl std::ops::Neg for S {
+        type Output = Result<u32, &'static str>;
+
+        fn neg(self) -> Self::Output {
+            funcall()
+        }
+    }
+
+    // Suggestion should be properly parenthesized
+    let _ = match -S {
+        //~^ manual_ok_err
+        Ok(v) => Some(v),
+        _ => None,
+    };
+
+    no_lint();
+}
+
+fn no_lint() {
+    let _ = match funcall() {
+        Ok(v) if v > 3 => Some(v),
+        _ => None,
+    };
+
+    let _ = match funcall() {
+        Err(_) => None,
+        Ok(3) => None,
+        Ok(v) => Some(v),
+    };
+
+    let _ = match funcall() {
+        _ => None,
+        Ok(v) => Some(v),
+    };
+
+    let _ = match funcall() {
+        Err(_) | Ok(3) => None,
+        Ok(v) => Some(v),
+    };
+
+    #[expect(clippy::redundant_pattern)]
+    let _ = match funcall() {
+        _v @ _ => None,
+        Ok(v) => Some(v),
+    };
+
+    // Content of `Option` and matching content of `Result` do
+    // not have the same type.
+    let _: Option<&dyn std::any::Any> = match Ok::<_, ()>(&1) {
+        Ok(v) => Some(v),
+        _ => None,
+    };
+
+    let _ = match Ok::<_, ()>(&1) {
+        _x => None,
+        Ok(v) => Some(v),
+    };
+
+    let _ = match Ok::<_, std::convert::Infallible>(1) {
+        Ok(3) => None,
+        Ok(v) => Some(v),
+    };
+}
+
+const fn cf(x: Result<u32, &'static str>) -> Option<u32> {
+    // Do not lint in const code
+    match x {
+        Ok(v) => Some(v),
+        Err(_) => None,
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_ok_err.stderr b/src/tools/clippy/tests/ui/manual_ok_err.stderr
new file mode 100644
index 00000000000..d0d5e2c81e9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_ok_err.stderr
@@ -0,0 +1,95 @@
+error: manual implementation of `ok`
+  --> tests/ui/manual_ok_err.rs:8:13
+   |
+LL |       let _ = match funcall() {
+   |  _____________^
+LL | |
+LL | |         Ok(v) => Some(v),
+LL | |         Err(_) => None,
+LL | |     };
+   | |_____^ help: replace with: `funcall().ok()`
+   |
+   = note: `-D clippy::manual-ok-err` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_ok_err)]`
+
+error: manual implementation of `ok`
+  --> tests/ui/manual_ok_err.rs:14:13
+   |
+LL |       let _ = match funcall() {
+   |  _____________^
+LL | |
+LL | |         Ok(v) => Some(v),
+LL | |         _v => None,
+LL | |     };
+   | |_____^ help: replace with: `funcall().ok()`
+
+error: manual implementation of `err`
+  --> tests/ui/manual_ok_err.rs:20:13
+   |
+LL |       let _ = match funcall() {
+   |  _____________^
+LL | |
+LL | |         Err(v) => Some(v),
+LL | |         Ok(_) => None,
+LL | |     };
+   | |_____^ help: replace with: `funcall().err()`
+
+error: manual implementation of `err`
+  --> tests/ui/manual_ok_err.rs:26:13
+   |
+LL |       let _ = match funcall() {
+   |  _____________^
+LL | |
+LL | |         Err(v) => Some(v),
+LL | |         _v => None,
+LL | |     };
+   | |_____^ help: replace with: `funcall().err()`
+
+error: manual implementation of `ok`
+  --> tests/ui/manual_ok_err.rs:32:13
+   |
+LL |       let _ = if let Ok(v) = funcall() {
+   |  _____________^
+LL | |
+LL | |         Some(v)
+LL | |     } else {
+LL | |         None
+LL | |     };
+   | |_____^ help: replace with: `funcall().ok()`
+
+error: manual implementation of `err`
+  --> tests/ui/manual_ok_err.rs:39:13
+   |
+LL |       let _ = if let Err(v) = funcall() {
+   |  _____________^
+LL | |
+LL | |         Some(v)
+LL | |     } else {
+LL | |         None
+LL | |     };
+   | |_____^ help: replace with: `funcall().err()`
+
+error: manual implementation of `ok`
+  --> tests/ui/manual_ok_err.rs:47:13
+   |
+LL |       let _ = match funcall() {
+   |  _____________^
+LL | |
+LL | |         Ok(v) => Some(v),
+LL | |         _v @ _ => None,
+LL | |     };
+   | |_____^ help: replace with: `funcall().ok()`
+
+error: manual implementation of `ok`
+  --> tests/ui/manual_ok_err.rs:64:13
+   |
+LL |       let _ = match -S {
+   |  _____________^
+LL | |
+LL | |         Ok(v) => Some(v),
+LL | |         _ => None,
+LL | |     };
+   | |_____^ help: replace with: `(-S).ok()`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_option_as_slice.fixed b/src/tools/clippy/tests/ui/manual_option_as_slice.fixed
new file mode 100644
index 00000000000..48337d7654d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_option_as_slice.fixed
@@ -0,0 +1,62 @@
+#![warn(clippy::manual_option_as_slice)]
+#![allow(clippy::redundant_closure, clippy::unwrap_or_default)]
+
+fn check(x: Option<u32>) {
+    _ = x.as_slice();
+
+    _ = x.as_slice();
+
+    _ = x.as_slice();
+    //~^ manual_option_as_slice
+
+    _ = x.as_slice();
+    //~^ manual_option_as_slice
+
+    _ = x.as_slice();
+    //~^ manual_option_as_slice
+
+    _ = x.as_slice();
+    //~^ manual_option_as_slice
+
+    {
+        use std::slice::from_ref;
+        _ = x.as_slice();
+        //~^ manual_option_as_slice
+    }
+
+    // possible false positives
+    let y = x.as_ref();
+    _ = match y {
+        // as_ref outside
+        Some(f) => &[f][..],
+        None => &[][..],
+    };
+    _ = match x.as_ref() {
+        Some(f) => std::slice::from_ref(f),
+        None => &[0],
+    };
+    _ = match x.as_ref() {
+        Some(42) => &[23],
+        Some(f) => std::slice::from_ref(f),
+        None => &[],
+    };
+    let b = &[42];
+    _ = if let Some(_f) = x.as_ref() {
+        std::slice::from_ref(b)
+    } else {
+        &[]
+    };
+    _ = x.as_ref().map_or(&[42][..], std::slice::from_ref);
+    _ = x.as_ref().map_or_else(|| &[42][..1], std::slice::from_ref);
+    _ = x.as_ref().map(|f| std::slice::from_ref(f)).unwrap_or_default();
+}
+
+#[clippy::msrv = "1.74"]
+fn check_msrv(x: Option<u32>) {
+    _ = x.as_ref().map_or(&[][..], std::slice::from_ref);
+}
+
+fn main() {
+    check(Some(1));
+    check_msrv(Some(175));
+}
diff --git a/src/tools/clippy/tests/ui/manual_option_as_slice.rs b/src/tools/clippy/tests/ui/manual_option_as_slice.rs
new file mode 100644
index 00000000000..561a8b53401
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_option_as_slice.rs
@@ -0,0 +1,71 @@
+#![warn(clippy::manual_option_as_slice)]
+#![allow(clippy::redundant_closure, clippy::unwrap_or_default)]
+
+fn check(x: Option<u32>) {
+    _ = match x.as_ref() {
+        //~^ manual_option_as_slice
+        Some(f) => std::slice::from_ref(f),
+        None => &[],
+    };
+
+    _ = if let Some(f) = x.as_ref() {
+        //~^ manual_option_as_slice
+        std::slice::from_ref(f)
+    } else {
+        &[]
+    };
+
+    _ = x.as_ref().map_or(&[][..], std::slice::from_ref);
+    //~^ manual_option_as_slice
+
+    _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref);
+    //~^ manual_option_as_slice
+
+    _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default();
+    //~^ manual_option_as_slice
+
+    _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref);
+    //~^ manual_option_as_slice
+
+    {
+        use std::slice::from_ref;
+        _ = x.as_ref().map_or_else(<&[_]>::default, from_ref);
+        //~^ manual_option_as_slice
+    }
+
+    // possible false positives
+    let y = x.as_ref();
+    _ = match y {
+        // as_ref outside
+        Some(f) => &[f][..],
+        None => &[][..],
+    };
+    _ = match x.as_ref() {
+        Some(f) => std::slice::from_ref(f),
+        None => &[0],
+    };
+    _ = match x.as_ref() {
+        Some(42) => &[23],
+        Some(f) => std::slice::from_ref(f),
+        None => &[],
+    };
+    let b = &[42];
+    _ = if let Some(_f) = x.as_ref() {
+        std::slice::from_ref(b)
+    } else {
+        &[]
+    };
+    _ = x.as_ref().map_or(&[42][..], std::slice::from_ref);
+    _ = x.as_ref().map_or_else(|| &[42][..1], std::slice::from_ref);
+    _ = x.as_ref().map(|f| std::slice::from_ref(f)).unwrap_or_default();
+}
+
+#[clippy::msrv = "1.74"]
+fn check_msrv(x: Option<u32>) {
+    _ = x.as_ref().map_or(&[][..], std::slice::from_ref);
+}
+
+fn main() {
+    check(Some(1));
+    check_msrv(Some(175));
+}
diff --git a/src/tools/clippy/tests/ui/manual_option_as_slice.stderr b/src/tools/clippy/tests/ui/manual_option_as_slice.stderr
new file mode 100644
index 00000000000..569269d3e2b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_option_as_slice.stderr
@@ -0,0 +1,58 @@
+error: use `Option::as_slice`
+  --> tests/ui/manual_option_as_slice.rs:5:9
+   |
+LL |       _ = match x.as_ref() {
+   |  _________^
+LL | |
+LL | |         Some(f) => std::slice::from_ref(f),
+LL | |         None => &[],
+LL | |     };
+   | |_____^ help: use: `x.as_slice()`
+   |
+   = note: `-D clippy::manual-option-as-slice` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_option_as_slice)]`
+
+error: use `Option::as_slice`
+  --> tests/ui/manual_option_as_slice.rs:11:9
+   |
+LL |       _ = if let Some(f) = x.as_ref() {
+   |  _________^
+LL | |
+LL | |         std::slice::from_ref(f)
+LL | |     } else {
+LL | |         &[]
+LL | |     };
+   | |_____^ help: use: `x.as_slice()`
+
+error: use `Option::as_slice`
+  --> tests/ui/manual_option_as_slice.rs:18:9
+   |
+LL |     _ = x.as_ref().map_or(&[][..], std::slice::from_ref);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
+
+error: use `Option::as_slice`
+  --> tests/ui/manual_option_as_slice.rs:21:9
+   |
+LL |     _ = x.as_ref().map_or_else(Default::default, std::slice::from_ref);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
+
+error: use `Option::as_slice`
+  --> tests/ui/manual_option_as_slice.rs:24:9
+   |
+LL |     _ = x.as_ref().map(std::slice::from_ref).unwrap_or_default();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
+
+error: use `Option::as_slice`
+  --> tests/ui/manual_option_as_slice.rs:27:9
+   |
+LL |     _ = x.as_ref().map_or_else(|| &[42][..0], std::slice::from_ref);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
+
+error: use `Option::as_slice`
+  --> tests/ui/manual_option_as_slice.rs:32:13
+   |
+LL |         _ = x.as_ref().map_or_else(<&[_]>::default, from_ref);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.as_slice()`
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_repeat_n.fixed b/src/tools/clippy/tests/ui/manual_repeat_n.fixed
new file mode 100644
index 00000000000..4235b02a89e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_repeat_n.fixed
@@ -0,0 +1,30 @@
+#![warn(clippy::manual_repeat_n)]
+
+use std::iter::repeat;
+
+fn main() {
+    let _ = std::iter::repeat_n(10, 3);
+
+    let _ = std::iter::repeat_n(String::from("foo"), 4);
+
+    for value in std::iter::repeat_n(5, 3) {}
+
+    let _: Vec<_> = std::iter::repeat_n(String::from("bar"), 10).collect();
+
+    let _ = std::iter::repeat_n(vec![1, 2], 2);
+}
+
+mod foo_lib {
+    pub fn iter() -> std::iter::Take<std::iter::Repeat<&'static [u8]>> {
+        todo!()
+    }
+}
+
+fn foo() {
+    let _ = match 1 {
+        1 => foo_lib::iter(),
+        // Shouldn't lint because `external_lib::iter` doesn't return `std::iter::RepeatN`.
+        2 => std::iter::repeat([1, 2].as_slice()).take(2),
+        _ => todo!(),
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_repeat_n.rs b/src/tools/clippy/tests/ui/manual_repeat_n.rs
new file mode 100644
index 00000000000..dbf9ac6a14a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_repeat_n.rs
@@ -0,0 +1,30 @@
+#![warn(clippy::manual_repeat_n)]
+
+use std::iter::repeat;
+
+fn main() {
+    let _ = repeat(10).take(3);
+
+    let _ = repeat(String::from("foo")).take(4);
+
+    for value in std::iter::repeat(5).take(3) {}
+
+    let _: Vec<_> = std::iter::repeat(String::from("bar")).take(10).collect();
+
+    let _ = repeat(vec![1, 2]).take(2);
+}
+
+mod foo_lib {
+    pub fn iter() -> std::iter::Take<std::iter::Repeat<&'static [u8]>> {
+        todo!()
+    }
+}
+
+fn foo() {
+    let _ = match 1 {
+        1 => foo_lib::iter(),
+        // Shouldn't lint because `external_lib::iter` doesn't return `std::iter::RepeatN`.
+        2 => std::iter::repeat([1, 2].as_slice()).take(2),
+        _ => todo!(),
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_repeat_n.stderr b/src/tools/clippy/tests/ui/manual_repeat_n.stderr
new file mode 100644
index 00000000000..87395b3f8bf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_repeat_n.stderr
@@ -0,0 +1,35 @@
+error: this `repeat().take()` can be written more concisely
+  --> tests/ui/manual_repeat_n.rs:6:13
+   |
+LL |     let _ = repeat(10).take(3);
+   |             ^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(10, 3)`
+   |
+   = note: `-D clippy::manual-repeat-n` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_repeat_n)]`
+
+error: this `repeat().take()` can be written more concisely
+  --> tests/ui/manual_repeat_n.rs:8:13
+   |
+LL |     let _ = repeat(String::from("foo")).take(4);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(String::from("foo"), 4)`
+
+error: this `repeat().take()` can be written more concisely
+  --> tests/ui/manual_repeat_n.rs:10:18
+   |
+LL |     for value in std::iter::repeat(5).take(3) {}
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(5, 3)`
+
+error: this `repeat().take()` can be written more concisely
+  --> tests/ui/manual_repeat_n.rs:12:21
+   |
+LL |     let _: Vec<_> = std::iter::repeat(String::from("bar")).take(10).collect();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(String::from("bar"), 10)`
+
+error: this `repeat().take()` can be written more concisely
+  --> tests/ui/manual_repeat_n.rs:14:13
+   |
+LL |     let _ = repeat(vec![1, 2]).take(2);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `repeat_n()` instead: `std::iter::repeat_n(vec![1, 2], 2)`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_slice_fill.fixed b/src/tools/clippy/tests/ui/manual_slice_fill.fixed
new file mode 100644
index 00000000000..397a156a2dc
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_slice_fill.fixed
@@ -0,0 +1,101 @@
+#![warn(clippy::manual_slice_fill)]
+#![allow(clippy::needless_range_loop)]
+
+macro_rules! assign_element {
+    ($slice:ident, $index:expr) => {
+        $slice[$index] = 0;
+    };
+}
+
+macro_rules! assign_element_2 {
+    ($i:expr) => {
+        $i = 0;
+    };
+}
+
+struct NoClone;
+
+fn num() -> usize {
+    5
+}
+
+fn should_lint() {
+    let mut some_slice = [1, 2, 3, 4, 5];
+
+    some_slice.fill(0);
+
+    let x = 5;
+    some_slice.fill(x);
+
+    some_slice.fill(0);
+
+    // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments
+    // within the loop might be purely informational.
+    some_slice.fill(0);
+}
+
+fn should_not_lint() {
+    let mut some_slice = [1, 2, 3, 4, 5];
+
+    // Should not lint because we can't determine if the scope of the loop is intended to access all the
+    // elements of the slice.
+    for i in 0..5 {
+        some_slice[i] = 0;
+    }
+
+    // Should not lint, as using a function to assign values to elements might be
+    // intentional. For example, the contents of `num()` could be temporary and subject to change
+    // later.
+    for i in 0..some_slice.len() {
+        some_slice[i] = num();
+    }
+
+    // Should not lint because this loop isn't equivalent to `fill`.
+    for i in 0..some_slice.len() {
+        some_slice[i] = 0;
+        println!("foo");
+    }
+
+    // Should not lint because it may be intentional to use a macro to perform an operation equivalent
+    // to `fill`.
+    for i in 0..some_slice.len() {
+        assign_element!(some_slice, i);
+    }
+
+    let another_slice = [1, 2, 3];
+    // Should not lint because the range is not for `some_slice`.
+    for i in 0..another_slice.len() {
+        some_slice[i] = 0;
+    }
+
+    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);
+    // Should not lint because `NoClone` does not have `Clone` trait.
+    for i in 0..vec.len() {
+        vec[i] = None;
+    }
+
+    // Should not lint, as using a function to assign values to elements might be
+    // intentional. For example, the contents of `num()` could be temporary and subject to change
+    // later.
+    for i in &mut some_slice {
+        *i = num();
+    }
+
+    // Should not lint because this loop isn't equivalent to `fill`.
+    for i in &mut some_slice {
+        *i = 0;
+        println!("foo");
+    }
+
+    // Should not lint because it may be intentional to use a macro to perform an operation equivalent
+    // to `fill`.
+    for i in &mut some_slice {
+        assign_element_2!(*i);
+    }
+
+    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);
+    // Should not lint because `NoClone` does not have `Clone` trait.
+    for i in &mut vec {
+        *i = None;
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_slice_fill.rs b/src/tools/clippy/tests/ui/manual_slice_fill.rs
new file mode 100644
index 00000000000..c25127ca613
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_slice_fill.rs
@@ -0,0 +1,110 @@
+#![warn(clippy::manual_slice_fill)]
+#![allow(clippy::needless_range_loop)]
+
+macro_rules! assign_element {
+    ($slice:ident, $index:expr) => {
+        $slice[$index] = 0;
+    };
+}
+
+macro_rules! assign_element_2 {
+    ($i:expr) => {
+        $i = 0;
+    };
+}
+
+struct NoClone;
+
+fn num() -> usize {
+    5
+}
+
+fn should_lint() {
+    let mut some_slice = [1, 2, 3, 4, 5];
+
+    for i in 0..some_slice.len() {
+        some_slice[i] = 0;
+    }
+
+    let x = 5;
+    for i in 0..some_slice.len() {
+        some_slice[i] = x;
+    }
+
+    for i in &mut some_slice {
+        *i = 0;
+    }
+
+    // This should trigger `manual_slice_fill`, but the applicability is `MaybeIncorrect` since comments
+    // within the loop might be purely informational.
+    for i in 0..some_slice.len() {
+        some_slice[i] = 0;
+        // foo
+    }
+}
+
+fn should_not_lint() {
+    let mut some_slice = [1, 2, 3, 4, 5];
+
+    // Should not lint because we can't determine if the scope of the loop is intended to access all the
+    // elements of the slice.
+    for i in 0..5 {
+        some_slice[i] = 0;
+    }
+
+    // Should not lint, as using a function to assign values to elements might be
+    // intentional. For example, the contents of `num()` could be temporary and subject to change
+    // later.
+    for i in 0..some_slice.len() {
+        some_slice[i] = num();
+    }
+
+    // Should not lint because this loop isn't equivalent to `fill`.
+    for i in 0..some_slice.len() {
+        some_slice[i] = 0;
+        println!("foo");
+    }
+
+    // Should not lint because it may be intentional to use a macro to perform an operation equivalent
+    // to `fill`.
+    for i in 0..some_slice.len() {
+        assign_element!(some_slice, i);
+    }
+
+    let another_slice = [1, 2, 3];
+    // Should not lint because the range is not for `some_slice`.
+    for i in 0..another_slice.len() {
+        some_slice[i] = 0;
+    }
+
+    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);
+    // Should not lint because `NoClone` does not have `Clone` trait.
+    for i in 0..vec.len() {
+        vec[i] = None;
+    }
+
+    // Should not lint, as using a function to assign values to elements might be
+    // intentional. For example, the contents of `num()` could be temporary and subject to change
+    // later.
+    for i in &mut some_slice {
+        *i = num();
+    }
+
+    // Should not lint because this loop isn't equivalent to `fill`.
+    for i in &mut some_slice {
+        *i = 0;
+        println!("foo");
+    }
+
+    // Should not lint because it may be intentional to use a macro to perform an operation equivalent
+    // to `fill`.
+    for i in &mut some_slice {
+        assign_element_2!(*i);
+    }
+
+    let mut vec: Vec<Option<NoClone>> = Vec::with_capacity(5);
+    // Should not lint because `NoClone` does not have `Clone` trait.
+    for i in &mut vec {
+        *i = None;
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_slice_fill.stderr b/src/tools/clippy/tests/ui/manual_slice_fill.stderr
new file mode 100644
index 00000000000..3aa980f6919
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_slice_fill.stderr
@@ -0,0 +1,38 @@
+error: manually filling a slice
+  --> tests/ui/manual_slice_fill.rs:25:5
+   |
+LL | /     for i in 0..some_slice.len() {
+LL | |         some_slice[i] = 0;
+LL | |     }
+   | |_____^ help: try: `some_slice.fill(0);`
+   |
+   = note: `-D clippy::manual-slice-fill` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_slice_fill)]`
+
+error: manually filling a slice
+  --> tests/ui/manual_slice_fill.rs:30:5
+   |
+LL | /     for i in 0..some_slice.len() {
+LL | |         some_slice[i] = x;
+LL | |     }
+   | |_____^ help: try: `some_slice.fill(x);`
+
+error: manually filling a slice
+  --> tests/ui/manual_slice_fill.rs:34:5
+   |
+LL | /     for i in &mut some_slice {
+LL | |         *i = 0;
+LL | |     }
+   | |_____^ help: try: `some_slice.fill(0);`
+
+error: manually filling a slice
+  --> tests/ui/manual_slice_fill.rs:40:5
+   |
+LL | /     for i in 0..some_slice.len() {
+LL | |         some_slice[i] = 0;
+LL | |         // foo
+LL | |     }
+   | |_____^ help: try: `some_slice.fill(0);`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.fixed b/src/tools/clippy/tests/ui/manual_str_repeat.fixed
index 5f2f1bd9916..da6f36f53b0 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.fixed
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.fixed
@@ -1,4 +1,4 @@
-#![allow(non_local_definitions)]
+#![allow(non_local_definitions, clippy::manual_repeat_n)]
 #![warn(clippy::manual_str_repeat)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/manual_str_repeat.rs b/src/tools/clippy/tests/ui/manual_str_repeat.rs
index 3e3c7f4db4a..686ed4fee7d 100644
--- a/src/tools/clippy/tests/ui/manual_str_repeat.rs
+++ b/src/tools/clippy/tests/ui/manual_str_repeat.rs
@@ -1,4 +1,4 @@
-#![allow(non_local_definitions)]
+#![allow(non_local_definitions, clippy::manual_repeat_n)]
 #![warn(clippy::manual_str_repeat)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.rs b/src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.rs
new file mode 100644
index 00000000000..acc54b52816
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.rs
@@ -0,0 +1,15 @@
+//@no-rustfix
+fn issue_12670() {
+    // no auto: type not found
+    #[allow(clippy::match_result_ok)]
+    let _ = if let Some(x) = "1".parse().ok() {
+        x
+    } else {
+        i32::default()
+    };
+    let _ = if let Some(x) = None { x } else { i32::default() };
+    // auto fix with unwrap_or_default
+    let a: Option<i32> = None;
+    let _ = if let Some(x) = a { x } else { i32::default() };
+    let _ = if let Some(x) = Some(99) { x } else { i32::default() };
+}
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.stderr b/src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.stderr
new file mode 100644
index 00000000000..3849d33cf25
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or_default_unfixable.stderr
@@ -0,0 +1,34 @@
+error: if let can be simplified with `.unwrap_or_default()`
+  --> tests/ui/manual_unwrap_or_default_unfixable.rs:5:13
+   |
+LL |       let _ = if let Some(x) = "1".parse().ok() {
+   |  _____________^
+LL | |         x
+LL | |     } else {
+LL | |         i32::default()
+LL | |     };
+   | |_____^ help: ascribe the type i32 and replace your expression with: `"1".parse().ok().unwrap_or_default()`
+   |
+   = note: `-D clippy::manual-unwrap-or-default` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_unwrap_or_default)]`
+
+error: if let can be simplified with `.unwrap_or_default()`
+  --> tests/ui/manual_unwrap_or_default_unfixable.rs:10:13
+   |
+LL |     let _ = if let Some(x) = None { x } else { i32::default() };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `None::<i32>.unwrap_or_default()`
+
+error: if let can be simplified with `.unwrap_or_default()`
+  --> tests/ui/manual_unwrap_or_default_unfixable.rs:13:13
+   |
+LL |     let _ = if let Some(x) = a { x } else { i32::default() };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.unwrap_or_default()`
+
+error: if let can be simplified with `.unwrap_or_default()`
+  --> tests/ui/manual_unwrap_or_default_unfixable.rs:14:13
+   |
+LL |     let _ = if let Some(x) = Some(99) { x } else { i32::default() };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(99).unwrap_or_default()`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/map_all_any_identity.stderr b/src/tools/clippy/tests/ui/map_all_any_identity.stderr
index 98fdcc2a939..39df2a3d961 100644
--- a/src/tools/clippy/tests/ui/map_all_any_identity.stderr
+++ b/src/tools/clippy/tests/ui/map_all_any_identity.stderr
@@ -8,8 +8,9 @@ LL |     let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a);
    = help: to override `-D warnings` add `#[allow(clippy::map_all_any_identity)]`
 help: use `.any(...)` instead
    |
-LL |     let _ = ["foo"].into_iter().any(|s| s == "foo");
-   |                                 ~~~~~~~~~~~~~~~~~~~
+LL -     let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a);
+LL +     let _ = ["foo"].into_iter().any(|s| s == "foo");
+   |
 
 error: usage of `.map(...).all(identity)`
   --> tests/ui/map_all_any_identity.rs:6:33
@@ -19,8 +20,9 @@ LL |     let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::ident
    |
 help: use `.all(...)` instead
    |
-LL |     let _ = ["foo"].into_iter().all(|s| s == "foo");
-   |                                 ~~~~~~~~~~~~~~~~~~~
+LL -     let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity);
+LL +     let _ = ["foo"].into_iter().all(|s| s == "foo");
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed
index cf520e71a64..18716e93d1e 100644
--- a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.fixed
@@ -14,7 +14,7 @@ fn do_something_interesting(x: usize, y: usize) -> usize {
     todo!()
 }
 
-macro_rules! gen {
+macro_rules! r#gen {
     () => {
         (0..10).map(|_| do_something());
     };
@@ -45,7 +45,7 @@ fn main() {
     std::iter::repeat_with(|| do_something()).take(1);
     std::iter::repeat_with(|| do_something()).take((1 << 4) - 0);
     // These should not be raised
-    gen!();
+    r#gen!();
     let lower = 2;
     let lower_fn = || 2;
     (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs
index 298eee9ca3f..596afd51e61 100644
--- a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.rs
@@ -14,7 +14,7 @@ fn do_something_interesting(x: usize, y: usize) -> usize {
     todo!()
 }
 
-macro_rules! gen {
+macro_rules! r#gen {
     () => {
         (0..10).map(|_| do_something());
     };
@@ -45,7 +45,7 @@ fn main() {
     (9..=9).map(|_| do_something());
     (1..=1 << 4).map(|_| do_something());
     // These should not be raised
-    gen!();
+    r#gen!();
     let lower = 2;
     let lower_fn = || 2;
     (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr
index 0b56c6d9521..840515f95df 100644
--- a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges.stderr
@@ -68,8 +68,9 @@ LL |     (0..10).map(|_| 3);
    |
 help: remove the explicit range and use `repeat_n`
    |
-LL |     std::iter::repeat_n(3, 10);
-   |     ~~~~~~~~~~~~~~~~~~~ ~~~~~
+LL -     (0..10).map(|_| 3);
+LL +     std::iter::repeat_n(3, 10);
+   |
 
 error: map of a closure that does not depend on its parameter over a range
   --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5
@@ -216,8 +217,9 @@ LL |     (0..10).map(|_| 3);
    |
 help: remove the explicit range and use `repeat` and `take`
    |
-LL |     std::iter::repeat(3).take(10);
-   |     ~~~~~~~~~~~~~~~~~ ~ +++++++++
+LL -     (0..10).map(|_| 3);
+LL +     std::iter::repeat(3).take(10);
+   |
 
 error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed
new file mode 100644
index 00000000000..65e59774905
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.fixed
@@ -0,0 +1,8 @@
+#![warn(clippy::map_with_unused_argument_over_ranges)]
+#![no_std]
+extern crate alloc;
+use alloc::vec::Vec;
+
+fn nostd(v: &mut [i32]) {
+    let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect();
+}
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.rs b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.rs
new file mode 100644
index 00000000000..dda7a69b33f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.rs
@@ -0,0 +1,8 @@
+#![warn(clippy::map_with_unused_argument_over_ranges)]
+#![no_std]
+extern crate alloc;
+use alloc::vec::Vec;
+
+fn nostd(v: &mut [i32]) {
+    let _: Vec<_> = (0..10).map(|_| 3 + 1).collect();
+}
diff --git a/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr
new file mode 100644
index 00000000000..975ded83560
--- /dev/null
+++ b/src/tools/clippy/tests/ui/map_with_unused_argument_over_ranges_nostd.stderr
@@ -0,0 +1,16 @@
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges_nostd.rs:7:21
+   |
+LL |     let _: Vec<_> = (0..10).map(|_| 3 + 1).collect();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::map-with-unused-argument-over-ranges` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::map_with_unused_argument_over_ranges)]`
+help: remove the explicit range and use `repeat_n`
+   |
+LL -     let _: Vec<_> = (0..10).map(|_| 3 + 1).collect();
+LL +     let _: Vec<_> = core::iter::repeat_n(3 + 1, 10).collect();
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/match_bool.fixed b/src/tools/clippy/tests/ui/match_bool.fixed
new file mode 100644
index 00000000000..61a8e54fa10
--- /dev/null
+++ b/src/tools/clippy/tests/ui/match_bool.fixed
@@ -0,0 +1,58 @@
+#![deny(clippy::match_bool)]
+#![allow(clippy::nonminimal_bool, clippy::eq_op)]
+
+fn match_bool() {
+    let test: bool = true;
+
+    if test { 0 } else { 42 };
+
+    let option = 1;
+    if option == 1 { 1 } else { 0 };
+
+    if !test {
+        println!("Noooo!");
+    };
+
+    if !test {
+        println!("Noooo!");
+    };
+
+    if !(test && test) {
+        println!("Noooo!");
+    };
+
+    if !test {
+        println!("Noooo!");
+    } else {
+        println!("Yes!");
+    };
+
+    // Not linted
+    match option {
+        1..=10 => 1,
+        11..=20 => 2,
+        _ => 3,
+    };
+
+    // Don't lint
+    let _ = match test {
+        #[cfg(feature = "foo")]
+        true if option == 5 => 10,
+        true => 0,
+        false => 1,
+    };
+
+    let _ = if test && option == 5 { 10 } else { 1 };
+
+    let _ = if !test && option == 5 { 10 } else { 1 };
+
+    if test && option == 5 { println!("Hello") };
+
+    if !(test && option == 5) { println!("Hello") };
+
+    if !test && option == 5 { println!("Hello") };
+
+    if !(!test && option == 5) { println!("Hello") };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/match_bool.rs b/src/tools/clippy/tests/ui/match_bool.rs
index f84af393e47..9c81d291786 100644
--- a/src/tools/clippy/tests/ui/match_bool.rs
+++ b/src/tools/clippy/tests/ui/match_bool.rs
@@ -1,24 +1,24 @@
-//@no-rustfix: overlapping suggestions
 #![deny(clippy::match_bool)]
+#![allow(clippy::nonminimal_bool, clippy::eq_op)]
 
 fn match_bool() {
     let test: bool = true;
 
     match test {
-        //~^ ERROR: you seem to be trying to match on a boolean expression
+        //~^ ERROR: `match` on a boolean expression
         true => 0,
         false => 42,
     };
 
     let option = 1;
     match option == 1 {
-        //~^ ERROR: you seem to be trying to match on a boolean expression
+        //~^ ERROR: `match` on a boolean expression
         true => 1,
         false => 0,
     };
 
     match test {
-        //~^ ERROR: you seem to be trying to match on a boolean expression
+        //~^ ERROR: `match` on a boolean expression
         true => (),
         false => {
             println!("Noooo!");
@@ -26,7 +26,7 @@ fn match_bool() {
     };
 
     match test {
-        //~^ ERROR: you seem to be trying to match on a boolean expression
+        //~^ ERROR: `match` on a boolean expression
         false => {
             println!("Noooo!");
         },
@@ -34,11 +34,7 @@ fn match_bool() {
     };
 
     match test && test {
-        //~^ ERROR: this boolean expression can be simplified
-        //~| NOTE: `-D clippy::nonminimal-bool` implied by `-D warnings`
-        //~| ERROR: you seem to be trying to match on a boolean expression
-        //~| ERROR: equal expressions as operands to `&&`
-        //~| NOTE: `#[deny(clippy::eq_op)]` on by default
+        //~^ ERROR: `match` on a boolean expression
         false => {
             println!("Noooo!");
         },
@@ -46,7 +42,7 @@ fn match_bool() {
     };
 
     match test {
-        //~^ ERROR: you seem to be trying to match on a boolean expression
+        //~^ ERROR: `match` on a boolean expression
         false => {
             println!("Noooo!");
         },
@@ -69,6 +65,42 @@ fn match_bool() {
         true => 0,
         false => 1,
     };
+
+    let _ = match test {
+        //~^ ERROR: `match` on a boolean expression
+        true if option == 5 => 10,
+        _ => 1,
+    };
+
+    let _ = match test {
+        //~^ ERROR: `match` on a boolean expression
+        false if option == 5 => 10,
+        _ => 1,
+    };
+
+    match test {
+        //~^ ERROR: `match` on a boolean expression
+        true if option == 5 => println!("Hello"),
+        _ => (),
+    };
+
+    match test {
+        //~^ ERROR: `match` on a boolean expression
+        true if option == 5 => (),
+        _ => println!("Hello"),
+    };
+
+    match test {
+        //~^ ERROR: `match` on a boolean expression
+        false if option == 5 => println!("Hello"),
+        _ => (),
+    };
+
+    match test {
+        //~^ ERROR: `match` on a boolean expression
+        false if option == 5 => (),
+        _ => println!("Hello"),
+    };
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/match_bool.stderr b/src/tools/clippy/tests/ui/match_bool.stderr
index fb24e67ecee..a4e504a0a82 100644
--- a/src/tools/clippy/tests/ui/match_bool.stderr
+++ b/src/tools/clippy/tests/ui/match_bool.stderr
@@ -1,13 +1,4 @@
-error: this boolean expression can be simplified
-  --> tests/ui/match_bool.rs:36:11
-   |
-LL |     match test && test {
-   |           ^^^^^^^^^^^^ help: try: `test`
-   |
-   = note: `-D clippy::nonminimal-bool` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
-
-error: you seem to be trying to match on a boolean expression
+error: `match` on a boolean expression
   --> tests/ui/match_bool.rs:7:5
    |
 LL | /     match test {
@@ -18,12 +9,12 @@ LL | |     };
    | |_____^ help: consider using an `if`/`else` expression: `if test { 0 } else { 42 }`
    |
 note: the lint level is defined here
-  --> tests/ui/match_bool.rs:2:9
+  --> tests/ui/match_bool.rs:1:9
    |
 LL | #![deny(clippy::match_bool)]
    |         ^^^^^^^^^^^^^^^^^^
 
-error: you seem to be trying to match on a boolean expression
+error: `match` on a boolean expression
   --> tests/ui/match_bool.rs:14:5
    |
 LL | /     match option == 1 {
@@ -33,7 +24,7 @@ LL | |         false => 0,
 LL | |     };
    | |_____^ help: consider using an `if`/`else` expression: `if option == 1 { 1 } else { 0 }`
 
-error: you seem to be trying to match on a boolean expression
+error: `match` on a boolean expression
   --> tests/ui/match_bool.rs:20:5
    |
 LL | /     match test {
@@ -52,7 +43,7 @@ LL +         println!("Noooo!");
 LL ~     };
    |
 
-error: you seem to be trying to match on a boolean expression
+error: `match` on a boolean expression
   --> tests/ui/match_bool.rs:28:5
    |
 LL | /     match test {
@@ -71,11 +62,14 @@ LL +         println!("Noooo!");
 LL ~     };
    |
 
-error: you seem to be trying to match on a boolean expression
+error: `match` on a boolean expression
   --> tests/ui/match_bool.rs:36:5
    |
 LL | /     match test && test {
-...  |
+LL | |
+LL | |         false => {
+LL | |             println!("Noooo!");
+LL | |         },
 LL | |         _ => (),
 LL | |     };
    | |_____^
@@ -87,16 +81,8 @@ LL +         println!("Noooo!");
 LL ~     };
    |
 
-error: equal expressions as operands to `&&`
-  --> tests/ui/match_bool.rs:36:11
-   |
-LL |     match test && test {
-   |           ^^^^^^^^^^^^
-   |
-   = note: `#[deny(clippy::eq_op)]` on by default
-
-error: you seem to be trying to match on a boolean expression
-  --> tests/ui/match_bool.rs:48:5
+error: `match` on a boolean expression
+  --> tests/ui/match_bool.rs:44:5
    |
 LL | /     match test {
 LL | |
@@ -109,12 +95,74 @@ LL | |     };
    |
 help: consider using an `if`/`else` expression
    |
-LL ~     if test {
-LL +         println!("Yes!");
-LL +     } else {
+LL ~     if !test {
 LL +         println!("Noooo!");
+LL +     } else {
+LL +         println!("Yes!");
 LL ~     };
    |
 
-error: aborting due to 8 previous errors
+error: `match` on a boolean expression
+  --> tests/ui/match_bool.rs:69:13
+   |
+LL |       let _ = match test {
+   |  _____________^
+LL | |
+LL | |         true if option == 5 => 10,
+LL | |         _ => 1,
+LL | |     };
+   | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { 10 } else { 1 }`
+
+error: `match` on a boolean expression
+  --> tests/ui/match_bool.rs:75:13
+   |
+LL |       let _ = match test {
+   |  _____________^
+LL | |
+LL | |         false if option == 5 => 10,
+LL | |         _ => 1,
+LL | |     };
+   | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { 10 } else { 1 }`
+
+error: `match` on a boolean expression
+  --> tests/ui/match_bool.rs:81:5
+   |
+LL | /     match test {
+LL | |
+LL | |         true if option == 5 => println!("Hello"),
+LL | |         _ => (),
+LL | |     };
+   | |_____^ help: consider using an `if`/`else` expression: `if test && option == 5 { println!("Hello") }`
+
+error: `match` on a boolean expression
+  --> tests/ui/match_bool.rs:87:5
+   |
+LL | /     match test {
+LL | |
+LL | |         true if option == 5 => (),
+LL | |         _ => println!("Hello"),
+LL | |     };
+   | |_____^ help: consider using an `if`/`else` expression: `if !(test && option == 5) { println!("Hello") }`
+
+error: `match` on a boolean expression
+  --> tests/ui/match_bool.rs:93:5
+   |
+LL | /     match test {
+LL | |
+LL | |         false if option == 5 => println!("Hello"),
+LL | |         _ => (),
+LL | |     };
+   | |_____^ help: consider using an `if`/`else` expression: `if !test && option == 5 { println!("Hello") }`
+
+error: `match` on a boolean expression
+  --> tests/ui/match_bool.rs:99:5
+   |
+LL | /     match test {
+LL | |
+LL | |         false if option == 5 => (),
+LL | |         _ => println!("Hello"),
+LL | |     };
+   | |_____^ help: consider using an `if`/`else` expression: `if !(!test && option == 5) { println!("Hello") }`
+
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_result_ok.stderr b/src/tools/clippy/tests/ui/match_result_ok.stderr
index b5b91cbe553..18b23bd7845 100644
--- a/src/tools/clippy/tests/ui/match_result_ok.stderr
+++ b/src/tools/clippy/tests/ui/match_result_ok.stderr
@@ -8,8 +8,9 @@ LL |     if let Some(y) = x.parse().ok() { y } else { 0 }
    = help: to override `-D warnings` add `#[allow(clippy::match_result_ok)]`
 help: consider matching on `Ok(y)` and removing the call to `ok` instead
    |
-LL |     if let Ok(y) = x.parse() { y } else { 0 }
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if let Some(y) = x.parse().ok() { y } else { 0 }
+LL +     if let Ok(y) = x.parse() { y } else { 0 }
+   |
 
 error: matching on `Some` with `ok()` is redundant
   --> tests/ui/match_result_ok.rs:23:9
@@ -19,8 +20,9 @@ LL |         if let Some(y) = x   .   parse()   .   ok   ()    {
    |
 help: consider matching on `Ok(y)` and removing the call to `ok` instead
    |
-LL |         if let Ok(y) = x   .   parse()    {
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -         if let Some(y) = x   .   parse()   .   ok   ()    {
+LL +         if let Ok(y) = x   .   parse()    {
+   |
 
 error: matching on `Some` with `ok()` is redundant
   --> tests/ui/match_result_ok.rs:49:5
@@ -30,8 +32,9 @@ LL |     while let Some(a) = wat.next().ok() {
    |
 help: consider matching on `Ok(a)` and removing the call to `ok` instead
    |
-LL |     while let Ok(a) = wat.next() {
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     while let Some(a) = wat.next().ok() {
+LL +     while let Ok(a) = wat.next() {
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
index 67e9ccaf6d2..5b14fd13a53 100644
--- a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
+++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
@@ -8,8 +8,9 @@ LL |         "Bar" => {},
    = help: to override `-D warnings` add `#[allow(clippy::match_str_case_mismatch)]`
 help: consider changing the case of this arm to respect `to_ascii_lowercase`
    |
-LL |         "bar" => {},
-   |         ~~~~~
+LL -         "Bar" => {},
+LL +         "bar" => {},
+   |
 
 error: this `match` arm has a differing case than its expression
   --> tests/ui/match_str_case_mismatch.rs:122:9
@@ -19,8 +20,9 @@ LL |         "~!@#$%^&*()-_=+Foo" => {},
    |
 help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization difference)
    |
-LL |         "~!@#$%^&*()-_=+foo" => {},
-   |         ~~~~~~~~~~~~~~~~~~~~
+LL -         "~!@#$%^&*()-_=+Foo" => {},
+LL +         "~!@#$%^&*()-_=+foo" => {},
+   |
 
 error: this `match` arm has a differing case than its expression
   --> tests/ui/match_str_case_mismatch.rs:134:9
@@ -30,8 +32,9 @@ LL |         "Воды" => {},
    |
 help: consider changing the case of this arm to respect `to_lowercase`
    |
-LL |         "воды" => {},
-   |         ~~~~~~
+LL -         "Воды" => {},
+LL +         "воды" => {},
+   |
 
 error: this `match` arm has a differing case than its expression
   --> tests/ui/match_str_case_mismatch.rs:145:9
@@ -41,8 +44,9 @@ LL |         "barDz" => {},
    |
 help: consider changing the case of this arm to respect `to_lowercase`
    |
-LL |         "bardz" => {},
-   |         ~~~~~~
+LL -         "barDz" => {},
+LL +         "bardz" => {},
+   |
 
 error: this `match` arm has a differing case than its expression
   --> tests/ui/match_str_case_mismatch.rs:155:9
@@ -52,8 +56,9 @@ LL |         "bARʁ" => {},
    |
 help: consider changing the case of this arm to respect `to_uppercase`
    |
-LL |         "BARʁ" => {},
-   |         ~~~~~~
+LL -         "bARʁ" => {},
+LL +         "BARʁ" => {},
+   |
 
 error: this `match` arm has a differing case than its expression
   --> tests/ui/match_str_case_mismatch.rs:165:9
@@ -63,8 +68,9 @@ LL |         "Bar" => {},
    |
 help: consider changing the case of this arm to respect `to_ascii_lowercase`
    |
-LL |         "bar" => {},
-   |         ~~~~~
+LL -         "Bar" => {},
+LL +         "bar" => {},
+   |
 
 error: this `match` arm has a differing case than its expression
   --> tests/ui/match_str_case_mismatch.rs:180:9
@@ -74,8 +80,9 @@ LL |         "bAR" => {},
    |
 help: consider changing the case of this arm to respect `to_ascii_uppercase`
    |
-LL |         "BAR" => {},
-   |         ~~~~~
+LL -         "bAR" => {},
+LL +         "BAR" => {},
+   |
 
 error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
index fdde68790a8..cdfdcd5007a 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
@@ -210,3 +210,9 @@ mod with_ty_alias {
         let _: Foo = 1;
     }
 }
+
+// Do not lint because mutable references in const functions are unstable in 1.82
+#[clippy::msrv = "1.82"]
+fn mut_add(x: &mut i32) {
+    *x += 1;
+}
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
index dd9dedcdd04..689060468c5 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.fixed
@@ -213,3 +213,8 @@ mod extern_fn {
     const extern "system-unwind" fn system_unwind() {}
     //~^ ERROR: this could be a `const fn`
 }
+
+const fn mut_add(x: &mut i32) {
+    //~^ ERROR: this could be a `const fn`
+    *x += 1;
+}
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
index f974478540c..492c47d7e49 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
@@ -213,3 +213,8 @@ mod extern_fn {
     extern "system-unwind" fn system_unwind() {}
     //~^ ERROR: this could be a `const fn`
 }
+
+fn mut_add(x: &mut i32) {
+    //~^ ERROR: this could be a `const fn`
+    *x += 1;
+}
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
index 33836bdfe9f..a06703e2ebf 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.stderr
@@ -316,5 +316,19 @@ help: make the function `const`
 LL |     const extern "system-unwind" fn system_unwind() {}
    |     +++++
 
-error: aborting due to 24 previous errors
+error: this could be a `const fn`
+  --> tests/ui/missing_const_for_fn/could_be_const.rs:217:1
+   |
+LL | / fn mut_add(x: &mut i32) {
+LL | |
+LL | |     *x += 1;
+LL | | }
+   | |_^
+   |
+help: make the function `const`
+   |
+LL | const fn mut_add(x: &mut i32) {
+   | +++++
+
+error: aborting due to 25 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_as_bytes.fixed b/src/tools/clippy/tests/ui/needless_as_bytes.fixed
index 042342311fd..74b4ba5be79 100644
--- a/src/tools/clippy/tests/ui/needless_as_bytes.fixed
+++ b/src/tools/clippy/tests/ui/needless_as_bytes.fixed
@@ -1,5 +1,6 @@
 #![warn(clippy::needless_as_bytes)]
 #![allow(clippy::const_is_empty)]
+#![feature(exact_size_is_empty)]
 
 struct S;
 
@@ -7,6 +8,9 @@ impl S {
     fn as_bytes(&self) -> &[u8] {
         &[]
     }
+    fn bytes(&self) -> &[u8] {
+        &[]
+    }
 }
 
 fn main() {
@@ -15,6 +19,11 @@ fn main() {
         println!("len = {}", "some string".len());
         //~^ needless_as_bytes
     }
+    if "some string".is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", "some string".len());
+        //~^ needless_as_bytes
+    }
 
     let s = String::from("yet another string");
     if s.is_empty() {
@@ -22,6 +31,11 @@ fn main() {
         println!("len = {}", s.len());
         //~^ needless_as_bytes
     }
+    if s.is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", s.len());
+        //~^ needless_as_bytes
+    }
 
     // Do not lint
     let _ = S.as_bytes().is_empty();
@@ -36,6 +50,18 @@ fn main() {
         };
     }
     m!(1).as_bytes().len();
+    let _ = S.bytes().is_empty();
+    let _ = S.bytes().len();
+    let _ = (&String::new() as &dyn Bytes).bytes().len();
+    macro_rules! m {
+        (1) => {
+            ""
+        };
+        (2) => {
+            "".bytes()
+        };
+    }
+    m!(1).bytes().len();
     m!(2).len();
 }
 
@@ -48,3 +74,13 @@ impl AsBytes for String {
         &[]
     }
 }
+
+pub trait Bytes {
+    fn bytes(&self) -> &[u8];
+}
+
+impl Bytes for String {
+    fn bytes(&self) -> &[u8] {
+        &[]
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_as_bytes.rs b/src/tools/clippy/tests/ui/needless_as_bytes.rs
index c481e041e0a..ffcce60bbbe 100644
--- a/src/tools/clippy/tests/ui/needless_as_bytes.rs
+++ b/src/tools/clippy/tests/ui/needless_as_bytes.rs
@@ -1,5 +1,6 @@
 #![warn(clippy::needless_as_bytes)]
 #![allow(clippy::const_is_empty)]
+#![feature(exact_size_is_empty)]
 
 struct S;
 
@@ -7,6 +8,9 @@ impl S {
     fn as_bytes(&self) -> &[u8] {
         &[]
     }
+    fn bytes(&self) -> &[u8] {
+        &[]
+    }
 }
 
 fn main() {
@@ -15,6 +19,11 @@ fn main() {
         println!("len = {}", "some string".as_bytes().len());
         //~^ needless_as_bytes
     }
+    if "some string".bytes().is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", "some string".bytes().len());
+        //~^ needless_as_bytes
+    }
 
     let s = String::from("yet another string");
     if s.as_bytes().is_empty() {
@@ -22,6 +31,11 @@ fn main() {
         println!("len = {}", s.as_bytes().len());
         //~^ needless_as_bytes
     }
+    if s.bytes().is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", s.bytes().len());
+        //~^ needless_as_bytes
+    }
 
     // Do not lint
     let _ = S.as_bytes().is_empty();
@@ -36,6 +50,18 @@ fn main() {
         };
     }
     m!(1).as_bytes().len();
+    let _ = S.bytes().is_empty();
+    let _ = S.bytes().len();
+    let _ = (&String::new() as &dyn Bytes).bytes().len();
+    macro_rules! m {
+        (1) => {
+            ""
+        };
+        (2) => {
+            "".bytes()
+        };
+    }
+    m!(1).bytes().len();
     m!(2).len();
 }
 
@@ -48,3 +74,13 @@ impl AsBytes for String {
         &[]
     }
 }
+
+pub trait Bytes {
+    fn bytes(&self) -> &[u8];
+}
+
+impl Bytes for String {
+    fn bytes(&self) -> &[u8] {
+        &[]
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_as_bytes.stderr b/src/tools/clippy/tests/ui/needless_as_bytes.stderr
index 3391238a142..138c6630ae7 100644
--- a/src/tools/clippy/tests/ui/needless_as_bytes.stderr
+++ b/src/tools/clippy/tests/ui/needless_as_bytes.stderr
@@ -1,5 +1,5 @@
-error: needless call to `as_bytes()`
-  --> tests/ui/needless_as_bytes.rs:13:8
+error: needless call to `as_bytes`
+  --> tests/ui/needless_as_bytes.rs:17:8
    |
 LL |     if "some string".as_bytes().is_empty() {
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()`
@@ -7,23 +7,47 @@ LL |     if "some string".as_bytes().is_empty() {
    = note: `-D clippy::needless-as-bytes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::needless_as_bytes)]`
 
-error: needless call to `as_bytes()`
-  --> tests/ui/needless_as_bytes.rs:15:30
+error: needless call to `as_bytes`
+  --> tests/ui/needless_as_bytes.rs:19:30
    |
 LL |         println!("len = {}", "some string".as_bytes().len());
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()`
 
-error: needless call to `as_bytes()`
-  --> tests/ui/needless_as_bytes.rs:20:8
+error: needless call to `bytes`
+  --> tests/ui/needless_as_bytes.rs:22:8
+   |
+LL |     if "some string".bytes().is_empty() {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()`
+
+error: needless call to `bytes`
+  --> tests/ui/needless_as_bytes.rs:24:30
+   |
+LL |         println!("len = {}", "some string".bytes().len());
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()`
+
+error: needless call to `as_bytes`
+  --> tests/ui/needless_as_bytes.rs:29:8
    |
 LL |     if s.as_bytes().is_empty() {
    |        ^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`
 
-error: needless call to `as_bytes()`
-  --> tests/ui/needless_as_bytes.rs:22:30
+error: needless call to `as_bytes`
+  --> tests/ui/needless_as_bytes.rs:31:30
    |
 LL |         println!("len = {}", s.as_bytes().len());
    |                              ^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`
 
-error: aborting due to 4 previous errors
+error: needless call to `bytes`
+  --> tests/ui/needless_as_bytes.rs:34:8
+   |
+LL |     if s.bytes().is_empty() {
+   |        ^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`
+
+error: needless call to `bytes`
+  --> tests/ui/needless_as_bytes.rs:36:30
+   |
+LL |         println!("len = {}", s.bytes().len());
+   |                              ^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`
+
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.stderr b/src/tools/clippy/tests/ui/needless_borrow_pat.stderr
index 2ad69449039..035376cabaf 100644
--- a/src/tools/clippy/tests/ui/needless_borrow_pat.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow_pat.stderr
@@ -15,8 +15,9 @@ LL |         Some(ref x) => *x,
    |
 help: try
    |
-LL |         Some(x) => x,
-   |              ~     ~
+LL -         Some(ref x) => *x,
+LL +         Some(x) => x,
+   |
 
 error: this pattern creates a reference to a reference
   --> tests/ui/needless_borrow_pat.rs:74:14
@@ -71,8 +72,9 @@ LL |         E::A(ref x) | E::B(ref x) => *x,
    |
 help: try
    |
-LL |         E::A(x) | E::B(x) => x,
-   |              ~         ~     ~
+LL -         E::A(ref x) | E::B(ref x) => *x,
+LL +         E::A(x) | E::B(x) => x,
+   |
 
 error: this pattern creates a reference to a reference
   --> tests/ui/needless_borrow_pat.rs:126:21
diff --git a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
index 682140a1dfd..722016b1212 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_for_each_unfixable.stderr
@@ -25,8 +25,9 @@ LL +     }
    |
 help: ...and replace `return` with `continue`
    |
-LL |             continue;
-   |             ~~~~~~~~
+LL -             return;
+LL +             continue;
+   |
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed
index 6db87049044..b4bd53ce7bf 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.fixed
+++ b/src/tools/clippy/tests/ui/needless_late_init.fixed
@@ -270,3 +270,14 @@ fn issue8911() -> u32 {
 
     3
 }
+
+macro_rules! issue13776_mac {
+    ($var:expr, $val:literal) => {
+        $var = $val;
+    };
+}
+
+fn issue13776() {
+    let x;
+    issue13776_mac!(x, 10); // should not lint
+}
diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs
index c1e86212a08..e25483625a6 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init.rs
@@ -270,3 +270,14 @@ fn issue8911() -> u32 {
 
     3
 }
+
+macro_rules! issue13776_mac {
+    ($var:expr, $val:literal) => {
+        $var = $val;
+    };
+}
+
+fn issue13776() {
+    let x;
+    issue13776_mac!(x, 10); // should not lint
+}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
index 8196d608abd..86cf9a9cdb6 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
@@ -6,6 +6,7 @@
     clippy::boxed_local,
     clippy::extra_unused_type_parameters,
     clippy::needless_pass_by_value,
+    clippy::redundant_allocation,
     clippy::unnecessary_wraps,
     dyn_drop,
     clippy::get_first
@@ -443,11 +444,20 @@ mod issue7296 {
         fn implicit_mut(&mut self) -> &() {
             &()
         }
-
-        fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
+        #[clippy::msrv = "1.81"]
+        fn explicit(self: &Arc<Self>) -> &() {
+            &()
+        }
+        #[clippy::msrv = "1.81"]
+        fn explicit_mut(self: &mut Rc<Self>) -> &() {
+            &()
+        }
+        #[clippy::msrv = "1.80"]
+        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a () {
             &()
         }
-        fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
+        #[clippy::msrv = "1.80"]
+        fn explicit_mut_older<'a>(self: &'a mut Rc<Self>) -> &'a () {
             &()
         }
 
@@ -462,8 +472,16 @@ mod issue7296 {
             &()
         }
 
-        fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
-        fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
+        #[clippy::msrv = "1.81"]
+        fn explicit(self: &Arc<Self>) -> &();
+        #[clippy::msrv = "1.81"]
+        fn explicit_provided(self: &Arc<Self>) -> &() {
+            &()
+        }
+        #[clippy::msrv = "1.80"]
+        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a ();
+        #[clippy::msrv = "1.80"]
+        fn explicit_provided_older<'a>(self: &'a Arc<Self>) -> &'a () {
             &()
         }
 
@@ -576,4 +594,85 @@ mod issue13749bis {
     impl<'a, T: 'a> Generic<T> {}
 }
 
+mod issue13923 {
+    struct Py<'py> {
+        data: &'py str,
+    }
+
+    enum Content<'t, 'py> {
+        Py(Py<'py>),
+        T1(&'t str),
+        T2(&'t str),
+    }
+
+    enum ContentString<'t> {
+        T1(&'t str),
+        T2(&'t str),
+    }
+
+    impl<'t, 'py> ContentString<'t> {
+        // `'py` cannot be elided
+        fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(content) => Content::T2(f(content)),
+            }
+        }
+    }
+
+    impl<'t> ContentString<'t> {
+        // `'py` can be elided because of `&self`
+        fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(content) => Content::T2(f(content)),
+            }
+        }
+    }
+
+    impl<'t> ContentString<'t> {
+        // `'py` can be elided because of `&'_ self`
+        fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(content) => Content::T2(f(content)),
+            }
+        }
+    }
+
+    impl<'t, 'py> ContentString<'t> {
+        // `'py` should not be elided as the default lifetime, even if working, could be named as `'t`
+        fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(_) => Content::T2(o),
+            }
+        }
+    }
+
+    impl<'t> ContentString<'t> {
+        // `'py` can be elided because of `&Self`
+        fn map_content5(
+            self: std::pin::Pin<&Self>,
+            f: impl FnOnce(&'t str) -> &'t str,
+            o: &'t str,
+        ) -> Content<'t, '_> {
+            match *self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(_) => Content::T2(o),
+            }
+        }
+    }
+
+    struct Cx<'a, 'b> {
+        a: &'a u32,
+        b: &'b u32,
+    }
+
+    // `'c` cannot be elided because we have several input lifetimes
+    fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {
+        x.b
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index b55dd99c46d..1ee0f4c6092 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -6,6 +6,7 @@
     clippy::boxed_local,
     clippy::extra_unused_type_parameters,
     clippy::needless_pass_by_value,
+    clippy::redundant_allocation,
     clippy::unnecessary_wraps,
     dyn_drop,
     clippy::get_first
@@ -443,13 +444,22 @@ mod issue7296 {
         fn implicit_mut<'a>(&'a mut self) -> &'a () {
             &()
         }
-
+        #[clippy::msrv = "1.81"]
         fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
             &()
         }
+        #[clippy::msrv = "1.81"]
         fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
             &()
         }
+        #[clippy::msrv = "1.80"]
+        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a () {
+            &()
+        }
+        #[clippy::msrv = "1.80"]
+        fn explicit_mut_older<'a>(self: &'a mut Rc<Self>) -> &'a () {
+            &()
+        }
 
         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
             &()
@@ -462,10 +472,18 @@ mod issue7296 {
             &()
         }
 
+        #[clippy::msrv = "1.81"]
         fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
+        #[clippy::msrv = "1.81"]
         fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
             &()
         }
+        #[clippy::msrv = "1.80"]
+        fn explicit_older<'a>(self: &'a Arc<Self>) -> &'a ();
+        #[clippy::msrv = "1.80"]
+        fn explicit_provided_older<'a>(self: &'a Arc<Self>) -> &'a () {
+            &()
+        }
 
         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
         fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
@@ -576,4 +594,85 @@ mod issue13749bis {
     impl<'a, T: 'a> Generic<T> {}
 }
 
+mod issue13923 {
+    struct Py<'py> {
+        data: &'py str,
+    }
+
+    enum Content<'t, 'py> {
+        Py(Py<'py>),
+        T1(&'t str),
+        T2(&'t str),
+    }
+
+    enum ContentString<'t> {
+        T1(&'t str),
+        T2(&'t str),
+    }
+
+    impl<'t, 'py> ContentString<'t> {
+        // `'py` cannot be elided
+        fn map_content1(self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(content) => Content::T2(f(content)),
+            }
+        }
+    }
+
+    impl<'t, 'py> ContentString<'t> {
+        // `'py` can be elided because of `&self`
+        fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(content) => Content::T2(f(content)),
+            }
+        }
+    }
+
+    impl<'t, 'py> ContentString<'t> {
+        // `'py` can be elided because of `&'_ self`
+        fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(content) => Content::T2(f(content)),
+            }
+        }
+    }
+
+    impl<'t, 'py> ContentString<'t> {
+        // `'py` should not be elided as the default lifetime, even if working, could be named as `'t`
+        fn map_content4(self, f: impl FnOnce(&'t str) -> &'t str, o: &'t str) -> Content<'t, 'py> {
+            match self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(_) => Content::T2(o),
+            }
+        }
+    }
+
+    impl<'t, 'py> ContentString<'t> {
+        // `'py` can be elided because of `&Self`
+        fn map_content5(
+            self: std::pin::Pin<&Self>,
+            f: impl FnOnce(&'t str) -> &'t str,
+            o: &'t str,
+        ) -> Content<'t, 'py> {
+            match *self {
+                Self::T1(content) => Content::T1(f(content)),
+                Self::T2(_) => Content::T2(o),
+            }
+        }
+    }
+
+    struct Cx<'a, 'b> {
+        a: &'a u32,
+        b: &'b u32,
+    }
+
+    // `'c` cannot be elided because we have several input lifetimes
+    fn one_explicit<'b>(x: Cx<'_, 'b>) -> &'b u32 {
+        &x.b
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index e56c914cc86..465d529bf16 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -1,5 +1,5 @@
 error: elided lifetime has a name
-  --> tests/ui/needless_lifetimes.rs:266:52
+  --> tests/ui/needless_lifetimes.rs:267:52
    |
 LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
    |                              --                    ^ this elided lifetime gets resolved as `'a`
@@ -10,7 +10,7 @@ LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
    = help: to override `-D warnings` add `#[allow(elided_named_lifetimes)]`
 
 error: the following explicit lifetimes could be elided: 'a, 'b
-  --> tests/ui/needless_lifetimes.rs:17:23
+  --> tests/ui/needless_lifetimes.rs:18:23
    |
 LL | fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {}
    |                       ^^  ^^       ^^          ^^
@@ -24,7 +24,7 @@ LL + fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a, 'b
-  --> tests/ui/needless_lifetimes.rs:19:24
+  --> tests/ui/needless_lifetimes.rs:20:24
    |
 LL | fn distinct_and_static<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: &'static u8) {}
    |                        ^^  ^^       ^^          ^^
@@ -36,7 +36,7 @@ LL + fn distinct_and_static(_x: &u8, _y: &u8, _z: &'static u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:29:15
+  --> tests/ui/needless_lifetimes.rs:30:15
    |
 LL | fn in_and_out<'a>(x: &'a u8, _y: u8) -> &'a u8 {
    |               ^^      ^^                 ^^
@@ -48,7 +48,7 @@ LL + fn in_and_out(x: &u8, _y: u8) -> &u8 {
    |
 
 error: the following explicit lifetimes could be elided: 'b
-  --> tests/ui/needless_lifetimes.rs:41:31
+  --> tests/ui/needless_lifetimes.rs:42:31
    |
 LL | fn multiple_in_and_out_2a<'a, 'b>(x: &'a u8, _y: &'b u8) -> &'a u8 {
    |                               ^^                  ^^
@@ -60,7 +60,7 @@ LL + fn multiple_in_and_out_2a<'a>(x: &'a u8, _y: &u8) -> &'a u8 {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:48:27
+  --> tests/ui/needless_lifetimes.rs:49:27
    |
 LL | fn multiple_in_and_out_2b<'a, 'b>(_x: &'a u8, y: &'b u8) -> &'b u8 {
    |                           ^^           ^^
@@ -72,7 +72,7 @@ LL + fn multiple_in_and_out_2b<'b>(_x: &u8, y: &'b u8) -> &'b u8 {
    |
 
 error: the following explicit lifetimes could be elided: 'b
-  --> tests/ui/needless_lifetimes.rs:65:26
+  --> tests/ui/needless_lifetimes.rs:66:26
    |
 LL | fn deep_reference_1a<'a, 'b>(x: &'a u8, _y: &'b u8) -> Result<&'a u8, ()> {
    |                          ^^                  ^^
@@ -84,7 +84,7 @@ LL + fn deep_reference_1a<'a>(x: &'a u8, _y: &u8) -> Result<&'a u8, ()> {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:72:22
+  --> tests/ui/needless_lifetimes.rs:73:22
    |
 LL | fn deep_reference_1b<'a, 'b>(_x: &'a u8, y: &'b u8) -> Result<&'b u8, ()> {
    |                      ^^           ^^
@@ -96,7 +96,7 @@ LL + fn deep_reference_1b<'b>(_x: &u8, y: &'b u8) -> Result<&'b u8, ()> {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:81:21
+  --> tests/ui/needless_lifetimes.rs:82:21
    |
 LL | fn deep_reference_3<'a>(x: &'a u8, _y: u8) -> Result<&'a u8, ()> {
    |                     ^^      ^^                        ^^
@@ -108,7 +108,7 @@ LL + fn deep_reference_3(x: &u8, _y: u8) -> Result<&u8, ()> {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:86:28
+  --> tests/ui/needless_lifetimes.rs:87:28
    |
 LL | fn where_clause_without_lt<'a, T>(x: &'a u8, _y: u8) -> Result<&'a u8, ()>
    |                            ^^         ^^                        ^^
@@ -120,7 +120,7 @@ LL + fn where_clause_without_lt<T>(x: &u8, _y: u8) -> Result<&u8, ()>
    |
 
 error: the following explicit lifetimes could be elided: 'a, 'b
-  --> tests/ui/needless_lifetimes.rs:98:21
+  --> tests/ui/needless_lifetimes.rs:99:21
    |
 LL | fn lifetime_param_2<'a, 'b>(_x: Ref<'a>, _y: &'b u8) {}
    |                     ^^  ^^          ^^        ^^
@@ -132,7 +132,7 @@ LL + fn lifetime_param_2(_x: Ref<'_>, _y: &u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:122:15
+  --> tests/ui/needless_lifetimes.rs:123:15
    |
 LL | fn fn_bound_2<'a, F, I>(_m: Lt<'a, I>, _f: F) -> Lt<'a, I>
    |               ^^               ^^                   ^^
@@ -144,7 +144,7 @@ LL + fn fn_bound_2<F, I>(_m: Lt<'_, I>, _f: F) -> Lt<'_, I>
    |
 
 error: the following explicit lifetimes could be elided: 's
-  --> tests/ui/needless_lifetimes.rs:152:21
+  --> tests/ui/needless_lifetimes.rs:153:21
    |
 LL |     fn self_and_out<'s>(&'s self) -> &'s u8 {
    |                     ^^   ^^           ^^
@@ -156,7 +156,7 @@ LL +     fn self_and_out(&self) -> &u8 {
    |
 
 error: the following explicit lifetimes could be elided: 't
-  --> tests/ui/needless_lifetimes.rs:159:30
+  --> tests/ui/needless_lifetimes.rs:160:30
    |
 LL |     fn self_and_in_out_1<'s, 't>(&'s self, _x: &'t u8) -> &'s u8 {
    |                              ^^                 ^^
@@ -168,7 +168,7 @@ LL +     fn self_and_in_out_1<'s>(&'s self, _x: &u8) -> &'s u8 {
    |
 
 error: the following explicit lifetimes could be elided: 's
-  --> tests/ui/needless_lifetimes.rs:166:26
+  --> tests/ui/needless_lifetimes.rs:167:26
    |
 LL |     fn self_and_in_out_2<'s, 't>(&'s self, x: &'t u8) -> &'t u8 {
    |                          ^^       ^^
@@ -180,7 +180,7 @@ LL +     fn self_and_in_out_2<'t>(&self, x: &'t u8) -> &'t u8 {
    |
 
 error: the following explicit lifetimes could be elided: 's, 't
-  --> tests/ui/needless_lifetimes.rs:170:29
+  --> tests/ui/needless_lifetimes.rs:171:29
    |
 LL |     fn distinct_self_and_in<'s, 't>(&'s self, _x: &'t u8) {}
    |                             ^^  ^^   ^^            ^^
@@ -192,7 +192,7 @@ LL +     fn distinct_self_and_in(&self, _x: &u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:189:19
+  --> tests/ui/needless_lifetimes.rs:190:19
    |
 LL | fn struct_with_lt<'a>(_foo: Foo<'a>) -> &'a str {
    |                   ^^            ^^       ^^
@@ -204,7 +204,7 @@ LL + fn struct_with_lt(_foo: Foo<'_>) -> &str {
    |
 
 error: the following explicit lifetimes could be elided: 'b
-  --> tests/ui/needless_lifetimes.rs:207:25
+  --> tests/ui/needless_lifetimes.rs:208:25
    |
 LL | fn struct_with_lt4a<'a, 'b>(_foo: &'a Foo<'b>) -> &'a str {
    |                         ^^                ^^
@@ -216,7 +216,7 @@ LL + fn struct_with_lt4a<'a>(_foo: &'a Foo<'_>) -> &'a str {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:215:21
+  --> tests/ui/needless_lifetimes.rs:216:21
    |
 LL | fn struct_with_lt4b<'a, 'b>(_foo: &'a Foo<'b>) -> &'b str {
    |                     ^^             ^^
@@ -228,7 +228,7 @@ LL + fn struct_with_lt4b<'b>(_foo: &Foo<'b>) -> &'b str {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:230:22
+  --> tests/ui/needless_lifetimes.rs:231:22
    |
 LL | fn trait_obj_elided2<'a>(_arg: &'a dyn Drop) -> &'a str {
    |                      ^^         ^^               ^^
@@ -240,7 +240,7 @@ LL + fn trait_obj_elided2(_arg: &dyn Drop) -> &str {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:236:18
+  --> tests/ui/needless_lifetimes.rs:237:18
    |
 LL | fn alias_with_lt<'a>(_foo: FooAlias<'a>) -> &'a str {
    |                  ^^                 ^^       ^^
@@ -252,7 +252,7 @@ LL + fn alias_with_lt(_foo: FooAlias<'_>) -> &str {
    |
 
 error: the following explicit lifetimes could be elided: 'b
-  --> tests/ui/needless_lifetimes.rs:254:24
+  --> tests/ui/needless_lifetimes.rs:255:24
    |
 LL | fn alias_with_lt4a<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'a str {
    |                        ^^                     ^^
@@ -264,7 +264,7 @@ LL + fn alias_with_lt4a<'a>(_foo: &'a FooAlias<'_>) -> &'a str {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:262:20
+  --> tests/ui/needless_lifetimes.rs:263:20
    |
 LL | fn alias_with_lt4b<'a, 'b>(_foo: &'a FooAlias<'b>) -> &'b str {
    |                    ^^             ^^
@@ -276,7 +276,7 @@ LL + fn alias_with_lt4b<'b>(_foo: &FooAlias<'b>) -> &'b str {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:266:30
+  --> tests/ui/needless_lifetimes.rs:267:30
    |
 LL | fn named_input_elided_output<'a>(_arg: &'a str) -> &str {
    |                              ^^         ^^          ^
@@ -288,7 +288,7 @@ LL + fn named_input_elided_output(_arg: &str) -> &str {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:274:19
+  --> tests/ui/needless_lifetimes.rs:275:19
    |
 LL | fn trait_bound_ok<'a, T: WithLifetime<'static>>(_: &'a u8, _: T) {
    |                   ^^                                ^^
@@ -300,7 +300,7 @@ LL + fn trait_bound_ok<T: WithLifetime<'static>>(_: &u8, _: T) {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:310:24
+  --> tests/ui/needless_lifetimes.rs:311:24
    |
 LL | fn out_return_type_lts<'a>(e: &'a str) -> Cow<'a> {
    |                        ^^      ^^             ^^
@@ -312,7 +312,7 @@ LL + fn out_return_type_lts(e: &str) -> Cow<'_> {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:317:24
+  --> tests/ui/needless_lifetimes.rs:318:24
    |
 LL |         fn needless_lt<'a>(x: &'a u8) {}
    |                        ^^      ^^
@@ -324,7 +324,7 @@ LL +         fn needless_lt(x: &u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:321:24
+  --> tests/ui/needless_lifetimes.rs:322:24
    |
 LL |         fn needless_lt<'a>(_x: &'a u8) {}
    |                        ^^       ^^
@@ -336,7 +336,7 @@ LL +         fn needless_lt(_x: &u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:332:10
+  --> tests/ui/needless_lifetimes.rs:333:10
    |
 LL |     impl<'a> Foo for Baz<'a> {}
    |          ^^              ^^
@@ -348,7 +348,7 @@ LL +     impl Foo for Baz<'_> {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:334:16
+  --> tests/ui/needless_lifetimes.rs:335:16
    |
 LL |         fn baz<'a>(&'a self) -> impl Foo + 'a {
    |                ^^   ^^                     ^^
@@ -360,7 +360,7 @@ LL +         fn baz(&self) -> impl Foo + '_ {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:366:55
+  --> tests/ui/needless_lifetimes.rs:367:55
    |
 LL |     fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 {
    |                                                       ^^      ^^                                    ^^
@@ -372,7 +372,7 @@ LL +     fn impl_trait_elidable_nested_anonymous_lifetimes(i: &i32, f: impl Fn(&
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:375:26
+  --> tests/ui/needless_lifetimes.rs:376:26
    |
 LL |     fn generics_elidable<'a, T: Fn(&i32) -> &i32>(i: &'a i32, f: T) -> &'a i32 {
    |                          ^^                           ^^                ^^
@@ -384,7 +384,7 @@ 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:30
+  --> tests/ui/needless_lifetimes.rs:388:30
    |
 LL |     fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
    |                              ^^         ^^                ^^
@@ -396,7 +396,7 @@ LL +     fn where_clause_elidable<T>(i: &i32, f: T) -> &i32
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:402:28
+  --> tests/ui/needless_lifetimes.rs:403:28
    |
 LL |     fn pointer_fn_elidable<'a>(i: &'a i32, f: fn(&i32) -> &i32) -> &'a i32 {
    |                            ^^      ^^                               ^^
@@ -408,7 +408,7 @@ LL +     fn pointer_fn_elidable(i: &i32, f: fn(&i32) -> &i32) -> &i32 {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:415:28
+  --> tests/ui/needless_lifetimes.rs:416:28
    |
 LL |     fn nested_fn_pointer_3<'a>(_: &'a i32) -> fn(fn(&i32) -> &i32) -> i32 {
    |                            ^^      ^^
@@ -420,7 +420,7 @@ LL +     fn nested_fn_pointer_3(_: &i32) -> fn(fn(&i32) -> &i32) -> i32 {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:418:28
+  --> tests/ui/needless_lifetimes.rs:419:28
    |
 LL |     fn nested_fn_pointer_4<'a>(_: &'a i32) -> impl Fn(fn(&i32)) {
    |                            ^^      ^^
@@ -432,7 +432,7 @@ LL +     fn nested_fn_pointer_4(_: &i32) -> impl Fn(fn(&i32)) {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:440:21
+  --> tests/ui/needless_lifetimes.rs:441:21
    |
 LL |         fn implicit<'a>(&'a self) -> &'a () {
    |                     ^^   ^^           ^^
@@ -444,7 +444,7 @@ LL +         fn implicit(&self) -> &() {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:443:25
+  --> tests/ui/needless_lifetimes.rs:444:25
    |
 LL |         fn implicit_mut<'a>(&'a mut self) -> &'a () {
    |                         ^^   ^^               ^^
@@ -456,7 +456,31 @@ LL +         fn implicit_mut(&mut self) -> &() {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:454:31
+  --> tests/ui/needless_lifetimes.rs:448:21
+   |
+LL |         fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
+   |                     ^^         ^^                ^^
+   |
+help: elide the lifetimes
+   |
+LL -         fn explicit<'a>(self: &'a Arc<Self>) -> &'a () {
+LL +         fn explicit(self: &Arc<Self>) -> &() {
+   |
+
+error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/needless_lifetimes.rs:452:25
+   |
+LL |         fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
+   |                         ^^         ^^                   ^^
+   |
+help: elide the lifetimes
+   |
+LL -         fn explicit_mut<'a>(self: &'a mut Rc<Self>) -> &'a () {
+LL +         fn explicit_mut(self: &mut Rc<Self>) -> &() {
+   |
+
+error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/needless_lifetimes.rs:464:31
    |
 LL |         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
    |                               ^^                          ^^         ^^
@@ -468,7 +492,7 @@ LL +         fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &() {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:460:21
+  --> tests/ui/needless_lifetimes.rs:470:21
    |
 LL |         fn implicit<'a>(&'a self) -> &'a ();
    |                     ^^   ^^           ^^
@@ -480,7 +504,7 @@ LL +         fn implicit(&self) -> &();
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:461:30
+  --> tests/ui/needless_lifetimes.rs:471:30
    |
 LL |         fn implicit_provided<'a>(&'a self) -> &'a () {
    |                              ^^   ^^           ^^
@@ -492,7 +516,31 @@ LL +         fn implicit_provided(&self) -> &() {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:470:31
+  --> tests/ui/needless_lifetimes.rs:476:21
+   |
+LL |         fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
+   |                     ^^         ^^                ^^
+   |
+help: elide the lifetimes
+   |
+LL -         fn explicit<'a>(self: &'a Arc<Self>) -> &'a ();
+LL +         fn explicit(self: &Arc<Self>) -> &();
+   |
+
+error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/needless_lifetimes.rs:478:30
+   |
+LL |         fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
+   |                              ^^         ^^                ^^
+   |
+help: elide the lifetimes
+   |
+LL -         fn explicit_provided<'a>(self: &'a Arc<Self>) -> &'a () {
+LL +         fn explicit_provided(self: &Arc<Self>) -> &() {
+   |
+
+error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/needless_lifetimes.rs:488:31
    |
 LL |         fn lifetime_elsewhere<'a>(self: Box<Self>, here: &'a ()) -> &'a ();
    |                               ^^                          ^^         ^^
@@ -504,7 +552,7 @@ LL +         fn lifetime_elsewhere(self: Box<Self>, here: &()) -> &();
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:471:40
+  --> tests/ui/needless_lifetimes.rs:489:40
    |
 LL |         fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () {
    |                                        ^^                          ^^         ^^
@@ -516,7 +564,7 @@ LL +         fn lifetime_elsewhere_provided(self: Box<Self>, here: &()) -> &() {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:480:12
+  --> tests/ui/needless_lifetimes.rs:498:12
    |
 LL |     fn foo<'a>(x: &'a u8, y: &'_ u8) {}
    |            ^^      ^^
@@ -528,7 +576,7 @@ LL +     fn foo(x: &u8, y: &'_ u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:482:12
+  --> tests/ui/needless_lifetimes.rs:500:12
    |
 LL |     fn bar<'a>(x: &'a u8, y: &'_ u8, z: &'_ u8) {}
    |            ^^      ^^
@@ -540,7 +588,7 @@ LL +     fn bar(x: &u8, y: &'_ u8, z: &'_ u8) {}
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:489:18
+  --> tests/ui/needless_lifetimes.rs:507:18
    |
 LL |     fn one_input<'a>(x: &'a u8) -> &'a u8 {
    |                  ^^      ^^         ^^
@@ -552,7 +600,7 @@ LL +     fn one_input(x: &u8) -> &u8 {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:494:42
+  --> tests/ui/needless_lifetimes.rs:512:42
    |
 LL |     fn multiple_inputs_output_not_elided<'a, 'b>(x: &'a u8, y: &'b u8, z: &'b u8) -> &'b u8 {
    |                                          ^^          ^^
@@ -564,7 +612,7 @@ LL +     fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8)
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:510:22
+  --> tests/ui/needless_lifetimes.rs:528:22
    |
 LL |         fn one_input<'a>(x: &'a u8) -> &'a u8 {
    |                      ^^      ^^         ^^
@@ -576,5 +624,64 @@ LL -         fn one_input<'a>(x: &'a u8) -> &'a u8 {
 LL +         fn one_input(x: &u8) -> &u8 {
    |
 
-error: aborting due to 48 previous errors
+error: the following explicit lifetimes could be elided: 'py
+  --> tests/ui/needless_lifetimes.rs:623:14
+   |
+LL |     impl<'t, 'py> ContentString<'t> {
+   |              ^^^
+LL |         // `'py` can be elided because of `&self`
+LL |         fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
+   |                                                                                   ^^^
+   |
+help: elide the lifetimes
+   |
+LL ~     impl<'t> ContentString<'t> {
+LL |         // `'py` can be elided because of `&self`
+LL ~         fn map_content2(&self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
+   |
+
+error: the following explicit lifetimes could be elided: 'py
+  --> tests/ui/needless_lifetimes.rs:633:14
+   |
+LL |     impl<'t, 'py> ContentString<'t> {
+   |              ^^^
+LL |         // `'py` can be elided because of `&'_ self`
+LL |         fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, 'py> {
+   |                                                                                      ^^^
+   |
+help: elide the lifetimes
+   |
+LL ~     impl<'t> ContentString<'t> {
+LL |         // `'py` can be elided because of `&'_ self`
+LL ~         fn map_content3(&'_ self, f: impl FnOnce(&'t str) -> &'t str) -> Content<'t, '_> {
+   |
+
+error: the following explicit lifetimes could be elided: 'py
+  --> tests/ui/needless_lifetimes.rs:653:14
+   |
+LL |     impl<'t, 'py> ContentString<'t> {
+   |              ^^^
+...
+LL |         ) -> Content<'t, 'py> {
+   |                          ^^^
+   |
+help: elide the lifetimes
+   |
+LL ~     impl<'t> ContentString<'t> {
+LL |         // `'py` can be elided because of `&Self`
+...
+LL |             o: &'t str,
+LL ~         ) -> Content<'t, '_> {
+   |
+
+error: this expression creates a reference which is immediately dereferenced by the compiler
+  --> tests/ui/needless_lifetimes.rs:674:9
+   |
+LL |         &x.b
+   |         ^^^^ help: change this to: `x.b`
+   |
+   = note: `-D clippy::needless-borrow` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`
+
+error: aborting due to 56 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_option_take.fixed b/src/tools/clippy/tests/ui/needless_option_take.fixed
new file mode 100644
index 00000000000..6514b67ef7a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_option_take.fixed
@@ -0,0 +1,58 @@
+struct MyStruct;
+
+impl MyStruct {
+    pub fn get_option() -> Option<Self> {
+        todo!()
+    }
+}
+
+fn return_option() -> Option<i32> {
+    todo!()
+}
+
+fn main() {
+    println!("Testing non erroneous option_take_on_temporary");
+    let mut option = Some(1);
+    let _ = Box::new(move || option.take().unwrap());
+
+    println!("Testing non erroneous option_take_on_temporary");
+    let x = Some(3);
+    x.as_ref();
+
+    let x = Some(3);
+    x.as_ref();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    println!("Testing non erroneous option_take_on_temporary");
+    let mut x = Some(3);
+    let y = x.as_mut();
+
+    let mut x = Some(3);
+    let y = x.as_mut();
+    //~^ ERROR: called `Option::take()` on a temporary value
+    let y = x.replace(289);
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let y = Some(3).as_mut();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let y = Option::as_mut(&mut x);
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let x = return_option();
+    let x = return_option();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let x = MyStruct::get_option();
+    let x = MyStruct::get_option();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let mut my_vec = vec![1, 2, 3];
+    my_vec.push(4);
+    let y = my_vec.first();
+    let y = my_vec.first();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let y = my_vec.first();
+    //~^ ERROR: called `Option::take()` on a temporary value
+}
diff --git a/src/tools/clippy/tests/ui/needless_option_take.stderr b/src/tools/clippy/tests/ui/needless_option_take.stderr
index e036bd53170..3fc339ed79e 100644
--- a/src/tools/clippy/tests/ui/needless_option_take.stderr
+++ b/src/tools/clippy/tests/ui/needless_option_take.stderr
@@ -2,7 +2,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:23:5
    |
 LL |     x.as_ref().take();
-   |     ^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^-------
+   |               |
+   |               help: remove
    |
    = note: `as_ref` creates a temporary value, so calling take() has no effect
    = note: `-D clippy::needless-option-take` implied by `-D warnings`
@@ -12,7 +14,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:31:13
    |
 LL |     let y = x.as_mut().take();
-   |             ^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^-------
+   |                       |
+   |                       help: remove
    |
    = note: `as_mut` creates a temporary value, so calling take() has no effect
 
@@ -20,7 +24,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:33:13
    |
 LL |     let y = x.replace(289).take();
-   |             ^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^-------
+   |                           |
+   |                           help: remove
    |
    = note: `replace` creates a temporary value, so calling take() has no effect
 
@@ -28,7 +34,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:36:13
    |
 LL |     let y = Some(3).as_mut().take();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^-------
+   |                             |
+   |                             help: remove
    |
    = note: `as_mut` creates a temporary value, so calling take() has no effect
 
@@ -36,7 +44,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:39:13
    |
 LL |     let y = Option::as_mut(&mut x).take();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^-------
+   |                                   |
+   |                                   help: remove
    |
    = note: `as_mut` creates a temporary value, so calling take() has no effect
 
@@ -44,7 +54,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:43:13
    |
 LL |     let x = return_option().take();
-   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^-------
+   |                            |
+   |                            help: remove
    |
    = note: `return_option` creates a temporary value, so calling take() has no effect
 
@@ -52,7 +64,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:47:13
    |
 LL |     let x = MyStruct::get_option().take();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^-------
+   |                                   |
+   |                                   help: remove
    |
    = note: `get_option` creates a temporary value, so calling take() has no effect
 
@@ -60,7 +74,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:53:13
    |
 LL |     let y = my_vec.first().take();
-   |             ^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^-------
+   |                           |
+   |                           help: remove
    |
    = note: `first` creates a temporary value, so calling take() has no effect
 
@@ -68,7 +84,9 @@ error: called `Option::take()` on a temporary value
   --> tests/ui/needless_option_take.rs:56:13
    |
 LL |     let y = my_vec.first().take();
-   |             ^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^-------
+   |                           |
+   |                           help: remove
    |
    = note: `first` creates a temporary value, so calling take() has no effect
 
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 2587d3f8c52..2c90da51252 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
@@ -63,12 +63,14 @@ LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |
 help: consider changing the type to
    |
-LL | fn issue_2114(s: String, t: &str, u: Vec<i32>, v: Vec<i32>) {
-   |                             ~~~~
+LL - fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
+LL + fn issue_2114(s: String, t: &str, u: Vec<i32>, v: Vec<i32>) {
+   |
 help: change `t.clone()` to
    |
-LL |     let _ = t.to_string();
-   |             ~~~~~~~~~~~~~
+LL -     let _ = t.clone();
+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:91:40
@@ -84,12 +86,14 @@ LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |
 help: consider changing the type to
    |
-LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: &[i32]) {
-   |                                                     ~~~~~~
+LL - fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
+LL + fn issue_2114(s: String, t: String, u: Vec<i32>, v: &[i32]) {
+   |
 help: change `v.clone()` to
    |
-LL |     let _ = v.to_owned();
-   |             ~~~~~~~~~~~~
+LL -     let _ = v.clone();
+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:108:12
diff --git a/src/tools/clippy/tests/ui/needless_range_loop.rs b/src/tools/clippy/tests/ui/needless_range_loop.rs
index 3f242195330..75f1896eded 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop.rs
+++ b/src/tools/clippy/tests/ui/needless_range_loop.rs
@@ -2,7 +2,8 @@
 #![allow(
     clippy::uninlined_format_args,
     clippy::unnecessary_literal_unwrap,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::manual_slice_fill
 )]
 //@no-rustfix
 static STATIC: [usize; 4] = [0, 1, 8, 16];
diff --git a/src/tools/clippy/tests/ui/needless_range_loop.stderr b/src/tools/clippy/tests/ui/needless_range_loop.stderr
index dc2cf437e02..831b8511e43 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop.stderr
+++ b/src/tools/clippy/tests/ui/needless_range_loop.stderr
@@ -1,5 +1,5 @@
 error: the loop variable `i` is only used to index `vec`
-  --> tests/ui/needless_range_loop.rs:15:14
+  --> tests/ui/needless_range_loop.rs:16:14
    |
 LL |     for i in 0..vec.len() {
    |              ^^^^^^^^^^^^
@@ -8,151 +8,165 @@ LL |     for i in 0..vec.len() {
    = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]`
 help: consider using an iterator
    |
-LL |     for <item> in &vec {
-   |         ~~~~~~    ~~~~
+LL -     for i in 0..vec.len() {
+LL +     for <item> in &vec {
+   |
 
 error: the loop variable `i` is only used to index `vec`
-  --> tests/ui/needless_range_loop.rs:26:14
+  --> tests/ui/needless_range_loop.rs:27:14
    |
 LL |     for i in 0..vec.len() {
    |              ^^^^^^^^^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in &vec {
-   |         ~~~~~~    ~~~~
+LL -     for i in 0..vec.len() {
+LL +     for <item> in &vec {
+   |
 
 error: the loop variable `j` is only used to index `STATIC`
-  --> tests/ui/needless_range_loop.rs:32:14
+  --> tests/ui/needless_range_loop.rs:33:14
    |
 LL |     for j in 0..4 {
    |              ^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in &STATIC {
-   |         ~~~~~~    ~~~~~~~
+LL -     for j in 0..4 {
+LL +     for <item> in &STATIC {
+   |
 
 error: the loop variable `j` is only used to index `CONST`
-  --> tests/ui/needless_range_loop.rs:37:14
+  --> tests/ui/needless_range_loop.rs:38:14
    |
 LL |     for j in 0..4 {
    |              ^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in &CONST {
-   |         ~~~~~~    ~~~~~~
+LL -     for j in 0..4 {
+LL +     for <item> in &CONST {
+   |
 
 error: the loop variable `i` is used to index `vec`
-  --> tests/ui/needless_range_loop.rs:42:14
+  --> tests/ui/needless_range_loop.rs:43:14
    |
 LL |     for i in 0..vec.len() {
    |              ^^^^^^^^^^^^
    |
 help: consider using an iterator and enumerate()
    |
-LL |     for (i, <item>) in vec.iter().enumerate() {
-   |         ~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 0..vec.len() {
+LL +     for (i, <item>) in vec.iter().enumerate() {
+   |
 
 error: the loop variable `i` is only used to index `vec2`
-  --> tests/ui/needless_range_loop.rs:51:14
+  --> tests/ui/needless_range_loop.rs:52:14
    |
 LL |     for i in 0..vec.len() {
    |              ^^^^^^^^^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec2.iter().take(vec.len()) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 0..vec.len() {
+LL +     for <item> in vec2.iter().take(vec.len()) {
+   |
 
 error: the loop variable `i` is only used to index `vec`
-  --> tests/ui/needless_range_loop.rs:56:14
+  --> tests/ui/needless_range_loop.rs:57:14
    |
 LL |     for i in 5..vec.len() {
    |              ^^^^^^^^^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec.iter().skip(5) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~
+LL -     for i in 5..vec.len() {
+LL +     for <item> in vec.iter().skip(5) {
+   |
 
 error: the loop variable `i` is only used to index `vec`
-  --> tests/ui/needless_range_loop.rs:61:14
+  --> tests/ui/needless_range_loop.rs:62:14
    |
 LL |     for i in 0..MAX_LEN {
    |              ^^^^^^^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec.iter().take(MAX_LEN) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 0..MAX_LEN {
+LL +     for <item> in vec.iter().take(MAX_LEN) {
+   |
 
 error: the loop variable `i` is only used to index `vec`
-  --> tests/ui/needless_range_loop.rs:66:14
+  --> tests/ui/needless_range_loop.rs:67:14
    |
 LL |     for i in 0..=MAX_LEN {
    |              ^^^^^^^^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec.iter().take(MAX_LEN + 1) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 0..=MAX_LEN {
+LL +     for <item> in vec.iter().take(MAX_LEN + 1) {
+   |
 
 error: the loop variable `i` is only used to index `vec`
-  --> tests/ui/needless_range_loop.rs:71:14
+  --> tests/ui/needless_range_loop.rs:72:14
    |
 LL |     for i in 5..10 {
    |              ^^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec.iter().take(10).skip(5) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 5..10 {
+LL +     for <item> in vec.iter().take(10).skip(5) {
+   |
 
 error: the loop variable `i` is only used to index `vec`
-  --> tests/ui/needless_range_loop.rs:76:14
+  --> tests/ui/needless_range_loop.rs:77:14
    |
 LL |     for i in 5..=10 {
    |              ^^^^^^
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec.iter().take(10 + 1).skip(5) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 5..=10 {
+LL +     for <item> in vec.iter().take(10 + 1).skip(5) {
+   |
 
 error: the loop variable `i` is used to index `vec`
-  --> tests/ui/needless_range_loop.rs:81:14
+  --> tests/ui/needless_range_loop.rs:82:14
    |
 LL |     for i in 5..vec.len() {
    |              ^^^^^^^^^^^^
    |
 help: consider using an iterator and enumerate()
    |
-LL |     for (i, <item>) in vec.iter().enumerate().skip(5) {
-   |         ~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 5..vec.len() {
+LL +     for (i, <item>) in vec.iter().enumerate().skip(5) {
+   |
 
 error: the loop variable `i` is used to index `vec`
-  --> tests/ui/needless_range_loop.rs:86:14
+  --> tests/ui/needless_range_loop.rs:87:14
    |
 LL |     for i in 5..10 {
    |              ^^^^^
    |
 help: consider using an iterator and enumerate()
    |
-LL |     for (i, <item>) in vec.iter().enumerate().take(10).skip(5) {
-   |         ~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 5..10 {
+LL +     for (i, <item>) in vec.iter().enumerate().take(10).skip(5) {
+   |
 
 error: the loop variable `i` is used to index `vec`
-  --> tests/ui/needless_range_loop.rs:92:14
+  --> tests/ui/needless_range_loop.rs:93:14
    |
 LL |     for i in 0..vec.len() {
    |              ^^^^^^^^^^^^
    |
 help: consider using an iterator and enumerate()
    |
-LL |     for (i, <item>) in vec.iter_mut().enumerate() {
-   |         ~~~~~~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 0..vec.len() {
+LL +     for (i, <item>) in vec.iter_mut().enumerate() {
+   |
 
 error: aborting due to 14 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_range_loop2.stderr b/src/tools/clippy/tests/ui/needless_range_loop2.stderr
index 353f30b1b26..f37e1f2872d 100644
--- a/src/tools/clippy/tests/ui/needless_range_loop2.stderr
+++ b/src/tools/clippy/tests/ui/needless_range_loop2.stderr
@@ -8,8 +8,9 @@ LL |     for i in 3..10 {
    = help: to override `-D warnings` add `#[allow(clippy::needless_range_loop)]`
 help: consider using an iterator
    |
-LL |     for <item> in ns.iter().take(10).skip(3) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in 3..10 {
+LL +     for <item> in ns.iter().take(10).skip(3) {
+   |
 
 error: the loop variable `i` is only used to index `ms`
   --> tests/ui/needless_range_loop2.rs:34:14
@@ -19,8 +20,9 @@ LL |     for i in 0..ms.len() {
    |
 help: consider using an iterator
    |
-LL |     for <item> in &mut ms {
-   |         ~~~~~~    ~~~~~~~
+LL -     for i in 0..ms.len() {
+LL +     for <item> in &mut ms {
+   |
 
 error: the loop variable `i` is only used to index `ms`
   --> tests/ui/needless_range_loop2.rs:41:14
@@ -30,8 +32,9 @@ LL |     for i in 0..ms.len() {
    |
 help: consider using an iterator
    |
-LL |     for <item> in &mut ms {
-   |         ~~~~~~    ~~~~~~~
+LL -     for i in 0..ms.len() {
+LL +     for <item> in &mut ms {
+   |
 
 error: the loop variable `i` is only used to index `vec`
   --> tests/ui/needless_range_loop2.rs:66:14
@@ -41,8 +44,9 @@ LL |     for i in x..x + 4 {
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec.iter_mut().skip(x).take(4) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in x..x + 4 {
+LL +     for <item> in vec.iter_mut().skip(x).take(4) {
+   |
 
 error: the loop variable `i` is only used to index `vec`
   --> tests/ui/needless_range_loop2.rs:74:14
@@ -52,8 +56,9 @@ LL |     for i in x..=x + 4 {
    |
 help: consider using an iterator
    |
-LL |     for <item> in vec.iter_mut().skip(x).take(4 + 1) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in x..=x + 4 {
+LL +     for <item> in vec.iter_mut().skip(x).take(4 + 1) {
+   |
 
 error: the loop variable `i` is only used to index `arr`
   --> tests/ui/needless_range_loop2.rs:81:14
@@ -63,8 +68,9 @@ LL |     for i in 0..3 {
    |
 help: consider using an iterator
    |
-LL |     for <item> in &arr {
-   |         ~~~~~~    ~~~~
+LL -     for i in 0..3 {
+LL +     for <item> in &arr {
+   |
 
 error: the loop variable `i` is only used to index `arr`
   --> tests/ui/needless_range_loop2.rs:86:14
@@ -74,8 +80,9 @@ LL |     for i in 0..2 {
    |
 help: consider using an iterator
    |
-LL |     for <item> in arr.iter().take(2) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~
+LL -     for i in 0..2 {
+LL +     for <item> in arr.iter().take(2) {
+   |
 
 error: the loop variable `i` is only used to index `arr`
   --> tests/ui/needless_range_loop2.rs:91:14
@@ -85,8 +92,9 @@ LL |     for i in 1..3 {
    |
 help: consider using an iterator
    |
-LL |     for <item> in arr.iter().skip(1) {
-   |         ~~~~~~    ~~~~~~~~~~~~~~~~~~
+LL -     for i in 1..3 {
+LL +     for <item> in arr.iter().skip(1) {
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index d3c2a6badc0..8d8b5b9e713 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -80,8 +80,9 @@ LL |         true => return false,
    |
 help: remove `return`
    |
-LL |         true => false,
-   |                 ~~~~~
+LL -         true => return false,
+LL +         true => false,
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:58:13
@@ -115,8 +116,9 @@ LL |     let _ = || return true;
    |
 help: remove `return`
    |
-LL |     let _ = || true;
-   |                ~~~~
+LL -     let _ = || return true;
+LL +     let _ = || true;
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:71:5
@@ -183,8 +185,9 @@ LL |         _ => return,
    |
 help: replace `return` with a unit value
    |
-LL |         _ => (),
-   |              ~~
+LL -         _ => return,
+LL +         _ => (),
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:97:24
@@ -209,8 +212,9 @@ LL |         _ => return,
    |
 help: replace `return` with a unit value
    |
-LL |         _ => (),
-   |              ~~
+LL -         _ => return,
+LL +         _ => (),
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:113:9
@@ -244,8 +248,9 @@ LL |         bar.unwrap_or_else(|_| return)
    |
 help: replace `return` with an empty block
    |
-LL |         bar.unwrap_or_else(|_| {})
-   |                                ~~
+LL -         bar.unwrap_or_else(|_| return)
+LL +         bar.unwrap_or_else(|_| {})
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:141:21
@@ -270,8 +275,9 @@ LL |         let _ = || return;
    |
 help: replace `return` with an empty block
    |
-LL |         let _ = || {};
-   |                    ~~
+LL -         let _ = || return;
+LL +         let _ = || {};
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:150:32
@@ -281,8 +287,9 @@ LL |         res.unwrap_or_else(|_| return Foo)
    |
 help: remove `return`
    |
-LL |         res.unwrap_or_else(|_| Foo)
-   |                                ~~~
+LL -         res.unwrap_or_else(|_| return Foo)
+LL +         res.unwrap_or_else(|_| Foo)
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:159:5
@@ -340,8 +347,9 @@ LL |         true => return false,
    |
 help: remove `return`
    |
-LL |         true => false,
-   |                 ~~~~~
+LL -         true => return false,
+LL +         true => false,
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:178:13
@@ -375,8 +383,9 @@ LL |     let _ = || return true;
    |
 help: remove `return`
    |
-LL |     let _ = || true;
-   |                ~~~~
+LL -     let _ = || return true;
+LL +     let _ = || true;
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:191:5
@@ -443,8 +452,9 @@ LL |         _ => return,
    |
 help: replace `return` with a unit value
    |
-LL |         _ => (),
-   |              ~~
+LL -         _ => return,
+LL +         _ => (),
+   |
 
 error: unneeded `return` statement
   --> tests/ui/needless_return.rs:222:9
diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr
index dab3488af10..203e3325822 100644
--- a/src/tools/clippy/tests/ui/never_loop.stderr
+++ b/src/tools/clippy/tests/ui/never_loop.stderr
@@ -77,8 +77,9 @@ LL | |     }
    |
 help: if you need the first element of the iterator, try writing
    |
-LL |     if let Some(x) = (0..10).next() {
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for x in 0..10 {
+LL +     if let Some(x) = (0..10).next() {
+   |
 
 error: this loop never actually loops
   --> tests/ui/never_loop.rs:167:5
@@ -145,8 +146,9 @@ LL | |             }
    |
 help: if you need the first element of the iterator, try writing
    |
-LL |             if let Some(_) = (0..20).next() {
-   |             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -             for _ in 0..20 {
+LL +             if let Some(_) = (0..20).next() {
+   |
 
 error: this loop never actually loops
   --> tests/ui/never_loop.rs:378:13
diff --git a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr
index a15379c5b1a..9f0c2ec4301 100644
--- a/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr
+++ b/src/tools/clippy/tests/ui/non_canonical_partial_ord_impl.stderr
@@ -25,8 +25,9 @@ LL | | }
    |
 help: change this to
    |
-LL |     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
-   |                           ~~~~~                             ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
+LL +     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/lazy_static.rs b/src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/lazy_static.rs
new file mode 100644
index 00000000000..85fb4e66079
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/lazy_static.rs
@@ -0,0 +1,20 @@
+//! **FAKE** lazy_static crate.
+
+#[macro_export]
+macro_rules! lazy_static {
+    (static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => {
+        static $N : &::core::marker::PhantomData<$T> = &::core::marker::PhantomData;
+
+        $crate::lazy_static! { $($t)* }
+    };
+    () => ()
+}
+
+#[macro_export]
+macro_rules! external {
+    () => {
+        $crate::lazy_static! {
+            static ref LZ_DERP: u32 = 12;
+        }
+    };
+}
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/once_cell.rs b/src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/once_cell.rs
new file mode 100644
index 00000000000..e860a0f7572
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/auxiliary/once_cell.rs
@@ -0,0 +1,55 @@
+//! **FAKE** once_cell crate.
+
+pub mod sync {
+    use std::marker::PhantomData;
+
+    pub struct Lazy<T, F = fn() -> T> {
+        cell: PhantomData<T>,
+        init: F,
+    }
+    unsafe impl<T, F: Send> Sync for Lazy<T, F> {}
+    impl<T, F> Lazy<T, F> {
+        pub const fn new(f: F) -> Lazy<T, F> {
+            Lazy {
+                cell: PhantomData,
+                init: f,
+            }
+        }
+
+        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {
+            unimplemented!()
+        }
+
+        pub fn force(_this: &Lazy<T, F>) -> &T {
+            unimplemented!()
+        }
+
+        pub fn force_mut(_this: &mut Lazy<T, F>) -> &mut T {
+            unimplemented!()
+        }
+
+        pub fn get(_this: &Lazy<T, F>) -> Option<&T> {
+            unimplemented!()
+        }
+
+        pub fn get_mut(_this: &mut Lazy<T, F>) -> Option<&mut T> {
+            unimplemented!()
+        }
+    }
+}
+pub mod race {
+    pub struct OnceBox<T>(T);
+
+    impl<T> OnceBox<T> {
+        pub fn get(&self) -> Option<&T> {
+            Some(&self.0)
+        }
+    }
+}
+
+#[macro_export]
+macro_rules! external {
+    () => {
+        static OC_DERP: $crate::sync::Lazy<u32> = $crate::sync::Lazy::new(|| 12);
+    };
+}
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.fixed b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.fixed
new file mode 100644
index 00000000000..f7c56b6fffe
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.fixed
@@ -0,0 +1,72 @@
+//@aux-build:once_cell.rs
+//@aux-build:lazy_static.rs
+
+#![warn(clippy::non_std_lazy_statics)]
+#![allow(static_mut_refs)]
+
+use once_cell::sync::Lazy;
+
+fn main() {}
+
+static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase());
+//~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    let x = "bar";
+    x.to_uppercase()
+});
+static LAZY_BAZ: std::sync::LazyLock<String> = { std::sync::LazyLock::new(|| "baz".to_uppercase()) };
+//~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+static LAZY_QUX: std::sync::LazyLock<String> = {
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    if "qux".len() == 3 {
+        std::sync::LazyLock::new(|| "qux".to_uppercase())
+    } else if "qux".is_ascii() {
+        std::sync::LazyLock::new(|| "qux".to_lowercase())
+    } else {
+        std::sync::LazyLock::new(|| "qux".to_string())
+    }
+};
+
+fn non_static() {
+    let _: Lazy<i32> = Lazy::new(|| 1);
+    let _: Lazy<String> = Lazy::new(|| String::from("hello"));
+    #[allow(clippy::declare_interior_mutable_const)]
+    const DONT_DO_THIS: Lazy<i32> = Lazy::new(|| 1);
+}
+
+mod once_cell_lazy_with_fns {
+    use once_cell::sync::Lazy;
+
+    static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "bar".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "baz".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+
+    fn calling_replaceable_fns() {
+        let _ = std::sync::LazyLock::force(&LAZY_FOO);
+        let _ = std::sync::LazyLock::force(&LAZY_BAR);
+        unsafe {
+            let _ = std::sync::LazyLock::force(&LAZY_BAZ);
+        }
+    }
+}
+
+#[clippy::msrv = "1.79"]
+mod msrv_not_meet {
+    use lazy_static::lazy_static;
+    use once_cell::sync::Lazy;
+
+    static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+
+    lazy_static! {
+        static ref LAZY_BAZ: f64 = 12.159 * 548;
+    }
+}
+
+mod external_macros {
+    once_cell::external!();
+    lazy_static::external!();
+}
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs
new file mode 100644
index 00000000000..90bc428137c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs
@@ -0,0 +1,72 @@
+//@aux-build:once_cell.rs
+//@aux-build:lazy_static.rs
+
+#![warn(clippy::non_std_lazy_statics)]
+#![allow(static_mut_refs)]
+
+use once_cell::sync::Lazy;
+
+fn main() {}
+
+static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+//~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+static LAZY_BAR: Lazy<String> = Lazy::new(|| {
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    let x = "bar";
+    x.to_uppercase()
+});
+static LAZY_BAZ: Lazy<String> = { Lazy::new(|| "baz".to_uppercase()) };
+//~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+static LAZY_QUX: Lazy<String> = {
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    if "qux".len() == 3 {
+        Lazy::new(|| "qux".to_uppercase())
+    } else if "qux".is_ascii() {
+        Lazy::new(|| "qux".to_lowercase())
+    } else {
+        Lazy::new(|| "qux".to_string())
+    }
+};
+
+fn non_static() {
+    let _: Lazy<i32> = Lazy::new(|| 1);
+    let _: Lazy<String> = Lazy::new(|| String::from("hello"));
+    #[allow(clippy::declare_interior_mutable_const)]
+    const DONT_DO_THIS: Lazy<i32> = Lazy::new(|| 1);
+}
+
+mod once_cell_lazy_with_fns {
+    use once_cell::sync::Lazy;
+
+    static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    static LAZY_BAR: Lazy<String> = Lazy::new(|| "bar".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+
+    fn calling_replaceable_fns() {
+        let _ = Lazy::force(&LAZY_FOO);
+        let _ = Lazy::force(&LAZY_BAR);
+        unsafe {
+            let _ = Lazy::force(&LAZY_BAZ);
+        }
+    }
+}
+
+#[clippy::msrv = "1.79"]
+mod msrv_not_meet {
+    use lazy_static::lazy_static;
+    use once_cell::sync::Lazy;
+
+    static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+
+    lazy_static! {
+        static ref LAZY_BAZ: f64 = 12.159 * 548;
+    }
+}
+
+mod external_macros {
+    once_cell::external!();
+    lazy_static::external!();
+}
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr
new file mode 100644
index 00000000000..333052ae1c1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.stderr
@@ -0,0 +1,103 @@
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:11:18
+   |
+LL | static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+   |                  ^^^^
+   |
+   = note: `-D clippy::non-std-lazy-statics` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::non_std_lazy_statics)]`
+help: use `std::sync::LazyLock` instead
+   |
+LL - static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+LL + static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase());
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:13:18
+   |
+LL | static LAZY_BAR: Lazy<String> = Lazy::new(|| {
+   |                  ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL - static LAZY_BAR: Lazy<String> = Lazy::new(|| {
+LL + static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| {
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:18:18
+   |
+LL | static LAZY_BAZ: Lazy<String> = { Lazy::new(|| "baz".to_uppercase()) };
+   |                  ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL - static LAZY_BAZ: Lazy<String> = { Lazy::new(|| "baz".to_uppercase()) };
+LL + static LAZY_BAZ: std::sync::LazyLock<String> = { std::sync::LazyLock::new(|| "baz".to_uppercase()) };
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:20:18
+   |
+LL | static LAZY_QUX: Lazy<String> = {
+   |                  ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL ~ static LAZY_QUX: std::sync::LazyLock<String> = {
+LL |
+LL |     if "qux".len() == 3 {
+LL ~         std::sync::LazyLock::new(|| "qux".to_uppercase())
+LL |     } else if "qux".is_ascii() {
+LL ~         std::sync::LazyLock::new(|| "qux".to_lowercase())
+LL |     } else {
+LL ~         std::sync::LazyLock::new(|| "qux".to_string())
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:41:22
+   |
+LL |     static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+   |                      ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL ~     static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase());
+LL |
+...
+LL |     fn calling_replaceable_fns() {
+LL ~         let _ = std::sync::LazyLock::force(&LAZY_FOO);
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:43:22
+   |
+LL |     static LAZY_BAR: Lazy<String> = Lazy::new(|| "bar".to_uppercase());
+   |                      ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL ~     static LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "bar".to_uppercase());
+LL |
+...
+LL |         let _ = Lazy::force(&LAZY_FOO);
+LL ~         let _ = std::sync::LazyLock::force(&LAZY_BAR);
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_fixable.rs:45:26
+   |
+LL |     static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase());
+   |                          ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL ~     static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "baz".to_uppercase());
+LL |
+...
+LL |         unsafe {
+LL ~             let _ = std::sync::LazyLock::force(&LAZY_BAZ);
+   |
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs
new file mode 100644
index 00000000000..6208612c698
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_no_std.rs
@@ -0,0 +1,20 @@
+//@aux-build:once_cell.rs
+//@aux-build:lazy_static.rs
+
+#![warn(clippy::non_std_lazy_statics)]
+#![no_std]
+
+use lazy_static::lazy_static;
+use once_cell::sync::Lazy;
+
+fn main() {}
+
+static LAZY_FOO: Lazy<usize> = Lazy::new(|| 42);
+static LAZY_BAR: Lazy<i32> = Lazy::new(|| {
+    let x: i32 = 0;
+    x.saturating_add(100)
+});
+
+lazy_static! {
+    static ref LAZY_BAZ: f64 = 12.159 * 548;
+}
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs
new file mode 100644
index 00000000000..8701a4b7729
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_other_once_cell.rs
@@ -0,0 +1,12 @@
+//@aux-build:once_cell.rs
+
+#![warn(clippy::non_std_lazy_statics)]
+
+// Should not error, since we used a type besides `sync::Lazy`
+fn use_once_cell_race(x: once_cell::race::OnceBox<String>) {
+    let _foo = x.get();
+}
+
+use once_cell::sync::Lazy;
+
+static LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase());
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs
new file mode 100644
index 00000000000..34f8dd1ccb2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs
@@ -0,0 +1,43 @@
+//@aux-build:once_cell.rs
+//@aux-build:lazy_static.rs
+//@no-rustfix
+
+#![warn(clippy::non_std_lazy_statics)]
+#![allow(static_mut_refs)]
+
+mod once_cell_lazy {
+    use once_cell::sync::Lazy;
+
+    static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    static mut LAZY_BAR: Lazy<String> = Lazy::new(|| "bar".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+    static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase());
+    //~^ ERROR: this type has been superceded by `LazyLock` in the standard library
+
+    fn calling_irreplaceable_fns() {
+        let _ = Lazy::get(&LAZY_FOO);
+
+        unsafe {
+            let _ = Lazy::get_mut(&mut LAZY_BAR);
+            let _ = Lazy::force_mut(&mut LAZY_BAZ);
+        }
+    }
+}
+
+mod lazy_static_lazy_static {
+    use lazy_static::lazy_static;
+
+    lazy_static! {
+        static ref LAZY_FOO: String = "foo".to_uppercase();
+    }
+    //~^^^ ERROR: this macro has been superceded by `std::sync::LazyLock`
+    lazy_static! {
+        static ref LAZY_BAR: String = "bar".to_uppercase();
+        static ref LAZY_BAZ: String = "baz".to_uppercase();
+    }
+    //~^^^^ ERROR: this macro has been superceded by `std::sync::LazyLock`
+    //~| ERROR: this macro has been superceded by `std::sync::LazyLock`
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr
new file mode 100644
index 00000000000..216190ae4ca
--- /dev/null
+++ b/src/tools/clippy/tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.stderr
@@ -0,0 +1,69 @@
+error: this macro has been superceded by `std::sync::LazyLock`
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:31:5
+   |
+LL | /     lazy_static! {
+LL | |         static ref LAZY_FOO: String = "foo".to_uppercase();
+LL | |     }
+   | |_____^
+   |
+   = note: `-D clippy::non-std-lazy-statics` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::non_std_lazy_statics)]`
+
+error: this macro has been superceded by `std::sync::LazyLock`
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:35:5
+   |
+LL | /     lazy_static! {
+LL | |         static ref LAZY_BAR: String = "bar".to_uppercase();
+LL | |         static ref LAZY_BAZ: String = "baz".to_uppercase();
+LL | |     }
+   | |_____^
+
+error: this macro has been superceded by `std::sync::LazyLock`
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:35:5
+   |
+LL | /     lazy_static! {
+LL | |         static ref LAZY_BAR: String = "bar".to_uppercase();
+LL | |         static ref LAZY_BAZ: String = "baz".to_uppercase();
+LL | |     }
+   | |_____^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:11:22
+   |
+LL |     static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+   |                      ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL -     static LAZY_FOO: Lazy<String> = Lazy::new(|| "foo".to_uppercase());
+LL +     static LAZY_FOO: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "foo".to_uppercase());
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:13:26
+   |
+LL |     static mut LAZY_BAR: Lazy<String> = Lazy::new(|| "bar".to_uppercase());
+   |                          ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL -     static mut LAZY_BAR: Lazy<String> = Lazy::new(|| "bar".to_uppercase());
+LL +     static mut LAZY_BAR: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "bar".to_uppercase());
+   |
+
+error: this type has been superceded by `LazyLock` in the standard library
+  --> tests/ui/non_std_lazy_static/non_std_lazy_static_unfixable.rs:15:26
+   |
+LL |     static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase());
+   |                          ^^^^
+   |
+help: use `std::sync::LazyLock` instead
+   |
+LL -     static mut LAZY_BAZ: Lazy<String> = Lazy::new(|| "baz".to_uppercase());
+LL +     static mut LAZY_BAZ: std::sync::LazyLock<String> = std::sync::LazyLock::new(|| "baz".to_uppercase());
+   |
+
+error: aborting due to 6 previous errors
+
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
index 578f918f013..56d6eb10ac0 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
@@ -51,10 +51,12 @@ LL |     let _ = a == b && c == 5 && a == b;
    |
 help: try
    |
-LL |     let _ = !(a != b || c != 5);
-   |             ~~~~~~~~~~~~~~~~~~~
-LL |     let _ = a == b && c == 5;
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = a == b && c == 5 && a == b;
+LL +     let _ = !(a != b || c != 5);
+   |
+LL -     let _ = a == b && c == 5 && a == b;
+LL +     let _ = a == b && c == 5;
+   |
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:44:13
@@ -64,10 +66,12 @@ LL |     let _ = a == b || c == 5 || a == b;
    |
 help: try
    |
-LL |     let _ = !(a != b && c != 5);
-   |             ~~~~~~~~~~~~~~~~~~~
-LL |     let _ = a == b || c == 5;
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = a == b || c == 5 || a == b;
+LL +     let _ = !(a != b && c != 5);
+   |
+LL -     let _ = a == b || c == 5 || a == b;
+LL +     let _ = a == b || c == 5;
+   |
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:46:13
@@ -77,10 +81,12 @@ LL |     let _ = a == b && c == 5 && b == a;
    |
 help: try
    |
-LL |     let _ = !(a != b || c != 5);
-   |             ~~~~~~~~~~~~~~~~~~~
-LL |     let _ = a == b && c == 5;
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = a == b && c == 5 && b == a;
+LL +     let _ = !(a != b || c != 5);
+   |
+LL -     let _ = a == b && c == 5 && b == a;
+LL +     let _ = a == b && c == 5;
+   |
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:48:13
@@ -90,10 +96,12 @@ LL |     let _ = a != b || !(a != b || c == d);
    |
 help: try
    |
-LL |     let _ = !(a == b && c == d);
-   |             ~~~~~~~~~~~~~~~~~~~
-LL |     let _ = a != b || c != d;
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = a != b || !(a != b || c == d);
+LL +     let _ = !(a == b && c == d);
+   |
+LL -     let _ = a != b || !(a != b || c == d);
+LL +     let _ = a != b || c != d;
+   |
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:50:13
@@ -103,10 +111,12 @@ LL |     let _ = a != b && !(a != b && c == d);
    |
 help: try
    |
-LL |     let _ = !(a == b || c == d);
-   |             ~~~~~~~~~~~~~~~~~~~
-LL |     let _ = a != b && c != d;
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = a != b && !(a != b && c == d);
+LL +     let _ = !(a == b || c == d);
+   |
+LL -     let _ = a != b && !(a != b && c == d);
+LL +     let _ = a != b && c != d;
+   |
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:81:8
diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.fixed b/src/tools/clippy/tests/ui/obfuscated_if_else.fixed
index c5ee569800a..bfe1c5e10cf 100644
--- a/src/tools/clippy/tests/ui/obfuscated_if_else.fixed
+++ b/src/tools/clippy/tests/ui/obfuscated_if_else.fixed
@@ -1,5 +1,18 @@
 #![warn(clippy::obfuscated_if_else)]
+#![allow(clippy::unnecessary_lazy_evaluations, clippy::unit_arg, clippy::unused_unit)]
 
 fn main() {
     if true { "a" } else { "b" };
+    if true { "a" } else { "b" };
+
+    let a = 1;
+    if a == 1 { "a" } else { "b" };
+    if a == 1 { "a" } else { "b" };
+
+    let partial = (a == 1).then_some("a");
+    partial.unwrap_or("b"); // not lint
+
+    let mut a = 0;
+    if true { a += 1 } else { () };
+    if true { () } else { a += 2 };
 }
diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.rs b/src/tools/clippy/tests/ui/obfuscated_if_else.rs
index 2b60c855a55..0ded2a2ceed 100644
--- a/src/tools/clippy/tests/ui/obfuscated_if_else.rs
+++ b/src/tools/clippy/tests/ui/obfuscated_if_else.rs
@@ -1,5 +1,18 @@
 #![warn(clippy::obfuscated_if_else)]
+#![allow(clippy::unnecessary_lazy_evaluations, clippy::unit_arg, clippy::unused_unit)]
 
 fn main() {
     true.then_some("a").unwrap_or("b");
+    true.then(|| "a").unwrap_or("b");
+
+    let a = 1;
+    (a == 1).then_some("a").unwrap_or("b");
+    (a == 1).then(|| "a").unwrap_or("b");
+
+    let partial = (a == 1).then_some("a");
+    partial.unwrap_or("b"); // not lint
+
+    let mut a = 0;
+    true.then_some(a += 1).unwrap_or(());
+    true.then_some(()).unwrap_or(a += 2);
 }
diff --git a/src/tools/clippy/tests/ui/obfuscated_if_else.stderr b/src/tools/clippy/tests/ui/obfuscated_if_else.stderr
index d4c2f9b331a..9ce1f475c48 100644
--- a/src/tools/clippy/tests/ui/obfuscated_if_else.stderr
+++ b/src/tools/clippy/tests/ui/obfuscated_if_else.stderr
@@ -1,5 +1,5 @@
-error: use of `.then_some(..).unwrap_or(..)` can be written more clearly with `if .. else ..`
-  --> tests/ui/obfuscated_if_else.rs:4:5
+error: this method chain can be written more clearly with `if .. else ..`
+  --> tests/ui/obfuscated_if_else.rs:5:5
    |
 LL |     true.then_some("a").unwrap_or("b");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }`
@@ -7,5 +7,35 @@ LL |     true.then_some("a").unwrap_or("b");
    = note: `-D clippy::obfuscated-if-else` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::obfuscated_if_else)]`
 
-error: aborting due to 1 previous error
+error: this method chain can be written more clearly with `if .. else ..`
+  --> tests/ui/obfuscated_if_else.rs:6:5
+   |
+LL |     true.then(|| "a").unwrap_or("b");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { "a" } else { "b" }`
+
+error: this method chain can be written more clearly with `if .. else ..`
+  --> tests/ui/obfuscated_if_else.rs:9:5
+   |
+LL |     (a == 1).then_some("a").unwrap_or("b");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }`
+
+error: this method chain can be written more clearly with `if .. else ..`
+  --> tests/ui/obfuscated_if_else.rs:10:5
+   |
+LL |     (a == 1).then(|| "a").unwrap_or("b");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if a == 1 { "a" } else { "b" }`
+
+error: this method chain can be written more clearly with `if .. else ..`
+  --> tests/ui/obfuscated_if_else.rs:16:5
+   |
+LL |     true.then_some(a += 1).unwrap_or(());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { a += 1 } else { () }`
+
+error: this method chain can be written more clearly with `if .. else ..`
+  --> tests/ui/obfuscated_if_else.rs:17:5
+   |
+LL |     true.then_some(()).unwrap_or(a += 2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `if true { () } else { a += 2 }`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/octal_escapes.stderr b/src/tools/clippy/tests/ui/octal_escapes.stderr
index 9343ba64a30..c8a89ac8bea 100644
--- a/src/tools/clippy/tests/ui/octal_escapes.stderr
+++ b/src/tools/clippy/tests/ui/octal_escapes.stderr
@@ -9,12 +9,14 @@ LL |     let _bad1 = "\033[0m";
    = help: to override `-D warnings` add `#[allow(clippy::octal_escapes)]`
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad1 = "\x1b[0m";
-   |                  ~~~~
+LL -     let _bad1 = "\033[0m";
+LL +     let _bad1 = "\x1b[0m";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad1 = "\x0033[0m";
-   |                  ~~~~~~
+LL -     let _bad1 = "\033[0m";
+LL +     let _bad1 = "\x0033[0m";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:6:19
@@ -24,12 +26,14 @@ LL |     let _bad2 = b"\033[0m";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad2 = b"\x1b[0m";
-   |                   ~~~~
+LL -     let _bad2 = b"\033[0m";
+LL +     let _bad2 = b"\x1b[0m";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad2 = b"\x0033[0m";
-   |                   ~~~~~~
+LL -     let _bad2 = b"\033[0m";
+LL +     let _bad2 = b"\x0033[0m";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:7:20
@@ -39,12 +43,14 @@ LL |     let _bad3 = "\\\033[0m";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad3 = "\\\x1b[0m";
-   |                    ~~~~
+LL -     let _bad3 = "\\\033[0m";
+LL +     let _bad3 = "\\\x1b[0m";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad3 = "\\\x0033[0m";
-   |                    ~~~~~~
+LL -     let _bad3 = "\\\033[0m";
+LL +     let _bad3 = "\\\x0033[0m";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:9:18
@@ -54,12 +60,14 @@ LL |     let _bad4 = "\01234567";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad4 = "\x0a34567";
-   |                  ~~~~
+LL -     let _bad4 = "\01234567";
+LL +     let _bad4 = "\x0a34567";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad4 = "\x001234567";
-   |                  ~~~~~~
+LL -     let _bad4 = "\01234567";
+LL +     let _bad4 = "\x001234567";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:10:20
@@ -69,12 +77,14 @@ LL |     let _bad5 = "\0\03";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad5 = "\0\x03";
-   |                    ~~~~
+LL -     let _bad5 = "\0\03";
+LL +     let _bad5 = "\0\x03";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad5 = "\0\x0003";
-   |                    ~~~~~~
+LL -     let _bad5 = "\0\03";
+LL +     let _bad5 = "\0\x0003";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:11:23
@@ -84,12 +94,14 @@ LL |     let _bad6 = "Text-\055\077-MoreText";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad6 = "Text-\x2d\077-MoreText";
-   |                       ~~~~
+LL -     let _bad6 = "Text-\055\077-MoreText";
+LL +     let _bad6 = "Text-\x2d\077-MoreText";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad6 = "Text-\x0055\077-MoreText";
-   |                       ~~~~~~
+LL -     let _bad6 = "Text-\055\077-MoreText";
+LL +     let _bad6 = "Text-\x0055\077-MoreText";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:11:27
@@ -99,12 +111,14 @@ LL |     let _bad6 = "Text-\055\077-MoreText";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad6 = "Text-\055\x3f-MoreText";
-   |                           ~~~~
+LL -     let _bad6 = "Text-\055\077-MoreText";
+LL +     let _bad6 = "Text-\055\x3f-MoreText";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad6 = "Text-\055\x0077-MoreText";
-   |                           ~~~~~~
+LL -     let _bad6 = "Text-\055\077-MoreText";
+LL +     let _bad6 = "Text-\055\x0077-MoreText";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:14:31
@@ -114,12 +128,14 @@ LL |     let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad7 = "EvenMoreText-\x01\02-ShortEscapes";
-   |                               ~~~~
+LL -     let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
+LL +     let _bad7 = "EvenMoreText-\x01\02-ShortEscapes";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes";
-   |                               ~~~~~~
+LL -     let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
+LL +     let _bad7 = "EvenMoreText-\x0001\02-ShortEscapes";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:14:34
@@ -129,12 +145,14 @@ LL |     let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad7 = "EvenMoreText-\01\x02-ShortEscapes";
-   |                                  ~~~~
+LL -     let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
+LL +     let _bad7 = "EvenMoreText-\01\x02-ShortEscapes";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes";
-   |                                  ~~~~~~
+LL -     let _bad7 = "EvenMoreText-\01\02-ShortEscapes";
+LL +     let _bad7 = "EvenMoreText-\01\x0002-ShortEscapes";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:17:19
@@ -144,12 +162,14 @@ LL |     let _bad8 = "锈\01锈";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad8 = "锈\x01锈";
-   |                    ~~~~
+LL -     let _bad8 = "锈\01锈";
+LL +     let _bad8 = "锈\x01锈";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad8 = "锈\x0001锈";
-   |                    ~~~~~~
+LL -     let _bad8 = "锈\01锈";
+LL +     let _bad8 = "锈\x0001锈";
+   |
 
 error: octal-looking escape in a literal
   --> tests/ui/octal_escapes.rs:18:19
@@ -159,12 +179,14 @@ LL |     let _bad9 = "锈\011锈";
    |
 help: if an octal escape is intended, use a hex escape instead
    |
-LL |     let _bad9 = "锈\x09锈";
-   |                    ~~~~
+LL -     let _bad9 = "锈\011锈";
+LL +     let _bad9 = "锈\x09锈";
+   |
 help: if a null escape is intended, disambiguate using
    |
-LL |     let _bad9 = "锈\x0011锈";
-   |                    ~~~~~~
+LL -     let _bad9 = "锈\011锈";
+LL +     let _bad9 = "锈\x0011锈";
+   |
 
 error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/op_ref.stderr b/src/tools/clippy/tests/ui/op_ref.stderr
index c5b68730a8f..ad002437c0c 100644
--- a/src/tools/clippy/tests/ui/op_ref.stderr
+++ b/src/tools/clippy/tests/ui/op_ref.stderr
@@ -8,8 +8,9 @@ LL |     let foo = &5 - &6;
    = help: to override `-D warnings` add `#[allow(clippy::op_ref)]`
 help: use the values directly
    |
-LL |     let foo = 5 - 6;
-   |               ~   ~
+LL -     let foo = &5 - &6;
+LL +     let foo = 5 - 6;
+   |
 
 error: taken reference of right operand
   --> tests/ui/op_ref.rs:58:13
diff --git a/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr b/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr
index 5892f2bdec5..0eda42b91b9 100644
--- a/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr
+++ b/src/tools/clippy/tests/ui/option_as_ref_cloned.stderr
@@ -8,8 +8,9 @@ LL |     let _: Option<String> = x.as_ref().cloned();
    = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_cloned)]`
 help: this can be written more concisely by cloning the `Option<_>` directly
    |
-LL |     let _: Option<String> = x.clone();
-   |                               ~~~~~
+LL -     let _: Option<String> = x.as_ref().cloned();
+LL +     let _: Option<String> = x.clone();
+   |
 
 error: cloning an `Option<_>` using `.as_mut().cloned()`
   --> tests/ui/option_as_ref_cloned.rs:8:31
@@ -19,8 +20,9 @@ LL |     let _: Option<String> = x.as_mut().cloned();
    |
 help: this can be written more concisely by cloning the `Option<_>` directly
    |
-LL |     let _: Option<String> = x.clone();
-   |                               ~~~~~
+LL -     let _: Option<String> = x.as_mut().cloned();
+LL +     let _: Option<String> = x.clone();
+   |
 
 error: cloning an `Option<_>` using `.as_ref().cloned()`
   --> tests/ui/option_as_ref_cloned.rs:11:32
@@ -30,8 +32,9 @@ LL |     let _: Option<&String> = y.as_ref().cloned();
    |
 help: this can be written more concisely by cloning the `Option<_>` directly
    |
-LL |     let _: Option<&String> = y.clone();
-   |                                ~~~~~
+LL -     let _: Option<&String> = y.as_ref().cloned();
+LL +     let _: Option<&String> = y.clone();
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/precedence.fixed b/src/tools/clippy/tests/ui/precedence.fixed
index 9864dd2550b..52144a18bac 100644
--- a/src/tools/clippy/tests/ui/precedence.fixed
+++ b/src/tools/clippy/tests/ui/precedence.fixed
@@ -20,10 +20,10 @@ fn main() {
     1 ^ (1 - 1);
     3 | (2 - 1);
     3 & (5 - 2);
-    0x0F00 & (0x00F0 << 4);
-    0x0F00 & (0xF000 >> 4);
-    (0x0F00 << 1) ^ 3;
-    (0x0F00 << 1) | 2;
+    0x0F00 & 0x00F0 << 4;
+    0x0F00 & 0xF000 >> 4;
+    0x0F00 << 1 ^ 3;
+    0x0F00 << 1 | 2;
 
     let b = 3;
     trip!(b * 8);
diff --git a/src/tools/clippy/tests/ui/precedence.stderr b/src/tools/clippy/tests/ui/precedence.stderr
index 0d63e827d66..68ad5cb4829 100644
--- a/src/tools/clippy/tests/ui/precedence.stderr
+++ b/src/tools/clippy/tests/ui/precedence.stderr
@@ -1,4 +1,4 @@
-error: operator precedence can trip the unwary
+error: operator precedence might not be obvious
   --> tests/ui/precedence.rs:16:5
    |
 LL |     1 << 2 + 3;
@@ -7,65 +7,41 @@ LL |     1 << 2 + 3;
    = note: `-D clippy::precedence` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::precedence)]`
 
-error: operator precedence can trip the unwary
+error: operator precedence might not be obvious
   --> tests/ui/precedence.rs:17:5
    |
 LL |     1 + 2 << 3;
    |     ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 2) << 3`
 
-error: operator precedence can trip the unwary
+error: operator precedence might not be obvious
   --> tests/ui/precedence.rs:18:5
    |
 LL |     4 >> 1 + 1;
    |     ^^^^^^^^^^ help: consider parenthesizing your expression: `4 >> (1 + 1)`
 
-error: operator precedence can trip the unwary
+error: operator precedence might not be obvious
   --> tests/ui/precedence.rs:19:5
    |
 LL |     1 + 3 >> 2;
    |     ^^^^^^^^^^ help: consider parenthesizing your expression: `(1 + 3) >> 2`
 
-error: operator precedence can trip the unwary
+error: operator precedence might not be obvious
   --> tests/ui/precedence.rs:20:5
    |
 LL |     1 ^ 1 - 1;
    |     ^^^^^^^^^ help: consider parenthesizing your expression: `1 ^ (1 - 1)`
 
-error: operator precedence can trip the unwary
+error: operator precedence might not be obvious
   --> tests/ui/precedence.rs:21:5
    |
 LL |     3 | 2 - 1;
    |     ^^^^^^^^^ help: consider parenthesizing your expression: `3 | (2 - 1)`
 
-error: operator precedence can trip the unwary
+error: operator precedence might not be obvious
   --> tests/ui/precedence.rs:22:5
    |
 LL |     3 & 5 - 2;
    |     ^^^^^^^^^ help: consider parenthesizing your expression: `3 & (5 - 2)`
 
-error: operator precedence can trip the unwary
-  --> tests/ui/precedence.rs:23:5
-   |
-LL |     0x0F00 & 0x00F0 << 4;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0x00F0 << 4)`
-
-error: operator precedence can trip the unwary
-  --> tests/ui/precedence.rs:24:5
-   |
-LL |     0x0F00 & 0xF000 >> 4;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0xF000 >> 4)`
-
-error: operator precedence can trip the unwary
-  --> tests/ui/precedence.rs:25:5
-   |
-LL |     0x0F00 << 1 ^ 3;
-   |     ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) ^ 3`
-
-error: operator precedence can trip the unwary
-  --> tests/ui/precedence.rs:26:5
-   |
-LL |     0x0F00 << 1 | 2;
-   |     ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) | 2`
-
-error: aborting due to 11 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/precedence_bits.fixed b/src/tools/clippy/tests/ui/precedence_bits.fixed
new file mode 100644
index 00000000000..82fea0d14e4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/precedence_bits.fixed
@@ -0,0 +1,35 @@
+#![warn(clippy::precedence_bits)]
+#![allow(
+    unused_must_use,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::precedence
+)]
+#![allow(clippy::identity_op)]
+#![allow(clippy::eq_op)]
+
+macro_rules! trip {
+    ($a:expr) => {
+        match $a & 0b1111_1111u8 {
+            0 => println!("a is zero ({})", $a),
+            _ => println!("a is {}", $a),
+        }
+    };
+}
+
+fn main() {
+    1 << 2 + 3;
+    1 + 2 << 3;
+    4 >> 1 + 1;
+    1 + 3 >> 2;
+    1 ^ 1 - 1;
+    3 | 2 - 1;
+    3 & 5 - 2;
+    0x0F00 & (0x00F0 << 4);
+    0x0F00 & (0xF000 >> 4);
+    (0x0F00 << 1) ^ 3;
+    (0x0F00 << 1) | 2;
+
+    let b = 3;
+    trip!(b * 8);
+}
diff --git a/src/tools/clippy/tests/ui/precedence_bits.rs b/src/tools/clippy/tests/ui/precedence_bits.rs
new file mode 100644
index 00000000000..9b353308b6e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/precedence_bits.rs
@@ -0,0 +1,35 @@
+#![warn(clippy::precedence_bits)]
+#![allow(
+    unused_must_use,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::precedence
+)]
+#![allow(clippy::identity_op)]
+#![allow(clippy::eq_op)]
+
+macro_rules! trip {
+    ($a:expr) => {
+        match $a & 0b1111_1111u8 {
+            0 => println!("a is zero ({})", $a),
+            _ => println!("a is {}", $a),
+        }
+    };
+}
+
+fn main() {
+    1 << 2 + 3;
+    1 + 2 << 3;
+    4 >> 1 + 1;
+    1 + 3 >> 2;
+    1 ^ 1 - 1;
+    3 | 2 - 1;
+    3 & 5 - 2;
+    0x0F00 & 0x00F0 << 4;
+    0x0F00 & 0xF000 >> 4;
+    0x0F00 << 1 ^ 3;
+    0x0F00 << 1 | 2;
+
+    let b = 3;
+    trip!(b * 8);
+}
diff --git a/src/tools/clippy/tests/ui/precedence_bits.stderr b/src/tools/clippy/tests/ui/precedence_bits.stderr
new file mode 100644
index 00000000000..f468186b363
--- /dev/null
+++ b/src/tools/clippy/tests/ui/precedence_bits.stderr
@@ -0,0 +1,29 @@
+error: operator precedence might not be obvious
+  --> tests/ui/precedence_bits.rs:28:5
+   |
+LL |     0x0F00 & 0x00F0 << 4;
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0x00F0 << 4)`
+   |
+   = note: `-D clippy::precedence-bits` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::precedence_bits)]`
+
+error: operator precedence might not be obvious
+  --> tests/ui/precedence_bits.rs:29:5
+   |
+LL |     0x0F00 & 0xF000 >> 4;
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `0x0F00 & (0xF000 >> 4)`
+
+error: operator precedence might not be obvious
+  --> tests/ui/precedence_bits.rs:30:5
+   |
+LL |     0x0F00 << 1 ^ 3;
+   |     ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) ^ 3`
+
+error: operator precedence might not be obvious
+  --> tests/ui/precedence_bits.rs:31:5
+   |
+LL |     0x0F00 << 1 | 2;
+   |     ^^^^^^^^^^^^^^^ help: consider parenthesizing your expression: `(0x0F00 << 1) | 2`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/print_literal.fixed b/src/tools/clippy/tests/ui/print_literal.fixed
index 1705a7ff01b..328e9a9b999 100644
--- a/src/tools/clippy/tests/ui/print_literal.fixed
+++ b/src/tools/clippy/tests/ui/print_literal.fixed
@@ -66,3 +66,17 @@ fn main() {
 
     println!("mixed: {{hello}} {world}");
 }
+
+fn issue_13959() {
+    println!("\"");
+    println!(
+        "
+        foo
+        \\
+        \\\\
+        \"
+        \\\"
+        bar
+"
+    );
+}
diff --git a/src/tools/clippy/tests/ui/print_literal.rs b/src/tools/clippy/tests/ui/print_literal.rs
index d10b26b5887..3130d0b6998 100644
--- a/src/tools/clippy/tests/ui/print_literal.rs
+++ b/src/tools/clippy/tests/ui/print_literal.rs
@@ -66,3 +66,18 @@ fn main() {
 
     println!("mixed: {} {world}", "{hello}");
 }
+
+fn issue_13959() {
+    println!("{}", r#"""#);
+    println!(
+        "{}",
+        r#"
+        foo
+        \
+        \\
+        "
+        \"
+        bar
+"#
+    );
+}
diff --git a/src/tools/clippy/tests/ui/print_literal.stderr b/src/tools/clippy/tests/ui/print_literal.stderr
index c4cbb8bed70..d967b7c2407 100644
--- a/src/tools/clippy/tests/ui/print_literal.stderr
+++ b/src/tools/clippy/tests/ui/print_literal.stderr
@@ -192,5 +192,41 @@ LL -     println!("mixed: {} {world}", "{hello}");
 LL +     println!("mixed: {{hello}} {world}");
    |
 
-error: aborting due to 16 previous errors
+error: literal with an empty format string
+  --> tests/ui/print_literal.rs:71:20
+   |
+LL |     println!("{}", r#"""#);
+   |                    ^^^^^^
+   |
+help: try
+   |
+LL -     println!("{}", r#"""#);
+LL +     println!("\"");
+   |
+
+error: literal with an empty format string
+  --> tests/ui/print_literal.rs:74:9
+   |
+LL | /         r#"
+LL | |         foo
+LL | |         \
+LL | |         \\
+...  |
+LL | |         bar
+LL | | "#
+   | |__^
+   |
+help: try
+   |
+LL ~         "
+LL +         foo
+LL +         \\
+LL +         \\\\
+LL +         \"
+LL +         \\\"
+LL +         bar
+LL ~ "
+   |
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/redundant_else.fixed b/src/tools/clippy/tests/ui/redundant_else.fixed
new file mode 100644
index 00000000000..47aa79302d2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_else.fixed
@@ -0,0 +1,154 @@
+#![warn(clippy::redundant_else)]
+#![allow(clippy::needless_return, clippy::if_same_then_else, clippy::needless_late_init)]
+
+fn main() {
+    loop {
+        // break
+        if foo() {
+            println!("Love your neighbor;");
+            break;
+        }
+        //~^ ERROR: redundant else block
+        println!("yet don't pull down your hedge.");
+        // continue
+        if foo() {
+            println!("He that lies down with Dogs,");
+            continue;
+        }
+        //~^ ERROR: redundant else block
+        println!("shall rise up with fleas.");
+        // match block
+        if foo() {
+            match foo() {
+                1 => break,
+                _ => return,
+            }
+        }
+        //~^ ERROR: redundant else block
+        println!("You may delay, but time will not.");
+    }
+    // else if
+    if foo() {
+        return;
+    } else if foo() {
+        return;
+    }
+    //~^ ERROR: redundant else block
+    println!("A fat kitchen makes a lean will.");
+    // let binding outside of block
+    let _ = {
+        if foo() {
+            return;
+        }
+        //~^ ERROR: redundant else block
+        1
+    };
+    // else if with let binding outside of block
+    let _ = {
+        if foo() {
+            return;
+        } else if foo() {
+            return;
+        }
+        //~^ ERROR: redundant else block
+        2
+    };
+    // inside if let
+    let _ = if let Some(1) = foo() {
+        let _ = 1;
+        if foo() {
+            return;
+        }
+        //~^ ERROR: redundant else block
+        1
+    } else {
+        1
+    };
+
+    //
+    // non-lint cases
+    //
+
+    // sanity check
+    if foo() {
+        let _ = 1;
+    } else {
+        println!("Who is wise? He that learns from every one.");
+    }
+    // else if without else
+    if foo() {
+        return;
+    } else if foo() {
+        foo()
+    };
+    // nested if return
+    if foo() {
+        if foo() {
+            return;
+        }
+    } else {
+        foo()
+    };
+    // match with non-breaking branch
+    if foo() {
+        match foo() {
+            1 => foo(),
+            _ => return,
+        }
+    } else {
+        println!("Three may keep a secret, if two of them are dead.");
+    }
+    // let binding
+    let _ = if foo() {
+        return;
+    } else {
+        1
+    };
+    // assign
+    let mut a;
+    a = if foo() {
+        return;
+    } else {
+        1
+    };
+    // assign-op
+    a += if foo() {
+        return;
+    } else {
+        1
+    };
+    // if return else if else
+    if foo() {
+        return;
+    } else if foo() {
+        1
+    } else {
+        2
+    };
+    // if else if return else
+    if foo() {
+        1
+    } else if foo() {
+        return;
+    } else {
+        2
+    };
+    // else if with let binding
+    let _ = if foo() {
+        return;
+    } else if foo() {
+        return;
+    } else {
+        2
+    };
+    // inside function call
+    Box::new(if foo() {
+        return;
+    } else {
+        1
+    });
+}
+
+fn foo<T>() -> T {
+    unimplemented!("I'm not Santa Claus")
+}
diff --git a/src/tools/clippy/tests/ui/redundant_else.stderr b/src/tools/clippy/tests/ui/redundant_else.stderr
index b649a210b5f..ecc16f7cda5 100644
--- a/src/tools/clippy/tests/ui/redundant_else.stderr
+++ b/src/tools/clippy/tests/ui/redundant_else.stderr
@@ -1,88 +1,123 @@
 error: redundant else block
-  --> tests/ui/redundant_else.rs:10:16
+  --> tests/ui/redundant_else.rs:10:10
    |
 LL |           } else {
-   |  ________________^
+   |  __________^
 LL | |
 LL | |             println!("yet don't pull down your hedge.");
 LL | |         }
    | |_________^
    |
-   = help: remove the `else` block and move the contents out
    = note: `-D clippy::redundant-else` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::redundant_else)]`
+help: remove the `else` block and move the contents out
+   |
+LL ~         }
+LL +
+LL +         println!("yet don't pull down your hedge.");
+   |
 
 error: redundant else block
-  --> tests/ui/redundant_else.rs:18:16
+  --> tests/ui/redundant_else.rs:18:10
    |
 LL |           } else {
-   |  ________________^
+   |  __________^
 LL | |
 LL | |             println!("shall rise up with fleas.");
 LL | |         }
    | |_________^
    |
-   = help: remove the `else` block and move the contents out
+help: remove the `else` block and move the contents out
+   |
+LL ~         }
+LL +
+LL +         println!("shall rise up with fleas.");
+   |
 
 error: redundant else block
-  --> tests/ui/redundant_else.rs:28:16
+  --> tests/ui/redundant_else.rs:28:10
    |
 LL |           } else {
-   |  ________________^
+   |  __________^
 LL | |
 LL | |             println!("You may delay, but time will not.");
 LL | |         }
    | |_________^
    |
-   = help: remove the `else` block and move the contents out
+help: remove the `else` block and move the contents out
+   |
+LL ~         }
+LL +
+LL +         println!("You may delay, but time will not.");
+   |
 
 error: redundant else block
-  --> tests/ui/redundant_else.rs:38:12
+  --> tests/ui/redundant_else.rs:38:6
    |
 LL |       } else {
-   |  ____________^
+   |  ______^
 LL | |
 LL | |         println!("A fat kitchen makes a lean will.");
 LL | |     }
    | |_____^
    |
-   = help: remove the `else` block and move the contents out
+help: remove the `else` block and move the contents out
+   |
+LL ~     }
+LL +
+LL +     println!("A fat kitchen makes a lean will.");
+   |
 
 error: redundant else block
-  --> tests/ui/redundant_else.rs:46:16
+  --> tests/ui/redundant_else.rs:46:10
    |
 LL |           } else {
-   |  ________________^
+   |  __________^
 LL | |
 LL | |             1
 LL | |         }
    | |_________^
    |
-   = help: remove the `else` block and move the contents out
+help: remove the `else` block and move the contents out
+   |
+LL ~         }
+LL +
+LL +         1
+   |
 
 error: redundant else block
-  --> tests/ui/redundant_else.rs:57:16
+  --> tests/ui/redundant_else.rs:57:10
    |
 LL |           } else {
-   |  ________________^
+   |  __________^
 LL | |
 LL | |             2
 LL | |         }
    | |_________^
    |
-   = help: remove the `else` block and move the contents out
+help: remove the `else` block and move the contents out
+   |
+LL ~         }
+LL +
+LL +         2
+   |
 
 error: redundant else block
-  --> tests/ui/redundant_else.rs:67:16
+  --> tests/ui/redundant_else.rs:67:10
    |
 LL |           } else {
-   |  ________________^
+   |  __________^
 LL | |
 LL | |             1
 LL | |         }
    | |_________^
    |
-   = help: remove the `else` block and move the contents out
+help: remove the `else` block and move the contents out
+   |
+LL ~         }
+LL +
+LL +         1
+   |
 
 error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr
index 7512546450b..a10cd5c2f48 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.stderr
+++ b/src/tools/clippy/tests/ui/redundant_guards.stderr
@@ -44,8 +44,9 @@ LL |         Some(x) if matches!(x, Some(1) if true) => ..,
    |
 help: try
    |
-LL |         Some(Some(1)) if true => ..,
-   |              ~~~~~~~  ~~~~~~~
+LL -         Some(x) if matches!(x, Some(1) if true) => ..,
+LL +         Some(Some(1)) if true => ..,
+   |
 
 error: redundant guard
   --> tests/ui/redundant_guards.rs:50:20
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
index e1d845721a9..8882a4d50a5 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
@@ -1,3 +1,4 @@
+//@aux-build:proc_macros.rs
 #![allow(dead_code)]
 #![warn(clippy::redundant_pub_crate)]
 
@@ -113,4 +114,10 @@ mod issue_8732 {
     pub(crate) use some_macro; // ok: macro exports are exempt
 }
 
+proc_macros::external! {
+    mod priv_mod {
+        pub(crate) fn dummy() {}
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.rs b/src/tools/clippy/tests/ui/redundant_pub_crate.rs
index 4d7f44892d0..5c8cab9be16 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.rs
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.rs
@@ -1,3 +1,4 @@
+//@aux-build:proc_macros.rs
 #![allow(dead_code)]
 #![warn(clippy::redundant_pub_crate)]
 
@@ -113,4 +114,10 @@ mod issue_8732 {
     pub(crate) use some_macro; // ok: macro exports are exempt
 }
 
+proc_macros::external! {
+    mod priv_mod {
+        pub(crate) fn dummy() {}
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.stderr b/src/tools/clippy/tests/ui/redundant_pub_crate.stderr
index 8f1005ab9b7..699e19b1abc 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.stderr
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.stderr
@@ -1,5 +1,5 @@
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:6:5
+  --> tests/ui/redundant_pub_crate.rs:7:5
    |
 LL |     pub(crate) fn g() {} // private due to m1
    |     ----------^^^^^
@@ -10,7 +10,7 @@ LL |     pub(crate) fn g() {} // private due to m1
    = help: to override `-D warnings` add `#[allow(clippy::redundant_pub_crate)]`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:11:9
+  --> tests/ui/redundant_pub_crate.rs:12:9
    |
 LL |         pub(crate) fn g() {} // private due to m1_1 and m1
    |         ----------^^^^^
@@ -18,7 +18,7 @@ LL |         pub(crate) fn g() {} // private due to m1_1 and m1
    |         help: consider using: `pub`
 
 error: pub(crate) module inside private module
-  --> tests/ui/redundant_pub_crate.rs:15:5
+  --> tests/ui/redundant_pub_crate.rs:16:5
    |
 LL |     pub(crate) mod m1_2 {
    |     ----------^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     pub(crate) mod m1_2 {
    |     help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:18:9
+  --> tests/ui/redundant_pub_crate.rs:19:9
    |
 LL |         pub(crate) fn g() {} // private due to m1_2 and m1
    |         ----------^^^^^
@@ -34,7 +34,7 @@ LL |         pub(crate) fn g() {} // private due to m1_2 and m1
    |         help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:24:9
+  --> tests/ui/redundant_pub_crate.rs:25:9
    |
 LL |         pub(crate) fn g() {} // private due to m1
    |         ----------^^^^^
@@ -42,7 +42,7 @@ LL |         pub(crate) fn g() {} // private due to m1
    |         help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:31:5
+  --> tests/ui/redundant_pub_crate.rs:32:5
    |
 LL |     pub(crate) fn g() {} // already crate visible due to m2
    |     ----------^^^^^
@@ -50,7 +50,7 @@ LL |     pub(crate) fn g() {} // already crate visible due to m2
    |     help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:36:9
+  --> tests/ui/redundant_pub_crate.rs:37:9
    |
 LL |         pub(crate) fn g() {} // private due to m2_1
    |         ----------^^^^^
@@ -58,7 +58,7 @@ LL |         pub(crate) fn g() {} // private due to m2_1
    |         help: consider using: `pub`
 
 error: pub(crate) module inside private module
-  --> tests/ui/redundant_pub_crate.rs:40:5
+  --> tests/ui/redundant_pub_crate.rs:41:5
    |
 LL |     pub(crate) mod m2_2 {
    |     ----------^^^^^^^^^
@@ -66,7 +66,7 @@ LL |     pub(crate) mod m2_2 {
    |     help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:43:9
+  --> tests/ui/redundant_pub_crate.rs:44:9
    |
 LL |         pub(crate) fn g() {} // already crate visible due to m2_2 and m2
    |         ----------^^^^^
@@ -74,7 +74,7 @@ LL |         pub(crate) fn g() {} // already crate visible due to m2_2 and m2
    |         help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:49:9
+  --> tests/ui/redundant_pub_crate.rs:50:9
    |
 LL |         pub(crate) fn g() {} // already crate visible due to m2
    |         ----------^^^^^
@@ -82,7 +82,7 @@ LL |         pub(crate) fn g() {} // already crate visible due to m2
    |         help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:61:9
+  --> tests/ui/redundant_pub_crate.rs:62:9
    |
 LL |         pub(crate) fn g() {} // private due to m3_1
    |         ----------^^^^^
@@ -90,7 +90,7 @@ LL |         pub(crate) fn g() {} // private due to m3_1
    |         help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:68:9
+  --> tests/ui/redundant_pub_crate.rs:69:9
    |
 LL |         pub(crate) fn g() {} // already crate visible due to m3_2
    |         ----------^^^^^
@@ -98,7 +98,7 @@ LL |         pub(crate) fn g() {} // already crate visible due to m3_2
    |         help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:81:5
+  --> tests/ui/redundant_pub_crate.rs:82:5
    |
 LL |     pub(crate) fn g() {} // private: not re-exported by `pub use m4::*`
    |     ----------^^^^^
@@ -106,7 +106,7 @@ LL |     pub(crate) fn g() {} // private: not re-exported by `pub use m4::*`
    |     help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:86:9
+  --> tests/ui/redundant_pub_crate.rs:87:9
    |
 LL |         pub(crate) fn g() {} // private due to m4_1
    |         ----------^^^^^
@@ -114,7 +114,7 @@ LL |         pub(crate) fn g() {} // private due to m4_1
    |         help: consider using: `pub`
 
 error: pub(crate) module inside private module
-  --> tests/ui/redundant_pub_crate.rs:90:5
+  --> tests/ui/redundant_pub_crate.rs:91:5
    |
 LL |     pub(crate) mod m4_2 {
    |     ----------^^^^^^^^^
@@ -122,7 +122,7 @@ LL |     pub(crate) mod m4_2 {
    |     help: consider using: `pub`
 
 error: pub(crate) function inside private module
-  --> tests/ui/redundant_pub_crate.rs:93:9
+  --> tests/ui/redundant_pub_crate.rs:94:9
    |
 LL |         pub(crate) fn g() {} // private due to m4_2
    |         ----------^^^^^
diff --git a/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr b/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr
index 25ab9822382..233416351a0 100644
--- a/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr
+++ b/src/tools/clippy/tests/ui/ref_binding_to_reference.stderr
@@ -8,8 +8,9 @@ LL |         Some(ref x) => x,
    = help: to override `-D warnings` add `#[allow(clippy::ref_binding_to_reference)]`
 help: try
    |
-LL |         Some(x) => &x,
-   |              ~     ~~
+LL -         Some(ref x) => x,
+LL +         Some(x) => &x,
+   |
 
 error: this pattern creates a reference to a reference
   --> tests/ui/ref_binding_to_reference.rs:38:14
@@ -34,8 +35,9 @@ LL |         Some(ref x) => m2!(x),
    |
 help: try
    |
-LL |         Some(x) => m2!(&x),
-   |              ~         ~~
+LL -         Some(ref x) => m2!(x),
+LL +         Some(x) => m2!(&x),
+   |
 
 error: this pattern creates a reference to a reference
   --> tests/ui/ref_binding_to_reference.rs:55:15
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
index b4c69ac6296..fd30628bdd8 100644
--- a/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr
@@ -55,8 +55,9 @@ 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>>) {}
-   |                   ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+LL - fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+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
@@ -85,8 +86,9 @@ 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>>) {}
-   |                           ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+LL - pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+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
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
index 17c90536da3..d3428f1891f 100644
--- a/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr
@@ -55,8 +55,9 @@ 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>>) {}
-   |                   ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+LL - fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+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
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 47d6e119543..501811fa491 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -13,9 +13,8 @@
 #![allow(clippy::disallowed_methods)]
 #![allow(clippy::disallowed_types)]
 #![allow(clippy::mixed_read_write_in_expression)]
-#![allow(clippy::manual_find_map)]
 #![allow(clippy::manual_filter_map)]
-#![allow(unpredictable_function_pointer_comparisons)]
+#![allow(clippy::manual_find_map)]
 #![allow(clippy::useless_conversion)]
 #![allow(clippy::redundant_pattern_matching)]
 #![allow(clippy::match_result_ok)]
@@ -30,6 +29,7 @@
 #![allow(clippy::unwrap_used)]
 #![allow(clippy::panicking_overflow_checks)]
 #![allow(clippy::needless_borrow)]
+#![allow(clippy::reversed_empty_ranges)]
 #![allow(clippy::single_char_add_str)]
 #![allow(clippy::module_name_repetitions)]
 #![allow(clippy::missing_const_for_thread_local)]
@@ -39,9 +39,11 @@
 #![allow(invalid_reference_casting)]
 #![allow(suspicious_double_ref_op)]
 #![allow(invalid_nan_comparisons)]
+#![allow(double_negations)]
 #![allow(drop_bounds)]
 #![allow(dropping_copy_types)]
 #![allow(dropping_references)]
+#![allow(unpredictable_function_pointer_comparisons)]
 #![allow(useless_ptr_null_checks)]
 #![allow(for_loops_over_fallibles)]
 #![allow(forgetting_copy_types)]
@@ -60,8 +62,6 @@
 #![allow(unknown_lints)]
 #![allow(unused_labels)]
 #![allow(ambiguous_wide_pointer_comparisons)]
-#![allow(unpredictable_function_pointer_comparisons)]
-#![allow(clippy::reversed_empty_ranges)]
 #![warn(clippy::almost_complete_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`
 #![warn(clippy::disallowed_names)] //~ ERROR: lint `clippy::blacklisted_name`
 #![warn(clippy::blocks_in_conditions)] //~ ERROR: lint `clippy::block_in_if_condition_expr`
@@ -74,9 +74,8 @@
 #![warn(clippy::disallowed_methods)] //~ ERROR: lint `clippy::disallowed_method`
 #![warn(clippy::disallowed_types)] //~ ERROR: lint `clippy::disallowed_type`
 #![warn(clippy::mixed_read_write_in_expression)] //~ ERROR: lint `clippy::eval_order_dependence`
-#![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map`
 #![warn(clippy::manual_filter_map)] //~ ERROR: lint `clippy::filter_map`
-#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`
+#![warn(clippy::manual_find_map)] //~ ERROR: lint `clippy::find_map`
 #![warn(clippy::useless_conversion)] //~ ERROR: lint `clippy::identity_conversion`
 #![warn(clippy::redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`
 #![warn(clippy::match_result_ok)] //~ ERROR: lint `clippy::if_let_some_result`
@@ -95,6 +94,7 @@
 #![warn(clippy::expect_used)] //~ ERROR: lint `clippy::result_expect_used`
 #![warn(clippy::map_unwrap_or)] //~ ERROR: lint `clippy::result_map_unwrap_or_else`
 #![warn(clippy::unwrap_used)] //~ ERROR: lint `clippy::result_unwrap_used`
+#![warn(clippy::reversed_empty_ranges)] //~ ERROR: lint `clippy::reverse_range_loop`
 #![warn(clippy::single_char_add_str)] //~ ERROR: lint `clippy::single_char_push_str`
 #![warn(clippy::module_name_repetitions)] //~ ERROR: lint `clippy::stutter`
 #![warn(clippy::missing_const_for_thread_local)] //~ ERROR: lint `clippy::thread_local_initializer_can_be_made_const`
@@ -104,9 +104,11 @@
 #![warn(invalid_reference_casting)] //~ ERROR: lint `clippy::cast_ref_to_mut`
 #![warn(suspicious_double_ref_op)] //~ ERROR: lint `clippy::clone_double_ref`
 #![warn(invalid_nan_comparisons)] //~ ERROR: lint `clippy::cmp_nan`
+#![warn(double_negations)] //~ ERROR: lint `clippy::double_neg`
 #![warn(drop_bounds)] //~ ERROR: lint `clippy::drop_bounds`
 #![warn(dropping_copy_types)] //~ ERROR: lint `clippy::drop_copy`
 #![warn(dropping_references)] //~ ERROR: lint `clippy::drop_ref`
+#![warn(unpredictable_function_pointer_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`
 #![warn(useless_ptr_null_checks)] //~ ERROR: lint `clippy::fn_null_check`
 #![warn(for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loop_over_option`
 #![warn(for_loops_over_fallibles)] //~ ERROR: lint `clippy::for_loop_over_result`
@@ -128,6 +130,5 @@
 #![warn(unknown_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints`
 #![warn(unused_labels)] //~ ERROR: lint `clippy::unused_label`
 #![warn(ambiguous_wide_pointer_comparisons)] //~ ERROR: lint `clippy::vtable_address_comparisons`
-#![warn(clippy::reversed_empty_ranges)] //~ ERROR: lint `clippy::reverse_range_loop`
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 12c7db69be2..7f4b8062e1b 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -13,9 +13,8 @@
 #![allow(clippy::disallowed_methods)]
 #![allow(clippy::disallowed_types)]
 #![allow(clippy::mixed_read_write_in_expression)]
-#![allow(clippy::manual_find_map)]
 #![allow(clippy::manual_filter_map)]
-#![allow(unpredictable_function_pointer_comparisons)]
+#![allow(clippy::manual_find_map)]
 #![allow(clippy::useless_conversion)]
 #![allow(clippy::redundant_pattern_matching)]
 #![allow(clippy::match_result_ok)]
@@ -30,6 +29,7 @@
 #![allow(clippy::unwrap_used)]
 #![allow(clippy::panicking_overflow_checks)]
 #![allow(clippy::needless_borrow)]
+#![allow(clippy::reversed_empty_ranges)]
 #![allow(clippy::single_char_add_str)]
 #![allow(clippy::module_name_repetitions)]
 #![allow(clippy::missing_const_for_thread_local)]
@@ -39,9 +39,11 @@
 #![allow(invalid_reference_casting)]
 #![allow(suspicious_double_ref_op)]
 #![allow(invalid_nan_comparisons)]
+#![allow(double_negations)]
 #![allow(drop_bounds)]
 #![allow(dropping_copy_types)]
 #![allow(dropping_references)]
+#![allow(unpredictable_function_pointer_comparisons)]
 #![allow(useless_ptr_null_checks)]
 #![allow(for_loops_over_fallibles)]
 #![allow(forgetting_copy_types)]
@@ -60,8 +62,6 @@
 #![allow(unknown_lints)]
 #![allow(unused_labels)]
 #![allow(ambiguous_wide_pointer_comparisons)]
-#![allow(unpredictable_function_pointer_comparisons)]
-#![allow(clippy::reversed_empty_ranges)]
 #![warn(clippy::almost_complete_letter_range)] //~ ERROR: lint `clippy::almost_complete_letter_range`
 #![warn(clippy::blacklisted_name)] //~ ERROR: lint `clippy::blacklisted_name`
 #![warn(clippy::block_in_if_condition_expr)] //~ ERROR: lint `clippy::block_in_if_condition_expr`
@@ -74,9 +74,8 @@
 #![warn(clippy::disallowed_method)] //~ ERROR: lint `clippy::disallowed_method`
 #![warn(clippy::disallowed_type)] //~ ERROR: lint `clippy::disallowed_type`
 #![warn(clippy::eval_order_dependence)] //~ ERROR: lint `clippy::eval_order_dependence`
-#![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map`
 #![warn(clippy::filter_map)] //~ ERROR: lint `clippy::filter_map`
-#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`
+#![warn(clippy::find_map)] //~ ERROR: lint `clippy::find_map`
 #![warn(clippy::identity_conversion)] //~ ERROR: lint `clippy::identity_conversion`
 #![warn(clippy::if_let_redundant_pattern_matching)] //~ ERROR: lint `clippy::if_let_redundant_pattern_matching`
 #![warn(clippy::if_let_some_result)] //~ ERROR: lint `clippy::if_let_some_result`
@@ -95,6 +94,7 @@
 #![warn(clippy::result_expect_used)] //~ ERROR: lint `clippy::result_expect_used`
 #![warn(clippy::result_map_unwrap_or_else)] //~ ERROR: lint `clippy::result_map_unwrap_or_else`
 #![warn(clippy::result_unwrap_used)] //~ ERROR: lint `clippy::result_unwrap_used`
+#![warn(clippy::reverse_range_loop)] //~ ERROR: lint `clippy::reverse_range_loop`
 #![warn(clippy::single_char_push_str)] //~ ERROR: lint `clippy::single_char_push_str`
 #![warn(clippy::stutter)] //~ ERROR: lint `clippy::stutter`
 #![warn(clippy::thread_local_initializer_can_be_made_const)] //~ ERROR: lint `clippy::thread_local_initializer_can_be_made_const`
@@ -104,9 +104,11 @@
 #![warn(clippy::cast_ref_to_mut)] //~ ERROR: lint `clippy::cast_ref_to_mut`
 #![warn(clippy::clone_double_ref)] //~ ERROR: lint `clippy::clone_double_ref`
 #![warn(clippy::cmp_nan)] //~ ERROR: lint `clippy::cmp_nan`
+#![warn(clippy::double_neg)] //~ ERROR: lint `clippy::double_neg`
 #![warn(clippy::drop_bounds)] //~ ERROR: lint `clippy::drop_bounds`
 #![warn(clippy::drop_copy)] //~ ERROR: lint `clippy::drop_copy`
 #![warn(clippy::drop_ref)] //~ ERROR: lint `clippy::drop_ref`
+#![warn(clippy::fn_address_comparisons)] //~ ERROR: lint `clippy::fn_address_comparisons`
 #![warn(clippy::fn_null_check)] //~ ERROR: lint `clippy::fn_null_check`
 #![warn(clippy::for_loop_over_option)] //~ ERROR: lint `clippy::for_loop_over_option`
 #![warn(clippy::for_loop_over_result)] //~ ERROR: lint `clippy::for_loop_over_result`
@@ -128,6 +130,5 @@
 #![warn(clippy::unknown_clippy_lints)] //~ ERROR: lint `clippy::unknown_clippy_lints`
 #![warn(clippy::unused_label)] //~ ERROR: lint `clippy::unused_label`
 #![warn(clippy::vtable_address_comparisons)] //~ ERROR: lint `clippy::vtable_address_comparisons`
-#![warn(clippy::reverse_range_loop)] //~ ERROR: lint `clippy::reverse_range_loop`
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 1ec45c4f1f7..f24eaec3917 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -73,132 +73,132 @@ error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_r
 LL | #![warn(clippy::eval_order_dependence)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
 
-error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map`
-  --> tests/ui/rename.rs:77:9
-   |
-LL | #![warn(clippy::find_map)]
-   |         ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map`
-
 error: lint `clippy::filter_map` has been renamed to `clippy::manual_filter_map`
-  --> tests/ui/rename.rs:78:9
+  --> tests/ui/rename.rs:77:9
    |
 LL | #![warn(clippy::filter_map)]
    |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_filter_map`
 
-error: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons`
-  --> tests/ui/rename.rs:79:9
+error: lint `clippy::find_map` has been renamed to `clippy::manual_find_map`
+  --> tests/ui/rename.rs:78:9
    |
-LL | #![warn(clippy::fn_address_comparisons)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons`
+LL | #![warn(clippy::find_map)]
+   |         ^^^^^^^^^^^^^^^^ help: use the new name: `clippy::manual_find_map`
 
 error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
-  --> tests/ui/rename.rs:80:9
+  --> tests/ui/rename.rs:79:9
    |
 LL | #![warn(clippy::identity_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
 
 error: lint `clippy::if_let_redundant_pattern_matching` has been renamed to `clippy::redundant_pattern_matching`
-  --> tests/ui/rename.rs:81:9
+  --> tests/ui/rename.rs:80:9
    |
 LL | #![warn(clippy::if_let_redundant_pattern_matching)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_pattern_matching`
 
 error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
-  --> tests/ui/rename.rs:82:9
+  --> tests/ui/rename.rs:81:9
    |
 LL | #![warn(clippy::if_let_some_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
 
 error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl`
-  --> tests/ui/rename.rs:83:9
+  --> tests/ui/rename.rs:82:9
    |
 LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl`
 
 error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl`
-  --> tests/ui/rename.rs:84:9
+  --> tests/ui/rename.rs:83:9
    |
 LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl`
 
 error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
-  --> tests/ui/rename.rs:85:9
+  --> tests/ui/rename.rs:84:9
    |
 LL | #![warn(clippy::integer_arithmetic)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`
 
 error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
-  --> tests/ui/rename.rs:86:9
+  --> tests/ui/rename.rs:85:9
    |
 LL | #![warn(clippy::logic_bug)]
    |         ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
 
 error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
-  --> tests/ui/rename.rs:87:9
+  --> tests/ui/rename.rs:86:9
    |
 LL | #![warn(clippy::new_without_default_derive)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
 
 error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
-  --> tests/ui/rename.rs:88:9
+  --> tests/ui/rename.rs:87:9
    |
 LL | #![warn(clippy::option_and_then_some)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
 
 error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
-  --> tests/ui/rename.rs:89:9
+  --> tests/ui/rename.rs:88:9
    |
 LL | #![warn(clippy::option_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
-  --> tests/ui/rename.rs:90:9
+  --> tests/ui/rename.rs:89:9
    |
 LL | #![warn(clippy::option_map_unwrap_or)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> tests/ui/rename.rs:91:9
+  --> tests/ui/rename.rs:90:9
    |
 LL | #![warn(clippy::option_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> tests/ui/rename.rs:92:9
+  --> tests/ui/rename.rs:91:9
    |
 LL | #![warn(clippy::option_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::overflow_check_conditional` has been renamed to `clippy::panicking_overflow_checks`
-  --> tests/ui/rename.rs:93:9
+  --> tests/ui/rename.rs:92:9
    |
 LL | #![warn(clippy::overflow_check_conditional)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::panicking_overflow_checks`
 
 error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
-  --> tests/ui/rename.rs:94:9
+  --> tests/ui/rename.rs:93:9
    |
 LL | #![warn(clippy::ref_in_deref)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
 
 error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
-  --> tests/ui/rename.rs:95:9
+  --> tests/ui/rename.rs:94:9
    |
 LL | #![warn(clippy::result_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> tests/ui/rename.rs:96:9
+  --> tests/ui/rename.rs:95:9
    |
 LL | #![warn(clippy::result_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> tests/ui/rename.rs:97:9
+  --> tests/ui/rename.rs:96:9
    |
 LL | #![warn(clippy::result_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
+error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges`
+  --> tests/ui/rename.rs:97:9
+   |
+LL | #![warn(clippy::reverse_range_loop)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges`
+
 error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
   --> tests/ui/rename.rs:98:9
    |
@@ -253,155 +253,161 @@ error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`
 LL | #![warn(clippy::cmp_nan)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`
 
-error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
+error: lint `clippy::double_neg` has been renamed to `double_negations`
   --> tests/ui/rename.rs:107:9
    |
+LL | #![warn(clippy::double_neg)]
+   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `double_negations`
+
+error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
+  --> tests/ui/rename.rs:108:9
+   |
 LL | #![warn(clippy::drop_bounds)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
 
 error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
-  --> tests/ui/rename.rs:108:9
+  --> tests/ui/rename.rs:109:9
    |
 LL | #![warn(clippy::drop_copy)]
    |         ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
 
 error: lint `clippy::drop_ref` has been renamed to `dropping_references`
-  --> tests/ui/rename.rs:109:9
+  --> tests/ui/rename.rs:110:9
    |
 LL | #![warn(clippy::drop_ref)]
    |         ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
 
+error: lint `clippy::fn_address_comparisons` has been renamed to `unpredictable_function_pointer_comparisons`
+  --> tests/ui/rename.rs:111:9
+   |
+LL | #![warn(clippy::fn_address_comparisons)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons`
+
 error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`
-  --> tests/ui/rename.rs:110:9
+  --> tests/ui/rename.rs:112:9
    |
 LL | #![warn(clippy::fn_null_check)]
    |         ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks`
 
 error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
-  --> tests/ui/rename.rs:111:9
+  --> tests/ui/rename.rs:113:9
    |
 LL | #![warn(clippy::for_loop_over_option)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
-  --> tests/ui/rename.rs:112:9
+  --> tests/ui/rename.rs:114:9
    |
 LL | #![warn(clippy::for_loop_over_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
-  --> tests/ui/rename.rs:113:9
+  --> tests/ui/rename.rs:115:9
    |
 LL | #![warn(clippy::for_loops_over_fallibles)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
-  --> tests/ui/rename.rs:114:9
+  --> tests/ui/rename.rs:116:9
    |
 LL | #![warn(clippy::forget_copy)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
 
 error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
-  --> tests/ui/rename.rs:115:9
+  --> tests/ui/rename.rs:117:9
    |
 LL | #![warn(clippy::forget_ref)]
    |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
 
 error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
-  --> tests/ui/rename.rs:116:9
+  --> tests/ui/rename.rs:118:9
    |
 LL | #![warn(clippy::into_iter_on_array)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
 
 error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
-  --> tests/ui/rename.rs:117:9
+  --> tests/ui/rename.rs:119:9
    |
 LL | #![warn(clippy::invalid_atomic_ordering)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
 
 error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
-  --> tests/ui/rename.rs:118:9
+  --> tests/ui/rename.rs:120:9
    |
 LL | #![warn(clippy::invalid_ref)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
 
 error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`
-  --> tests/ui/rename.rs:119:9
+  --> tests/ui/rename.rs:121:9
    |
 LL | #![warn(clippy::invalid_utf8_in_unchecked)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
 
 error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
-  --> tests/ui/rename.rs:120:9
+  --> tests/ui/rename.rs:122:9
    |
 LL | #![warn(clippy::let_underscore_drop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
 
 error: lint `clippy::maybe_misused_cfg` has been renamed to `unexpected_cfgs`
-  --> tests/ui/rename.rs:121:9
+  --> tests/ui/rename.rs:123:9
    |
 LL | #![warn(clippy::maybe_misused_cfg)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
 
 error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> tests/ui/rename.rs:122:9
+  --> tests/ui/rename.rs:124:9
    |
 LL | #![warn(clippy::mem_discriminant_non_enum)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
 error: lint `clippy::mismatched_target_os` has been renamed to `unexpected_cfgs`
-  --> tests/ui/rename.rs:123:9
+  --> tests/ui/rename.rs:125:9
    |
 LL | #![warn(clippy::mismatched_target_os)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unexpected_cfgs`
 
 error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
-  --> tests/ui/rename.rs:124:9
+  --> tests/ui/rename.rs:126:9
    |
 LL | #![warn(clippy::panic_params)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
 
 error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
-  --> tests/ui/rename.rs:125:9
+  --> tests/ui/rename.rs:127:9
    |
 LL | #![warn(clippy::positional_named_format_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
 
 error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `dangling_pointers_from_temporaries`
-  --> tests/ui/rename.rs:126:9
+  --> tests/ui/rename.rs:128:9
    |
 LL | #![warn(clippy::temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `dangling_pointers_from_temporaries`
 
 error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
-  --> tests/ui/rename.rs:127:9
+  --> tests/ui/rename.rs:129:9
    |
 LL | #![warn(clippy::undropped_manually_drops)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
 
 error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
-  --> tests/ui/rename.rs:128:9
+  --> tests/ui/rename.rs:130:9
    |
 LL | #![warn(clippy::unknown_clippy_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
 
 error: lint `clippy::unused_label` has been renamed to `unused_labels`
-  --> tests/ui/rename.rs:129:9
+  --> tests/ui/rename.rs:131:9
    |
 LL | #![warn(clippy::unused_label)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
 error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons`
-  --> tests/ui/rename.rs:130:9
+  --> tests/ui/rename.rs:132:9
    |
 LL | #![warn(clippy::vtable_address_comparisons)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons`
 
-error: lint `clippy::reverse_range_loop` has been renamed to `clippy::reversed_empty_ranges`
-  --> tests/ui/rename.rs:131:9
-   |
-LL | #![warn(clippy::reverse_range_loop)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges`
-
-error: aborting due to 67 previous errors
+error: aborting due to 68 previous errors
 
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
index 43027c9cb89..05513a8859a 100644
--- a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
@@ -9,8 +9,9 @@ LL |         vec![Vec::<()>::with_capacity(42); 123];
    = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]`
 help: if you intended to initialize multiple `Vec`s with an initial capacity, try
    |
-LL |         (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -         vec![Vec::<()>::with_capacity(42); 123];
+LL +         (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
+   |
 
 error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
   --> tests/ui/repeat_vec_with_capacity.rs:12:9
@@ -21,8 +22,9 @@ LL |         vec![Vec::<()>::with_capacity(42); n];
    = note: only the last `Vec` will have the capacity
 help: if you intended to initialize multiple `Vec`s with an initial capacity, try
    |
-LL |         (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -         vec![Vec::<()>::with_capacity(42); n];
+LL +         (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
+   |
 
 error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity
   --> tests/ui/repeat_vec_with_capacity.rs:27:9
@@ -33,8 +35,9 @@ LL |         std::iter::repeat(Vec::<()>::with_capacity(42));
    = note: none of the yielded `Vec`s will have the requested capacity
 help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try
    |
-LL |         std::iter::repeat_with(|| Vec::<()>::with_capacity(42));
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -         std::iter::repeat(Vec::<()>::with_capacity(42));
+LL +         std::iter::repeat_with(|| Vec::<()>::with_capacity(42));
+   |
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.fixed b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.fixed
new file mode 100644
index 00000000000..ef316f1def4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::repeat_vec_with_capacity)]
+#![allow(clippy::manual_repeat_n)]
+#![no_std]
+use core::iter;
+extern crate alloc;
+use alloc::vec::Vec;
+
+fn nostd() {
+    let _: Vec<Vec<u8>> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect();
+}
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.rs b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.rs
new file mode 100644
index 00000000000..83b418a5667
--- /dev/null
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::repeat_vec_with_capacity)]
+#![allow(clippy::manual_repeat_n)]
+#![no_std]
+use core::iter;
+extern crate alloc;
+use alloc::vec::Vec;
+
+fn nostd() {
+    let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();
+}
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr
new file mode 100644
index 00000000000..092167485ce
--- /dev/null
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity_nostd.stderr
@@ -0,0 +1,17 @@
+error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity
+  --> tests/ui/repeat_vec_with_capacity_nostd.rs:9:27
+   |
+LL |     let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: none of the yielded `Vec`s will have the requested capacity
+   = note: `-D clippy::repeat-vec-with-capacity` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]`
+help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try
+   |
+LL -     let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();
+LL +     let _: Vec<Vec<u8>> = core::iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect();
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/return_and_then.fixed b/src/tools/clippy/tests/ui/return_and_then.fixed
new file mode 100644
index 00000000000..9736a51ac86
--- /dev/null
+++ b/src/tools/clippy/tests/ui/return_and_then.fixed
@@ -0,0 +1,67 @@
+#![warn(clippy::return_and_then)]
+
+fn main() {
+    fn test_opt_block(opt: Option<i32>) -> Option<i32> {
+        let n = opt?;
+        let mut ret = n + 1;
+        ret += n;
+        if n > 1 { Some(ret) } else { None }
+    }
+
+    fn test_opt_func(opt: Option<i32>) -> Option<i32> {
+        let n = opt?;
+        test_opt_block(Some(n))
+    }
+
+    fn test_call_chain() -> Option<i32> {
+        let n = gen_option(1)?;
+        test_opt_block(Some(n))
+    }
+
+    fn test_res_block(opt: Result<i32, i32>) -> Result<i32, i32> {
+        let n = opt?;
+        if n > 1 { Ok(n + 1) } else { Err(n) }
+    }
+
+    fn test_res_func(opt: Result<i32, i32>) -> Result<i32, i32> {
+        let n = opt?;
+        test_res_block(Ok(n))
+    }
+
+    fn test_ref_only() -> Option<i32> {
+        // ref: empty string
+        let x = Some("")?;
+        if x.len() > 2 { Some(3) } else { None }
+    }
+
+    fn test_tmp_only() -> Option<i32> {
+        // unused temporary: vec![1, 2, 4]
+        let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) {
+            (a, _) if a.len() > 1 => a,
+            (_, b) => b,
+        })?;
+        if x.len() > 2 { Some(3) } else { None }
+    }
+
+    // should not lint
+    fn test_tmp_ref() -> Option<String> {
+        String::from("<BOOM>")
+            .strip_prefix("<")
+            .and_then(|s| s.strip_suffix(">").map(String::from))
+    }
+
+    // should not lint
+    fn test_unconsumed_tmp() -> Option<i32> {
+        [1, 2, 3]
+            .iter()
+            .map(|x| x + 1)
+            .collect::<Vec<_>>() // temporary Vec created here
+            .as_slice() // creates temporary slice
+            .first() // creates temporary reference
+            .and_then(|x| test_opt_block(Some(*x)))
+    }
+}
+
+fn gen_option(n: i32) -> Option<i32> {
+    Some(n)
+}
diff --git a/src/tools/clippy/tests/ui/return_and_then.rs b/src/tools/clippy/tests/ui/return_and_then.rs
new file mode 100644
index 00000000000..8bcbdfc3a63
--- /dev/null
+++ b/src/tools/clippy/tests/ui/return_and_then.rs
@@ -0,0 +1,63 @@
+#![warn(clippy::return_and_then)]
+
+fn main() {
+    fn test_opt_block(opt: Option<i32>) -> Option<i32> {
+        opt.and_then(|n| {
+            let mut ret = n + 1;
+            ret += n;
+            if n > 1 { Some(ret) } else { None }
+        })
+    }
+
+    fn test_opt_func(opt: Option<i32>) -> Option<i32> {
+        opt.and_then(|n| test_opt_block(Some(n)))
+    }
+
+    fn test_call_chain() -> Option<i32> {
+        gen_option(1).and_then(|n| test_opt_block(Some(n)))
+    }
+
+    fn test_res_block(opt: Result<i32, i32>) -> Result<i32, i32> {
+        opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) })
+    }
+
+    fn test_res_func(opt: Result<i32, i32>) -> Result<i32, i32> {
+        opt.and_then(|n| test_res_block(Ok(n)))
+    }
+
+    fn test_ref_only() -> Option<i32> {
+        // ref: empty string
+        Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None })
+    }
+
+    fn test_tmp_only() -> Option<i32> {
+        // unused temporary: vec![1, 2, 4]
+        Some(match (vec![1, 2, 3], vec![1, 2, 4]) {
+            (a, _) if a.len() > 1 => a,
+            (_, b) => b,
+        })
+        .and_then(|x| if x.len() > 2 { Some(3) } else { None })
+    }
+
+    // should not lint
+    fn test_tmp_ref() -> Option<String> {
+        String::from("<BOOM>")
+            .strip_prefix("<")
+            .and_then(|s| s.strip_suffix(">").map(String::from))
+    }
+
+    // should not lint
+    fn test_unconsumed_tmp() -> Option<i32> {
+        [1, 2, 3]
+            .iter()
+            .map(|x| x + 1)
+            .collect::<Vec<_>>() // temporary Vec created here
+            .as_slice() // creates temporary slice
+            .first() // creates temporary reference
+            .and_then(|x| test_opt_block(Some(*x)))
+    }
+}
+
+fn gen_option(n: i32) -> Option<i32> {
+    Some(n)
+}
diff --git a/src/tools/clippy/tests/ui/return_and_then.stderr b/src/tools/clippy/tests/ui/return_and_then.stderr
new file mode 100644
index 00000000000..b2e8bf2ca45
--- /dev/null
+++ b/src/tools/clippy/tests/ui/return_and_then.stderr
@@ -0,0 +1,101 @@
+error: use the question mark operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:5:9
+   |
+LL | /         opt.and_then(|n| {
+LL | |             let mut ret = n + 1;
+LL | |             ret += n;
+LL | |             if n > 1 { Some(ret) } else { None }
+LL | |         })
+   | |__________^
+   |
+   = note: `-D clippy::return-and-then` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::return_and_then)]`
+help: try
+   |
+LL ~         let n = opt?;
+LL +         let mut ret = n + 1;
+LL +         ret += n;
+LL +         if n > 1 { Some(ret) } else { None }
+   |
+
+error: use the question mark operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:13:9
+   |
+LL |         opt.and_then(|n| test_opt_block(Some(n)))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~         let n = opt?;
+LL +         test_opt_block(Some(n))
+   |
+
+error: use the question mark operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:17:9
+   |
+LL |         gen_option(1).and_then(|n| test_opt_block(Some(n)))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~         let n = gen_option(1)?;
+LL +         test_opt_block(Some(n))
+   |
+
+error: use the question mark operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:21:9
+   |
+LL |         opt.and_then(|n| if n > 1 { Ok(n + 1) } else { Err(n) })
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~         let n = opt?;
+LL +         if n > 1 { Ok(n + 1) } else { Err(n) }
+   |
+
+error: use the question mark operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:25:9
+   |
+LL |         opt.and_then(|n| test_res_block(Ok(n)))
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~         let n = opt?;
+LL +         test_res_block(Ok(n))
+   |
+
+error: use the question mark operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:30:9
+   |
+LL |         Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None })
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~         let x = Some("")?;
+LL +         if x.len() > 2 { Some(3) } else { None }
+   |
+
+error: use the question mark operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:35:9
+   |
+LL | /         Some(match (vec![1, 2, 3], vec![1, 2, 4]) {
+LL | |             (a, _) if a.len() > 1 => a,
+LL | |             (_, b) => b,
+LL | |         })
+LL | |         .and_then(|x| if x.len() > 2 { Some(3) } else { None })
+   | |_______________________________________________________________^
+   |
+help: try
+   |
+LL ~         let x = Some(match (vec![1, 2, 3], vec![1, 2, 4]) {
+LL +             (a, _) if a.len() > 1 => a,
+LL +             (_, b) => b,
+LL +         })?;
+LL +         if x.len() > 2 { Some(3) } else { None }
+   |
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr
index 3747eb9deeb..24cb959c96a 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_fixable.stderr
@@ -8,8 +8,9 @@ LL |     (42..=21).for_each(|x| println!("{}", x));
    = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     (21..=42).rev().for_each(|x| println!("{}", x));
-   |     ~~~~~~~~~~~~~~~
+LL -     (42..=21).for_each(|x| println!("{}", x));
+LL +     (21..=42).rev().for_each(|x| println!("{}", x));
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_fixable.rs:10:13
@@ -19,8 +20,9 @@ LL |     let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>(
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();
-   |             ~~~~~~~~~~~~~~~~~~
+LL -     let _ = (ANSWER..21).filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();
+LL +     let _ = (21..ANSWER).rev().filter(|x| x % 2 == 0).take(10).collect::<Vec<_>>();
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_fixable.rs:12:14
@@ -30,8 +32,9 @@ LL |     for _ in -21..=-42 {}
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for _ in (-42..=-21).rev() {}
-   |              ~~~~~~~~~~~~~~~~~
+LL -     for _ in -21..=-42 {}
+LL +     for _ in (-42..=-21).rev() {}
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_fixable.rs:13:14
@@ -41,8 +44,9 @@ LL |     for _ in 42u32..21u32 {}
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for _ in (21u32..42u32).rev() {}
-   |              ~~~~~~~~~~~~~~~~~~~~
+LL -     for _ in 42u32..21u32 {}
+LL +     for _ in (21u32..42u32).rev() {}
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr
index d5df34c42f4..3e9ccb653fe 100644
--- a/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr
+++ b/src/tools/clippy/tests/ui/reversed_empty_ranges_loops_fixable.stderr
@@ -8,8 +8,9 @@ LL |     for i in 10..0 {
    = help: to override `-D warnings` add `#[allow(clippy::reversed_empty_ranges)]`
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for i in (0..10).rev() {
-   |              ~~~~~~~~~~~~~
+LL -     for i in 10..0 {
+LL +     for i in (0..10).rev() {
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_loops_fixable.rs:11:14
@@ -19,8 +20,9 @@ LL |     for i in 10..=0 {
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for i in (0..=10).rev() {
-   |              ~~~~~~~~~~~~~~
+LL -     for i in 10..=0 {
+LL +     for i in (0..=10).rev() {
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_loops_fixable.rs:15:14
@@ -30,8 +32,9 @@ LL |     for i in MAX_LEN..0 {
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for i in (0..MAX_LEN).rev() {
-   |              ~~~~~~~~~~~~~~~~~~
+LL -     for i in MAX_LEN..0 {
+LL +     for i in (0..MAX_LEN).rev() {
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_loops_fixable.rs:34:14
@@ -41,8 +44,9 @@ LL |     for i in (10..0).map(|x| x * 2) {
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for i in (0..10).rev().map(|x| x * 2) {
-   |              ~~~~~~~~~~~~~
+LL -     for i in (10..0).map(|x| x * 2) {
+LL +     for i in (0..10).rev().map(|x| x * 2) {
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_loops_fixable.rs:39:14
@@ -52,8 +56,9 @@ LL |     for i in 10..5 + 4 {
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for i in (5 + 4..10).rev() {
-   |              ~~~~~~~~~~~~~~~~~
+LL -     for i in 10..5 + 4 {
+LL +     for i in (5 + 4..10).rev() {
+   |
 
 error: this range is empty so it will yield no values
   --> tests/ui/reversed_empty_ranges_loops_fixable.rs:43:14
@@ -63,8 +68,9 @@ LL |     for i in (5 + 2)..(3 - 1) {
    |
 help: consider using the following if you are attempting to iterate over this range in reverse
    |
-LL |     for i in ((3 - 1)..(5 + 2)).rev() {
-   |              ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     for i in (5 + 2)..(3 - 1) {
+LL +     for i in ((3 - 1)..(5 + 2)).rev() {
+   |
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/same_item_push.rs b/src/tools/clippy/tests/ui/same_item_push.rs
index df9c2817f50..87fd59ad317 100644
--- a/src/tools/clippy/tests/ui/same_item_push.rs
+++ b/src/tools/clippy/tests/ui/same_item_push.rs
@@ -21,33 +21,43 @@ fn main() {
     let item = 2;
     for _ in 5..=20 {
         vec.push(item);
-        //~^ ERROR: it looks like the same item is being pushed into this Vec
+        //~^ ERROR: it looks like the same item is being pushed into this `Vec`
     }
 
     let mut vec: Vec<u8> = Vec::new();
     for _ in 0..15 {
         let item = 2;
         vec.push(item);
-        //~^ ERROR: it looks like the same item is being pushed into this Vec
+        //~^ ERROR: it looks like the same item is being pushed into this `Vec`
     }
 
     let mut vec: Vec<u8> = Vec::new();
     for _ in 0..15 {
         vec.push(13);
-        //~^ ERROR: it looks like the same item is being pushed into this Vec
+        //~^ ERROR: it looks like the same item is being pushed into this `Vec`
     }
 
     let mut vec = Vec::new();
     for _ in 0..20 {
         vec.push(VALUE);
-        //~^ ERROR: it looks like the same item is being pushed into this Vec
+        //~^ ERROR: it looks like the same item is being pushed into this `Vec`
     }
 
     let mut vec = Vec::new();
     let item = VALUE;
     for _ in 0..20 {
         vec.push(item);
-        //~^ ERROR: it looks like the same item is being pushed into this Vec
+        //~^ ERROR: it looks like the same item is being pushed into this `Vec`
+    }
+
+    #[clippy::msrv = "1.81"]
+    fn older_msrv() {
+        let mut vec = Vec::new();
+        let item = VALUE;
+        for _ in 0..20 {
+            vec.push(item);
+            //~^ ERROR: it looks like the same item is being pushed into this `Vec`
+        }
     }
 
     // ** non-linted cases **
diff --git a/src/tools/clippy/tests/ui/same_item_push.stderr b/src/tools/clippy/tests/ui/same_item_push.stderr
index eb296ed4ce4..e3fa4f9cbce 100644
--- a/src/tools/clippy/tests/ui/same_item_push.stderr
+++ b/src/tools/clippy/tests/ui/same_item_push.stderr
@@ -1,44 +1,58 @@
-error: it looks like the same item is being pushed into this Vec
+error: it looks like the same item is being pushed into this `Vec`
   --> tests/ui/same_item_push.rs:23:9
    |
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using `vec![item;SIZE]`
+   = help: or `vec.extend(std::iter::repeat_n(item, SIZE))`
    = note: `-D clippy::same-item-push` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::same_item_push)]`
 
-error: it looks like the same item is being pushed into this Vec
+error: it looks like the same item is being pushed into this `Vec`
   --> tests/ui/same_item_push.rs:30:9
    |
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using `vec![item;SIZE]`
+   = help: or `vec.extend(std::iter::repeat_n(item, SIZE))`
 
-error: it looks like the same item is being pushed into this Vec
+error: it looks like the same item is being pushed into this `Vec`
   --> tests/ui/same_item_push.rs:36:9
    |
 LL |         vec.push(13);
    |         ^^^
    |
-   = help: consider using vec![13;SIZE] or vec.resize(NEW_SIZE, 13)
+   = help: consider using `vec![13;SIZE]`
+   = help: or `vec.extend(std::iter::repeat_n(13, SIZE))`
 
-error: it looks like the same item is being pushed into this Vec
+error: it looks like the same item is being pushed into this `Vec`
   --> tests/ui/same_item_push.rs:42:9
    |
 LL |         vec.push(VALUE);
    |         ^^^
    |
-   = help: consider using vec![VALUE;SIZE] or vec.resize(NEW_SIZE, VALUE)
+   = help: consider using `vec![VALUE;SIZE]`
+   = help: or `vec.extend(std::iter::repeat_n(VALUE, SIZE))`
 
-error: it looks like the same item is being pushed into this Vec
+error: it looks like the same item is being pushed into this `Vec`
   --> tests/ui/same_item_push.rs:49:9
    |
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using `vec![item;SIZE]`
+   = help: or `vec.extend(std::iter::repeat_n(item, SIZE))`
 
-error: aborting due to 5 previous errors
+error: it looks like the same item is being pushed into this `Vec`
+  --> tests/ui/same_item_push.rs:58:13
+   |
+LL |             vec.push(item);
+   |             ^^^
+   |
+   = help: consider using `vec![item;SIZE]`
+   = help: or `vec.resize(NEW_SIZE, item)`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.fixed b/src/tools/clippy/tests/ui/short_circuit_statement.fixed
index a9930ef4dbb..a2bf07ac605 100644
--- a/src/tools/clippy/tests/ui/short_circuit_statement.fixed
+++ b/src/tools/clippy/tests/ui/short_circuit_statement.fixed
@@ -3,8 +3,35 @@
 
 fn main() {
     if f() { g(); }
+    //~^ ERROR: boolean short circuit operator in statement
     if !f() { g(); }
+    //~^ ERROR: boolean short circuit operator in statement
     if 1 != 2 { g(); }
+    //~^ ERROR: boolean short circuit operator in statement
+    if f() || g() { H * 2; }
+    //~^ ERROR: boolean short circuit operator in statement
+    if !(f() || g()) { H * 2; }
+    //~^ ERROR: boolean short circuit operator in statement
+
+    macro_rules! mac {
+        ($f:ident or $g:ident) => {
+            $f() || $g()
+        };
+        ($f:ident and $g:ident) => {
+            $f() && $g()
+        };
+        () => {
+            f() && g()
+        };
+    }
+
+    if mac!() { mac!(); }
+    //~^ ERROR: boolean short circuit operator in statement
+    if !mac!() { mac!(); }
+    //~^ ERROR: boolean short circuit operator in statement
+
+    // Do not lint if the expression comes from a macro
+    mac!();
 }
 
 fn f() -> bool {
@@ -14,3 +41,12 @@ fn f() -> bool {
 fn g() -> bool {
     false
 }
+
+struct H;
+
+impl std::ops::Mul<u32> for H {
+    type Output = bool;
+    fn mul(self, other: u32) -> Self::Output {
+        true
+    }
+}
diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.rs b/src/tools/clippy/tests/ui/short_circuit_statement.rs
index 71f7c7f2abf..bdba546ad8f 100644
--- a/src/tools/clippy/tests/ui/short_circuit_statement.rs
+++ b/src/tools/clippy/tests/ui/short_circuit_statement.rs
@@ -3,8 +3,35 @@
 
 fn main() {
     f() && g();
+    //~^ ERROR: boolean short circuit operator in statement
     f() || g();
+    //~^ ERROR: boolean short circuit operator in statement
     1 == 2 || g();
+    //~^ ERROR: boolean short circuit operator in statement
+    (f() || g()) && (H * 2);
+    //~^ ERROR: boolean short circuit operator in statement
+    (f() || g()) || (H * 2);
+    //~^ ERROR: boolean short circuit operator in statement
+
+    macro_rules! mac {
+        ($f:ident or $g:ident) => {
+            $f() || $g()
+        };
+        ($f:ident and $g:ident) => {
+            $f() && $g()
+        };
+        () => {
+            f() && g()
+        };
+    }
+
+    mac!() && mac!();
+    //~^ ERROR: boolean short circuit operator in statement
+    mac!() || mac!();
+    //~^ ERROR: boolean short circuit operator in statement
+
+    // Do not lint if the expression comes from a macro
+    mac!();
 }
 
 fn f() -> bool {
@@ -14,3 +41,12 @@ fn f() -> bool {
 fn g() -> bool {
     false
 }
+
+struct H;
+
+impl std::ops::Mul<u32> for H {
+    type Output = bool;
+    fn mul(self, other: u32) -> Self::Output {
+        true
+    }
+}
diff --git a/src/tools/clippy/tests/ui/short_circuit_statement.stderr b/src/tools/clippy/tests/ui/short_circuit_statement.stderr
index e7a8f2ca60c..ecf6676405b 100644
--- a/src/tools/clippy/tests/ui/short_circuit_statement.stderr
+++ b/src/tools/clippy/tests/ui/short_circuit_statement.stderr
@@ -8,16 +8,40 @@ LL |     f() && g();
    = help: to override `-D warnings` add `#[allow(clippy::short_circuit_statement)]`
 
 error: boolean short circuit operator in statement may be clearer using an explicit test
-  --> tests/ui/short_circuit_statement.rs:6:5
+  --> tests/ui/short_circuit_statement.rs:7:5
    |
 LL |     f() || g();
    |     ^^^^^^^^^^^ help: replace it with: `if !f() { g(); }`
 
 error: boolean short circuit operator in statement may be clearer using an explicit test
-  --> tests/ui/short_circuit_statement.rs:7:5
+  --> tests/ui/short_circuit_statement.rs:9:5
    |
 LL |     1 == 2 || g();
    |     ^^^^^^^^^^^^^^ help: replace it with: `if 1 != 2 { g(); }`
 
-error: aborting due to 3 previous errors
+error: boolean short circuit operator in statement may be clearer using an explicit test
+  --> tests/ui/short_circuit_statement.rs:11:5
+   |
+LL |     (f() || g()) && (H * 2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `if f() || g() { H * 2; }`
+
+error: boolean short circuit operator in statement may be clearer using an explicit test
+  --> tests/ui/short_circuit_statement.rs:13:5
+   |
+LL |     (f() || g()) || (H * 2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `if !(f() || g()) { H * 2; }`
+
+error: boolean short circuit operator in statement may be clearer using an explicit test
+  --> tests/ui/short_circuit_statement.rs:28:5
+   |
+LL |     mac!() && mac!();
+   |     ^^^^^^^^^^^^^^^^^ help: replace it with: `if mac!() { mac!(); }`
+
+error: boolean short circuit operator in statement may be clearer using an explicit test
+  --> tests/ui/short_circuit_statement.rs:30:5
+   |
+LL |     mac!() || mac!();
+   |     ^^^^^^^^^^^^^^^^^ help: replace it with: `if !mac!() { mac!(); }`
+
+error: aborting due to 7 previous errors
 
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 8468d1d7c7d..39d550398d7 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
@@ -832,4 +832,36 @@ fn should_trigger_lint_in_while_let() {
     }
 }
 
+async fn foo_async(mutex: &Mutex<i32>) -> Option<MutexGuard<'_, i32>> {
+    Some(mutex.lock().unwrap())
+}
+
+async fn should_trigger_lint_for_async(mutex: Mutex<i32>) -> i32 {
+    match *foo_async(&mutex).await.unwrap() {
+        n if n < 10 => n,
+        _ => 10,
+    }
+}
+
+async fn should_not_trigger_lint_in_async_expansion(mutex: Mutex<i32>) -> i32 {
+    match foo_async(&mutex).await {
+        Some(guard) => *guard,
+        _ => 0,
+    }
+}
+
+fn should_trigger_lint_in_match_expr() {
+    let mutex = Mutex::new(State {});
+
+    // Should trigger lint because the lifetime of the temporary MutexGuard is surprising because it
+    // is preserved until the end of the match, but there is no clear indication that this is the
+    // case.
+    let _ = match mutex.lock().unwrap().foo() {
+        //~^ ERROR: temporary with significant `Drop` in `match` scrutinee will live until the
+        //~| NOTE: this might lead to deadlocks or other unexpected behavior
+        true => 0,
+        false => 1,
+    };
+}
+
 fn main() {}
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 62030cbe70e..f99d862aa6b 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
@@ -568,5 +568,37 @@ LL |     }
    |
    = note: this might lead to deadlocks or other unexpected behavior
 
-error: aborting due to 29 previous errors
+error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
+  --> tests/ui/significant_drop_in_scrutinee.rs:840:11
+   |
+LL |     match *foo_async(&mutex).await.unwrap() {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     }
+   |      - temporary lives until here
+   |
+   = note: this might lead to deadlocks or other unexpected behavior
+help: try moving the temporary above the match
+   |
+LL ~     let value = *foo_async(&mutex).await.unwrap();
+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:859:19
+   |
+LL |     let _ = match mutex.lock().unwrap().foo() {
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     };
+   |      - temporary lives until here
+   |
+   = note: this might lead to deadlocks or other unexpected behavior
+help: try moving the temporary above the match
+   |
+LL ~     let value = mutex.lock().unwrap().foo();
+LL ~     let _ = match value {
+   |
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr b/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr
index 9c125adb51a..b3bc8dd4aca 100644
--- a/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr
+++ b/src/tools/clippy/tests/ui/single_range_in_vec_init.stderr
@@ -8,12 +8,14 @@ LL |     [0..200];
    = help: to override `-D warnings` add `#[allow(clippy::single_range_in_vec_init)]`
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0..200).collect::<std::vec::Vec<i32>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     [0..200];
+LL +     (0..200).collect::<std::vec::Vec<i32>>();
+   |
 help: if you wanted an array of len 200, try
    |
-LL |     [0; 200];
-   |      ~~~~~~
+LL -     [0..200];
+LL +     [0; 200];
+   |
 
 error: a `Vec` of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:27:5
@@ -23,12 +25,14 @@ LL |     vec![0..200];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0..200).collect::<std::vec::Vec<i32>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     vec![0..200];
+LL +     (0..200).collect::<std::vec::Vec<i32>>();
+   |
 help: if you wanted a `Vec` of len 200, try
    |
-LL |     vec![0; 200];
-   |          ~~~~~~
+LL -     vec![0..200];
+LL +     vec![0; 200];
+   |
 
 error: an array of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:28:5
@@ -38,12 +42,14 @@ LL |     [0u8..200];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0u8..200).collect::<std::vec::Vec<u8>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     [0u8..200];
+LL +     (0u8..200).collect::<std::vec::Vec<u8>>();
+   |
 help: if you wanted an array of len 200, try
    |
-LL |     [0u8; 200];
-   |      ~~~~~~~~
+LL -     [0u8..200];
+LL +     [0u8; 200];
+   |
 
 error: an array of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:29:5
@@ -53,12 +59,14 @@ LL |     [0usize..200];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0usize..200).collect::<std::vec::Vec<usize>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     [0usize..200];
+LL +     (0usize..200).collect::<std::vec::Vec<usize>>();
+   |
 help: if you wanted an array of len 200, try
    |
-LL |     [0usize; 200];
-   |      ~~~~~~~~~~~
+LL -     [0usize..200];
+LL +     [0usize; 200];
+   |
 
 error: an array of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:30:5
@@ -68,12 +76,14 @@ LL |     [0..200usize];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0..200usize).collect::<std::vec::Vec<usize>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     [0..200usize];
+LL +     (0..200usize).collect::<std::vec::Vec<usize>>();
+   |
 help: if you wanted an array of len 200usize, try
    |
-LL |     [0; 200usize];
-   |      ~~~~~~~~~~~
+LL -     [0..200usize];
+LL +     [0; 200usize];
+   |
 
 error: a `Vec` of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:31:5
@@ -83,12 +93,14 @@ LL |     vec![0u8..200];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0u8..200).collect::<std::vec::Vec<u8>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     vec![0u8..200];
+LL +     (0u8..200).collect::<std::vec::Vec<u8>>();
+   |
 help: if you wanted a `Vec` of len 200, try
    |
-LL |     vec![0u8; 200];
-   |          ~~~~~~~~
+LL -     vec![0u8..200];
+LL +     vec![0u8; 200];
+   |
 
 error: a `Vec` of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:32:5
@@ -98,12 +110,14 @@ LL |     vec![0usize..200];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0usize..200).collect::<std::vec::Vec<usize>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     vec![0usize..200];
+LL +     (0usize..200).collect::<std::vec::Vec<usize>>();
+   |
 help: if you wanted a `Vec` of len 200, try
    |
-LL |     vec![0usize; 200];
-   |          ~~~~~~~~~~~
+LL -     vec![0usize..200];
+LL +     vec![0usize; 200];
+   |
 
 error: a `Vec` of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:33:5
@@ -113,12 +127,14 @@ LL |     vec![0..200usize];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0..200usize).collect::<std::vec::Vec<usize>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     vec![0..200usize];
+LL +     (0..200usize).collect::<std::vec::Vec<usize>>();
+   |
 help: if you wanted a `Vec` of len 200usize, try
    |
-LL |     vec![0; 200usize];
-   |          ~~~~~~~~~~~
+LL -     vec![0..200usize];
+LL +     vec![0; 200usize];
+   |
 
 error: an array of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:35:5
@@ -128,8 +144,9 @@ LL |     [0..200isize];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0..200isize).collect::<std::vec::Vec<isize>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     [0..200isize];
+LL +     (0..200isize).collect::<std::vec::Vec<isize>>();
+   |
 
 error: a `Vec` of `Range` that is only one element
   --> tests/ui/single_range_in_vec_init.rs:36:5
@@ -139,8 +156,9 @@ LL |     vec![0..200isize];
    |
 help: if you wanted a `Vec` that contains the entire range, try
    |
-LL |     (0..200isize).collect::<std::vec::Vec<isize>>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     vec![0..200isize];
+LL +     (0..200isize).collect::<std::vec::Vec<isize>>();
+   |
 
 error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs
index 91b7ea3922c..f405ba200ac 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.rs
@@ -8,11 +8,11 @@ fn main() {
     const SIZE: usize = 128;
     const HALF_SIZE: usize = SIZE / 2;
     const DOUBLE_SIZE: usize = SIZE * 2;
-    let mut x = [2u8; SIZE];
-    let mut y = [2u8; SIZE];
+    let mut x = [2u16; SIZE];
+    let mut y = [2u16; SIZE];
 
     // Count expression involving multiplication of size_of (Should trigger the lint)
-    unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
+    unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>() * SIZE) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
     // Count expression involving nested multiplications of size_of (Should trigger the lint)
@@ -20,22 +20,19 @@ fn main() {
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
     // Count expression involving divisions of size_of (Should trigger the lint)
-    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u8>() / 2) };
+    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u16>() / 2) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
     // Count expression involving divisions by size_of (Should not trigger the lint)
-    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::<u8>()) };
+    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / size_of::<u16>()) };
 
     // Count expression involving divisions by multiple size_of (Should not trigger the lint)
-    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 * size_of::<u8>())) };
+    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 * size_of::<u16>())) };
 
     // Count expression involving recursive divisions by size_of (Should trigger the lint)
-    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u8>())) };
+    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u16>())) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
     // No size_of calls (Should not trigger the lint)
     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), SIZE) };
-
-    // Different types for pointee and size_of (Should not trigger the lint)
-    unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::<u16>() / 2 * SIZE) };
 }
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
index 6396afd7f39..74be0d7773d 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/expressions.stderr
@@ -1,8 +1,8 @@
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/expressions.rs:15:62
    |
-LL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>() * SIZE) };
-   |                                                              ^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>() * SIZE) };
+   |                                                              ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
    = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
@@ -19,16 +19,16 @@ LL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), HALF_SIZE * si
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/expressions.rs:23:47
    |
-LL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u8>() / 2) };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE * size_of::<u16>() / 2) };
+   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/expressions.rs:33:47
    |
-LL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u8>())) };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), DOUBLE_SIZE / (2 / size_of::<u16>())) };
+   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs
index 3501cbdf81c..af18136a1db 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.rs
@@ -11,57 +11,52 @@ fn main() {
     const SIZE: usize = 128;
     const HALF_SIZE: usize = SIZE / 2;
     const DOUBLE_SIZE: usize = SIZE * 2;
-    let mut x = [2u8; SIZE];
-    let mut y = [2u8; SIZE];
+    let mut x = [2u16; SIZE];
+    let mut y = [2u16; SIZE];
 
     // Count is size_of (Should trigger the lint)
-    unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
+    unsafe { copy_nonoverlapping::<u16>(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
-    unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u8>()) };
+    unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u8>()) };
+    unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u8>()) };
+    unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u8>()) };
+    unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
-    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
+    unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
-    unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::<u8>() * SIZE) };
-    //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::<u8>() * SIZE) };
-    //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-
-    unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u8>() * SIZE) };
+    unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u16>() * SIZE) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
-    slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE);
+    slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE);
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    slice_from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE);
+    slice_from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE);
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
-    unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE) };
+    unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    unsafe { from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE) };
+    unsafe { from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 
-    unsafe { y.as_mut_ptr().sub(size_of::<u8>()) };
+    unsafe { y.as_mut_ptr().sub(size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    y.as_ptr().wrapping_sub(size_of::<u8>());
+    y.as_ptr().wrapping_sub(size_of::<u16>());
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    unsafe { y.as_ptr().add(size_of::<u8>()) };
+    unsafe { y.as_ptr().add(size_of::<u16>()) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    y.as_mut_ptr().wrapping_add(size_of::<u8>());
+    y.as_mut_ptr().wrapping_add(size_of::<u16>());
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    unsafe { y.as_ptr().offset(size_of::<u8>() as isize) };
+    unsafe { y.as_ptr().offset(size_of::<u16>() as isize) };
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
-    y.as_mut_ptr().wrapping_offset(size_of::<u8>() as isize);
+    y.as_mut_ptr().wrapping_offset(size_of::<u16>() as isize);
     //~^ ERROR: found a count of bytes instead of a count of elements of `T`
 }
diff --git a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
index abde7dc7cd2..de54789b225 100644
--- a/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
+++ b/src/tools/clippy/tests/ui/size_of_in_element_count/functions.stderr
@@ -1,8 +1,8 @@
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:18:68
+  --> tests/ui/size_of_in_element_count/functions.rs:18:69
    |
-LL |     unsafe { copy_nonoverlapping::<u8>(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
-   |                                                                    ^^^^^^^^^^^^^^^
+LL |     unsafe { copy_nonoverlapping::<u16>(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };
+   |                                                                     ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
    = note: `-D clippy::size-of-in-element-count` implied by `-D warnings`
@@ -19,40 +19,40 @@ LL |     unsafe { copy_nonoverlapping(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/functions.rs:23:49
    |
-LL |     unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u8>()) };
-   |                                                 ^^^^^^^^^^^^^^^
+LL |     unsafe { x.as_ptr().copy_to(y.as_mut_ptr(), size_of::<u16>()) };
+   |                                                 ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/functions.rs:25:64
    |
-LL |     unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u8>()) };
-   |                                                                ^^^^^^^^^^^^^^^
+LL |     unsafe { x.as_ptr().copy_to_nonoverlapping(y.as_mut_ptr(), size_of::<u16>()) };
+   |                                                                ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/functions.rs:27:51
    |
-LL |     unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u8>()) };
-   |                                                   ^^^^^^^^^^^^^^^
+LL |     unsafe { y.as_mut_ptr().copy_from(x.as_ptr(), size_of::<u16>()) };
+   |                                                   ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/functions.rs:29:66
    |
-LL |     unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u8>()) };
-   |                                                                  ^^^^^^^^^^^^^^^
+LL |     unsafe { y.as_mut_ptr().copy_from_nonoverlapping(x.as_ptr(), size_of::<u16>()) };
+   |                                                                  ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
   --> tests/ui/size_of_in_element_count/functions.rs:32:47
    |
-LL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u8>()) };
-   |                                               ^^^^^^^^^^^^^^^
+LL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of::<u16>()) };
+   |                                               ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
@@ -65,108 +65,92 @@ LL |     unsafe { copy(x.as_ptr(), y.as_mut_ptr(), size_of_val(&x[0])) };
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:37:46
+  --> tests/ui/size_of_in_element_count/functions.rs:37:66
    |
-LL |     unsafe { y.as_mut_ptr().write_bytes(0u8, size_of::<u8>() * SIZE) };
-   |                                              ^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u16>() * SIZE) };
+   |                                                                  ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:39:47
+  --> tests/ui/size_of_in_element_count/functions.rs:40:46
    |
-LL |     unsafe { write_bytes(y.as_mut_ptr(), 0u8, size_of::<u8>() * SIZE) };
-   |                                               ^^^^^^^^^^^^^^^^^^^^^^
+LL |     slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE);
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:42:66
+  --> tests/ui/size_of_in_element_count/functions.rs:42:38
    |
-LL |     unsafe { swap_nonoverlapping(y.as_mut_ptr(), x.as_mut_ptr(), size_of::<u8>() * SIZE) };
-   |                                                                  ^^^^^^^^^^^^^^^^^^^^^^
+LL |     slice_from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE);
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:45:46
+  --> tests/ui/size_of_in_element_count/functions.rs:45:49
    |
-LL |     slice_from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE);
-   |                                              ^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u16>() * SIZE) };
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:47:38
+  --> tests/ui/size_of_in_element_count/functions.rs:47:41
    |
-LL |     slice_from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE);
-   |                                      ^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { from_raw_parts(y.as_ptr(), size_of::<u16>() * SIZE) };
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:50:49
+  --> tests/ui/size_of_in_element_count/functions.rs:50:33
    |
-LL |     unsafe { from_raw_parts_mut(y.as_mut_ptr(), size_of::<u8>() * SIZE) };
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^
+LL |     unsafe { y.as_mut_ptr().sub(size_of::<u16>()) };
+   |                                 ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:52:41
+  --> tests/ui/size_of_in_element_count/functions.rs:52:29
    |
-LL |     unsafe { from_raw_parts(y.as_ptr(), size_of::<u8>() * SIZE) };
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^
+LL |     y.as_ptr().wrapping_sub(size_of::<u16>());
+   |                             ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:55:33
+  --> tests/ui/size_of_in_element_count/functions.rs:54:29
    |
-LL |     unsafe { y.as_mut_ptr().sub(size_of::<u8>()) };
-   |                                 ^^^^^^^^^^^^^^^
+LL |     unsafe { y.as_ptr().add(size_of::<u16>()) };
+   |                             ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:57:29
+  --> tests/ui/size_of_in_element_count/functions.rs:56:33
    |
-LL |     y.as_ptr().wrapping_sub(size_of::<u8>());
-   |                             ^^^^^^^^^^^^^^^
+LL |     y.as_mut_ptr().wrapping_add(size_of::<u16>());
+   |                                 ^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:59:29
+  --> tests/ui/size_of_in_element_count/functions.rs:58:32
    |
-LL |     unsafe { y.as_ptr().add(size_of::<u8>()) };
-   |                             ^^^^^^^^^^^^^^^
+LL |     unsafe { y.as_ptr().offset(size_of::<u16>() as isize) };
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
 error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:61:33
+  --> tests/ui/size_of_in_element_count/functions.rs:60:36
    |
-LL |     y.as_mut_ptr().wrapping_add(size_of::<u8>());
-   |                                 ^^^^^^^^^^^^^^^
+LL |     y.as_mut_ptr().wrapping_offset(size_of::<u16>() as isize);
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
 
-error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:63:32
-   |
-LL |     unsafe { y.as_ptr().offset(size_of::<u8>() as isize) };
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
-
-error: found a count of bytes instead of a count of elements of `T`
-  --> tests/ui/size_of_in_element_count/functions.rs:65:36
-   |
-LL |     y.as_mut_ptr().wrapping_offset(size_of::<u8>() as isize);
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = help: use a count of elements instead of a count of bytes, it already gets multiplied by the size of the type
-
-error: aborting due to 21 previous errors
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/sliced_string_as_bytes.fixed b/src/tools/clippy/tests/ui/sliced_string_as_bytes.fixed
new file mode 100644
index 00000000000..469ad27a99b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/sliced_string_as_bytes.fixed
@@ -0,0 +1,34 @@
+#![allow(unused)]
+#![warn(clippy::sliced_string_as_bytes)]
+
+use std::ops::{Index, Range};
+
+struct Foo;
+
+struct Bar;
+
+impl Bar {
+    fn as_bytes(&self) -> &[u8] {
+        &[0, 1, 2, 3]
+    }
+}
+
+impl Index<Range<usize>> for Foo {
+    type Output = Bar;
+
+    fn index(&self, _: Range<usize>) -> &Self::Output {
+        &Bar
+    }
+}
+
+fn main() {
+    let s = "Lorem ipsum";
+    let string: String = "dolor sit amet".to_owned();
+
+    let bytes = &s.as_bytes()[1..5];
+    let bytes = &string.as_bytes()[1..];
+    let bytes = &"consectetur adipiscing".as_bytes()[..=5];
+
+    let f = Foo;
+    let bytes = f[0..4].as_bytes();
+}
diff --git a/src/tools/clippy/tests/ui/sliced_string_as_bytes.rs b/src/tools/clippy/tests/ui/sliced_string_as_bytes.rs
new file mode 100644
index 00000000000..4a4605e5a1a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/sliced_string_as_bytes.rs
@@ -0,0 +1,34 @@
+#![allow(unused)]
+#![warn(clippy::sliced_string_as_bytes)]
+
+use std::ops::{Index, Range};
+
+struct Foo;
+
+struct Bar;
+
+impl Bar {
+    fn as_bytes(&self) -> &[u8] {
+        &[0, 1, 2, 3]
+    }
+}
+
+impl Index<Range<usize>> for Foo {
+    type Output = Bar;
+
+    fn index(&self, _: Range<usize>) -> &Self::Output {
+        &Bar
+    }
+}
+
+fn main() {
+    let s = "Lorem ipsum";
+    let string: String = "dolor sit amet".to_owned();
+
+    let bytes = s[1..5].as_bytes();
+    let bytes = string[1..].as_bytes();
+    let bytes = "consectetur adipiscing"[..=5].as_bytes();
+
+    let f = Foo;
+    let bytes = f[0..4].as_bytes();
+}
diff --git a/src/tools/clippy/tests/ui/sliced_string_as_bytes.stderr b/src/tools/clippy/tests/ui/sliced_string_as_bytes.stderr
new file mode 100644
index 00000000000..1342f4c01a4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/sliced_string_as_bytes.stderr
@@ -0,0 +1,23 @@
+error: calling `as_bytes` after slicing a string
+  --> tests/ui/sliced_string_as_bytes.rs:28:17
+   |
+LL |     let bytes = s[1..5].as_bytes();
+   |                 ^^^^^^^^^^^^^^^^^^ help: try: `&s.as_bytes()[1..5]`
+   |
+   = note: `-D clippy::sliced-string-as-bytes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::sliced_string_as_bytes)]`
+
+error: calling `as_bytes` after slicing a string
+  --> tests/ui/sliced_string_as_bytes.rs:29:17
+   |
+LL |     let bytes = string[1..].as_bytes();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&string.as_bytes()[1..]`
+
+error: calling `as_bytes` after slicing a string
+  --> tests/ui/sliced_string_as_bytes.rs:30:17
+   |
+LL |     let bytes = "consectetur adipiscing"[..=5].as_bytes();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&"consectetur adipiscing".as_bytes()[..=5]`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/slow_vector_initialization.fixed b/src/tools/clippy/tests/ui/slow_vector_initialization.fixed
new file mode 100644
index 00000000000..a8570366e64
--- /dev/null
+++ b/src/tools/clippy/tests/ui/slow_vector_initialization.fixed
@@ -0,0 +1,86 @@
+#![allow(clippy::useless_vec, clippy::manual_repeat_n)]
+
+use std::iter::repeat;
+fn main() {
+    resize_vector();
+    extend_vector();
+    mixed_extend_resize_vector();
+    from_empty_vec();
+}
+
+fn extend_vector() {
+    // Extend with constant expression
+    let len = 300;
+    let mut vec1 = vec![0; len];
+
+    // Extend with len expression
+    let mut vec2 = vec![0; len - 10];
+
+    // Extend with mismatching expression should not be warned
+    let mut vec3 = Vec::with_capacity(24322);
+    vec3.extend(repeat(0).take(2));
+
+    let mut vec4 = vec![0; len];
+}
+
+fn mixed_extend_resize_vector() {
+    // Mismatching len
+    let mut mismatching_len = Vec::with_capacity(30);
+    mismatching_len.extend(repeat(0).take(40));
+
+    // Slow initialization
+    let mut resized_vec = vec![0; 30];
+
+    let mut extend_vec = vec![0; 30];
+}
+
+fn resize_vector() {
+    // Resize with constant expression
+    let len = 300;
+    let mut vec1 = vec![0; len];
+
+    // Resize mismatch len
+    let mut vec2 = Vec::with_capacity(200);
+    vec2.resize(10, 0);
+
+    // Resize with len expression
+    let mut vec3 = vec![0; len - 10];
+
+    let mut vec4 = vec![0; len];
+
+    // Reinitialization should be warned
+    vec1 = vec![0; 10];
+}
+
+fn from_empty_vec() {
+    // Resize with constant expression
+    let len = 300;
+    let mut vec1 = vec![0; len];
+
+    // Resize with len expression
+    let mut vec3 = vec![0; len - 10];
+
+    // Reinitialization should be warned
+    vec1 = vec![0; 10];
+
+    vec1 = vec![0; 10];
+
+    macro_rules! x {
+        () => {
+            vec![]
+        };
+    }
+
+    // `vec![]` comes from another macro, don't warn
+    vec1 = x!();
+    vec1.resize(10, 0);
+}
+
+fn do_stuff(vec: &mut [u8]) {}
+
+fn extend_vector_with_manipulations_between() {
+    let len = 300;
+    let mut vec1: Vec<u8> = Vec::with_capacity(len);
+    do_stuff(&mut vec1);
+    vec1.extend(repeat(0).take(len));
+}
diff --git a/src/tools/clippy/tests/ui/slow_vector_initialization.rs b/src/tools/clippy/tests/ui/slow_vector_initialization.rs
index 2ba87f41250..4b30fad409e 100644
--- a/src/tools/clippy/tests/ui/slow_vector_initialization.rs
+++ b/src/tools/clippy/tests/ui/slow_vector_initialization.rs
@@ -1,4 +1,5 @@
-//@no-rustfix
+#![allow(clippy::useless_vec, clippy::manual_repeat_n)]
+
 use std::iter::repeat;
 fn main() {
     resize_vector();
diff --git a/src/tools/clippy/tests/ui/slow_vector_initialization.stderr b/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
index 7f4b9f7b67a..4a25cafcddf 100644
--- a/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
+++ b/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
@@ -1,5 +1,5 @@
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:13:20
+  --> tests/ui/slow_vector_initialization.rs:14:20
    |
 LL |       let mut vec1 = Vec::with_capacity(len);
    |  ____________________^
@@ -11,7 +11,7 @@ LL | |     vec1.extend(repeat(0).take(len));
    = help: to override `-D warnings` add `#[allow(clippy::slow_vector_initialization)]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:19:20
+  --> tests/ui/slow_vector_initialization.rs:20:20
    |
 LL |       let mut vec2 = Vec::with_capacity(len - 10);
    |  ____________________^
@@ -20,7 +20,7 @@ LL | |     vec2.extend(repeat(0).take(len - 10));
    | |_________________________________________^ help: consider replacing this with: `vec![0; len - 10]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:27:20
+  --> tests/ui/slow_vector_initialization.rs:28:20
    |
 LL |       let mut vec4 = Vec::with_capacity(len);
    |  ____________________^
@@ -29,7 +29,7 @@ LL | |     vec4.extend(repeat(0).take(vec4.capacity()));
    | |________________________________________________^ help: consider replacing this with: `vec![0; len]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:38:27
+  --> tests/ui/slow_vector_initialization.rs:39:27
    |
 LL |       let mut resized_vec = Vec::with_capacity(30);
    |  ___________________________^
@@ -38,7 +38,7 @@ LL | |     resized_vec.resize(30, 0);
    | |_____________________________^ help: consider replacing this with: `vec![0; 30]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:42:26
+  --> tests/ui/slow_vector_initialization.rs:43:26
    |
 LL |       let mut extend_vec = Vec::with_capacity(30);
    |  __________________________^
@@ -47,7 +47,7 @@ LL | |     extend_vec.extend(repeat(0).take(30));
    | |_________________________________________^ help: consider replacing this with: `vec![0; 30]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:50:20
+  --> tests/ui/slow_vector_initialization.rs:51:20
    |
 LL |       let mut vec1 = Vec::with_capacity(len);
    |  ____________________^
@@ -56,7 +56,7 @@ LL | |     vec1.resize(len, 0);
    | |_______________________^ help: consider replacing this with: `vec![0; len]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:59:20
+  --> tests/ui/slow_vector_initialization.rs:60:20
    |
 LL |       let mut vec3 = Vec::with_capacity(len - 10);
    |  ____________________^
@@ -65,7 +65,7 @@ LL | |     vec3.resize(len - 10, 0);
    | |____________________________^ help: consider replacing this with: `vec![0; len - 10]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:63:20
+  --> tests/ui/slow_vector_initialization.rs:64:20
    |
 LL |       let mut vec4 = Vec::with_capacity(len);
    |  ____________________^
@@ -74,7 +74,7 @@ LL | |     vec4.resize(vec4.capacity(), 0);
    | |___________________________________^ help: consider replacing this with: `vec![0; len]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:68:12
+  --> tests/ui/slow_vector_initialization.rs:69:12
    |
 LL |       vec1 = Vec::with_capacity(10);
    |  ____________^
@@ -83,7 +83,7 @@ LL | |     vec1.resize(10, 0);
    | |______________________^ help: consider replacing this with: `vec![0; 10]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:76:20
+  --> tests/ui/slow_vector_initialization.rs:77:20
    |
 LL |       let mut vec1 = Vec::new();
    |  ____________________^
@@ -92,7 +92,7 @@ LL | |     vec1.resize(len, 0);
    | |_______________________^ help: consider replacing this with: `vec![0; len]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:81:20
+  --> tests/ui/slow_vector_initialization.rs:82:20
    |
 LL |       let mut vec3 = Vec::new();
    |  ____________________^
@@ -101,7 +101,7 @@ LL | |     vec3.resize(len - 10, 0);
    | |____________________________^ help: consider replacing this with: `vec![0; len - 10]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:86:12
+  --> tests/ui/slow_vector_initialization.rs:87:12
    |
 LL |       vec1 = Vec::new();
    |  ____________^
@@ -110,7 +110,7 @@ LL | |     vec1.resize(10, 0);
    | |______________________^ help: consider replacing this with: `vec![0; 10]`
 
 error: slow zero-filling initialization
-  --> tests/ui/slow_vector_initialization.rs:90:12
+  --> tests/ui/slow_vector_initialization.rs:91:12
    |
 LL |       vec1 = vec![];
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/string_lit_chars_any.stderr b/src/tools/clippy/tests/ui/string_lit_chars_any.stderr
index 4d3ca98e623..1e28ae7b163 100644
--- a/src/tools/clippy/tests/ui/string_lit_chars_any.stderr
+++ b/src/tools/clippy/tests/ui/string_lit_chars_any.stderr
@@ -8,8 +8,9 @@ LL |     "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c);
    = help: to override `-D warnings` add `#[allow(clippy::string_lit_chars_any)]`
 help: use `matches!(...)` instead
    |
-LL |     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "\\.+*?()|[]{}^$#&-~".chars().any(|x| x == c);
+LL +     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+   |
 
 error: usage of `.chars().any(...)` to check if a char matches any from a string literal
   --> tests/ui/string_lit_chars_any.rs:19:5
@@ -19,8 +20,9 @@ LL |     r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c);
    |
 help: use `matches!(...)` instead
    |
-LL |     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| x == c);
+LL +     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+   |
 
 error: usage of `.chars().any(...)` to check if a char matches any from a string literal
   --> tests/ui/string_lit_chars_any.rs:20:5
@@ -30,8 +32,9 @@ LL |     "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x);
    |
 help: use `matches!(...)` instead
    |
-LL |     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "\\.+*?()|[]{}^$#&-~".chars().any(|x| c == x);
+LL +     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+   |
 
 error: usage of `.chars().any(...)` to check if a char matches any from a string literal
   --> tests/ui/string_lit_chars_any.rs:21:5
@@ -41,8 +44,9 @@ LL |     r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x);
    |
 help: use `matches!(...)` instead
    |
-LL |     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     r#"\.+*?()|[]{}^$#&-~"#.chars().any(|x| c == x);
+LL +     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+   |
 
 error: usage of `.chars().any(...)` to check if a char matches any from a string literal
   --> tests/ui/string_lit_chars_any.rs:23:5
@@ -52,8 +56,9 @@ LL |     "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c });
    |
 help: use `matches!(...)` instead
    |
-LL |     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     "\\.+*?()|[]{}^$#&-~".chars().any(|x| { x == c });
+LL +     matches!(c, '\\' | '.' | '+' | '*' | '?' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
+   |
 
 error: aborting due to 5 previous errors
 
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 6fd07d07d7b..8952a3ffe4b 100644
--- a/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_command_arg_space.stderr
@@ -8,8 +8,9 @@ LL |     std::process::Command::new("echo").arg("-n hello").spawn().unwrap();
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_command_arg_space)]`
 help: consider splitting the argument
    |
-LL |     std::process::Command::new("echo").args(["-n", "hello"]).spawn().unwrap();
-   |                                        ~~~~ ~~~~~~~~~~~~~~~
+LL -     std::process::Command::new("echo").arg("-n hello").spawn().unwrap();
+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:7:43
@@ -19,8 +20,9 @@ LL |     std::process::Command::new("cat").arg("--number file").spawn().unwrap()
    |
 help: consider splitting the argument
    |
-LL |     std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap();
-   |                                       ~~~~ ~~~~~~~~~~~~~~~~~~~~
+LL -     std::process::Command::new("cat").arg("--number file").spawn().unwrap();
+LL +     std::process::Command::new("cat").args(["--number", "file"]).spawn().unwrap();
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
index 614fc03571e..d3df6a41cb1 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.fixed
@@ -1,5 +1,6 @@
 #![allow(unused)]
 #![warn(clippy::suspicious_doc_comments)]
+#![allow(clippy::empty_line_after_doc_comments)]
 
 //! Real module documentation.
 //! Fake module documentation.
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
index 7dcba0fefc9..04db2b199c0 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.rs
@@ -1,5 +1,6 @@
 #![allow(unused)]
 #![warn(clippy::suspicious_doc_comments)]
+#![allow(clippy::empty_line_after_doc_comments)]
 
 //! Real module documentation.
 ///! Fake module documentation.
diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
index f12053b1595..7e5933df237 100644
--- a/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_doc_comments.stderr
@@ -1,5 +1,5 @@
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:5:1
+  --> tests/ui/suspicious_doc_comments.rs:6:1
    |
 LL | ///! Fake module documentation.
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,22 +8,24 @@ LL | ///! Fake module documentation.
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_doc_comments)]`
 help: use an inner doc comment to document the parent module or crate
    |
-LL | //! Fake module documentation.
+LL - ///! Fake module documentation.
+LL + //! Fake module documentation.
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:9:5
+  --> tests/ui/suspicious_doc_comments.rs:10:5
    |
 LL |     ///! This module contains useful functions.
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: use an inner doc comment to document the parent module or crate
    |
-LL |     //! This module contains useful functions.
+LL -     ///! This module contains useful functions.
+LL +     //! This module contains useful functions.
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:21:5
+  --> tests/ui/suspicious_doc_comments.rs:22:5
    |
 LL | /     /**! This module contains useful functions.
 LL | |      */
@@ -36,7 +38,7 @@ LL +      */
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:35:5
+  --> tests/ui/suspicious_doc_comments.rs:36:5
    |
 LL | /     ///! This module
 LL | |     ///! contains
@@ -51,7 +53,7 @@ LL ~     //! useful functions.
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:43:5
+  --> tests/ui/suspicious_doc_comments.rs:44:5
    |
 LL | /     ///! a
 LL | |     ///! b
@@ -64,18 +66,19 @@ LL ~     //! b
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:51:5
+  --> tests/ui/suspicious_doc_comments.rs:52:5
    |
 LL |     ///! a
    |     ^^^^^^
    |
 help: use an inner doc comment to document the parent module or crate
    |
-LL |     //! a
+LL -     ///! a
+LL +     //! a
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:57:5
+  --> tests/ui/suspicious_doc_comments.rs:58:5
    |
 LL | /     ///! a
 LL | |
@@ -90,25 +93,27 @@ LL ~     //! b
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:69:5
+  --> tests/ui/suspicious_doc_comments.rs:70:5
    |
 LL |     ///! Very cool macro
    |     ^^^^^^^^^^^^^^^^^^^^
    |
 help: use an inner doc comment to document the parent module or crate
    |
-LL |     //! Very cool macro
+LL -     ///! Very cool macro
+LL +     //! Very cool macro
    |
 
 error: this is an outer doc comment and does not apply to the parent module or crate
-  --> tests/ui/suspicious_doc_comments.rs:76:5
+  --> tests/ui/suspicious_doc_comments.rs:77:5
    |
 LL |     ///! Huh.
    |     ^^^^^^^^^
    |
 help: use an inner doc comment to document the parent module or crate
    |
-LL |     //! Huh.
+LL -     ///! Huh.
+LL +     //! Huh.
    |
 
 error: aborting due to 9 previous errors
diff --git a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
index 255f211e655..74bbcfcca51 100644
--- a/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_to_owned.stderr
@@ -8,12 +8,14 @@ LL |     let _ = cow.to_owned();
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_to_owned)]`
 help: depending on intent, either make the Cow an Owned variant
    |
-LL |     let _ = cow.into_owned();
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.into_owned();
+   |
 help: or clone the Cow itself
    |
-LL |     let _ = cow.clone();
-   |             ~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.clone();
+   |
 
 error: this `to_owned` call clones the Cow<'_, [char; 3]> itself and does not cause the Cow<'_, [char; 3]> contents to become owned
   --> tests/ui/suspicious_to_owned.rs:29:13
@@ -23,12 +25,14 @@ LL |     let _ = cow.to_owned();
    |
 help: depending on intent, either make the Cow an Owned variant
    |
-LL |     let _ = cow.into_owned();
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.into_owned();
+   |
 help: or clone the Cow itself
    |
-LL |     let _ = cow.clone();
-   |             ~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.clone();
+   |
 
 error: this `to_owned` call clones the Cow<'_, Vec<char>> itself and does not cause the Cow<'_, Vec<char>> contents to become owned
   --> tests/ui/suspicious_to_owned.rs:40:13
@@ -38,12 +42,14 @@ LL |     let _ = cow.to_owned();
    |
 help: depending on intent, either make the Cow an Owned variant
    |
-LL |     let _ = cow.into_owned();
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.into_owned();
+   |
 help: or clone the Cow itself
    |
-LL |     let _ = cow.clone();
-   |             ~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.clone();
+   |
 
 error: this `to_owned` call clones the Cow<'_, str> itself and does not cause the Cow<'_, str> contents to become owned
   --> tests/ui/suspicious_to_owned.rs:51:13
@@ -53,12 +59,14 @@ LL |     let _ = cow.to_owned();
    |
 help: depending on intent, either make the Cow an Owned variant
    |
-LL |     let _ = cow.into_owned();
-   |             ~~~~~~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.into_owned();
+   |
 help: or clone the Cow itself
    |
-LL |     let _ = cow.clone();
-   |             ~~~~~~~~~~~
+LL -     let _ = cow.to_owned();
+LL +     let _ = cow.clone();
+   |
 
 error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
   --> tests/ui/suspicious_to_owned.rs:66:13
diff --git a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr
index 43b03676b1d..2a153169bd3 100644
--- a/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_xor_used_as_pow.stderr
@@ -8,8 +8,9 @@ LL |     let _ = 2 ^ 5;
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_xor_used_as_pow)]`
 help: did you mean to write
    |
-LL |     let _ = 2.pow(5);
-   |             ~~~~~~~~
+LL -     let _ = 2 ^ 5;
+LL +     let _ = 2.pow(5);
+   |
 
 error: `^` is not the exponentiation operator
   --> tests/ui/suspicious_xor_used_as_pow.rs:22:13
@@ -19,8 +20,9 @@ LL |     let _ = 2i32 ^ 9i32;
    |
 help: did you mean to write
    |
-LL |     let _ = 2i32.pow(9i32);
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = 2i32 ^ 9i32;
+LL +     let _ = 2i32.pow(9i32);
+   |
 
 error: `^` is not the exponentiation operator
   --> tests/ui/suspicious_xor_used_as_pow.rs:24:13
@@ -30,8 +32,9 @@ LL |     let _ = 2i32 ^ 2i32;
    |
 help: did you mean to write
    |
-LL |     let _ = 2i32.pow(2i32);
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = 2i32 ^ 2i32;
+LL +     let _ = 2i32.pow(2i32);
+   |
 
 error: `^` is not the exponentiation operator
   --> tests/ui/suspicious_xor_used_as_pow.rs:26:13
@@ -41,8 +44,9 @@ LL |     let _ = 50i32 ^ 3i32;
    |
 help: did you mean to write
    |
-LL |     let _ = 50i32.pow(3i32);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = 50i32 ^ 3i32;
+LL +     let _ = 50i32.pow(3i32);
+   |
 
 error: `^` is not the exponentiation operator
   --> tests/ui/suspicious_xor_used_as_pow.rs:28:13
@@ -52,8 +56,9 @@ LL |     let _ = 5i32 ^ 8i32;
    |
 help: did you mean to write
    |
-LL |     let _ = 5i32.pow(8i32);
-   |             ~~~~~~~~~~~~~~
+LL -     let _ = 5i32 ^ 8i32;
+LL +     let _ = 5i32.pow(8i32);
+   |
 
 error: `^` is not the exponentiation operator
   --> tests/ui/suspicious_xor_used_as_pow.rs:30:13
@@ -63,8 +68,9 @@ LL |     let _ = 2i32 ^ 32i32;
    |
 help: did you mean to write
    |
-LL |     let _ = 2i32.pow(32i32);
-   |             ~~~~~~~~~~~~~~~
+LL -     let _ = 2i32 ^ 32i32;
+LL +     let _ = 2i32.pow(32i32);
+   |
 
 error: `^` is not the exponentiation operator
   --> tests/ui/suspicious_xor_used_as_pow.rs:13:9
@@ -78,8 +84,9 @@ LL |     macro_test_inside!();
    = note: this error originates in the macro `macro_test_inside` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: did you mean to write
    |
-LL |         1.pow(2) // should warn even if inside macro
-   |         ~~~~~~~~
+LL -         1 ^ 2 // should warn even if inside macro
+LL +         1.pow(2) // should warn even if inside macro
+   |
 
 error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr
index fb8fb1a0090..26166e2fc8d 100644
--- a/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr
+++ b/src/tools/clippy/tests/ui/toplevel_ref_arg_non_rustfix.stderr
@@ -1,4 +1,4 @@
-error: `ref` directly on a function argument is ignored. Consider using a reference type instead
+error: `ref` directly on a function parameter does not prevent taking ownership of the passed argument. Consider using a reference type instead
   --> tests/ui/toplevel_ref_arg_non_rustfix.rs:9:15
    |
 LL | fn the_answer(ref mut x: u8) {
@@ -7,7 +7,7 @@ LL | fn the_answer(ref mut x: u8) {
    = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::toplevel_ref_arg)]`
 
-error: `ref` directly on a function argument is ignored. Consider using a reference type instead
+error: `ref` directly on a function parameter does not prevent taking ownership of the passed argument. Consider using a reference type instead
   --> tests/ui/toplevel_ref_arg_non_rustfix.rs:20:24
    |
 LL |         fn fun_example(ref _x: usize) {}
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr
index 8801eb943ce..f4f83cd7ac6 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.stderr
@@ -8,8 +8,9 @@ LL |         let _: *const f32 = transmute(ptr);
    = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
 help: use `pointer::cast` instead
    |
-LL |         let _: *const f32 = ptr.cast::<f32>();
-   |                             ~~~~~~~~~~~~~~~~~
+LL -         let _: *const f32 = transmute(ptr);
+LL +         let _: *const f32 = ptr.cast::<f32>();
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:34:27
@@ -19,8 +20,9 @@ LL |         let _: *mut f32 = transmute(mut_ptr);
    |
 help: use `pointer::cast` instead
    |
-LL |         let _: *mut f32 = mut_ptr.cast::<f32>();
-   |                           ~~~~~~~~~~~~~~~~~~~~~
+LL -         let _: *mut f32 = transmute(mut_ptr);
+LL +         let _: *mut f32 = mut_ptr.cast::<f32>();
+   |
 
 error: transmute from a reference to a reference
   --> tests/ui/transmute_ptr_to_ptr.rs:37:23
@@ -60,8 +62,9 @@ LL |         let _: *const u32 = transmute(mut_ptr);
    |
 help: use `pointer::cast_const` instead
    |
-LL |         let _: *const u32 = mut_ptr.cast_const();
-   |                             ~~~~~~~~~~~~~~~~~~~~
+LL -         let _: *const u32 = transmute(mut_ptr);
+LL +         let _: *const u32 = mut_ptr.cast_const();
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:52:27
@@ -71,8 +74,9 @@ LL |         let _: *mut u32 = transmute(ptr);
    |
 help: use `pointer::cast_mut` instead
    |
-LL |         let _: *mut u32 = ptr.cast_mut();
-   |                           ~~~~~~~~~~~~~~
+LL -         let _: *mut u32 = transmute(ptr);
+LL +         let _: *mut u32 = ptr.cast_mut();
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:64:14
@@ -82,8 +86,9 @@ LL |     unsafe { transmute(v) }
    |
 help: use an `as` cast instead
    |
-LL |     unsafe { v as *const &() }
-   |              ~~~~~~~~~~~~~~~
+LL -     unsafe { transmute(v) }
+LL +     unsafe { v as *const &() }
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:79:28
@@ -93,8 +98,9 @@ LL |         let _: *const i8 = transmute(ptr);
    |
 help: use an `as` cast instead
    |
-LL |         let _: *const i8 = ptr as *const i8;
-   |                            ~~~~~~~~~~~~~~~~
+LL -         let _: *const i8 = transmute(ptr);
+LL +         let _: *const i8 = ptr as *const i8;
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:86:28
@@ -104,8 +110,9 @@ LL |         let _: *const i8 = transmute(ptr);
    |
 help: use `pointer::cast` instead
    |
-LL |         let _: *const i8 = ptr.cast::<i8>();
-   |                            ~~~~~~~~~~~~~~~~
+LL -         let _: *const i8 = transmute(ptr);
+LL +         let _: *const i8 = ptr.cast::<i8>();
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:93:26
@@ -115,8 +122,9 @@ LL |         let _: *mut u8 = transmute(ptr);
    |
 help: use an `as` cast instead
    |
-LL |         let _: *mut u8 = ptr as *mut u8;
-   |                          ~~~~~~~~~~~~~~
+LL -         let _: *mut u8 = transmute(ptr);
+LL +         let _: *mut u8 = ptr as *mut u8;
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:94:28
@@ -126,8 +134,9 @@ LL |         let _: *const u8 = transmute(mut_ptr);
    |
 help: use an `as` cast instead
    |
-LL |         let _: *const u8 = mut_ptr as *const u8;
-   |                            ~~~~~~~~~~~~~~~~~~~~
+LL -         let _: *const u8 = transmute(mut_ptr);
+LL +         let _: *const u8 = mut_ptr as *const u8;
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:101:26
@@ -137,8 +146,9 @@ LL |         let _: *mut u8 = transmute(ptr);
    |
 help: use `pointer::cast_mut` instead
    |
-LL |         let _: *mut u8 = ptr.cast_mut();
-   |                          ~~~~~~~~~~~~~~
+LL -         let _: *mut u8 = transmute(ptr);
+LL +         let _: *mut u8 = ptr.cast_mut();
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmute_ptr_to_ptr.rs:102:28
@@ -148,8 +158,9 @@ LL |         let _: *const u8 = transmute(mut_ptr);
    |
 help: use `pointer::cast_const` instead
    |
-LL |         let _: *const u8 = mut_ptr.cast_const();
-   |                            ~~~~~~~~~~~~~~~~~~~~
+LL -         let _: *const u8 = transmute(mut_ptr);
+LL +         let _: *const u8 = mut_ptr.cast_const();
+   |
 
 error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr
index 2d74967ede5..21edd39e7ad 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.stderr
@@ -17,8 +17,9 @@ LL |     let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr
    = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
 help: use `pointer::cast` instead
    |
-LL |     let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };
-   |                                      ~~~~~~~~~~~~~~~~~~~~
+LL -     let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) };
+LL +     let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };
+   |
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46
@@ -28,8 +29,9 @@ LL |     let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *con
    |
 help: use an `as` cast instead
    |
-LL |     let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] };
-   |                                              ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) };
+LL +     let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] };
+   |
 
 error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead
   --> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50
diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr
index 41ad1a2d383..bf79e93e444 100644
--- a/src/tools/clippy/tests/ui/unit_arg.stderr
+++ b/src/tools/clippy/tests/ui/unit_arg.stderr
@@ -10,7 +10,8 @@ LL | |     });
    = help: to override `-D warnings` add `#[allow(clippy::unit_arg)]`
 help: remove the semicolon from the last statement in the block
    |
-LL |         1
+LL -         1;
+LL +         1
    |
 help: or move the expression in front of the call and replace it with the unit literal `()`
    |
@@ -43,7 +44,8 @@ LL | |     });
    |
 help: remove the semicolon from the last statement in the block
    |
-LL |         foo(2)
+LL -         foo(2);
+LL +         foo(2)
    |
 help: or move the expression in front of the call and replace it with the unit literal `()`
    |
@@ -64,7 +66,8 @@ LL | |     });
    |
 help: remove the semicolon from the last statement in the block
    |
-LL |         1
+LL -         1;
+LL +         1
    |
 help: or move the expression in front of the call and replace it with the unit literal `()`
    |
@@ -98,7 +101,8 @@ LL | |     });
    |
 help: remove the semicolon from the last statement in the block
    |
-LL |         foo(2)
+LL -         foo(2);
+LL +         foo(2)
    |
 help: or move the expressions in front of the call and replace them with the unit literal `()`
    |
@@ -124,11 +128,13 @@ LL | |     );
    |
 help: remove the semicolon from the last statement in the block
    |
-LL |             foo(1)
+LL -             foo(1);
+LL +             foo(1)
    |
 help: remove the semicolon from the last statement in the block
    |
-LL |             foo(3)
+LL -             foo(3);
+LL +             foo(3)
    |
 help: or move the expressions in front of the call and replace them with the unit literal `()`
    |
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
index aa2c2f3c0e2..ea925cd3a9f 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
@@ -39,8 +39,9 @@ LL | #[warn(clippy::dead_cod)]
    |
 help: a lint with a similar name exists in `rustc` lints
    |
-LL | #[warn(dead_code)]
-   |        ~~~~~~~~~
+LL - #[warn(clippy::dead_cod)]
+LL + #[warn(dead_code)]
+   |
 
 error: unknown lint: `clippy::unused_colle`
   --> tests/ui/unknown_clippy_lints.rs:13:8
@@ -62,8 +63,9 @@ LL | #[warn(clippy::missing_docs)]
    |
 help: a lint with a similar name exists in `rustc` lints
    |
-LL | #[warn(missing_docs)]
-   |        ~~~~~~~~~~~~
+LL - #[warn(clippy::missing_docs)]
+LL + #[warn(missing_docs)]
+   |
 
 error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
index 35a2144c389..9bb1b71f0ed 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
@@ -8,8 +8,9 @@ LL |     let _ = opt.unwrap_or_else(|| 2);
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
 help: use `unwrap_or` instead
    |
-LL |     let _ = opt.unwrap_or(2);
-   |                 ~~~~~~~~~~~~
+LL -     let _ = opt.unwrap_or_else(|| 2);
+LL +     let _ = opt.unwrap_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:84:13
@@ -19,8 +20,9 @@ LL |     let _ = opt.unwrap_or_else(|| astronomers_pi);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = opt.unwrap_or(astronomers_pi);
-   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = opt.unwrap_or_else(|| astronomers_pi);
+LL +     let _ = opt.unwrap_or(astronomers_pi);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:85:13
@@ -30,8 +32,9 @@ LL |     let _ = opt.unwrap_or_else(|| ext_str.some_field);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = opt.unwrap_or(ext_str.some_field);
-   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = opt.unwrap_or_else(|| ext_str.some_field);
+LL +     let _ = opt.unwrap_or(ext_str.some_field);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:87:13
@@ -41,8 +44,9 @@ LL |     let _ = opt.and_then(|_| ext_opt);
    |
 help: use `and` instead
    |
-LL |     let _ = opt.and(ext_opt);
-   |                 ~~~~~~~~~~~~
+LL -     let _ = opt.and_then(|_| ext_opt);
+LL +     let _ = opt.and(ext_opt);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:88:13
@@ -52,8 +56,9 @@ LL |     let _ = opt.or_else(|| ext_opt);
    |
 help: use `or` instead
    |
-LL |     let _ = opt.or(ext_opt);
-   |                 ~~~~~~~~~~~
+LL -     let _ = opt.or_else(|| ext_opt);
+LL +     let _ = opt.or(ext_opt);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:89:13
@@ -63,8 +68,9 @@ LL |     let _ = opt.or_else(|| None);
    |
 help: use `or` instead
    |
-LL |     let _ = opt.or(None);
-   |                 ~~~~~~~~
+LL -     let _ = opt.or_else(|| None);
+LL +     let _ = opt.or(None);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:90:13
@@ -74,8 +80,9 @@ LL |     let _ = opt.get_or_insert_with(|| 2);
    |
 help: use `get_or_insert` instead
    |
-LL |     let _ = opt.get_or_insert(2);
-   |                 ~~~~~~~~~~~~~~~~
+LL -     let _ = opt.get_or_insert_with(|| 2);
+LL +     let _ = opt.get_or_insert(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:91:13
@@ -85,8 +92,9 @@ LL |     let _ = opt.ok_or_else(|| 2);
    |
 help: use `ok_or` instead
    |
-LL |     let _ = opt.ok_or(2);
-   |                 ~~~~~~~~
+LL -     let _ = opt.ok_or_else(|| 2);
+LL +     let _ = opt.ok_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:92:13
@@ -96,8 +104,9 @@ LL |     let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = nested_tuple_opt.unwrap_or(Some((1, 2)));
-   |                              ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
+LL +     let _ = nested_tuple_opt.unwrap_or(Some((1, 2)));
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:93:13
@@ -107,8 +116,9 @@ LL |     let _ = cond.then(|| astronomers_pi);
    |
 help: use `then_some` instead
    |
-LL |     let _ = cond.then_some(astronomers_pi);
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = cond.then(|| astronomers_pi);
+LL +     let _ = cond.then_some(astronomers_pi);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:94:13
@@ -118,8 +128,9 @@ LL |     let _ = true.then(|| -> _ {});
    |
 help: use `then_some` instead
    |
-LL |     let _ = true.then_some({});
-   |                  ~~~~~~~~~~~~~
+LL -     let _ = true.then(|| -> _ {});
+LL +     let _ = true.then_some({});
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:95:13
@@ -129,8 +140,9 @@ LL |     let _ = true.then(|| {});
    |
 help: use `then_some` instead
    |
-LL |     let _ = true.then_some({});
-   |                  ~~~~~~~~~~~~~
+LL -     let _ = true.then(|| {});
+LL +     let _ = true.then_some({});
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:99:13
@@ -140,8 +152,9 @@ LL |     let _ = Some(1).unwrap_or_else(|| *r);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = Some(1).unwrap_or(*r);
-   |                     ~~~~~~~~~~~~~
+LL -     let _ = Some(1).unwrap_or_else(|| *r);
+LL +     let _ = Some(1).unwrap_or(*r);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:101:13
@@ -151,8 +164,9 @@ LL |     let _ = Some(1).unwrap_or_else(|| *b);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = Some(1).unwrap_or(*b);
-   |                     ~~~~~~~~~~~~~
+LL -     let _ = Some(1).unwrap_or_else(|| *b);
+LL +     let _ = Some(1).unwrap_or(*b);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:103:13
@@ -162,8 +176,9 @@ LL |     let _ = Some(1).as_ref().unwrap_or_else(|| &r);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = Some(1).as_ref().unwrap_or(&r);
-   |                              ~~~~~~~~~~~~~
+LL -     let _ = Some(1).as_ref().unwrap_or_else(|| &r);
+LL +     let _ = Some(1).as_ref().unwrap_or(&r);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:104:13
@@ -173,8 +188,9 @@ LL |     let _ = Some(1).as_ref().unwrap_or_else(|| &b);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = Some(1).as_ref().unwrap_or(&b);
-   |                              ~~~~~~~~~~~~~
+LL -     let _ = Some(1).as_ref().unwrap_or_else(|| &b);
+LL +     let _ = Some(1).as_ref().unwrap_or(&b);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:107:13
@@ -184,8 +200,9 @@ LL |     let _ = Some(10).unwrap_or_else(|| 2);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = Some(10).unwrap_or(2);
-   |                      ~~~~~~~~~~~~
+LL -     let _ = Some(10).unwrap_or_else(|| 2);
+LL +     let _ = Some(10).unwrap_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:108:13
@@ -195,8 +212,9 @@ LL |     let _ = Some(10).and_then(|_| ext_opt);
    |
 help: use `and` instead
    |
-LL |     let _ = Some(10).and(ext_opt);
-   |                      ~~~~~~~~~~~~
+LL -     let _ = Some(10).and_then(|_| ext_opt);
+LL +     let _ = Some(10).and(ext_opt);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:109:28
@@ -206,8 +224,9 @@ LL |     let _: Option<usize> = None.or_else(|| ext_opt);
    |
 help: use `or` instead
    |
-LL |     let _: Option<usize> = None.or(ext_opt);
-   |                                 ~~~~~~~~~~~
+LL -     let _: Option<usize> = None.or_else(|| ext_opt);
+LL +     let _: Option<usize> = None.or(ext_opt);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:110:13
@@ -217,8 +236,9 @@ LL |     let _ = None.get_or_insert_with(|| 2);
    |
 help: use `get_or_insert` instead
    |
-LL |     let _ = None.get_or_insert(2);
-   |                  ~~~~~~~~~~~~~~~~
+LL -     let _ = None.get_or_insert_with(|| 2);
+LL +     let _ = None.get_or_insert(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:111:35
@@ -228,8 +248,9 @@ LL |     let _: Result<usize, usize> = None.ok_or_else(|| 2);
    |
 help: use `ok_or` instead
    |
-LL |     let _: Result<usize, usize> = None.ok_or(2);
-   |                                        ~~~~~~~~
+LL -     let _: Result<usize, usize> = None.ok_or_else(|| 2);
+LL +     let _: Result<usize, usize> = None.ok_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:112:28
@@ -239,8 +260,9 @@ LL |     let _: Option<usize> = None.or_else(|| None);
    |
 help: use `or` instead
    |
-LL |     let _: Option<usize> = None.or(None);
-   |                                 ~~~~~~~~
+LL -     let _: Option<usize> = None.or_else(|| None);
+LL +     let _: Option<usize> = None.or(None);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:115:13
@@ -250,8 +272,9 @@ LL |     let _ = deep.0.unwrap_or_else(|| 2);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = deep.0.unwrap_or(2);
-   |                    ~~~~~~~~~~~~
+LL -     let _ = deep.0.unwrap_or_else(|| 2);
+LL +     let _ = deep.0.unwrap_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:116:13
@@ -261,8 +284,9 @@ LL |     let _ = deep.0.and_then(|_| ext_opt);
    |
 help: use `and` instead
    |
-LL |     let _ = deep.0.and(ext_opt);
-   |                    ~~~~~~~~~~~~
+LL -     let _ = deep.0.and_then(|_| ext_opt);
+LL +     let _ = deep.0.and(ext_opt);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:117:13
@@ -272,8 +296,9 @@ LL |     let _ = deep.0.or_else(|| None);
    |
 help: use `or` instead
    |
-LL |     let _ = deep.0.or(None);
-   |                    ~~~~~~~~
+LL -     let _ = deep.0.or_else(|| None);
+LL +     let _ = deep.0.or(None);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:118:13
@@ -283,8 +308,9 @@ LL |     let _ = deep.0.get_or_insert_with(|| 2);
    |
 help: use `get_or_insert` instead
    |
-LL |     let _ = deep.0.get_or_insert(2);
-   |                    ~~~~~~~~~~~~~~~~
+LL -     let _ = deep.0.get_or_insert_with(|| 2);
+LL +     let _ = deep.0.get_or_insert(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:119:13
@@ -294,8 +320,9 @@ LL |     let _ = deep.0.ok_or_else(|| 2);
    |
 help: use `ok_or` instead
    |
-LL |     let _ = deep.0.ok_or(2);
-   |                    ~~~~~~~~
+LL -     let _ = deep.0.ok_or_else(|| 2);
+LL +     let _ = deep.0.ok_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:150:28
@@ -305,8 +332,9 @@ LL |     let _: Option<usize> = None.or_else(|| Some(3));
    |
 help: use `or` instead
    |
-LL |     let _: Option<usize> = None.or(Some(3));
-   |                                 ~~~~~~~~~~~
+LL -     let _: Option<usize> = None.or_else(|| Some(3));
+LL +     let _: Option<usize> = None.or(Some(3));
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:151:13
@@ -316,8 +344,9 @@ LL |     let _ = deep.0.or_else(|| Some(3));
    |
 help: use `or` instead
    |
-LL |     let _ = deep.0.or(Some(3));
-   |                    ~~~~~~~~~~~
+LL -     let _ = deep.0.or_else(|| Some(3));
+LL +     let _ = deep.0.or(Some(3));
+   |
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:152:13
@@ -327,8 +356,9 @@ LL |     let _ = opt.or_else(|| Some(3));
    |
 help: use `or` instead
    |
-LL |     let _ = opt.or(Some(3));
-   |                 ~~~~~~~~~~~
+LL -     let _ = opt.or_else(|| Some(3));
+LL +     let _ = opt.or(Some(3));
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:158:13
@@ -338,8 +368,9 @@ LL |     let _ = res2.unwrap_or_else(|_| 2);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = res2.unwrap_or(2);
-   |                  ~~~~~~~~~~~~
+LL -     let _ = res2.unwrap_or_else(|_| 2);
+LL +     let _ = res2.unwrap_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:159:13
@@ -349,8 +380,9 @@ LL |     let _ = res2.unwrap_or_else(|_| astronomers_pi);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = res2.unwrap_or(astronomers_pi);
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = res2.unwrap_or_else(|_| astronomers_pi);
+LL +     let _ = res2.unwrap_or(astronomers_pi);
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:160:13
@@ -360,8 +392,9 @@ LL |     let _ = res2.unwrap_or_else(|_| ext_str.some_field);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = res2.unwrap_or(ext_str.some_field);
-   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _ = res2.unwrap_or_else(|_| ext_str.some_field);
+LL +     let _ = res2.unwrap_or(ext_str.some_field);
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:182:35
@@ -371,8 +404,9 @@ LL |     let _: Result<usize, usize> = res.and_then(|_| Err(2));
    |
 help: use `and` instead
    |
-LL |     let _: Result<usize, usize> = res.and(Err(2));
-   |                                       ~~~~~~~~~~~
+LL -     let _: Result<usize, usize> = res.and_then(|_| Err(2));
+LL +     let _: Result<usize, usize> = res.and(Err(2));
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:183:35
@@ -382,8 +416,9 @@ LL |     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
    |
 help: use `and` instead
    |
-LL |     let _: Result<usize, usize> = res.and(Err(astronomers_pi));
-   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
+LL +     let _: Result<usize, usize> = res.and(Err(astronomers_pi));
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:184:35
@@ -393,8 +428,9 @@ LL |     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field))
    |
 help: use `and` instead
    |
-LL |     let _: Result<usize, usize> = res.and(Err(ext_str.some_field));
-   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
+LL +     let _: Result<usize, usize> = res.and(Err(ext_str.some_field));
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:186:35
@@ -404,8 +440,9 @@ LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(2));
    |
 help: use `or` instead
    |
-LL |     let _: Result<usize, usize> = res.or(Ok(2));
-   |                                       ~~~~~~~~~
+LL -     let _: Result<usize, usize> = res.or_else(|_| Ok(2));
+LL +     let _: Result<usize, usize> = res.or(Ok(2));
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:187:35
@@ -415,8 +452,9 @@ LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
    |
 help: use `or` instead
    |
-LL |     let _: Result<usize, usize> = res.or(Ok(astronomers_pi));
-   |                                       ~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
+LL +     let _: Result<usize, usize> = res.or(Ok(astronomers_pi));
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:188:35
@@ -426,8 +464,9 @@ LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
    |
 help: use `or` instead
    |
-LL |     let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));
-   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
+LL +     let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:189:35
@@ -440,8 +479,9 @@ LL | |     or_else(|_| Ok(ext_str.some_field));
    |
 help: use `or` instead
    |
-LL |     or(Ok(ext_str.some_field));
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     or_else(|_| Ok(ext_str.some_field));
+LL +     or(Ok(ext_str.some_field));
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:219:14
@@ -451,8 +491,9 @@ LL |     let _x = false.then(|| i32::MAX + 1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(i32::MAX + 1);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| i32::MAX + 1);
+LL +     let _x = false.then_some(i32::MAX + 1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:221:14
@@ -462,8 +503,9 @@ LL |     let _x = false.then(|| i32::MAX * 2);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(i32::MAX * 2);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| i32::MAX * 2);
+LL +     let _x = false.then_some(i32::MAX * 2);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:223:14
@@ -473,8 +515,9 @@ LL |     let _x = false.then(|| i32::MAX - 1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(i32::MAX - 1);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| i32::MAX - 1);
+LL +     let _x = false.then_some(i32::MAX - 1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:225:14
@@ -484,8 +527,9 @@ LL |     let _x = false.then(|| i32::MIN - 1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(i32::MIN - 1);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| i32::MIN - 1);
+LL +     let _x = false.then_some(i32::MIN - 1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:227:14
@@ -495,8 +539,9 @@ LL |     let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);
+LL +     let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:229:14
@@ -506,8 +551,9 @@ LL |     let _x = false.then(|| 255u8 << 7);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(255u8 << 7);
-   |                    ~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 255u8 << 7);
+LL +     let _x = false.then_some(255u8 << 7);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:231:14
@@ -517,8 +563,9 @@ LL |     let _x = false.then(|| 255u8 << 8);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(255u8 << 8);
-   |                    ~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 255u8 << 8);
+LL +     let _x = false.then_some(255u8 << 8);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:233:14
@@ -528,8 +575,9 @@ LL |     let _x = false.then(|| 255u8 >> 8);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(255u8 >> 8);
-   |                    ~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 255u8 >> 8);
+LL +     let _x = false.then_some(255u8 >> 8);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:236:14
@@ -539,8 +587,9 @@ LL |     let _x = false.then(|| i32::MAX + -1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(i32::MAX + -1);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| i32::MAX + -1);
+LL +     let _x = false.then_some(i32::MAX + -1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:238:14
@@ -550,8 +599,9 @@ LL |     let _x = false.then(|| -i32::MAX);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(-i32::MAX);
-   |                    ~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| -i32::MAX);
+LL +     let _x = false.then_some(-i32::MAX);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:240:14
@@ -561,8 +611,9 @@ LL |     let _x = false.then(|| -i32::MIN);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(-i32::MIN);
-   |                    ~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| -i32::MIN);
+LL +     let _x = false.then_some(-i32::MIN);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:243:14
@@ -572,8 +623,9 @@ LL |     let _x = false.then(|| 255 >> -7);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(255 >> -7);
-   |                    ~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 255 >> -7);
+LL +     let _x = false.then_some(255 >> -7);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:245:14
@@ -583,8 +635,9 @@ LL |     let _x = false.then(|| 255 << -1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(255 << -1);
-   |                    ~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 255 << -1);
+LL +     let _x = false.then_some(255 << -1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:247:14
@@ -594,8 +647,9 @@ LL |     let _x = false.then(|| 1 / 0);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(1 / 0);
-   |                    ~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 1 / 0);
+LL +     let _x = false.then_some(1 / 0);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:249:14
@@ -605,8 +659,9 @@ LL |     let _x = false.then(|| x << -1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(x << -1);
-   |                    ~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| x << -1);
+LL +     let _x = false.then_some(x << -1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:251:14
@@ -616,8 +671,9 @@ LL |     let _x = false.then(|| x << 2);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(x << 2);
-   |                    ~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| x << 2);
+LL +     let _x = false.then_some(x << 2);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:261:14
@@ -627,8 +683,9 @@ LL |     let _x = false.then(|| x / 0);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(x / 0);
-   |                    ~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| x / 0);
+LL +     let _x = false.then_some(x / 0);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:263:14
@@ -638,8 +695,9 @@ LL |     let _x = false.then(|| x % 0);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(x % 0);
-   |                    ~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| x % 0);
+LL +     let _x = false.then_some(x % 0);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:266:14
@@ -649,8 +707,9 @@ LL |     let _x = false.then(|| 1 / -1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(1 / -1);
-   |                    ~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 1 / -1);
+LL +     let _x = false.then_some(1 / -1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:268:14
@@ -660,8 +719,9 @@ LL |     let _x = false.then(|| i32::MIN / -1);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(i32::MIN / -1);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| i32::MIN / -1);
+LL +     let _x = false.then_some(i32::MIN / -1);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:271:14
@@ -671,8 +731,9 @@ LL |     let _x = false.then(|| i32::MIN / 0);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(i32::MIN / 0);
-   |                    ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| i32::MIN / 0);
+LL +     let _x = false.then_some(i32::MIN / 0);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:273:14
@@ -682,8 +743,9 @@ LL |     let _x = false.then(|| 4 / 2);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(4 / 2);
-   |                    ~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| 4 / 2);
+LL +     let _x = false.then_some(4 / 2);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:281:14
@@ -693,8 +755,9 @@ LL |     let _x = false.then(|| f1 + f2);
    |
 help: use `then_some` instead
    |
-LL |     let _x = false.then_some(f1 + f2);
-   |                    ~~~~~~~~~~~~~~~~~~
+LL -     let _x = false.then(|| f1 + f2);
+LL +     let _x = false.then_some(f1 + f2);
+   |
 
 error: aborting due to 63 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
index 390235b2124..9688c44c914 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
@@ -8,8 +8,9 @@ LL |     let _ = Ok(1).unwrap_or_else(|()| 2);
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
 help: use `unwrap_or` instead
    |
-LL |     let _ = Ok(1).unwrap_or(2);
-   |                   ~~~~~~~~~~~~
+LL -     let _ = Ok(1).unwrap_or_else(|()| 2);
+LL +     let _ = Ok(1).unwrap_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13
@@ -19,8 +20,9 @@ LL |     let _ = Ok(1).unwrap_or_else(|e::E| 2);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = Ok(1).unwrap_or(2);
-   |                   ~~~~~~~~~~~~
+LL -     let _ = Ok(1).unwrap_or_else(|e::E| 2);
+LL +     let _ = Ok(1).unwrap_or(2);
+   |
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:21:13
@@ -30,8 +32,9 @@ LL |     let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);
    |
 help: use `unwrap_or` instead
    |
-LL |     let _ = Ok(1).unwrap_or(2);
-   |                   ~~~~~~~~~~~~
+LL -     let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);
+LL +     let _ = Ok(1).unwrap_or(2);
+   |
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:31:13
@@ -41,8 +44,9 @@ LL |     let _ = true.then(|| -> &[u8] { &[] });
    |
 help: use `then_some` instead
    |
-LL |     let _ = true.then_some({ &[] });
-   |                  ~~~~~~~~~~~~~~~~~~
+LL -     let _ = true.then(|| -> &[u8] { &[] });
+LL +     let _ = true.then_some({ &[] });
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr
index 37ee9195fce..631bf083726 100644
--- a/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_literal_unwrap.stderr
@@ -62,8 +62,9 @@ LL |     let _val = None::<()>.expect("this always happens");
    |
 help: remove the `None` and `expect()`
    |
-LL |     let _val = panic!("this always happens");
-   |                ~~~~~~~
+LL -     let _val = None::<()>.expect("this always happens");
+LL +     let _val = panic!("this always happens");
+   |
 
 error: used `unwrap_or_default()` on `None` value
   --> tests/ui/unnecessary_literal_unwrap.rs:22:24
@@ -133,8 +134,9 @@ LL |     None::<()>.expect("this always happens");
    |
 help: remove the `None` and `expect()`
    |
-LL |     panic!("this always happens");
-   |     ~~~~~~~
+LL -     None::<()>.expect("this always happens");
+LL +     panic!("this always happens");
+   |
 
 error: used `unwrap_or_default()` on `None` value
   --> tests/ui/unnecessary_literal_unwrap.rs:30:5
@@ -222,8 +224,9 @@ LL |     let _val = Ok::<_, ()>(1).unwrap_err();
    |
 help: remove the `Ok` and `unwrap_err()`
    |
-LL |     let _val = panic!("{:?}", 1);
-   |                ~~~~~~~~~~~~~~  ~
+LL -     let _val = Ok::<_, ()>(1).unwrap_err();
+LL +     let _val = panic!("{:?}", 1);
+   |
 
 error: used `expect_err()` on `Ok` value
   --> tests/ui/unnecessary_literal_unwrap.rs:41:16
@@ -233,8 +236,9 @@ LL |     let _val = Ok::<_, ()>(1).expect_err("this always happens");
    |
 help: remove the `Ok` and `expect_err()`
    |
-LL |     let _val = panic!("{1}: {:?}", 1, "this always happens");
-   |                ~~~~~~~~~~~~~~~~~~~  ~
+LL -     let _val = Ok::<_, ()>(1).expect_err("this always happens");
+LL +     let _val = panic!("{1}: {:?}", 1, "this always happens");
+   |
 
 error: used `unwrap()` on `Ok` value
   --> tests/ui/unnecessary_literal_unwrap.rs:43:5
@@ -268,8 +272,9 @@ LL |     Ok::<_, ()>(1).unwrap_err();
    |
 help: remove the `Ok` and `unwrap_err()`
    |
-LL |     panic!("{:?}", 1);
-   |     ~~~~~~~~~~~~~~  ~
+LL -     Ok::<_, ()>(1).unwrap_err();
+LL +     panic!("{:?}", 1);
+   |
 
 error: used `expect_err()` on `Ok` value
   --> tests/ui/unnecessary_literal_unwrap.rs:46:5
@@ -279,8 +284,9 @@ LL |     Ok::<_, ()>(1).expect_err("this always happens");
    |
 help: remove the `Ok` and `expect_err()`
    |
-LL |     panic!("{1}: {:?}", 1, "this always happens");
-   |     ~~~~~~~~~~~~~~~~~~~  ~
+LL -     Ok::<_, ()>(1).expect_err("this always happens");
+LL +     panic!("{1}: {:?}", 1, "this always happens");
+   |
 
 error: used `unwrap_err()` on `Err` value
   --> tests/ui/unnecessary_literal_unwrap.rs:50:16
@@ -314,8 +320,9 @@ LL |     let _val = Err::<(), _>(1).unwrap();
    |
 help: remove the `Err` and `unwrap()`
    |
-LL |     let _val = panic!("{:?}", 1);
-   |                ~~~~~~~~~~~~~~  ~
+LL -     let _val = Err::<(), _>(1).unwrap();
+LL +     let _val = panic!("{:?}", 1);
+   |
 
 error: used `expect()` on `Err` value
   --> tests/ui/unnecessary_literal_unwrap.rs:53:16
@@ -325,8 +332,9 @@ LL |     let _val = Err::<(), _>(1).expect("this always happens");
    |
 help: remove the `Err` and `expect()`
    |
-LL |     let _val = panic!("{1}: {:?}", 1, "this always happens");
-   |                ~~~~~~~~~~~~~~~~~~~  ~
+LL -     let _val = Err::<(), _>(1).expect("this always happens");
+LL +     let _val = panic!("{1}: {:?}", 1, "this always happens");
+   |
 
 error: used `unwrap_err()` on `Err` value
   --> tests/ui/unnecessary_literal_unwrap.rs:55:5
@@ -360,8 +368,9 @@ LL |     Err::<(), _>(1).unwrap();
    |
 help: remove the `Err` and `unwrap()`
    |
-LL |     panic!("{:?}", 1);
-   |     ~~~~~~~~~~~~~~  ~
+LL -     Err::<(), _>(1).unwrap();
+LL +     panic!("{:?}", 1);
+   |
 
 error: used `expect()` on `Err` value
   --> tests/ui/unnecessary_literal_unwrap.rs:58:5
@@ -371,8 +380,9 @@ LL |     Err::<(), _>(1).expect("this always happens");
    |
 help: remove the `Err` and `expect()`
    |
-LL |     panic!("{1}: {:?}", 1, "this always happens");
-   |     ~~~~~~~~~~~~~~~~~~~  ~
+LL -     Err::<(), _>(1).expect("this always happens");
+LL +     panic!("{1}: {:?}", 1, "this always happens");
+   |
 
 error: used `unwrap_or()` on `Some` value
   --> tests/ui/unnecessary_literal_unwrap.rs:62:16
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
index efea28e7045..5a6e77a06b8 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
@@ -82,3 +82,20 @@ fn msrv_1_81() {
     // is_none_or added in 1.82.0
     let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });
 }
+
+fn with_refs(o: &mut Option<u32>) -> bool {
+    o.is_none_or(|n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5)
+}
+
+struct S;
+
+impl std::ops::Deref for S {
+    type Target = Option<u32>;
+    fn deref(&self) -> &Self::Target {
+        &Some(0)
+    }
+}
+
+fn with_deref(o: &S) -> bool {
+    o.is_none_or(|n| n > 5)
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.rs b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
index 05a0ca816ef..5ba63121659 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
@@ -85,3 +85,20 @@ fn msrv_1_81() {
     // is_none_or added in 1.82.0
     let _ = Some(5).map_or(true, |n| n == if 2 > 1 { n } else { 0 });
 }
+
+fn with_refs(o: &mut Option<u32>) -> bool {
+    o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+}
+
+struct S;
+
+impl std::ops::Deref for S {
+    type Target = Option<u32>;
+    fn deref(&self) -> &Self::Target {
+        &Some(0)
+    }
+}
+
+fn with_deref(o: &S) -> bool {
+    o.map_or(true, |n| n > 5)
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
index 2b78996d5f3..9f38b8c8d93 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
@@ -2,16 +2,27 @@ error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:13:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == 5);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `Some(5) == Some(5)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::unnecessary-map-or` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_or)]`
+help: use a standard comparison instead
+   |
+LL -     let _ = Some(5).map_or(false, |n| n == 5);
+LL +     let _ = Some(5) == Some(5);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:14:13
    |
 LL |     let _ = Some(5).map_or(true, |n| n != 5);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `Some(5) != Some(5)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = Some(5).map_or(true, |n| n != 5);
+LL +     let _ = Some(5) != Some(5);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:15:13
@@ -21,7 +32,16 @@ LL |       let _ = Some(5).map_or(false, |n| {
 LL | |         let _ = 1;
 LL | |         n == 5
 LL | |     });
-   | |______^ help: use a standard comparison instead: `Some(5) == Some(5)`
+   | |______^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = Some(5).map_or(false, |n| {
+LL -         let _ = 1;
+LL -         n == 5
+LL -     });
+LL +     let _ = Some(5) == Some(5);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:19:13
@@ -35,113 +55,249 @@ LL | |     });
    |
 help: use is_some_and instead
    |
-LL ~     let _ = Some(5).is_some_and(|n| {
-LL +         let _ = n;
-LL +         6 >= 5
-LL ~     });
+LL -     let _ = Some(5).map_or(false, |n| {
+LL +     let _ = Some(5).is_some_and(|n| {
    |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:23:13
    |
 LL |     let _ = Some(vec![5]).map_or(false, |n| n == [5]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![5]).is_some_and(|n| n == [5])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     let _ = Some(vec![5]).map_or(false, |n| n == [5]);
+LL +     let _ = Some(vec![5]).is_some_and(|n| n == [5]);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:24:13
    |
 LL |     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(vec![1]).is_some_and(|n| vec![2] == n)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     let _ = Some(vec![1]).map_or(false, |n| vec![2] == n);
+LL +     let _ = Some(vec![1]).is_some_and(|n| vec![2] == n);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:25:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == n);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == n)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     let _ = Some(5).map_or(false, |n| n == n);
+LL +     let _ = Some(5).is_some_and(|n| n == n);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:26:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 })`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     let _ = Some(5).map_or(false, |n| n == if 2 > 1 { n } else { 0 });
+LL +     let _ = Some(5).is_some_and(|n| n == if 2 > 1 { n } else { 0 });
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:27:13
    |
 LL |     let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_ok_and instead
+   |
+LL -     let _ = Ok::<Vec<i32>, i32>(vec![5]).map_or(false, |n| n == [5]);
+LL +     let _ = Ok::<Vec<i32>, i32>(vec![5]).is_ok_and(|n| n == [5]);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:28:13
    |
 LL |     let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `Ok::<i32, i32>(5) == Ok(5)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = Ok::<i32, i32>(5).map_or(false, |n| n == 5);
+LL +     let _ = Ok::<i32, i32>(5) == Ok(5);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:29:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = Some(5).map_or(false, |n| n == 5).then(|| 1);
+LL +     let _ = (Some(5) == Some(5)).then(|| 1);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:30:13
    |
 LL |     let _ = Some(5).map_or(true, |n| n == 5);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(|n| n == 5)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     let _ = Some(5).map_or(true, |n| n == 5);
+LL +     let _ = Some(5).is_none_or(|n| n == 5);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:31:13
    |
 LL |     let _ = Some(5).map_or(true, |n| 5 == n);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(|n| 5 == n)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     let _ = Some(5).map_or(true, |n| 5 == n);
+LL +     let _ = Some(5).is_none_or(|n| 5 == n);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:32:14
    |
 LL |     let _ = !Some(5).map_or(false, |n| n == 5);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = !Some(5).map_or(false, |n| n == 5);
+LL +     let _ = !(Some(5) == Some(5));
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:33:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == 5) || false;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = Some(5).map_or(false, |n| n == 5) || false;
+LL +     let _ = (Some(5) == Some(5)) || false;
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:34:13
    |
 LL |     let _ = Some(5).map_or(false, |n| n == 5) as usize;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `(Some(5) == Some(5))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = Some(5).map_or(false, |n| n == 5) as usize;
+LL +     let _ = (Some(5) == Some(5)) as usize;
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:58:13
    |
 LL |     let _ = r.map_or(false, |x| x == 7);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `r.is_ok_and(|x| x == 7)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_ok_and instead
+   |
+LL -     let _ = r.map_or(false, |x| x == 7);
+LL +     let _ = r.is_ok_and(|x| x == 7);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:63:13
    |
 LL |     let _ = r.map_or(false, func);
-   |             ^^^^^^^^^^^^^^^^^^^^^ help: use is_ok_and instead: `r.is_ok_and(func)`
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_ok_and instead
+   |
+LL -     let _ = r.map_or(false, func);
+LL +     let _ = r.is_ok_and(func);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:64:13
    |
 LL |     let _ = Some(5).map_or(false, func);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_some_and instead: `Some(5).is_some_and(func)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     let _ = Some(5).map_or(false, func);
+LL +     let _ = Some(5).is_some_and(func);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:65:13
    |
 LL |     let _ = Some(5).map_or(true, func);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use is_none_or instead: `Some(5).is_none_or(func)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     let _ = Some(5).map_or(true, func);
+LL +     let _ = Some(5).is_none_or(func);
+   |
 
 error: this `map_or` can be simplified
   --> tests/ui/unnecessary_map_or.rs:70:13
    |
 LL |     let _ = r.map_or(false, |x| x == 8);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a standard comparison instead: `r == Ok(8)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     let _ = r.map_or(false, |x| x == 8);
+LL +     let _ = r == Ok(8);
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:90:5
+   |
+LL |     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+LL +     o.is_none_or(|n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:90:34
+   |
+LL |     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     o.map_or(true, |n| n > 5) || (o as &Option<u32>).map_or(true, |n| n < 5)
+LL +     o.map_or(true, |n| n > 5) || (o as &Option<u32>).is_none_or(|n| n < 5)
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:103:5
+   |
+LL |     o.map_or(true, |n| n > 5)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_none_or instead
+   |
+LL -     o.map_or(true, |n| n > 5)
+LL +     o.is_none_or(|n| n > 5)
+   |
 
-error: aborting due to 21 previous errors
+error: aborting due to 24 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.fixed b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.fixed
new file mode 100644
index 00000000000..343c88b9815
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.fixed
@@ -0,0 +1,63 @@
+//@revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+
+#![warn(clippy::unnecessary_semicolon)]
+#![feature(postfix_match)]
+#![allow(clippy::single_match)]
+
+fn no_lint(mut x: u32) -> Option<u32> {
+    Some(())?;
+
+    {
+        let y = 3;
+        dbg!(x + y)
+    };
+
+    {
+        let (mut a, mut b) = (10, 20);
+        (a, b) = (b + 1, a + 1);
+    }
+
+    Some(0)
+}
+
+fn main() {
+    let mut a = 3;
+    if a == 2 {
+        println!("This is weird");
+    }
+    //~^ ERROR: unnecessary semicolon
+
+    a.match {
+        3 => println!("three"),
+        _ => println!("not three"),
+    }
+    //~^ ERROR: unnecessary semicolon
+}
+
+// This is a problem in edition 2021 and below
+fn borrow_issue() {
+    let v = std::cell::RefCell::new(Some(vec![1]));
+    match &*v.borrow() {
+        Some(v) => {
+            dbg!(v);
+        },
+        None => {},
+    };
+}
+
+fn no_borrow_issue(a: u32, b: u32) {
+    match Some(a + b) {
+        Some(v) => {
+            dbg!(v);
+        },
+        None => {},
+    }
+}
+
+fn issue14100() -> bool {
+    // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be
+    // cast into the `bool` function return type.
+    if return true {};
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.stderr b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.stderr
new file mode 100644
index 00000000000..ccff3308417
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2021.stderr
@@ -0,0 +1,23 @@
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:29:6
+   |
+LL |     };
+   |      ^ help: remove
+   |
+   = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]`
+
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:35:6
+   |
+LL |     };
+   |      ^ help: remove
+
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:56:6
+   |
+LL |     };
+   |      ^ help: remove
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.fixed b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.fixed
new file mode 100644
index 00000000000..1cba5760eb0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.fixed
@@ -0,0 +1,63 @@
+//@revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+
+#![warn(clippy::unnecessary_semicolon)]
+#![feature(postfix_match)]
+#![allow(clippy::single_match)]
+
+fn no_lint(mut x: u32) -> Option<u32> {
+    Some(())?;
+
+    {
+        let y = 3;
+        dbg!(x + y)
+    };
+
+    {
+        let (mut a, mut b) = (10, 20);
+        (a, b) = (b + 1, a + 1);
+    }
+
+    Some(0)
+}
+
+fn main() {
+    let mut a = 3;
+    if a == 2 {
+        println!("This is weird");
+    }
+    //~^ ERROR: unnecessary semicolon
+
+    a.match {
+        3 => println!("three"),
+        _ => println!("not three"),
+    }
+    //~^ ERROR: unnecessary semicolon
+}
+
+// This is a problem in edition 2021 and below
+fn borrow_issue() {
+    let v = std::cell::RefCell::new(Some(vec![1]));
+    match &*v.borrow() {
+        Some(v) => {
+            dbg!(v);
+        },
+        None => {},
+    }
+}
+
+fn no_borrow_issue(a: u32, b: u32) {
+    match Some(a + b) {
+        Some(v) => {
+            dbg!(v);
+        },
+        None => {},
+    }
+}
+
+fn issue14100() -> bool {
+    // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be
+    // cast into the `bool` function return type.
+    if return true {};
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.stderr b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.stderr
new file mode 100644
index 00000000000..4e526af2147
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_semicolon.edition2024.stderr
@@ -0,0 +1,29 @@
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:29:6
+   |
+LL |     };
+   |      ^ help: remove
+   |
+   = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]`
+
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:35:6
+   |
+LL |     };
+   |      ^ help: remove
+
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:47:6
+   |
+LL |     };
+   |      ^ help: remove
+
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:56:6
+   |
+LL |     };
+   |      ^ help: remove
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_semicolon.fixed b/src/tools/clippy/tests/ui/unnecessary_semicolon.fixed
new file mode 100644
index 00000000000..36d5c7806fe
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_semicolon.fixed
@@ -0,0 +1,32 @@
+#![warn(clippy::unnecessary_semicolon)]
+#![feature(postfix_match)]
+
+fn no_lint(mut x: u32) -> Option<u32> {
+    Some(())?;
+
+    {
+        let y = 3;
+        dbg!(x + y)
+    };
+
+    {
+        let (mut a, mut b) = (10, 20);
+        (a, b) = (b + 1, a + 1);
+    }
+
+    Some(0)
+}
+
+fn main() {
+    let mut a = 3;
+    if a == 2 {
+        println!("This is weird");
+    }
+    //~^ ERROR: unnecessary semicolon
+
+    a.match {
+        3 => println!("three"),
+        _ => println!("not three"),
+    }
+    //~^ ERROR: unnecessary semicolon
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_semicolon.rs b/src/tools/clippy/tests/ui/unnecessary_semicolon.rs
new file mode 100644
index 00000000000..6abbbd79aaf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_semicolon.rs
@@ -0,0 +1,63 @@
+//@revisions: edition2021 edition2024
+//@[edition2021] edition:2021
+//@[edition2024] edition:2024
+
+#![warn(clippy::unnecessary_semicolon)]
+#![feature(postfix_match)]
+#![allow(clippy::single_match)]
+
+fn no_lint(mut x: u32) -> Option<u32> {
+    Some(())?;
+
+    {
+        let y = 3;
+        dbg!(x + y)
+    };
+
+    {
+        let (mut a, mut b) = (10, 20);
+        (a, b) = (b + 1, a + 1);
+    }
+
+    Some(0)
+}
+
+fn main() {
+    let mut a = 3;
+    if a == 2 {
+        println!("This is weird");
+    };
+    //~^ ERROR: unnecessary semicolon
+
+    a.match {
+        3 => println!("three"),
+        _ => println!("not three"),
+    };
+    //~^ ERROR: unnecessary semicolon
+}
+
+// This is a problem in edition 2021 and below
+fn borrow_issue() {
+    let v = std::cell::RefCell::new(Some(vec![1]));
+    match &*v.borrow() {
+        Some(v) => {
+            dbg!(v);
+        },
+        None => {},
+    };
+}
+
+fn no_borrow_issue(a: u32, b: u32) {
+    match Some(a + b) {
+        Some(v) => {
+            dbg!(v);
+        },
+        None => {},
+    };
+}
+
+fn issue14100() -> bool {
+    // Removing the `;` would make the block type be `()` instead of `!`, and this could no longer be
+    // cast into the `bool` function return type.
+    if return true {};
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_semicolon.stderr b/src/tools/clippy/tests/ui/unnecessary_semicolon.stderr
new file mode 100644
index 00000000000..e6bf36e81e8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_semicolon.stderr
@@ -0,0 +1,17 @@
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:24:6
+   |
+LL |     };
+   |      ^ help: remove
+   |
+   = note: `-D clippy::unnecessary-semicolon` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_semicolon)]`
+
+error: unnecessary semicolon
+  --> tests/ui/unnecessary_semicolon.rs:30:6
+   |
+LL |     };
+   |      ^ help: remove
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index fdcac8fb08d..027dac41937 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -585,3 +585,9 @@ fn borrow_checks() {
     HashSet::<i32>::new().foo::<&str>(&"".to_owned());
     HashSet::<String>::new().get(&1.to_string());
 }
+
+fn issue13624() -> impl IntoIterator {
+    let cow: Cow<'_, Vec<String>> = Cow::Owned(vec![String::from("foo")]);
+
+    cow.into_owned().into_iter()
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index 10a9727a9a7..b89f3d552f8 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -585,3 +585,9 @@ fn borrow_checks() {
     HashSet::<i32>::new().foo::<&str>(&"".to_owned());
     HashSet::<String>::new().get(&1.to_string());
 }
+
+fn issue13624() -> impl IntoIterator {
+    let cow: Cow<'_, Vec<String>> = Cow::Owned(vec![String::from("foo")]);
+
+    cow.into_owned().into_iter()
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
index b304d4dce6e..b06ab91dc8d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_wraps.stderr
@@ -13,8 +13,9 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_wraps)]`
 help: remove `Option` from the return type...
    |
-LL | fn func1(a: bool, b: bool) -> i32 {
-   |                               ~~~
+LL - fn func1(a: bool, b: bool) -> Option<i32> {
+LL + fn func1(a: bool, b: bool) -> i32 {
+   |
 help: ...and then change returning expressions
    |
 LL ~         return 42;
@@ -40,8 +41,9 @@ LL | | }
    |
 help: remove `Option` from the return type...
    |
-LL | fn func2(a: bool, b: bool) -> i32 {
-   |                               ~~~
+LL - fn func2(a: bool, b: bool) -> Option<i32> {
+LL + fn func2(a: bool, b: bool) -> i32 {
+   |
 help: ...and then change returning expressions
    |
 LL ~         return 10;
@@ -60,11 +62,13 @@ LL | | }
    |
 help: remove `Option` from the return type...
    |
-LL | fn func5() -> i32 {
-   |               ~~~
+LL - fn func5() -> Option<i32> {
+LL + fn func5() -> i32 {
+   |
 help: ...and then change returning expressions
    |
-LL |     1
+LL -     Some(1)
+LL +     1
    |
 
 error: this function's return value is unnecessarily wrapped by `Result`
@@ -78,11 +82,13 @@ LL | | }
    |
 help: remove `Result` from the return type...
    |
-LL | fn func7() -> i32 {
-   |               ~~~
+LL - fn func7() -> Result<i32, ()> {
+LL + fn func7() -> i32 {
+   |
 help: ...and then change returning expressions
    |
-LL |     1
+LL -     Ok(1)
+LL +     1
    |
 
 error: this function's return value is unnecessarily wrapped by `Option`
@@ -96,11 +102,13 @@ LL | |     }
    |
 help: remove `Option` from the return type...
    |
-LL |     fn func12() -> i32 {
-   |                    ~~~
+LL -     fn func12() -> Option<i32> {
+LL +     fn func12() -> i32 {
+   |
 help: ...and then change returning expressions
    |
-LL |         1
+LL -         Some(1)
+LL +         1
    |
 
 error: this function's return value is unnecessary
@@ -116,8 +124,9 @@ LL | | }
    |
 help: remove the return type...
    |
-LL | fn issue_6640_1(a: bool, b: bool) -> () {
-   |                                      ~~
+LL - fn issue_6640_1(a: bool, b: bool) -> Option<()> {
+LL + fn issue_6640_1(a: bool, b: bool) -> () {
+   |
 help: ...and then remove returned values
    |
 LL ~         return ;
@@ -142,8 +151,9 @@ LL | | }
    |
 help: remove the return type...
    |
-LL | fn issue_6640_2(a: bool, b: bool) -> () {
-   |                                      ~~
+LL - fn issue_6640_2(a: bool, b: bool) -> Result<(), i32> {
+LL + fn issue_6640_2(a: bool, b: bool) -> () {
+   |
 help: ...and then remove returned values
    |
 LL ~         return ;
diff --git a/src/tools/clippy/tests/ui/unneeded_struct_pattern.fixed b/src/tools/clippy/tests/ui/unneeded_struct_pattern.fixed
new file mode 100644
index 00000000000..5bd269896a6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unneeded_struct_pattern.fixed
@@ -0,0 +1,177 @@
+//@aux-build:non-exhaustive-enum.rs
+#![allow(
+    clippy::manual_unwrap_or_default,
+    clippy::manual_unwrap_or,
+    clippy::redundant_pattern_matching
+)]
+#![warn(clippy::unneeded_struct_pattern)]
+
+extern crate non_exhaustive_enum;
+use non_exhaustive_enum::*;
+
+fn noop() {}
+
+fn main() {
+    match Some(114514) {
+        Some(v) => v,
+        None => 0,
+    };
+
+    match Some(1919810) {
+        Some(v) => v,
+        None => 0,
+    };
+
+    match Some(123456) {
+        Some(v) => v,
+        None => 0,
+    };
+
+    match Some(Some(123456)) {
+        Some(Some(v)) => v,
+        Some(None) => 0,
+        None => 0,
+    };
+
+    if let None = Some(0) {}
+    if let None = Some(0) {}
+    if let Some(None) = Some(Some(0)) {}
+    let None = Some(0) else { panic!() };
+    let None = Some(0) else { panic!() };
+    let Some(None) = Some(Some(0)) else { panic!() };
+
+    enum Custom {
+        HasFields {
+            field: i32,
+        },
+        HasBracketsNoFields {},
+        NoBrackets,
+        #[non_exhaustive]
+        NoBracketsNonExhaustive,
+        Init,
+    };
+
+    match Custom::Init {
+        Custom::HasFields { field: value } => value,
+        Custom::HasBracketsNoFields {} => 0,
+        Custom::NoBrackets => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        Custom::NoBracketsNonExhaustive => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match Custom::Init {
+        Custom::HasFields { field: value } => value,
+        Custom::HasBracketsNoFields { .. } => 0,
+        Custom::NoBrackets => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        Custom::NoBracketsNonExhaustive => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match Custom::Init {
+        Custom::NoBrackets if true => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match Custom::Init {
+        Custom::NoBrackets | Custom::NoBracketsNonExhaustive => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    if let Custom::HasFields { field: value } = Custom::Init {
+        noop();
+    }
+    if let Custom::HasBracketsNoFields {} = Custom::Init {
+        noop();
+    }
+    if let Custom::HasBracketsNoFields { .. } = Custom::Init {
+        noop();
+    }
+    if let Custom::NoBrackets = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBrackets = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBrackets | Custom::NoBracketsNonExhaustive = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBracketsNonExhaustive = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBracketsNonExhaustive = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+
+    let Custom::HasFields { field: value } = Custom::Init else {
+        panic!()
+    };
+
+    let Custom::HasBracketsNoFields {} = Custom::Init else {
+        panic!()
+    };
+
+    let Custom::HasBracketsNoFields { .. } = Custom::Init else {
+        panic!()
+    };
+    let Custom::NoBrackets = Custom::Init else { panic!() }; //~ ERROR: struct pattern is not needed for a unit variant
+
+    let Custom::NoBrackets = Custom::Init else {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        panic!()
+    };
+    let Custom::NoBracketsNonExhaustive = Custom::Init else {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        panic!()
+    };
+    let Custom::NoBracketsNonExhaustive = Custom::Init else {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        panic!()
+    };
+
+    enum Refutable {
+        Variant,
+    }
+
+    fn pat_in_fn_param_1(Refutable::Variant: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant
+    fn pat_in_fn_param_2(Refutable::Variant: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant
+
+    for Refutable::Variant in [] {} //~ ERROR: struct pattern is not needed for a unit variant
+    for Refutable::Variant in [] {} //~ ERROR: struct pattern is not needed for a unit variant
+}
+
+fn external_crate() {
+    use ExtNonExhaustiveVariant::*;
+
+    match ExhaustiveUnit {
+        // Expected
+        ExhaustiveUnit => 0,
+        _ => 0,
+    };
+
+    match ExhaustiveUnit {
+        // Exhaustive variant
+        ExhaustiveUnit => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match ExhaustiveUnit {
+        // Exhaustive variant
+        ExhaustiveUnit => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match ExhaustiveUnit {
+        ExhaustiveUnit => 0,
+        // vvvvv Non-exhaustive variants, should all be ignored
+        Unit { .. } => 0,
+        Tuple { 0: field, .. } => field,
+        StructNoField { .. } => 0,
+        Struct { field, .. } => field,
+        _ => 0,
+    };
+}
diff --git a/src/tools/clippy/tests/ui/unneeded_struct_pattern.rs b/src/tools/clippy/tests/ui/unneeded_struct_pattern.rs
new file mode 100644
index 00000000000..c7658617ad3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unneeded_struct_pattern.rs
@@ -0,0 +1,177 @@
+//@aux-build:non-exhaustive-enum.rs
+#![allow(
+    clippy::manual_unwrap_or_default,
+    clippy::manual_unwrap_or,
+    clippy::redundant_pattern_matching
+)]
+#![warn(clippy::unneeded_struct_pattern)]
+
+extern crate non_exhaustive_enum;
+use non_exhaustive_enum::*;
+
+fn noop() {}
+
+fn main() {
+    match Some(114514) {
+        Some(v) => v,
+        None {} => 0,
+    };
+
+    match Some(1919810) {
+        Some(v) => v,
+        None { .. } => 0,
+    };
+
+    match Some(123456) {
+        Some(v) => v,
+        None => 0,
+    };
+
+    match Some(Some(123456)) {
+        Some(Some(v)) => v,
+        Some(None {}) => 0,
+        None {} => 0,
+    };
+
+    if let None {} = Some(0) {}
+    if let None { .. } = Some(0) {}
+    if let Some(None {}) = Some(Some(0)) {}
+    let None {} = Some(0) else { panic!() };
+    let None { .. } = Some(0) else { panic!() };
+    let Some(None {}) = Some(Some(0)) else { panic!() };
+
+    enum Custom {
+        HasFields {
+            field: i32,
+        },
+        HasBracketsNoFields {},
+        NoBrackets,
+        #[non_exhaustive]
+        NoBracketsNonExhaustive,
+        Init,
+    };
+
+    match Custom::Init {
+        Custom::HasFields { field: value } => value,
+        Custom::HasBracketsNoFields {} => 0,
+        Custom::NoBrackets {} => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        Custom::NoBracketsNonExhaustive {} => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match Custom::Init {
+        Custom::HasFields { field: value } => value,
+        Custom::HasBracketsNoFields { .. } => 0,
+        Custom::NoBrackets { .. } => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        Custom::NoBracketsNonExhaustive { .. } => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match Custom::Init {
+        Custom::NoBrackets {} if true => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match Custom::Init {
+        Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    if let Custom::HasFields { field: value } = Custom::Init {
+        noop();
+    }
+    if let Custom::HasBracketsNoFields {} = Custom::Init {
+        noop();
+    }
+    if let Custom::HasBracketsNoFields { .. } = Custom::Init {
+        noop();
+    }
+    if let Custom::NoBrackets {} = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBrackets { .. } = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBracketsNonExhaustive {} = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+    if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        noop();
+    }
+
+    let Custom::HasFields { field: value } = Custom::Init else {
+        panic!()
+    };
+
+    let Custom::HasBracketsNoFields {} = Custom::Init else {
+        panic!()
+    };
+
+    let Custom::HasBracketsNoFields { .. } = Custom::Init else {
+        panic!()
+    };
+    let Custom::NoBrackets {} = Custom::Init else { panic!() }; //~ ERROR: struct pattern is not needed for a unit variant
+
+    let Custom::NoBrackets { .. } = Custom::Init else {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        panic!()
+    };
+    let Custom::NoBracketsNonExhaustive {} = Custom::Init else {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        panic!()
+    };
+    let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else {
+        //~^ ERROR: struct pattern is not needed for a unit variant
+        panic!()
+    };
+
+    enum Refutable {
+        Variant,
+    }
+
+    fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant
+    fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {} //~ ERROR: struct pattern is not needed for a unit variant
+
+    for Refutable::Variant {} in [] {} //~ ERROR: struct pattern is not needed for a unit variant
+    for Refutable::Variant { .. } in [] {} //~ ERROR: struct pattern is not needed for a unit variant
+}
+
+fn external_crate() {
+    use ExtNonExhaustiveVariant::*;
+
+    match ExhaustiveUnit {
+        // Expected
+        ExhaustiveUnit => 0,
+        _ => 0,
+    };
+
+    match ExhaustiveUnit {
+        // Exhaustive variant
+        ExhaustiveUnit { .. } => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match ExhaustiveUnit {
+        // Exhaustive variant
+        ExhaustiveUnit {} => 0, //~ ERROR: struct pattern is not needed for a unit variant
+        _ => 0,
+    };
+
+    match ExhaustiveUnit {
+        ExhaustiveUnit => 0,
+        // vvvvv Non-exhaustive variants, should all be ignored
+        Unit { .. } => 0,
+        Tuple { 0: field, .. } => field,
+        StructNoField { .. } => 0,
+        Struct { field, .. } => field,
+        _ => 0,
+    };
+}
diff --git a/src/tools/clippy/tests/ui/unneeded_struct_pattern.stderr b/src/tools/clippy/tests/ui/unneeded_struct_pattern.stderr
new file mode 100644
index 00000000000..3a7f5958380
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unneeded_struct_pattern.stderr
@@ -0,0 +1,203 @@
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:17:13
+   |
+LL |         None {} => 0,
+   |             ^^^ help: remove the struct pattern
+   |
+   = note: `-D clippy::unneeded-struct-pattern` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unneeded_struct_pattern)]`
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:22:13
+   |
+LL |         None { .. } => 0,
+   |             ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:32:18
+   |
+LL |         Some(None {}) => 0,
+   |                  ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:33:13
+   |
+LL |         None {} => 0,
+   |             ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:36:16
+   |
+LL |     if let None {} = Some(0) {}
+   |                ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:37:16
+   |
+LL |     if let None { .. } = Some(0) {}
+   |                ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:38:21
+   |
+LL |     if let Some(None {}) = Some(Some(0)) {}
+   |                     ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:39:13
+   |
+LL |     let None {} = Some(0) else { panic!() };
+   |             ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:40:13
+   |
+LL |     let None { .. } = Some(0) else { panic!() };
+   |             ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:41:18
+   |
+LL |     let Some(None {}) = Some(Some(0)) else { panic!() };
+   |                  ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:57:27
+   |
+LL |         Custom::NoBrackets {} => 0,
+   |                           ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:58:40
+   |
+LL |         Custom::NoBracketsNonExhaustive {} => 0,
+   |                                        ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:65:27
+   |
+LL |         Custom::NoBrackets { .. } => 0,
+   |                           ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:66:40
+   |
+LL |         Custom::NoBracketsNonExhaustive { .. } => 0,
+   |                                        ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:71:27
+   |
+LL |         Custom::NoBrackets {} if true => 0,
+   |                           ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:76:27
+   |
+LL |         Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0,
+   |                           ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:76:64
+   |
+LL |         Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} => 0,
+   |                                                                ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:89:30
+   |
+LL |     if let Custom::NoBrackets {} = Custom::Init {
+   |                              ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:93:30
+   |
+LL |     if let Custom::NoBrackets { .. } = Custom::Init {
+   |                              ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:97:30
+   |
+LL |     if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init {
+   |                              ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:97:67
+   |
+LL |     if let Custom::NoBrackets {} | Custom::NoBracketsNonExhaustive {} = Custom::Init {
+   |                                                                   ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:101:43
+   |
+LL |     if let Custom::NoBracketsNonExhaustive {} = Custom::Init {
+   |                                           ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:105:43
+   |
+LL |     if let Custom::NoBracketsNonExhaustive { .. } = Custom::Init {
+   |                                           ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:121:27
+   |
+LL |     let Custom::NoBrackets {} = Custom::Init else { panic!() };
+   |                           ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:123:27
+   |
+LL |     let Custom::NoBrackets { .. } = Custom::Init else {
+   |                           ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:127:40
+   |
+LL |     let Custom::NoBracketsNonExhaustive {} = Custom::Init else {
+   |                                        ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:131:40
+   |
+LL |     let Custom::NoBracketsNonExhaustive { .. } = Custom::Init else {
+   |                                        ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:140:44
+   |
+LL |     fn pat_in_fn_param_1(Refutable::Variant {}: Refutable) {}
+   |                                            ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:141:44
+   |
+LL |     fn pat_in_fn_param_2(Refutable::Variant { .. }: Refutable) {}
+   |                                            ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:143:27
+   |
+LL |     for Refutable::Variant {} in [] {}
+   |                           ^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:144:27
+   |
+LL |     for Refutable::Variant { .. } in [] {}
+   |                           ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:158:23
+   |
+LL |         ExhaustiveUnit { .. } => 0,
+   |                       ^^^^^^^ help: remove the struct pattern
+
+error: struct pattern is not needed for a unit variant
+  --> tests/ui/unneeded_struct_pattern.rs:164:23
+   |
+LL |         ExhaustiveUnit {} => 0,
+   |                       ^^^ help: remove the struct pattern
+
+error: aborting due to 33 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
index bd15ef62368..4325df14304 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
@@ -8,8 +8,9 @@ LL |     if let box 0 | box 2 = Box::new(0) {}
    = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]`
 help: nest the patterns
    |
-LL |     if let box (0 | 2) = Box::new(0) {}
-   |            ~~~~~~~~~~~
+LL -     if let box 0 | box 2 = Box::new(0) {}
+LL +     if let box (0 | 2) = Box::new(0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:17:12
@@ -19,8 +20,9 @@ LL |     if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
    |
 help: nest the patterns
    |
-LL |     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
-   |            ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
+LL +     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:19:12
@@ -30,8 +32,9 @@ LL |     if let Some(1) | C0 | Some(2) = None {}
    |
 help: nest the patterns
    |
-LL |     if let Some(1 | 2) | C0 = None {}
-   |            ~~~~~~~~~~~~~~~~
+LL -     if let Some(1) | C0 | Some(2) = None {}
+LL +     if let Some(1 | 2) | C0 = None {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:20:12
@@ -41,8 +44,9 @@ LL |     if let &mut 0 | &mut 2 = &mut 0 {}
    |
 help: nest the patterns
    |
-LL |     if let &mut (0 | 2) = &mut 0 {}
-   |            ~~~~~~~~~~~~
+LL -     if let &mut 0 | &mut 2 = &mut 0 {}
+LL +     if let &mut (0 | 2) = &mut 0 {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:21:12
@@ -52,8 +56,9 @@ LL |     if let x @ 0 | x @ 2 = 0 {}
    |
 help: nest the patterns
    |
-LL |     if let x @ (0 | 2) = 0 {}
-   |            ~~~~~~~~~~~
+LL -     if let x @ 0 | x @ 2 = 0 {}
+LL +     if let x @ (0 | 2) = 0 {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:22:12
@@ -63,8 +68,9 @@ LL |     if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
    |
 help: nest the patterns
    |
-LL |     if let (0, 1 | 2 | 3) = (0, 0) {}
-   |            ~~~~~~~~~~~~~~
+LL -     if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
+LL +     if let (0, 1 | 2 | 3) = (0, 0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:23:12
@@ -74,8 +80,9 @@ LL |     if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}
    |
 help: nest the patterns
    |
-LL |     if let (1 | 2 | 3, 0) = (0, 0) {}
-   |            ~~~~~~~~~~~~~~
+LL -     if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}
+LL +     if let (1 | 2 | 3, 0) = (0, 0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:24:12
@@ -85,8 +92,9 @@ LL |     if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}
    |
 help: nest the patterns
    |
-LL |     if let (x, ..) | (x, 1 | 2) = (0, 1) {}
-   |            ~~~~~~~~~~~~~~~~~~~~
+LL -     if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}
+LL +     if let (x, ..) | (x, 1 | 2) = (0, 1) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:25:12
@@ -96,8 +104,9 @@ LL |     if let [0] | [1] = [0] {}
    |
 help: nest the patterns
    |
-LL |     if let [0 | 1] = [0] {}
-   |            ~~~~~~~
+LL -     if let [0] | [1] = [0] {}
+LL +     if let [0 | 1] = [0] {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:26:12
@@ -107,8 +116,9 @@ LL |     if let [x, 0] | [x, 1] = [0, 1] {}
    |
 help: nest the patterns
    |
-LL |     if let [x, 0 | 1] = [0, 1] {}
-   |            ~~~~~~~~~~
+LL -     if let [x, 0] | [x, 1] = [0, 1] {}
+LL +     if let [x, 0 | 1] = [0, 1] {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:27:12
@@ -118,8 +128,9 @@ LL |     if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}
    |
 help: nest the patterns
    |
-LL |     if let [x, 0 | 1 | 2] = [0, 1] {}
-   |            ~~~~~~~~~~~~~~
+LL -     if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}
+LL +     if let [x, 0 | 1 | 2] = [0, 1] {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:28:12
@@ -129,8 +140,9 @@ LL |     if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}
    |
 help: nest the patterns
    |
-LL |     if let [x, ..] | [x, 1 | 2] = [0, 1] {}
-   |            ~~~~~~~~~~~~~~~~~~~~
+LL -     if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}
+LL +     if let [x, ..] | [x, 1 | 2] = [0, 1] {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:30:12
@@ -140,8 +152,9 @@ LL |     if let TS(0, x) | TS(1, x) = TS(0, 0) {}
    |
 help: nest the patterns
    |
-LL |     if let TS(0 | 1, x) = TS(0, 0) {}
-   |            ~~~~~~~~~~~~
+LL -     if let TS(0, x) | TS(1, x) = TS(0, 0) {}
+LL +     if let TS(0 | 1, x) = TS(0, 0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:31:12
@@ -151,8 +164,9 @@ LL |     if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}
    |
 help: nest the patterns
    |
-LL |     if let TS(1 | 2 | 3, 0) = TS(0, 0) {}
-   |            ~~~~~~~~~~~~~~~~
+LL -     if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}
+LL +     if let TS(1 | 2 | 3, 0) = TS(0, 0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:32:12
@@ -162,8 +176,9 @@ LL |     if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
    |
 help: nest the patterns
    |
-LL |     if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
-   |            ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
+LL +     if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:37:12
@@ -173,8 +188,9 @@ LL |     if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
    |
 help: nest the patterns
    |
-LL |     if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
-   |            ~~~~~~~~~~~~~~~~~
+LL -     if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
+LL +     if let S { x: 0 | 1, y } = (S { x: 0, y: 1 }) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns.rs:48:12
@@ -184,8 +200,9 @@ LL |     if let [1] | [53] = [0] {}
    |
 help: nest the patterns
    |
-LL |     if let [1 | 53] = [0] {}
-   |            ~~~~~~~~
+LL -     if let [1] | [53] = [0] {}
+LL +     if let [1 | 53] = [0] {}
+   |
 
 error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr
index 54f03937508..3d8968551b9 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns2.stderr
@@ -8,8 +8,9 @@ LL |     if let Some(Some(0)) | Some(Some(1)) = None {}
    = help: to override `-D warnings` add `#[allow(clippy::unnested_or_patterns)]`
 help: nest the patterns
    |
-LL |     if let Some(Some(0 | 1)) = None {}
-   |            ~~~~~~~~~~~~~~~~~
+LL -     if let Some(Some(0)) | Some(Some(1)) = None {}
+LL +     if let Some(Some(0 | 1)) = None {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns2.rs:13:12
@@ -19,8 +20,9 @@ LL |     if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {}
    |
 help: nest the patterns
    |
-LL |     if let Some(Some(0 | 1 | 2)) = None {}
-   |            ~~~~~~~~~~~~~~~~~~~~~
+LL -     if let Some(Some(0)) | Some(Some(1) | Some(2)) = None {}
+LL +     if let Some(Some(0 | 1 | 2)) = None {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns2.rs:14:12
@@ -30,8 +32,9 @@ LL |     if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {}
    |
 help: nest the patterns
    |
-LL |     if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {}
-   |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if let Some(Some(0 | 1) | Some(2)) | Some(Some(3) | Some(4)) = None {}
+LL +     if let Some(Some(0 | 1 | 2 | 3 | 4)) = None {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns2.rs:15:12
@@ -41,8 +44,9 @@ LL |     if let Some(Some(0) | Some(1 | 2)) = None {}
    |
 help: nest the patterns
    |
-LL |     if let Some(Some(0 | 1 | 2)) = None {}
-   |            ~~~~~~~~~~~~~~~~~~~~~
+LL -     if let Some(Some(0) | Some(1 | 2)) = None {}
+LL +     if let Some(Some(0 | 1 | 2)) = None {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns2.rs:16:12
@@ -52,8 +56,9 @@ LL |     if let ((0,),) | ((1,) | (2,),) = ((0,),) {}
    |
 help: nest the patterns
    |
-LL |     if let ((0 | 1 | 2,),) = ((0,),) {}
-   |            ~~~~~~~~~~~~~~~
+LL -     if let ((0,),) | ((1,) | (2,),) = ((0,),) {}
+LL +     if let ((0 | 1 | 2,),) = ((0,),) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns2.rs:17:12
@@ -63,8 +68,9 @@ LL |     if let 0 | (1 | 2) = 0 {}
    |
 help: nest the patterns
    |
-LL |     if let 0 | 1 | 2 = 0 {}
-   |            ~~~~~~~~~
+LL -     if let 0 | (1 | 2) = 0 {}
+LL +     if let 0 | 1 | 2 = 0 {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns2.rs:18:12
@@ -74,8 +80,9 @@ LL |     if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {}
    |
 help: nest the patterns
    |
-LL |     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
-   |            ~~~~~~~~~~~~~~~~~~~~~~~
+LL -     if let box (0 | 1) | (box 2 | box (3 | 4)) = Box::new(0) {}
+LL +     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
+   |
 
 error: unnested or-patterns
   --> tests/ui/unnested_or_patterns2.rs:19:12
@@ -85,8 +92,9 @@ LL |     if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {}
    |
 help: nest the patterns
    |
-LL |     if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {}
-   |            ~~~~~~~~~~~~~~~~~~~
+LL -     if let box box 0 | box (box 2 | box 4) = Box::new(Box::new(0)) {}
+LL +     if let box box (0 | 2 | 4) = Box::new(Box::new(0)) {}
+   |
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unused_enumerate_index.stderr b/src/tools/clippy/tests/ui/unused_enumerate_index.stderr
index 6ec07dcbff0..02d65f06430 100644
--- a/src/tools/clippy/tests/ui/unused_enumerate_index.stderr
+++ b/src/tools/clippy/tests/ui/unused_enumerate_index.stderr
@@ -8,8 +8,9 @@ LL |     for (_, x) in v.iter().enumerate() {
    = help: to override `-D warnings` add `#[allow(clippy::unused_enumerate_index)]`
 help: remove the `.enumerate()` call
    |
-LL |     for x in v.iter() {
-   |         ~    ~~~~~~~~
+LL -     for (_, x) in v.iter().enumerate() {
+LL +     for x in v.iter() {
+   |
 
 error: you seem to use `.enumerate()` and immediately discard the index
   --> tests/ui/unused_enumerate_index.rs:59:19
@@ -19,8 +20,9 @@ LL |     for (_, x) in dummy.enumerate() {
    |
 help: remove the `.enumerate()` call
    |
-LL |     for x in dummy {
-   |         ~    ~~~~~
+LL -     for (_, x) in dummy.enumerate() {
+LL +     for x in dummy {
+   |
 
 error: you seem to use `.enumerate()` and immediately discard the index
   --> tests/ui/unused_enumerate_index.rs:63:39
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.stderr b/src/tools/clippy/tests/ui/unused_format_specs.stderr
index df61d59130e..d3c0530ced4 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs.stderr
+++ b/src/tools/clippy/tests/ui/unused_format_specs.stderr
@@ -8,8 +8,9 @@ LL |     println!("{:5}.", format_args!(""));
    = help: to override `-D warnings` add `#[allow(clippy::unused_format_specs)]`
 help: for the width to apply consider using `format!()`
    |
-LL |     println!("{:5}.", format!(""));
-   |                       ~~~~~~
+LL -     println!("{:5}.", format_args!(""));
+LL +     println!("{:5}.", format!(""));
+   |
 help: if the current behavior is intentional, remove the format specifiers
    |
 LL -     println!("{:5}.", format_args!(""));
@@ -24,8 +25,9 @@ LL |     println!("{:.3}", format_args!("abcde"));
    |
 help: for the precision to apply consider using `format!()`
    |
-LL |     println!("{:.3}", format!("abcde"));
-   |                       ~~~~~~
+LL -     println!("{:.3}", format_args!("abcde"));
+LL +     println!("{:.3}", format!("abcde"));
+   |
 help: if the current behavior is intentional, remove the format specifiers
    |
 LL -     println!("{:.3}", format_args!("abcde"));
@@ -66,8 +68,9 @@ LL |     usr_println!(true, "{:5}.", format_args!(""));
    |
 help: for the width to apply consider using `format!()`
    |
-LL |     usr_println!(true, "{:5}.", format!(""));
-   |                                 ~~~~~~
+LL -     usr_println!(true, "{:5}.", format_args!(""));
+LL +     usr_println!(true, "{:5}.", format!(""));
+   |
 help: if the current behavior is intentional, remove the format specifiers
    |
 LL -     usr_println!(true, "{:5}.", format_args!(""));
@@ -82,8 +85,9 @@ LL |     usr_println!(true, "{:.3}", format_args!("abcde"));
    |
 help: for the precision to apply consider using `format!()`
    |
-LL |     usr_println!(true, "{:.3}", format!("abcde"));
-   |                                 ~~~~~~
+LL -     usr_println!(true, "{:.3}", format_args!("abcde"));
+LL +     usr_println!(true, "{:.3}", format!("abcde"));
+   |
 help: if the current behavior is intentional, remove the format specifiers
    |
 LL -     usr_println!(true, "{:.3}", format_args!("abcde"));
diff --git a/src/tools/clippy/tests/ui/unused_result_ok.stderr b/src/tools/clippy/tests/ui/unused_result_ok.stderr
index 241e0c71261..024aafa6bbb 100644
--- a/src/tools/clippy/tests/ui/unused_result_ok.stderr
+++ b/src/tools/clippy/tests/ui/unused_result_ok.stderr
@@ -8,8 +8,9 @@ LL |     x.parse::<u32>().ok();
    = help: to override `-D warnings` add `#[allow(clippy::unused_result_ok)]`
 help: consider using `let _ =` and removing the call to `.ok()` instead
    |
-LL |     let _ = x.parse::<u32>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     x.parse::<u32>().ok();
+LL +     let _ = x.parse::<u32>();
+   |
 
 error: ignoring a result with `.ok()` is misleading
   --> tests/ui/unused_result_ok.rs:18:5
@@ -19,8 +20,9 @@ LL |     x   .   parse::<i32>()   .   ok   ();
    |
 help: consider using `let _ =` and removing the call to `.ok()` instead
    |
-LL |     let _ = x   .   parse::<i32>();
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LL -     x   .   parse::<i32>()   .   ok   ();
+LL +     let _ = x   .   parse::<i32>();
+   |
 
 error: ignoring a result with `.ok()` is misleading
   --> tests/ui/unused_result_ok.rs:34:5
@@ -30,8 +32,9 @@ LL |     v!().ok();
    |
 help: consider using `let _ =` and removing the call to `.ok()` instead
    |
-LL |     let _ = v!();
-   |     ~~~~~~~~~~~~
+LL -     v!().ok();
+LL +     let _ = v!();
+   |
 
 error: ignoring a result with `.ok()` is misleading
   --> tests/ui/unused_result_ok.rs:29:9
@@ -45,8 +48,9 @@ LL |     w!();
    = note: this error originates in the macro `w` (in Nightly builds, run with -Z macro-backtrace for more info)
 help: consider using `let _ =` and removing the call to `.ok()` instead
    |
-LL |         let _ = Ok::<(), ()>(());
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~
+LL -         Ok::<(), ()>(()).ok();
+LL +         let _ = Ok::<(), ()>(());
+   |
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed
index 2f7edd92bb7..697d437b388 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.fixed
+++ b/src/tools/clippy/tests/ui/useless_conversion.fixed
@@ -342,3 +342,56 @@ fn gen_identity<T>(x: [T; 3]) -> Vec<T> {
     x.into_iter().collect()
     //~^ useless_conversion
 }
+
+mod issue11819 {
+    fn takes_into_iter(_: impl IntoIterator<Item = String>) {}
+
+    pub struct MyStruct<T> {
+        my_field: T,
+    }
+
+    impl<T> MyStruct<T> {
+        pub fn with_ref<'a>(&'a mut self)
+        where
+            &'a T: IntoIterator<Item = String>,
+        {
+            takes_into_iter(&self.my_field);
+            //~^ useless_conversion
+        }
+
+        pub fn with_ref_mut<'a>(&'a mut self)
+        where
+            &'a mut T: IntoIterator<Item = String>,
+        {
+            takes_into_iter(&mut self.my_field);
+            //~^ useless_conversion
+        }
+
+        pub fn with_deref<Y>(&mut self)
+        where
+            T: std::ops::Deref<Target = Y>,
+            Y: IntoIterator<Item = String> + Copy,
+        {
+            takes_into_iter(*self.my_field);
+            //~^ useless_conversion
+        }
+
+        pub fn with_reborrow<'a, Y: 'a>(&'a mut self)
+        where
+            T: std::ops::Deref<Target = Y>,
+            &'a Y: IntoIterator<Item = String>,
+        {
+            takes_into_iter(&*self.my_field);
+            //~^ useless_conversion
+        }
+
+        pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self)
+        where
+            T: std::ops::Deref<Target = Y> + std::ops::DerefMut,
+            &'a mut Y: IntoIterator<Item = String>,
+        {
+            takes_into_iter(&mut *self.my_field);
+            //~^ useless_conversion
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs
index eacdf77f905..4d8ad61a8c9 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.rs
+++ b/src/tools/clippy/tests/ui/useless_conversion.rs
@@ -342,3 +342,56 @@ fn gen_identity<T>(x: [T; 3]) -> Vec<T> {
     x.into_iter().map(Into::into).collect()
     //~^ useless_conversion
 }
+
+mod issue11819 {
+    fn takes_into_iter(_: impl IntoIterator<Item = String>) {}
+
+    pub struct MyStruct<T> {
+        my_field: T,
+    }
+
+    impl<T> MyStruct<T> {
+        pub fn with_ref<'a>(&'a mut self)
+        where
+            &'a T: IntoIterator<Item = String>,
+        {
+            takes_into_iter(self.my_field.into_iter());
+            //~^ useless_conversion
+        }
+
+        pub fn with_ref_mut<'a>(&'a mut self)
+        where
+            &'a mut T: IntoIterator<Item = String>,
+        {
+            takes_into_iter(self.my_field.into_iter());
+            //~^ useless_conversion
+        }
+
+        pub fn with_deref<Y>(&mut self)
+        where
+            T: std::ops::Deref<Target = Y>,
+            Y: IntoIterator<Item = String> + Copy,
+        {
+            takes_into_iter(self.my_field.into_iter());
+            //~^ useless_conversion
+        }
+
+        pub fn with_reborrow<'a, Y: 'a>(&'a mut self)
+        where
+            T: std::ops::Deref<Target = Y>,
+            &'a Y: IntoIterator<Item = String>,
+        {
+            takes_into_iter(self.my_field.into_iter());
+            //~^ useless_conversion
+        }
+
+        pub fn with_reborrow_mut<'a, Y: 'a>(&'a mut self)
+        where
+            T: std::ops::Deref<Target = Y> + std::ops::DerefMut,
+            &'a mut Y: IntoIterator<Item = String>,
+        {
+            takes_into_iter(self.my_field.into_iter());
+            //~^ useless_conversion
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr
index 6aeb382902b..ed50f307186 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion.stderr
@@ -122,7 +122,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:189:7
    |
 LL |     b(vec![1, 2].into_iter());
-   |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
+   |       ^^^^^^^^^^------------
+   |                 |
+   |                 help: consider removing the `.into_iter()`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:179:13
@@ -134,7 +136,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:190:7
    |
 LL |     c(vec![1, 2].into_iter());
-   |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
+   |       ^^^^^^^^^^------------
+   |                 |
+   |                 help: consider removing the `.into_iter()`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:180:18
@@ -146,7 +150,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:191:7
    |
 LL |     d(vec![1, 2].into_iter());
-   |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
+   |       ^^^^^^^^^^------------
+   |                 |
+   |                 help: consider removing the `.into_iter()`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:183:12
@@ -158,7 +164,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:194:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter());
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
+   |       ^^^^^^^^^^------------------------
+   |                 |
+   |                 help: consider removing the `.into_iter()`s
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:179:13
@@ -170,7 +178,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:195:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter().into_iter());
-   |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
+   |       ^^^^^^^^^^------------------------------------
+   |                 |
+   |                 help: consider removing the `.into_iter()`s
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:179:13
@@ -182,7 +192,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:241:24
    |
 LL |         foo2::<i32, _>([1, 2, 3].into_iter());
-   |                        ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+   |                        ^^^^^^^^^------------
+   |                                 |
+   |                                 help: consider removing the `.into_iter()`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:220:12
@@ -194,7 +206,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:249:14
    |
 LL |         foo3([1, 2, 3].into_iter());
-   |              ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+   |              ^^^^^^^^^------------
+   |                       |
+   |                       help: consider removing the `.into_iter()`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:229:12
@@ -206,7 +220,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:258:16
    |
 LL |         S1.foo([1, 2].into_iter());
-   |                ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]`
+   |                ^^^^^^------------
+   |                      |
+   |                      help: consider removing the `.into_iter()`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:255:27
@@ -218,7 +234,9 @@ error: explicit call to `.into_iter()` in function argument accepting `IntoItera
   --> tests/ui/useless_conversion.rs:277:44
    |
 LL |         v0.into_iter().interleave_shortest(v1.into_iter());
-   |                                            ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1`
+   |                                            ^^------------
+   |                                              |
+   |                                              help: consider removing the `.into_iter()`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
   --> tests/ui/useless_conversion.rs:264:20
@@ -274,5 +292,90 @@ error: useless conversion to the same type: `T`
 LL |     x.into_iter().map(Into::into).collect()
    |                  ^^^^^^^^^^^^^^^^ help: consider removing
 
-error: aborting due to 36 previous errors
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> tests/ui/useless_conversion.rs:358:29
+   |
+LL |             takes_into_iter(self.my_field.into_iter());
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> tests/ui/useless_conversion.rs:347:32
+   |
+LL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider removing the `.into_iter()`
+   |
+LL -             takes_into_iter(self.my_field.into_iter());
+LL +             takes_into_iter(&self.my_field);
+   |
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> tests/ui/useless_conversion.rs:366:29
+   |
+LL |             takes_into_iter(self.my_field.into_iter());
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> tests/ui/useless_conversion.rs:347:32
+   |
+LL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider removing the `.into_iter()`
+   |
+LL -             takes_into_iter(self.my_field.into_iter());
+LL +             takes_into_iter(&mut self.my_field);
+   |
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> tests/ui/useless_conversion.rs:375:29
+   |
+LL |             takes_into_iter(self.my_field.into_iter());
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> tests/ui/useless_conversion.rs:347:32
+   |
+LL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider removing the `.into_iter()`
+   |
+LL -             takes_into_iter(self.my_field.into_iter());
+LL +             takes_into_iter(*self.my_field);
+   |
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> tests/ui/useless_conversion.rs:384:29
+   |
+LL |             takes_into_iter(self.my_field.into_iter());
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> tests/ui/useless_conversion.rs:347:32
+   |
+LL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider removing the `.into_iter()`
+   |
+LL -             takes_into_iter(self.my_field.into_iter());
+LL +             takes_into_iter(&*self.my_field);
+   |
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> tests/ui/useless_conversion.rs:393:29
+   |
+LL |             takes_into_iter(self.my_field.into_iter());
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> tests/ui/useless_conversion.rs:347:32
+   |
+LL |     fn takes_into_iter(_: impl IntoIterator<Item = String>) {}
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider removing the `.into_iter()`
+   |
+LL -             takes_into_iter(self.my_field.into_iter());
+LL +             takes_into_iter(&mut *self.my_field);
+   |
+
+error: aborting due to 41 previous errors
 
diff --git a/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.fixed b/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.fixed
new file mode 100644
index 00000000000..03b34afa54e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.fixed
@@ -0,0 +1,52 @@
+#![warn(clippy::useless_nonzero_new_unchecked)]
+
+use std::num::{NonZero, NonZeroUsize};
+
+#[clippy::msrv = "1.83"]
+const fn func() -> NonZeroUsize {
+    const { NonZeroUsize::new(3).unwrap() }
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+}
+
+#[clippy::msrv = "1.82"]
+const fn func_older() -> NonZeroUsize {
+    unsafe { NonZeroUsize::new_unchecked(3) }
+}
+
+const fn func_performance_hit_if_linted() -> NonZeroUsize {
+    unsafe { NonZeroUsize::new_unchecked(3) }
+}
+
+const fn func_may_panic_at_run_time_if_linted(x: usize) -> NonZeroUsize {
+    unsafe { NonZeroUsize::new_unchecked(x) }
+}
+
+macro_rules! uns {
+    ($expr:expr) => {
+        unsafe { $expr }
+    };
+}
+
+macro_rules! nzu {
+    () => {
+        NonZeroUsize::new_unchecked(1)
+    };
+}
+
+fn main() {
+    const _A: NonZeroUsize = NonZeroUsize::new(3).unwrap();
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    static _B: NonZero<u8> = NonZero::<u8>::new(42).unwrap();
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    const _C: usize = unsafe { NonZeroUsize::new(3).unwrap().get() };
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    const AUX: usize = 3;
+    const _D: NonZeroUsize = NonZeroUsize::new(AUX).unwrap();
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3));
+    const _Y: NonZeroUsize = unsafe { nzu!() };
+}
diff --git a/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.rs b/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.rs
new file mode 100644
index 00000000000..d450e3a03ec
--- /dev/null
+++ b/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.rs
@@ -0,0 +1,52 @@
+#![warn(clippy::useless_nonzero_new_unchecked)]
+
+use std::num::{NonZero, NonZeroUsize};
+
+#[clippy::msrv = "1.83"]
+const fn func() -> NonZeroUsize {
+    const { unsafe { NonZeroUsize::new_unchecked(3) } }
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+}
+
+#[clippy::msrv = "1.82"]
+const fn func_older() -> NonZeroUsize {
+    unsafe { NonZeroUsize::new_unchecked(3) }
+}
+
+const fn func_performance_hit_if_linted() -> NonZeroUsize {
+    unsafe { NonZeroUsize::new_unchecked(3) }
+}
+
+const fn func_may_panic_at_run_time_if_linted(x: usize) -> NonZeroUsize {
+    unsafe { NonZeroUsize::new_unchecked(x) }
+}
+
+macro_rules! uns {
+    ($expr:expr) => {
+        unsafe { $expr }
+    };
+}
+
+macro_rules! nzu {
+    () => {
+        NonZeroUsize::new_unchecked(1)
+    };
+}
+
+fn main() {
+    const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    static _B: NonZero<u8> = unsafe { NonZero::<u8>::new_unchecked(42) };
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() };
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    const AUX: usize = 3;
+    const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) };
+    //~^ ERROR: `Option::unwrap()` can be safely used in a `const` context
+
+    const _X: NonZeroUsize = uns!(NonZeroUsize::new_unchecked(3));
+    const _Y: NonZeroUsize = unsafe { nzu!() };
+}
diff --git a/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.stderr b/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.stderr
new file mode 100644
index 00000000000..adb14616763
--- /dev/null
+++ b/src/tools/clippy/tests/ui/useless_nonzero_new_unchecked.stderr
@@ -0,0 +1,37 @@
+error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context
+  --> tests/ui/useless_nonzero_new_unchecked.rs:7:13
+   |
+LL |     const { unsafe { NonZeroUsize::new_unchecked(3) } }
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()`
+   |
+   = note: `-D clippy::useless-nonzero-new-unchecked` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::useless_nonzero_new_unchecked)]`
+
+error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context
+  --> tests/ui/useless_nonzero_new_unchecked.rs:37:30
+   |
+LL |     const _A: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(3) };
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()`
+
+error: `NonZero::<u8>::new()` and `Option::unwrap()` can be safely used in a `const` context
+  --> tests/ui/useless_nonzero_new_unchecked.rs:40:30
+   |
+LL |     static _B: NonZero<u8> = unsafe { NonZero::<u8>::new_unchecked(42) };
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZero::<u8>::new(42).unwrap()`
+
+error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context
+  --> tests/ui/useless_nonzero_new_unchecked.rs:43:32
+   |
+LL |     const _C: usize = unsafe { NonZeroUsize::new_unchecked(3).get() };
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(3).unwrap()`
+   |
+   = note: the fixed expression does not require an `unsafe` context
+
+error: `NonZeroUsize::new()` and `Option::unwrap()` can be safely used in a `const` context
+  --> tests/ui/useless_nonzero_new_unchecked.rs:47:30
+   |
+LL |     const _D: NonZeroUsize = unsafe { NonZeroUsize::new_unchecked(AUX) };
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use instead: `NonZeroUsize::new(AUX).unwrap()`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/write_literal.fixed b/src/tools/clippy/tests/ui/write_literal.fixed
index 3d216b76cbf..f1def776e1b 100644
--- a/src/tools/clippy/tests/ui/write_literal.fixed
+++ b/src/tools/clippy/tests/ui/write_literal.fixed
@@ -62,3 +62,19 @@ fn main() {
     writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4);
     //~^ ERROR: literal with an empty format string
 }
+
+fn issue_13959() {
+    let mut v = Vec::new();
+    writeln!(v, "\"");
+    writeln!(
+        v,
+        "
+        foo
+        \\
+        \\\\
+        \"
+        \\\"
+        bar
+"
+    );
+}
diff --git a/src/tools/clippy/tests/ui/write_literal.rs b/src/tools/clippy/tests/ui/write_literal.rs
index 79d6daa2e3b..1b7df91b47e 100644
--- a/src/tools/clippy/tests/ui/write_literal.rs
+++ b/src/tools/clippy/tests/ui/write_literal.rs
@@ -62,3 +62,20 @@ fn main() {
     writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4);
     //~^ ERROR: literal with an empty format string
 }
+
+fn issue_13959() {
+    let mut v = Vec::new();
+    writeln!(v, "{}", r#"""#);
+    writeln!(
+        v,
+        "{}",
+        r#"
+        foo
+        \
+        \\
+        "
+        \"
+        bar
+"#
+    );
+}
diff --git a/src/tools/clippy/tests/ui/write_literal.stderr b/src/tools/clippy/tests/ui/write_literal.stderr
index 9f4cdfd91e8..35c93d567cd 100644
--- a/src/tools/clippy/tests/ui/write_literal.stderr
+++ b/src/tools/clippy/tests/ui/write_literal.stderr
@@ -144,5 +144,41 @@ LL -     writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4);
 LL +     writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4);
    |
 
-error: aborting due to 12 previous errors
+error: literal with an empty format string
+  --> tests/ui/write_literal.rs:68:23
+   |
+LL |     writeln!(v, "{}", r#"""#);
+   |                       ^^^^^^
+   |
+help: try
+   |
+LL -     writeln!(v, "{}", r#"""#);
+LL +     writeln!(v, "\"");
+   |
+
+error: literal with an empty format string
+  --> tests/ui/write_literal.rs:72:9
+   |
+LL | /         r#"
+LL | |         foo
+LL | |         \
+LL | |         \\
+...  |
+LL | |         bar
+LL | | "#
+   | |__^
+   |
+help: try
+   |
+LL ~         "
+LL +         foo
+LL +         \\
+LL +         \\\\
+LL +         \"
+LL +         \\\"
+LL +         bar
+LL ~ "
+   |
+
+error: aborting due to 14 previous errors
 
diff --git a/src/tools/clippy/tests/versioncheck.rs b/src/tools/clippy/tests/versioncheck.rs
index e29898f068d..ed357137095 100644
--- a/src/tools/clippy/tests/versioncheck.rs
+++ b/src/tools/clippy/tests/versioncheck.rs
@@ -88,5 +88,5 @@ fn check_that_clippy_has_the_same_major_version_as_rustc() {
         _ => {
             panic!("Failed to parse rustc version: {vsplit:?}");
         },
-    };
+    }
 }
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index eadfd7107c7..3d35116ebc1 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -29,7 +29,6 @@ users_on_vacation = [
 "*" = [
     "@Manishearth",
     "@llogiq",
-    "@xFrednet",
     "@Alexendoo",
     "@dswij",
     "@Jarcho",
diff --git a/src/tools/clippy/util/gh-pages/index_template.html b/src/tools/clippy/util/gh-pages/index_template.html
index deb0ef0b499..a9b64628003 100644
--- a/src/tools/clippy/util/gh-pages/index_template.html
+++ b/src/tools/clippy/util/gh-pages/index_template.html
@@ -24,14 +24,16 @@ Otherwise, have a great day =^.^=
     <link id="styleNight" rel="stylesheet" href="https://rust-lang.github.io/mdBook/tomorrow-night.css" disabled="true"> {# #}
     <link id="styleAyu" rel="stylesheet" href="https://rust-lang.github.io/mdBook/ayu-highlight.css" disabled="true"> {# #}
     <link rel="stylesheet" href="style.css"> {# #}
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js" defer></script> {# #}
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js" defer></script> {# #}
+    <script src="script.js" defer></script> {# #}
 </head> {# #}
 <body> {# #}
-    <script src="theme.js"></script> {# #}
     <div id="settings-dropdown"> {# #}
         <button class="settings-icon" tabindex="-1"></button> {# #}
         <div class="settings-menu" tabindex="-1"> {# #}
             <div class="setting-radio-name">Theme</div> {# #}
-            <select id="theme-choice" onchange="setTheme(this.value, true)"> {# #}
+            <select id="theme-choice"> {# #}
                 <option value="ayu">Ayu</option> {# #}
                 <option value="coal">Coal</option> {# #}
                 <option value="light">Light</option> {# #}
@@ -39,11 +41,12 @@ Otherwise, have a great day =^.^=
                 <option value="rust">Rust</option> {# #}
             </select> {# #}
             <label> {# #}
-                <input type="checkbox" id="disable-shortcuts" onchange="changeSetting(this)"> {#+ #}
+                <input type="checkbox" id="disable-shortcuts"> {#+ #}
                 <span>Disable keyboard shortcuts</span> {# #}
             </label> {# #}
         </div> {# #}
     </div> {# #}
+    <script src="theme.js"></script> {# #}
 
     <div class="container"> {# #}
         <div class="page-header"> {# #}
@@ -133,10 +136,10 @@ Otherwise, have a great day =^.^=
                         </div> {# #}
                     </div> {# #}
                     <div class="col-12 col-md-2 btn-group expansion-group"> {# #}
-                        <button title="Collapse All" class="btn btn-default expansion-control" type="button" onclick="toggleExpansion(false)"> {# #}
+                        <button title="Collapse All" class="btn btn-default expansion-control" type="button" id="collapse-all"> {# #}
                             <span class="glyphicon glyphicon-collapse-up"></span> {# #}
                         </button> {# #}
-                        <button title="Expand All" class="btn btn-default expansion-control" type="button" onclick="toggleExpansion(true)"> {# #}
+                        <button title="Expand All" class="btn btn-default expansion-control" type="button" id="expand-all"> {# #}
                             <span class="glyphicon glyphicon-collapse-down"></span> {# #}
                         </button> {# #}
                     </div> {# #}
@@ -145,13 +148,13 @@ Otherwise, have a great day =^.^=
             {% for lint in lints %}
                 <article class="panel panel-default" id="{{lint.id}}"> {# #}
                     <input id="label-{{lint.id}}" type="checkbox"> {# #}
-                    <label for="label-{{lint.id}}" onclick="highlightIfNeeded('{{lint.id}}')"> {# #}
+                    <label for="label-{{lint.id}}"> {# #}
                         <header class="panel-heading"> {# #}
                             <h2 class="panel-title"> {# #}
                                 <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
                                     <span>{{lint.id}}</span> {#+ #}
-                                    <a href="#{{lint.id}}" onclick="lintAnchor(event)" class="anchor label label-default">&para;</a> {#+ #}
-                                    <a href="" class="anchor label label-default" onclick="copyToClipboard(event)"> {# #}
+                                    <a href="#{{lint.id}}" class="lint-anchor anchor label label-default">&para;</a> {#+ #}
+                                    <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
                                         &#128203; {# #}
                                     </a> {# #}
                                 </div> {# #}
@@ -227,9 +230,5 @@ Otherwise, have a great day =^.^=
             ></path> {# #}
         </svg> {# #}
     </a> {# #}
-
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/highlight.min.js"></script> {# #}
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/languages/rust.min.js"></script> {# #}
-    <script src="script.js"></script> {# #}
 </body> {# #}
 </html> {# #}
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index c2197b89c56..c942a6a05a1 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -1,3 +1,5 @@
+"use strict";
+
 window.searchState = {
     timeout: null,
     inputElem: document.getElementById("search-input"),
@@ -124,13 +126,6 @@ function toggleElements(filter, value) {
     }
 }
 
-function changeSetting(elem) {
-    if (elem.id === "disable-shortcuts") {
-        disableShortcuts = elem.checked;
-        storeValue(elem.id, elem.checked);
-    }
-}
-
 function onEachLazy(lazyArray, func) {
     const arr = Array.prototype.slice.call(lazyArray);
     for (const el of arr) {
@@ -138,17 +133,9 @@ function onEachLazy(lazyArray, func) {
     }
 }
 
-function highlightIfNeeded(lintId) {
-    onEachLazy(document.querySelectorAll(`#${lintId} pre > code:not(.hljs)`), el => {
-        hljs.highlightElement(el.parentElement)
-        el.classList.add("highlighted");
-    });
-}
-
 function expandLint(lintId) {
     const elem = document.querySelector(`#${lintId} > input[type="checkbox"]`);
     elem.checked = true;
-    highlightIfNeeded(lintId);
 }
 
 function lintAnchor(event) {
@@ -194,13 +181,9 @@ function handleBlur(event, elementId) {
 }
 
 function toggleExpansion(expand) {
-    onEachLazy(
-        document.querySelectorAll("article"),
-        expand ? el => {
-            el.classList.remove("collapsed");
-            highlightIfNeeded(el);
-        } : el => el.classList.add("collapsed"),
-    );
+    for (const checkbox of document.querySelectorAll("article input[type=checkbox]")) {
+        checkbox.checked = expand;
+    }
 }
 
 // Returns the current URL without any query parameter or hash.
@@ -341,8 +324,8 @@ window.filters = {
                 || !filters.levels_filter[lint.level]
                 || !filters.applicabilities_filter[lint.applicability]
                 || !(filters.version_filter["="] === null || lint.version === filters.version_filter["="])
-                || !(filters.version_filter["≥"] === null || lint.version > filters.version_filter["≥"])
-                || !(filters.version_filter["≤"] === null || lint.version < filters.version_filter["≤"])
+                || !(filters.version_filter["≥"] === null || lint.version >= filters.version_filter["≥"])
+                || !(filters.version_filter["≤"] === null || lint.version <= filters.version_filter["≤"])
             );
             if (lint.filteredOut || lint.searchFilteredOut) {
                 lint.elem.style.display = "none";
@@ -535,7 +518,7 @@ function parseURLFilters() {
         for (const [corres_key, corres_value] of Object.entries(URL_PARAMS_CORRESPONDENCE)) {
             if (corres_value === key) {
                 if (key !== "versions") {
-                    const settings  = new Set(value.split(","));
+                    const settings = new Set(value.split(","));
                     onEachLazy(document.querySelectorAll(`#lint-${key} ul input`), elem => {
                         elem.checked = settings.has(elem.getAttribute("data-value"));
                         updateFilter(elem, corres_key, true);
@@ -555,12 +538,60 @@ function parseURLFilters() {
     }
 }
 
-document.getElementById(`theme-choice`).value = loadValue("theme");
-let disableShortcuts = loadValue('disable-shortcuts') === "true";
-document.getElementById("disable-shortcuts").checked = disableShortcuts;
+function addListeners() {
+    disableShortcutsButton.addEventListener("change", () => {
+        disableShortcuts = disableShortcutsButton.checked;
+        storeValue("disable-shortcuts", disableShortcuts);
+    });
+
+    document.getElementById("expand-all").addEventListener("click", () => toggleExpansion(true));
+    document.getElementById("collapse-all").addEventListener("click", () => toggleExpansion(false));
+
+    // A delegated listener to avoid the upfront cost of >1000 listeners
+    document.addEventListener("click", event => {
+        if (!event.target instanceof HTMLAnchorElement) {
+            return;
+        }
+
+        if (event.target.classList.contains("lint-anchor")) {
+            lintAnchor(event);
+        } else if (event.target.classList.contains("copy-to-clipboard")) {
+            copyToClipboard(event);
+        }
+    });
+
+    document.addEventListener("keypress", handleShortcut);
+    document.addEventListener("keydown", handleShortcut);
+}
+
+// Highlight code blocks only when they approach the viewport so that clicking the "Expand All"
+// button doesn't take a long time
+function highlightLazily() {
+    if (!'IntersectionObserver' in window) {
+        return;
+    }
+    const observer = new IntersectionObserver((entries) => {
+        for (const entry of entries) {
+            if (entry.isIntersecting) {
+                observer.unobserve(entry.target);
+                for (const code of entry.target.querySelectorAll("pre code")) {
+                    hljs.highlightElement(code);
+                }
+            }
+        }
+    });
+    for (const docs of document.querySelectorAll(".lint-docs")) {
+        observer.observe(docs);
+    }
+}
+
+let disableShortcuts = loadValue("disable-shortcuts") === "true";
+
+const disableShortcutsButton = document.getElementById("disable-shortcuts");
+disableShortcutsButton.checked = disableShortcuts;
 
-document.addEventListener("keypress", handleShortcut);
-document.addEventListener("keydown", handleShortcut);
+addListeners();
+highlightLazily();
 
 generateSettings();
 generateSearch();
diff --git a/src/tools/clippy/util/gh-pages/style.css b/src/tools/clippy/util/gh-pages/style.css
index 896f2fdac76..3cc7a919c23 100644
--- a/src/tools/clippy/util/gh-pages/style.css
+++ b/src/tools/clippy/util/gh-pages/style.css
@@ -1,9 +1,5 @@
 blockquote { font-size: 1em; }
 
-[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
-    display: none !important;
-}
-
 .dropdown-menu {
     color: var(--fg);
     background: var(--theme-popup-bg);
@@ -188,8 +184,8 @@ details {
     padding: .5em .5em 0;
 }
 
-code {
-    white-space: pre !important;
+pre {
+    padding: 0;
 }
 
 summary {
diff --git a/src/tools/clippy/util/gh-pages/theme.js b/src/tools/clippy/util/gh-pages/theme.js
index 90f57d4469d..a5dfeed9e8c 100644
--- a/src/tools/clippy/util/gh-pages/theme.js
+++ b/src/tools/clippy/util/gh-pages/theme.js
@@ -1,3 +1,5 @@
+"use strict";
+
 function storeValue(settingName, value) {
     try {
         localStorage.setItem(`clippy-lint-list-${settingName}`, value);
@@ -57,4 +59,11 @@ function setTheme(theme, store) {
     } else {
         setTheme(theme, false);
     }
+
+    const themeChoice = document.getElementById("theme-choice");
+
+    themeChoice.value = loadValue("theme");
+    document.getElementById("theme-choice").addEventListener("change", (e) => {
+        setTheme(themeChoice.value, true);
+    });
 })();