From 1cc50519d103c84ec68f466af17c728e4584087e Mon Sep 17 00:00:00 2001
From: Philipp Krones <hello@philkrones.com>
Date: Thu, 26 Dec 2024 15:01:07 +0100
Subject: [PATCH 1/6] Merge commit '609cd310be44677ae31d452a17b0f8207e1abfe1'
 into clippy-subtree-update

---
 CHANGELOG.md                                  |   5 +
 .../development/common_tools_writing_lints.md |   2 +-
 .../development/infrastructure/backport.md    | 126 ++--
 .../src/development/infrastructure/release.md | 128 ++--
 book/src/development/infrastructure/sync.md   |  41 +-
 book/src/development/the_team.md              |   2 +-
 book/src/development/type_checking.md         |   2 +-
 book/src/lint_configuration.md                |  10 +
 clippy_config/src/conf.rs                     |   3 +
 .../src/arbitrary_source_item_ordering.rs     |   2 +-
 clippy_lints/src/attrs/mod.rs                 |  41 ++
 clippy_lints/src/attrs/repr_attributes.rs     |  43 ++
 clippy_lints/src/attrs/useless_attribute.rs   |  22 +-
 clippy_lints/src/attrs/utils.rs               |  21 +-
 clippy_lints/src/booleans.rs                  |   2 +-
 .../src/casts/as_pointer_underscore.rs        |  19 +
 clippy_lints/src/casts/borrow_as_ptr.rs       |  35 +-
 clippy_lints/src/casts/mod.rs                 |  51 +-
 clippy_lints/src/comparison_chain.rs          |  16 +-
 clippy_lints/src/declared_lints.rs            |   4 +
 clippy_lints/src/default_numeric_fallback.rs  |   7 +-
 clippy_lints/src/dereference.rs               |  11 +-
 clippy_lints/src/derive.rs                    |   8 +-
 clippy_lints/src/disallowed_macros.rs         |   1 -
 clippy_lints/src/disallowed_methods.rs        |   2 -
 .../src/doc/include_in_doc_without_cfg.rs     |   4 +-
 clippy_lints/src/doc/mod.rs                   | 116 +++-
 clippy_lints/src/explicit_write.rs            |   2 +-
 clippy_lints/src/functions/mod.rs             |  11 +-
 clippy_lints/src/functions/must_use.rs        |  58 +-
 clippy_lints/src/functions/result.rs          |  29 +-
 clippy_lints/src/if_not_else.rs               |  54 +-
 clippy_lints/src/incompatible_msrv.rs         |   2 +-
 clippy_lints/src/index_refutable_slice.rs     |  36 +-
 clippy_lints/src/indexing_slicing.rs          |  44 +-
 clippy_lints/src/large_include_file.rs        |   4 +-
 clippy_lints/src/lib.rs                       |   7 +-
 clippy_lints/src/lifetimes.rs                 |   9 +-
 .../literal_string_with_formatting_args.rs    | 167 +++++
 clippy_lints/src/manual_async_fn.rs           |  21 +-
 clippy_lints/src/manual_float_methods.rs      |   6 +-
 clippy_lints/src/manual_is_power_of_two.rs    |  16 +-
 clippy_lints/src/matches/match_same_arms.rs   |  20 +-
 clippy_lints/src/matches/mod.rs               |  27 +-
 clippy_lints/src/matches/needless_match.rs    |   6 +-
 clippy_lints/src/matches/single_match.rs      |   2 +-
 .../src/methods/filter_map_identity.rs        |  10 +
 .../map_with_unused_argument_over_ranges.rs   |   2 +-
 clippy_lints/src/methods/mod.rs               |  11 +-
 .../src/methods/needless_option_take.rs       |  55 +-
 clippy_lints/src/methods/str_splitn.rs        |  22 +-
 .../src/methods/unnecessary_iter_cloned.rs    |  16 +-
 .../src/methods/unnecessary_sort_by.rs        |   8 +-
 .../src/missing_const_for_thread_local.rs     |   2 -
 clippy_lints/src/no_effect.rs                 |   2 +-
 .../src/operators/numeric_arithmetic.rs       |   4 +-
 clippy_lints/src/precedence.rs                |  33 +-
 clippy_lints/src/question_mark.rs             |   2 +-
 clippy_lints/src/redundant_slicing.rs         |   3 +-
 clippy_lints/src/shadow.rs                    |  58 +-
 .../src/significant_drop_tightening.rs        |  12 +-
 clippy_lints/src/single_range_in_vec_init.rs  |   3 +-
 clippy_lints/src/strings.rs                   |   4 -
 clippy_lints/src/unit_types/let_unit_value.rs |  35 +-
 clippy_lints/src/unit_types/unit_arg.rs       |   4 +-
 clippy_lints/src/unnecessary_literal_bound.rs |   2 +-
 .../src/unnecessary_struct_initialization.rs  |   6 +-
 clippy_lints/src/useless_conversion.rs        |  55 +-
 clippy_lints/src/utils/author.rs              |   6 +-
 .../almost_standard_lint_formulation.rs       |   5 +-
 .../interning_defined_symbol.rs               |   2 +-
 .../internal_lints/lint_without_lint_pass.rs  |  10 +-
 .../internal_lints/slow_symbol_comparisons.rs |  17 +-
 clippy_lints/src/zombie_processes.rs          | 275 +++++---
 clippy_utils/README.md                        |   2 +-
 .../src/{ast_utils.rs => ast_utils/mod.rs}    |   0
 clippy_utils/src/attrs.rs                     |   6 +-
 clippy_utils/src/higher.rs                    |   2 +-
 clippy_utils/src/hir_utils.rs                 |  22 +-
 clippy_utils/src/lib.rs                       |  67 +-
 clippy_utils/src/msrvs.rs                     |   9 +-
 clippy_utils/src/paths.rs                     |   1 -
 clippy_utils/src/{ty.rs => ty/mod.rs}         |   2 +-
 clippy_utils/src/visitors.rs                  |   2 +-
 lintcheck/src/main.rs                         |   3 +-
 rust-toolchain                                |   2 +-
 src/driver.rs                                 |   4 +-
 .../interning_defined_symbol.fixed            |   2 +-
 .../interning_defined_symbol.stderr           |   2 +-
 .../ui-internal/unnecessary_symbol_str.fixed  |   4 +-
 .../ui-internal/unnecessary_symbol_str.stderr |   4 +-
 tests/ui-toml/indexing_slicing/clippy.toml    |   1 +
 .../indexing_slicing/indexing_slicing.rs      |  19 +
 .../indexing_slicing/indexing_slicing.stderr  |  12 +
 .../large_include_file/large_include_file.rs  |   1 +
 .../large_include_file.stderr                 |   6 +-
 .../index_refutable_slice.fixed               |  24 +
 .../index_refutable_slice.rs                  |   2 -
 .../index_refutable_slice.stderr              |  14 +-
 .../toml_unknown_key/conf_unknown_key.stderr  |   3 +
 tests/ui/as_pointer_underscore.fixed          |  15 +
 tests/ui/as_pointer_underscore.rs             |  15 +
 tests/ui/as_pointer_underscore.stderr         |  17 +
 tests/ui/auxiliary/proc_macro_derive.rs       |   1 +
 tests/ui/borrow_and_ref_as_ptr.fixed          |  11 +
 tests/ui/borrow_and_ref_as_ptr.rs             |  11 +
 tests/ui/borrow_and_ref_as_ptr.stderr         |  17 +
 tests/ui/borrow_as_ptr_raw_ref.fixed          |  19 +
 tests/ui/borrow_as_ptr_raw_ref.rs             |  19 +
 tests/ui/borrow_as_ptr_raw_ref.stderr         |  17 +
 tests/ui/comparison_chain.rs                  |  13 +
 tests/ui/comparison_chain.stderr              |  53 +-
 tests/ui/default_union_representation.rs      |   1 +
 tests/ui/default_union_representation.stderr  |   8 +-
 tests/ui/derive.rs                            |   1 +
 tests/ui/derive.stderr                        |  20 +-
 tests/ui/doc/doc_lazy_list.fixed              |   6 +
 tests/ui/doc/doc_lazy_list.rs                 |   6 +
 .../ui/doc/doc_nested_refdef_blockquote.fixed | 133 ++++
 tests/ui/doc/doc_nested_refdef_blockquote.rs  | 133 ++++
 .../doc/doc_nested_refdef_blockquote.stderr   | 148 +++++
 .../ui/doc/doc_nested_refdef_list_item.fixed  |  71 +++
 tests/ui/doc/doc_nested_refdef_list_item.rs   |  71 +++
 .../ui/doc/doc_nested_refdef_list_item.stderr | 148 +++++
 tests/ui/filter_map_identity.fixed            |   5 +
 tests/ui/filter_map_identity.rs               |   5 +
 tests/ui/format.fixed                         |   3 +-
 tests/ui/format.rs                            |   3 +-
 tests/ui/format.stderr                        |  30 +-
 tests/ui/if_not_else.fixed                    |  73 +++
 tests/ui/if_not_else.rs                       |  42 ++
 tests/ui/if_not_else.stderr                   | 116 +++-
 .../if_let_slice_binding.fixed                | 177 ++++++
 .../if_let_slice_binding.rs                   |   2 -
 .../if_let_slice_binding.stderr               | 122 ++--
 .../slice_indexing_in_macro.fixed             |  29 +
 .../slice_indexing_in_macro.rs                |   2 -
 .../slice_indexing_in_macro.stderr            |  13 +-
 tests/ui/let_unit.fixed                       | 196 ++++++
 tests/ui/let_unit.rs                          |   2 -
 tests/ui/let_unit.stderr                      |  22 +-
 .../ui/literal_string_with_formatting_arg.rs  |  37 ++
 .../literal_string_with_formatting_arg.stderr |  71 +++
 tests/ui/manual_async_fn.fixed                | 116 ++++
 tests/ui/manual_async_fn.rs                   |   3 +-
 tests/ui/manual_async_fn.stderr               | 134 ++--
 tests/ui/manual_split_once.fixed              | 144 +++++
 tests/ui/manual_split_once.rs                 |   2 -
 tests/ui/manual_split_once.stderr             | 108 ++--
 tests/ui/match_same_arms.stderr               |  63 +-
 tests/ui/match_same_arms2.fixed               | 259 ++++++++
 tests/ui/match_same_arms2.rs                  |   2 -
 tests/ui/match_same_arms2.stderr              | 141 ++---
 tests/ui/must_use_unit.fixed                  |   6 +
 tests/ui/must_use_unit.rs                     |   6 +
 tests/ui/must_use_unit.stderr                 |  18 +-
 tests/ui/needless_lifetimes.fixed             |  14 +
 tests/ui/needless_lifetimes.rs                |  14 +
 tests/ui/needless_match.fixed                 |  53 ++
 tests/ui/needless_match.rs                    |  61 ++
 tests/ui/needless_match.stderr                |  14 +-
 tests/ui/needless_option_take.fixed           |  13 -
 tests/ui/needless_option_take.rs              |  47 +-
 tests/ui/needless_option_take.stderr          |  71 ++-
 tests/ui/precedence.fixed                     |   4 +
 tests/ui/precedence.rs                        |   4 +
 tests/ui/precedence.stderr                    |  26 +-
 tests/ui/print_literal.fixed                  |   2 +-
 tests/ui/print_literal.rs                     |   2 +-
 tests/ui/rename.fixed                         |   1 +
 tests/ui/rename.rs                            |   1 +
 tests/ui/rename.stderr                        | 134 ++--
 tests/ui/repr_packed_without_abi.rs           |  37 ++
 tests/ui/repr_packed_without_abi.stderr       |  35 ++
 tests/ui/result_unit_error_no_std.rs          |  26 +
 tests/ui/result_unit_error_no_std.stderr      |  12 +
 tests/ui/shadow.rs                            |  22 +
 tests/ui/shadow.stderr                        |  38 +-
 tests/ui/significant_drop_tightening.fixed    | 144 +++++
 tests/ui/significant_drop_tightening.rs       |   2 -
 tests/ui/significant_drop_tightening.stderr   |  18 +-
 tests/ui/single_match.fixed                   |  34 +-
 tests/ui/single_match.rs                      |  27 +
 tests/ui/single_match.stderr                  |  32 +-
 tests/ui/trailing_empty_array.rs              |   1 +
 tests/ui/trailing_empty_array.stderr          |  22 +-
 ...nlined_format_args_panic.edition2018.fixed |   1 +
 ...lined_format_args_panic.edition2018.stderr |   2 +-
 ...nlined_format_args_panic.edition2021.fixed |   1 +
 ...lined_format_args_panic.edition2021.stderr |  12 +-
 tests/ui/uninlined_format_args_panic.rs       |   1 +
 tests/ui/unnecessary_iter_cloned.fixed        | 201 ++++++
 tests/ui/unnecessary_iter_cloned.rs           |   2 -
 tests/ui/unnecessary_iter_cloned.stderr       |  43 +-
 tests/ui/unnecessary_sort_by_no_std.fixed     |  20 +
 tests/ui/unnecessary_sort_by_no_std.rs        |  20 +
 tests/ui/unnecessary_sort_by_no_std.stderr    |  17 +
 tests/ui/unnecessary_to_owned.fixed           | 587 ++++++++++++++++++
 tests/ui/unnecessary_to_owned.rs              |   2 -
 tests/ui/unnecessary_to_owned.stderr          | 194 +++---
 tests/ui/useless_attribute.fixed              |   9 +
 tests/ui/useless_attribute.rs                 |   9 +
 tests/ui/useless_conversion.fixed             |  45 ++
 tests/ui/useless_conversion.rs                |  45 ++
 tests/ui/useless_conversion.stderr            | 124 ++--
 tests/ui/zombie_processes.rs                  |  41 +-
 tests/ui/zombie_processes.stderr              |  85 ++-
 util/gh-pages/script.js                       |  14 +-
 208 files changed, 6002 insertions(+), 1415 deletions(-)
 create mode 100644 clippy_lints/src/attrs/repr_attributes.rs
 create mode 100644 clippy_lints/src/casts/as_pointer_underscore.rs
 create mode 100644 clippy_lints/src/literal_string_with_formatting_args.rs
 rename clippy_utils/src/{ast_utils.rs => ast_utils/mod.rs} (100%)
 rename clippy_utils/src/{ty.rs => ty/mod.rs} (99%)
 create mode 100644 tests/ui-toml/indexing_slicing/clippy.toml
 create mode 100644 tests/ui-toml/indexing_slicing/indexing_slicing.rs
 create mode 100644 tests/ui-toml/indexing_slicing/indexing_slicing.stderr
 create mode 100644 tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed
 create mode 100644 tests/ui/as_pointer_underscore.fixed
 create mode 100644 tests/ui/as_pointer_underscore.rs
 create mode 100644 tests/ui/as_pointer_underscore.stderr
 create mode 100644 tests/ui/borrow_and_ref_as_ptr.fixed
 create mode 100644 tests/ui/borrow_and_ref_as_ptr.rs
 create mode 100644 tests/ui/borrow_and_ref_as_ptr.stderr
 create mode 100644 tests/ui/borrow_as_ptr_raw_ref.fixed
 create mode 100644 tests/ui/borrow_as_ptr_raw_ref.rs
 create mode 100644 tests/ui/borrow_as_ptr_raw_ref.stderr
 create mode 100644 tests/ui/doc/doc_nested_refdef_blockquote.fixed
 create mode 100644 tests/ui/doc/doc_nested_refdef_blockquote.rs
 create mode 100644 tests/ui/doc/doc_nested_refdef_blockquote.stderr
 create mode 100644 tests/ui/doc/doc_nested_refdef_list_item.fixed
 create mode 100644 tests/ui/doc/doc_nested_refdef_list_item.rs
 create mode 100644 tests/ui/doc/doc_nested_refdef_list_item.stderr
 create mode 100644 tests/ui/if_not_else.fixed
 create mode 100644 tests/ui/index_refutable_slice/if_let_slice_binding.fixed
 create mode 100644 tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
 create mode 100644 tests/ui/let_unit.fixed
 create mode 100644 tests/ui/literal_string_with_formatting_arg.rs
 create mode 100644 tests/ui/literal_string_with_formatting_arg.stderr
 create mode 100644 tests/ui/manual_async_fn.fixed
 create mode 100644 tests/ui/manual_split_once.fixed
 create mode 100644 tests/ui/match_same_arms2.fixed
 delete mode 100644 tests/ui/needless_option_take.fixed
 create mode 100644 tests/ui/repr_packed_without_abi.rs
 create mode 100644 tests/ui/repr_packed_without_abi.stderr
 create mode 100644 tests/ui/result_unit_error_no_std.rs
 create mode 100644 tests/ui/result_unit_error_no_std.stderr
 create mode 100644 tests/ui/significant_drop_tightening.fixed
 create mode 100644 tests/ui/unnecessary_iter_cloned.fixed
 create mode 100644 tests/ui/unnecessary_sort_by_no_std.fixed
 create mode 100644 tests/ui/unnecessary_sort_by_no_std.rs
 create mode 100644 tests/ui/unnecessary_sort_by_no_std.stderr
 create mode 100644 tests/ui/unnecessary_to_owned.fixed

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 61efaa3bf3e6..b6033de93501 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5380,6 +5380,7 @@ Released 2018-09-13
 [`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/master/index.html#arc_with_non_send_sync
 [`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects
 [`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
+[`as_pointer_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_pointer_underscore
 [`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut
 [`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore
 [`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
@@ -5490,6 +5491,7 @@ Released 2018-09-13
 [`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation
 [`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
 [`double_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_comparisons
 [`double_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_must_use
 [`double_neg`]: https://rust-lang.github.io/rust-clippy/master/index.html#double_neg
@@ -5685,6 +5687,7 @@ Released 2018-09-13
 [`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok
 [`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist
 [`lint_groups_priority`]: https://rust-lang.github.io/rust-clippy/master/index.html#lint_groups_priority
+[`literal_string_with_formatting_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#literal_string_with_formatting_args
 [`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes
 [`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug
 [`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal
@@ -5966,6 +5969,7 @@ Released 2018-09-13
 [`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once
 [`repeat_vec_with_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity
 [`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts
+[`repr_packed_without_abi`]: https://rust-lang.github.io/rust-clippy/master/index.html#repr_packed_without_abi
 [`reserve_after_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#reserve_after_initialization
 [`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs
 [`result_expect_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_expect_used
@@ -6210,6 +6214,7 @@ Released 2018-09-13
 [`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
 [`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests
 [`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests
+[`allow-indexing-slicing-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-indexing-slicing-in-tests
 [`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args
 [`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
 [`allow-panic-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-panic-in-tests
diff --git a/book/src/development/common_tools_writing_lints.md b/book/src/development/common_tools_writing_lints.md
index 77910917963e..c354e8914f5d 100644
--- a/book/src/development/common_tools_writing_lints.md
+++ b/book/src/development/common_tools_writing_lints.md
@@ -37,7 +37,7 @@ impl LateLintPass<'_> for MyStructLint {
         // Get type of `expr`
         let ty = cx.typeck_results().expr_ty(expr);
         // Match its kind to enter its type
-        match ty.kind {
+        match ty.kind() {
             ty::Adt(adt_def, _) if adt_def.is_struct() => println!("Our `expr` is a struct!"),
             _ => ()
         }
diff --git a/book/src/development/infrastructure/backport.md b/book/src/development/infrastructure/backport.md
index 6920c4e46561..9526d8af1c9d 100644
--- a/book/src/development/infrastructure/backport.md
+++ b/book/src/development/infrastructure/backport.md
@@ -5,68 +5,108 @@ Backports in Clippy are rare and should be approved by the Clippy team. For
 example, a backport is done, if a crucial ICE was fixed or a lint is broken to a
 point, that it has to be disabled, before landing on stable.
 
-Backports are done to the `beta` branch of Clippy. Backports to stable Clippy
-releases basically don't exist, since this would require a Rust point release,
-which is almost never justifiable for a Clippy fix.
+> Note: If you think a PR should be backported you can label it with
+> `beta-nominated`. This has to be done before the Thursday the week before the
+> release.
 
+## Filtering PRs to backport
 
-## Backport the changes
+First, find all labeled PRs using [this filter][beta-accepted-prs].
+
+Next, look at each PR individually. There are a few things to check. Those need
+some explanation and are quite subjective. Good judgement is required.
+
+1. **Is the fix worth a backport?**
+
+   This is really subjective. An ICE fix usually is. Moving a lint to a _lower_
+   group (from warn- to allow-by-default) usually as well. An FP fix usually not
+   (on its own). If a backport is done anyway, FP fixes might also be included.
+   If the PR has a lot of changes, backports must be considered more carefully.
+
+2. **Is the problem that was fixed by the PR already in `beta`?**
+
+   It could be that the problem that was fixed by the PR hasn't made it to the
+   `beta` branch of the Rust repo yet. If that's the case, and the fix is
+   already synced to the Rust repo, the fix doesn't need to be backported, as it
+   will hit stable together with the commit that introduced the problem. If the
+   fix PR is not synced yet, the fix PR either needs to be "backported" to the
+   Rust `master` branch or to `beta` in the next backport cycle.
+
+3. **Make sure that the fix is on `master` before porting to `beta`**
+
+   The fix must already be synced to the Rust `master` branch. Otherwise, the
+   next `beta` will be missing this fix again. If it is not yet in `master` it
+   should probably not be backported. If the backport is really important, do an
+   out-of-cycle sync first. However, the out-of-cycle sync should be small,
+   because the changes in that sync will get right into `beta`, without being
+   tested in `nightly` first.
+
+[beta-accepted-prs]: https://github.com/rust-lang/rust-clippy/issues?q=label%3Abeta-nominated
+
+## Preparation
+
+> Note: All commands in this chapter will be run in the Rust clone.
+
+Follow the instructions in [defining remotes] to define the `clippy-upstream`
+remote in the Rust repository.
 
-Backports are done on the beta branch of the Clippy repository.
+After that, fetch the remote with
 
 ```bash
-# Assuming the current directory corresponds to the Clippy repository
-$ git checkout beta
-$ git checkout -b backport
-$ git cherry-pick <SHA>  # `<SHA>` is the commit hash of the commit(s), that should be backported
-$ git push origin backport
+git fetch clippy-upstream master
 ```
 
-Now you should test that the backport passes all the tests in the Rust
-repository. You can do this with:
+Then, switch to the `beta` branch:
 
 ```bash
-# Assuming the current directory corresponds to the Rust repository
-$ git checkout beta
-# Make sure to change `your-github-name` to your github name in the following command
-$ git subtree pull -p src/tools/clippy https://github.com/<your-github-name>/rust-clippy backport
-$ ./x.py test src/tools/clippy
+git switch beta
+git fetch upstream
+git reset --hard upstream/beta
 ```
 
-Should the test fail, you can fix Clippy directly in the Rust repository. This
-has to be first applied to the Clippy beta branch and then again synced to the
-Rust repository, though. The easiest way to do this is:
+[defining remotes]: release.md#defining-remotes
+
+## Backport the changes
+
+When a PR is merged with the GitHub merge queue, the PR is closed with the message
+
+> \<PR title\> (#\<PR number\>)
+
+This commit needs to be backported. To do that, find the `<sha1>` of that commit
+and run the following command in the clone of the **Rust repository**:
 
 ```bash
-# In the Rust repository
-$ git diff --patch --relative=src/tools/clippy > clippy.patch
-# In the Clippy repository
-$ git apply /path/to/clippy.patch
-$ git add -u
-$ git commit -m "Fix rustup fallout"
-$ git push origin backport
+git cherry-pick -m 1 `<sha1>`
 ```
 
-After this, you can open a PR to the `beta` branch of the Clippy repository.
+Do this for all PRs that should be backported.
 
+## Open PR in the Rust repository
 
-## Update Clippy in the Rust Repository
+Next, open the PR for the backport. Make sure, the PR is opened towards the
+`beta` branch and not the `master` branch. The PR description should look like
+this:
 
-This step must be done, **after** the PR of the previous step was merged.
+```
+[beta] Clippy backports
 
-After the backport landed in the Clippy repository, the branch has to be synced
-back to the beta branch of the Rust repository.
+r? @Mark-Simulacrum
 
-```bash
-# Assuming the current directory corresponds to the Rust repository
-$ git checkout beta
-$ git checkout -b clippy_backport
-$ git subtree pull -p src/tools/clippy https://github.com/rust-lang/rust-clippy beta
-$ git push origin clippy_backport
+Backports:
+- <Link to the Clippy PR>
+- ...
+
+<Short summary of what is backported and why>
 ```
 
-Make sure to test the backport in the Rust repository before opening a PR. This
-is done with `./x.py test src/tools/clippy`. If that passes all tests, open a PR
-to the `beta` branch of the Rust repository. In this PR you should tag the
-Clippy team member, that agreed to the backport or the `@rust-lang/clippy` team.
-Make sure to add `[beta]` to the title of the PR.
+Mark is from the release team and they ultimately have to merge the PR before
+branching a new `beta` version. Tag them to take care of the backport. Next,
+list all the backports and give a short summary what's backported and why it is
+worth backporting this.
+
+## Relabel backported PRs
+
+When a PR is backported to Rust `beta`, label the PR with `beta-accepted`. This
+will then get picked up when [writing the changelog].
+
+[writing the changelog]: changelog_update.md#31-include-beta-accepted-prs
diff --git a/book/src/development/infrastructure/release.md b/book/src/development/infrastructure/release.md
index 98fabf8e89ae..20b870eb69a8 100644
--- a/book/src/development/infrastructure/release.md
+++ b/book/src/development/infrastructure/release.md
@@ -7,112 +7,114 @@ Clippy is released together with stable Rust releases. The dates for these
 releases can be found at the [Rust Forge]. This document explains the necessary
 steps to create a Clippy release.
 
-1. [Remerge the `beta` branch](#remerge-the-beta-branch)
-2. [Update the `beta` branch](#update-the-beta-branch)
-3. [Find the Clippy commit](#find-the-clippy-commit)
-4. [Tag the stable commit](#tag-the-stable-commit)
-5. [Update `CHANGELOG.md`](#update-changelogmd)
-
-> _NOTE:_ This document is for stable Rust releases, not for point releases. For
-> point releases, step 1. and 2. should be enough.
+1. [Defining Remotes](#defining-remotes)
+1. [Bump Version](#bump-version)
+1. [Find the Clippy commit](#find-the-clippy-commit)
+1. [Update the `beta` branch](#update-the-beta-branch)
+1. [Update the `stable` branch](#update-the-stable-branch)
+1. [Tag the stable commit](#tag-the-stable-commit)
+1. [Update `CHANGELOG.md`](#update-changelogmd)
 
 [Rust Forge]: https://forge.rust-lang.org/
 
-## Remerge the `beta` branch
+## Defining Remotes
+
+You may want to define the `upstream` remote of the Clippy project to simplify
+the following steps. However, this is optional and you can replace `upstream`
+with the full URL instead.
+
+```bash
+git remote add upstream git@github.com:rust-lang/rust-clippy
+```
 
-This step is only necessary, if since the last release something was backported
-to the beta Rust release. The remerge is then necessary, to make sure that the
-Clippy commit, that was used by the now stable Rust release, persists in the
-tree of the Clippy repository.
+## Bump Version
 
-To find out if this step is necessary run
+When a release needs to be done, `cargo test` will fail, if the versions in the
+`Cargo.toml` are not correct. During that sync, the versions need to be bumped.
+This is done by running:
 
 ```bash
-# Assumes that the local master branch of rust-lang/rust-clippy is up-to-date
-$ git fetch upstream
-$ git branch master --contains upstream/beta
+cargo dev release bump_version
 ```
 
-If this command outputs `master`, this step is **not** necessary.
+This will increase the version number of each relevant `Cargo.toml` file. After
+that, just commit the updated files with:
 
 ```bash
-# Assuming `HEAD` is the current `master` branch of rust-lang/rust-clippy
-$ git checkout -b backport_remerge
-$ git merge upstream/beta
-$ git diff  # This diff has to be empty, otherwise something with the remerge failed
-$ git push origin backport_remerge  # This can be pushed to your fork
+git commit -m "Bump Clippy version -> 0.1.XY" **/*Cargo.toml
 ```
 
-After this, open a PR to the master branch. In this PR, the commit hash of the
-`HEAD` of the `beta` branch must exist. In addition to that, no files should be
-changed by this PR.
+`XY` should be exchanged with the corresponding version
 
-## Update the `beta` branch
+## Find the Clippy commit
 
-This step must be done **after** the PR of the previous step was merged.
+For both updating the `beta` and the `stable` branch, the first step is to find
+the Clippy commit of the last Clippy sync done in the respective Rust branch.
 
-First, the Clippy commit of the `beta` branch of the Rust repository has to be
-determined.
+Running the following commands _in the Rust repo_ will get the commit for the
+specified `<branch>`:
 
 ```bash
-# Assuming the current directory corresponds to the Rust repository
-$ git fetch upstream
-$ git checkout upstream/beta
-$ BETA_SHA=$(git log --oneline -- src/tools/clippy/ | grep -o "Merge commit '[a-f0-9]*' into .*" | head -1 | sed -e "s/Merge commit '\([a-f0-9]*\)' into .*/\1/g")
+git switch <branch>
+SHA=$(git log --oneline -- src/tools/clippy/ | grep -o "Merge commit '[a-f0-9]*' into .*" | head -1 | sed -e "s/Merge commit '\([a-f0-9]*\)' into .*/\1/g")
 ```
 
-After finding the Clippy commit, the `beta` branch in the Clippy repository can
-be updated.
+Where `<branch>` is one of `stable`, `beta`, or `master`.
+
+## Update the `beta` branch
+
+After getting the commit of the `beta` branch, the `beta` branch in the Clippy
+repository can be updated.
 
 ```bash
-# Assuming the current directory corresponds to the Clippy repository
-$ git checkout beta
-$ git reset --hard $BETA_SHA
-$ git push upstream beta
+git checkout beta
+git reset --hard $SHA
+git push upstream beta
 ```
 
-## Find the Clippy commit
+## Update the `stable` branch
 
-The first step is to tag the Clippy commit, that is included in the stable Rust
-release. This commit can be found in the Rust repository.
+After getting the commit of the `stable` branch, the `stable` branch in the
+Clippy repository can be updated.
 
 ```bash
-# Assuming the current directory corresponds to the Rust repository
-$ git fetch upstream    # `upstream` is the `rust-lang/rust` remote
-$ git checkout 1.XX.0   # XX should be exchanged with the corresponding version
-$ SHA=$(git log --oneline -- src/tools/clippy/ | grep -o "Merge commit '[a-f0-9]*' into .*" | head -1 | sed -e "s/Merge commit '\([a-f0-9]*\)' into .*/\1/g")
+git checkout stable
+git reset --hard $SHA
+git push upstream stable
 ```
 
-## Tag the stable commit
+## Tag the `stable` commit
 
-After finding the Clippy commit, it can be tagged with the release number.
+After updating the `stable` branch, tag the HEAD commit and push it to the
+Clippy repo.
+
+> Note: Only push the tag once the Deploy GitHub action of the `beta` branch is
+> finished. Otherwise the deploy for the tag might fail.
 
 ```bash
-# Assuming the current directory corresponds to the Clippy repository
-$ git checkout $SHA
-$ git tag rust-1.XX.0               # XX should be exchanged with the corresponding version
-$ git push upstream rust-1.XX.0     # `upstream` is the `rust-lang/rust-clippy` remote
+git tag rust-1.XX.0               # XX should be exchanged with the corresponding version
+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].
 
 [release page]: https://github.com/rust-lang/rust-clippy/releases
 
-## Update the `stable` branch
+## Publish `clippy_utils`
+
+The `clippy_utils` crate is published to `crates.io` without any stability
+guarantees. To do this, after the [sync] and the release is done, switch back to
+the `upstream/master` branch and publish `clippy_utils`:
 
-At this step you should have already checked out the commit of the `rust-1.XX.0`
-tag. Updating the stable branch from here is as easy as:
+> Note: The Rustup PR bumping the nightly and Clippy version **must** be merged
+> before doing this.
 
 ```bash
-# Assuming the current directory corresponds to the Clippy repository and the
-# commit of the just created rust-1.XX.0 tag is checked out.
-$ git push upstream rust-1.XX.0:stable  # `upstream` is the `rust-lang/rust-clippy` remote
+git switch master && git pull upstream master
+cargo publish --manifest-path clippy_utils/Cargo.toml
 ```
 
-> _NOTE:_ Usually there are no stable backports for Clippy, so this update
-> should be possible without force pushing or anything like this. If there
-> should have happened a stable backport, make sure to re-merge those changes
-> just as with the `beta` branch.
+[sync]: sync.md
 
 ## Update `CHANGELOG.md`
 
diff --git a/book/src/development/infrastructure/sync.md b/book/src/development/infrastructure/sync.md
index e1fe92f95250..da1ad586607f 100644
--- a/book/src/development/infrastructure/sync.md
+++ b/book/src/development/infrastructure/sync.md
@@ -21,6 +21,8 @@ to beta. For reference, the first sync following this cadence was performed the
 This process is described in detail in the following sections. For general
 information about `subtree`s in the Rust repository see [the rustc-dev-guide][subtree].
 
+[subtree]: https://rustc-dev-guide.rust-lang.org/external-repos.html#external-dependencies-subtree
+
 ## Patching git-subtree to work with big repos
 
 Currently, there's a bug in `git-subtree` that prevents it from working properly
@@ -50,23 +52,11 @@ sudo chown --reference=/usr/lib/git-core/git-subtree~ /usr/lib/git-core/git-subt
 > `bash` instead. You can do this by editing the first line of the `git-subtree`
 > script and changing `sh` to `bash`.
 
-## Defining remotes
-
-You may want to define remotes, so you don't have to type out the remote
-addresses on every sync. You can do this with the following commands (these
-commands still have to be run inside the `rust` directory):
-
-```bash
-# Set clippy-upstream remote for pulls
-$ git remote add clippy-upstream https://github.com/rust-lang/rust-clippy
-# Make sure to not push to the upstream repo
-$ git remote set-url --push clippy-upstream DISABLED
-# Set a local remote
-$ git remote add clippy-local /path/to/rust-clippy
-```
+> Note: The following sections assume that you have set up remotes following the
+> instructions in [defining remotes].
 
-> Note: The following sections assume that you have set those remotes with the
-> above remote names.
+[gitgitgadget-pr]: https://github.com/gitgitgadget/git/pull/493
+[defining remotes]: release.md#defining-remotes
 
 ## Performing the sync from [`rust-lang/rust`] to Clippy
 
@@ -78,9 +68,9 @@ to be run inside the `rust` directory):
    `rustup check`.
 3. Sync the changes to the rust-copy of Clippy to your Clippy fork:
     ```bash
-    # Be sure to either use a net-new branch, e.g. `sync-from-rust`, or delete the branch beforehand
+    # Be sure to either use a net-new branch, e.g. `rustup`, or delete the branch beforehand
     # because changes cannot be fast forwarded and you have to run this command again.
-    git subtree push -P src/tools/clippy clippy-local sync-from-rust
+    git subtree push -P src/tools/clippy clippy-local rustup
     ```
 
     > _Note:_ Most of the time you have to create a merge commit in the
@@ -88,21 +78,22 @@ to be run inside the `rust` directory):
     > rust-copy of Clippy):
     ```bash
     git fetch upstream  # assuming upstream is the rust-lang/rust remote
-    git checkout sync-from-rust
+    git switch rustup
     git merge upstream/master --no-ff
     ```
     > Note: This is one of the few instances where a merge commit is allowed in
     > a PR.
-4. Bump the nightly version in the Clippy repository by changing the date in the
-   rust-toolchain file to the current date and committing it with the message:
+4. Bump the nightly version in the Clippy repository by running these commands:
    ```bash
-   git commit -m "Bump nightly version -> YYYY-MM-DD"
+   cargo dev sync update_nightly
+   git commit -m "Bump nightly version -> YYYY-MM-DD" rust-toolchain clippy_utils/README.md
    ```
 5. Open a PR to `rust-lang/rust-clippy` and wait for it to get merged (to
    accelerate the process ping the `@rust-lang/clippy` team in your PR and/or
    ask them in the [Zulip] stream.)
 
 [Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/clippy
+[`rust-lang/rust`]: https://github.com/rust-lang/rust
 
 ## Performing the sync from Clippy to [`rust-lang/rust`]
 
@@ -111,11 +102,7 @@ All the following commands have to be run inside the `rust` directory.
 1. Make sure you have checked out the latest `master` of `rust-lang/rust`.
 2. Sync the `rust-lang/rust-clippy` master to the rust-copy of Clippy:
     ```bash
-    git checkout -b sync-from-clippy
+    git switch -c clippy-subtree-update
     git subtree pull -P src/tools/clippy clippy-upstream master
     ```
 3. Open a PR to [`rust-lang/rust`]
-
-[gitgitgadget-pr]: https://github.com/gitgitgadget/git/pull/493
-[subtree]: https://rustc-dev-guide.rust-lang.org/external-repos.html#external-dependencies-subtree
-[`rust-lang/rust`]: https://github.com/rust-lang/rust
diff --git a/book/src/development/the_team.md b/book/src/development/the_team.md
index 10341791cec4..6bc0783b166a 100644
--- a/book/src/development/the_team.md
+++ b/book/src/development/the_team.md
@@ -72,7 +72,7 @@ you to the alumni group. You're always welcome to come back.
 
 ## The Clippy Team
 
-[The Clippy team](https://www.rust-lang.org/governance/teams/dev-tools#Clippy%20team)
+[The Clippy team](https://www.rust-lang.org/governance/teams/dev-tools#team-clippy)
 is responsible for maintaining Clippy.
 
 ### Duties
diff --git a/book/src/development/type_checking.md b/book/src/development/type_checking.md
index e6da4322a179..578836ecc568 100644
--- a/book/src/development/type_checking.md
+++ b/book/src/development/type_checking.md
@@ -94,7 +94,7 @@ impl LateLintPass<'_> for MyStructLint {
         // Get type of `expr`
         let ty = cx.typeck_results().expr_ty(expr);
         // Match its kind to enter the type
-        match ty.kind {
+        match ty.kind() {
             ty::Adt(adt_def, _) if adt_def.is_struct() => println!("Our `expr` is a struct!"),
             _ => ()
         }
diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md
index 275d125096e9..ea1d7d11389d 100644
--- a/book/src/lint_configuration.md
+++ b/book/src/lint_configuration.md
@@ -81,6 +81,16 @@ Whether `expect` should be allowed in test functions or `#[cfg(test)]`
 * [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)
 
 
+## `allow-indexing-slicing-in-tests`
+Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]`
+
+**Default Value:** `false`
+
+---
+**Affected lints:**
+* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)
+
+
 ## `allow-mixed-uninlined-format-args`
 Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
 
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs
index 41b56b45d9ae..bffa04f6f090 100644
--- a/clippy_config/src/conf.rs
+++ b/clippy_config/src/conf.rs
@@ -291,6 +291,9 @@ define_Conf! {
     /// Whether `expect` should be allowed in test functions or `#[cfg(test)]`
     #[lints(expect_used)]
     allow_expect_in_tests: bool = false,
+    /// Whether `indexing_slicing` should be allowed in test functions or `#[cfg(test)]`
+    #[lints(indexing_slicing)]
+    allow_indexing_slicing_in_tests: bool = false,
     /// Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
     #[lints(uninlined_format_args)]
     allow_mixed_uninlined_format_args: bool = true,
diff --git a/clippy_lints/src/arbitrary_source_item_ordering.rs b/clippy_lints/src/arbitrary_source_item_ordering.rs
index 8719f61a8903..cf33e1444e47 100644
--- a/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -126,7 +126,7 @@ declare_clippy_lint! {
     ///
     /// [cargo-pgo]: https://github.com/Kobzol/cargo-pgo/blob/main/README.md
     ///
-    #[clippy::version = "1.82.0"]
+    #[clippy::version = "1.84.0"]
     pub ARBITRARY_SOURCE_ITEM_ORDERING,
     restriction,
     "arbitrary source item ordering"
diff --git a/clippy_lints/src/attrs/mod.rs b/clippy_lints/src/attrs/mod.rs
index a9766597d50d..92efd1a4ddcd 100644
--- a/clippy_lints/src/attrs/mod.rs
+++ b/clippy_lints/src/attrs/mod.rs
@@ -7,6 +7,7 @@ mod duplicated_attributes;
 mod inline_always;
 mod mixed_attributes_style;
 mod non_minimal_cfg;
+mod repr_attributes;
 mod should_panic_without_expect;
 mod unnecessary_clippy_cfg;
 mod useless_attribute;
@@ -272,6 +273,44 @@ declare_clippy_lint! {
     "ensures that all `should_panic` attributes specify its expected panic message"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for items with `#[repr(packed)]`-attribute without ABI qualification
+    ///
+    /// ### Why is this bad?
+    /// Without qualification, `repr(packed)` implies `repr(Rust)`. The Rust-ABI is inherently unstable.
+    /// While this is fine as long as the type is accessed correctly within Rust-code, most uses
+    /// of `#[repr(packed)]` involve FFI and/or data structures specified by network-protocols or
+    /// other external specifications. In such situations, the unstable Rust-ABI implied in
+    /// `#[repr(packed)]` may lead to future bugs should the Rust-ABI change.
+    ///
+    /// In case you are relying on a well defined and stable memory layout, qualify the type's
+    /// representation using the `C`-ABI. Otherwise, if the type in question is only ever
+    /// accessed from Rust-code according to Rust's rules, use the `Rust`-ABI explicitly.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[repr(packed)]
+    /// struct NetworkPacketHeader {
+    ///     header_length: u8,
+    ///     header_version: u16
+    /// }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[repr(C, packed)]
+    /// struct NetworkPacketHeader {
+    ///     header_length: u8,
+    ///     header_version: u16
+    /// }
+    /// ```
+    #[clippy::version = "1.84.0"]
+    pub REPR_PACKED_WITHOUT_ABI,
+    suspicious,
+    "ensures that `repr(packed)` always comes with a qualified ABI"
+}
+
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for `any` and `all` combinators in `cfg` with only one condition.
@@ -415,6 +454,7 @@ pub struct Attributes {
 
 impl_lint_pass!(Attributes => [
     INLINE_ALWAYS,
+    REPR_PACKED_WITHOUT_ABI,
 ]);
 
 impl Attributes {
@@ -431,6 +471,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
         if is_relevant_item(cx, item) {
             inline_always::check(cx, item.span, item.ident.name, attrs);
         }
+        repr_attributes::check(cx, item.span, attrs, &self.msrv);
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
diff --git a/clippy_lints/src/attrs/repr_attributes.rs b/clippy_lints/src/attrs/repr_attributes.rs
new file mode 100644
index 000000000000..6d1ab46aa0c1
--- /dev/null
+++ b/clippy_lints/src/attrs/repr_attributes.rs
@@ -0,0 +1,43 @@
+use rustc_hir::Attribute;
+use rustc_lint::LateContext;
+use rustc_span::{Span, sym};
+
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::msrvs;
+
+use super::REPR_PACKED_WITHOUT_ABI;
+
+pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute], msrv: &msrvs::Msrv) {
+    if msrv.meets(msrvs::REPR_RUST) {
+        check_packed(cx, item_span, attrs);
+    }
+}
+
+fn check_packed(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute]) {
+    if let Some(items) = attrs.iter().find_map(|attr| {
+        if attr.ident().is_some_and(|ident| matches!(ident.name, sym::repr)) {
+            attr.meta_item_list()
+        } else {
+            None
+        }
+    }) && let Some(packed) = items
+        .iter()
+        .find(|item| item.ident().is_some_and(|ident| matches!(ident.name, sym::packed)))
+        && !items.iter().any(|item| {
+            item.ident()
+                .is_some_and(|ident| matches!(ident.name, sym::C | sym::Rust))
+        })
+    {
+        span_lint_and_then(
+            cx,
+            REPR_PACKED_WITHOUT_ABI,
+            item_span,
+            "item uses `packed` representation without ABI-qualification",
+            |diag| {
+                diag.warn("unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI")
+                    .help("qualify the desired ABI explicity via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`")
+                    .span_label(packed.span(), "`packed` representation set here");
+            },
+        );
+    }
+}
diff --git a/clippy_lints/src/attrs/useless_attribute.rs b/clippy_lints/src/attrs/useless_attribute.rs
index e21853598c3b..e7158a6a6b6c 100644
--- a/clippy_lints/src/attrs/useless_attribute.rs
+++ b/clippy_lints/src/attrs/useless_attribute.rs
@@ -1,8 +1,8 @@
 use super::USELESS_ATTRIBUTE;
-use super::utils::{extract_clippy_lint, is_lint_level, is_word};
+use super::utils::{is_lint_level, is_word, namespace_and_lint};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{SpanRangeExt, first_line_of_span};
-use rustc_ast::{Attribute, Item, ItemKind, MetaItemInner};
+use rustc_ast::{Attribute, Item, ItemKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -20,11 +20,13 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
                 for lint in lint_list {
                     match item.kind {
                         ItemKind::Use(..) => {
-                            if let MetaItemInner::MetaItem(meta_item) = lint
-                                && meta_item.is_word()
-                                && let Some(ident) = meta_item.ident()
+                            let (namespace @ (Some(sym::clippy) | None), Some(name)) = namespace_and_lint(lint) else {
+                                return;
+                            };
+
+                            if namespace.is_none()
                                 && matches!(
-                                    ident.name.as_str(),
+                                    name.as_str(),
                                     "ambiguous_glob_reexports"
                                         | "dead_code"
                                         | "deprecated"
@@ -39,9 +41,9 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
                                 return;
                             }
 
-                            if extract_clippy_lint(lint).is_some_and(|symbol| {
-                                matches!(
-                                    symbol.as_str(),
+                            if namespace == Some(sym::clippy)
+                                && matches!(
+                                    name.as_str(),
                                     "wildcard_imports"
                                         | "enum_glob_use"
                                         | "redundant_pub_crate"
@@ -52,7 +54,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
                                         | "disallowed_types"
                                         | "unused_trait_names"
                                 )
-                            }) {
+                            {
                                 return;
                             }
                         },
diff --git a/clippy_lints/src/attrs/utils.rs b/clippy_lints/src/attrs/utils.rs
index 3bb02688bf22..96de06429040 100644
--- a/clippy_lints/src/attrs/utils.rs
+++ b/clippy_lints/src/attrs/utils.rs
@@ -75,13 +75,18 @@ fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>
 
 /// Returns the lint name if it is clippy lint.
 pub(super) fn extract_clippy_lint(lint: &MetaItemInner) -> Option<Symbol> {
-    if let Some(meta_item) = lint.meta_item()
-        && meta_item.path.segments.len() > 1
-        && let tool_name = meta_item.path.segments[0].ident
-        && tool_name.name == sym::clippy
-    {
-        let lint_name = meta_item.path.segments.last().unwrap().ident.name;
-        return Some(lint_name);
+    match namespace_and_lint(lint) {
+        (Some(sym::clippy), name) => name,
+        _ => None,
+    }
+}
+
+/// Returns the lint namespace, if any, as well as the lint name. (`None`, `None`) means
+/// the lint had less than 1 or more than 2 segments.
+pub(super) fn namespace_and_lint(lint: &MetaItemInner) -> (Option<Symbol>, Option<Symbol>) {
+    match lint.meta_item().map(|m| m.path.segments.as_slice()).unwrap_or_default() {
+        [name] => (None, Some(name.ident.name)),
+        [namespace, name] => (Some(namespace.ident.name), Some(name.ident.name)),
+        _ => (None, None),
     }
-    None
 }
diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index f68a7a89b399..f8c30d1c881d 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -5,11 +5,11 @@ use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use rustc_ast::ast::LitKind;
+use rustc_attr_parsing::RustcVersion;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
 use rustc_lint::{LateContext, LateLintPass, Level};
-use rustc_attr_parsing::RustcVersion;
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{Span, sym};
diff --git a/clippy_lints/src/casts/as_pointer_underscore.rs b/clippy_lints/src/casts/as_pointer_underscore.rs
new file mode 100644
index 000000000000..536126fd02b3
--- /dev/null
+++ b/clippy_lints/src/casts/as_pointer_underscore.rs
@@ -0,0 +1,19 @@
+use rustc_errors::Applicability;
+use rustc_lint::LateContext;
+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)
+    {
+        clippy_utils::diagnostics::span_lint_and_sugg(
+            cx,
+            super::AS_POINTER_UNDERSCORE,
+            cast_to_hir.span,
+            "using inferred pointer cast",
+            "use explicit type",
+            ty_into.to_string(),
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/clippy_lints/src/casts/borrow_as_ptr.rs b/clippy_lints/src/casts/borrow_as_ptr.rs
index 4dd51dcbc9a2..67aa33ca06c3 100644
--- a/clippy_lints/src/casts/borrow_as_ptr.rs
+++ b/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::Msrv;
 use clippy_utils::source::snippet_with_context;
-use clippy_utils::std_or_core;
+use clippy_utils::{is_lint_allowed, msrvs, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
@@ -13,15 +14,12 @@ pub(super) fn check<'tcx>(
     expr: &'tcx Expr<'_>,
     cast_expr: &'tcx Expr<'_>,
     cast_to: &'tcx Ty<'_>,
-) {
+    msrv: &Msrv,
+) -> bool {
     if matches!(cast_to.kind, TyKind::Ptr(_))
         && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
-        && let Some(std_or_core) = std_or_core(cx)
+        && !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id)
     {
-        let macro_name = match mutability {
-            Mutability::Not => "addr_of",
-            Mutability::Mut => "addr_of_mut",
-        };
         let mut app = Applicability::MachineApplicable;
         let snip = snippet_with_context(cx, e.span, cast_expr.span.ctxt(), "..", &mut app).0;
         // Fix #9884
@@ -31,17 +29,36 @@ pub(super) fn check<'tcx>(
                 .get(base.hir_id)
                 .is_some_and(|x| x.iter().any(|adj| matches!(adj.kind, Adjust::Deref(_))))
         }) {
-            return;
+            return false;
         }
 
+        let suggestion = if msrv.meets(msrvs::RAW_REF_OP) {
+            let operator_kind = match mutability {
+                Mutability::Not => "const",
+                Mutability::Mut => "mut",
+            };
+            format!("&raw {operator_kind} {snip}")
+        } else {
+            let Some(std_or_core) = std_or_core(cx) else {
+                return false;
+            };
+            let macro_name = match mutability {
+                Mutability::Not => "addr_of",
+                Mutability::Mut => "addr_of_mut",
+            };
+            format!("{std_or_core}::ptr::{macro_name}!({snip})")
+        };
+
         span_lint_and_sugg(
             cx,
             BORROW_AS_PTR,
             expr.span,
             "borrow as raw pointer",
             "try",
-            format!("{std_or_core}::ptr::{macro_name}!({snip})"),
+            suggestion,
             Applicability::MachineApplicable,
         );
+        return true;
     }
+    false
 }
diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs
index 8b884399f923..c64c0e15144d 100644
--- a/clippy_lints/src/casts/mod.rs
+++ b/clippy_lints/src/casts/mod.rs
@@ -1,3 +1,4 @@
+mod as_pointer_underscore;
 mod as_ptr_cast_mut;
 mod as_underscore;
 mod borrow_as_ptr;
@@ -574,13 +575,13 @@ declare_clippy_lint! {
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for the usage of `&expr as *const T` or
-    /// `&mut expr as *mut T`, and suggest using `ptr::addr_of` or
-    /// `ptr::addr_of_mut` instead.
+    /// `&mut expr as *mut T`, and suggest using `&raw const` or
+    /// `&raw mut` instead.
     ///
     /// ### Why is this bad?
     /// This would improve readability and avoid creating a reference
     /// that points to an uninitialized value or unaligned place.
-    /// Read the `ptr::addr_of` docs for more information.
+    /// Read the `&raw` explanation in the Reference for more information.
     ///
     /// ### Example
     /// ```no_run
@@ -593,10 +594,10 @@ declare_clippy_lint! {
     /// Use instead:
     /// ```no_run
     /// let val = 1;
-    /// let p = std::ptr::addr_of!(val);
+    /// let p = &raw const val;
     ///
     /// let mut val_mut = 1;
-    /// let p_mut = std::ptr::addr_of_mut!(val_mut);
+    /// let p_mut = &raw mut val_mut;
     /// ```
     #[clippy::version = "1.60.0"]
     pub BORROW_AS_PTR,
@@ -726,6 +727,33 @@ declare_clippy_lint! {
     "using `as` to cast a reference to pointer"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for the usage of `as *const _` or `as *mut _` conversion using inferred type.
+    ///
+    /// ### Why restrict this?
+    /// The conversion might include a dangerous cast that might go undetected due to the type being inferred.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// fn as_usize<T>(t: &T) -> usize {
+    ///     // BUG: `t` is already a reference, so we will here
+    ///     // return a dangling pointer to a temporary value instead
+    ///     &t as *const _ as usize
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// fn as_usize<T>(t: &T) -> usize {
+    ///     t as *const T as usize
+    /// }
+    /// ```
+    #[clippy::version = "1.81.0"]
+    pub AS_POINTER_UNDERSCORE,
+    restriction,
+    "detects `as *mut _` and `as *const _` conversion"
+}
+
 pub struct Casts {
     msrv: Msrv,
 }
@@ -763,6 +791,7 @@ impl_lint_pass!(Casts => [
     CAST_NAN_TO_INT,
     ZERO_PTR,
     REF_AS_PTR,
+    AS_POINTER_UNDERSCORE,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -805,11 +834,15 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             }
 
             as_underscore::check(cx, expr, cast_to_hir);
-
-            if self.msrv.meets(msrvs::PTR_FROM_REF) {
+            as_pointer_underscore::check(cx, cast_to, cast_to_hir);
+
+            let was_borrow_as_ptr_emitted = if self.msrv.meets(msrvs::BORROW_AS_PTR) {
+                borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir, &self.msrv)
+            } else {
+                false
+            };
+            if self.msrv.meets(msrvs::PTR_FROM_REF) && !was_borrow_as_ptr_emitted {
                 ref_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
-            } else if self.msrv.meets(msrvs::BORROW_AS_PTR) {
-                borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
             }
         }
 
diff --git a/clippy_lints/src/comparison_chain.rs b/clippy_lints/src/comparison_chain.rs
index c85e3500ebdc..61c92d441d09 100644
--- a/clippy_lints/src/comparison_chain.rs
+++ b/clippy_lints/src/comparison_chain.rs
@@ -1,6 +1,8 @@
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{SpanlessEq, if_sequence, is_else_clause, is_in_const_context};
+use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -120,13 +122,19 @@ impl<'tcx> LateLintPass<'tcx> for ComparisonChain {
                 return;
             }
         }
-        span_lint_and_help(
+        let ExprKind::Binary(_, lhs, rhs) = conds[0].kind else {
+            unreachable!();
+        };
+        let lhs = Sugg::hir(cx, lhs, "..").maybe_par();
+        let rhs = Sugg::hir(cx, rhs, "..").addr();
+        span_lint_and_sugg(
             cx,
             COMPARISON_CHAIN,
             expr.span,
             "`if` chain can be rewritten with `match`",
-            None,
-            "consider rewriting the `if` chain to use `cmp` and `match`",
+            "consider rewriting the `if` chain with `match`",
+            format!("match {lhs}.cmp({rhs}) {{...}}"),
+            Applicability::HasPlaceholders,
         );
     }
 }
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
index 022ed180ed8c..7451fb909ef8 100644
--- a/clippy_lints/src/declared_lints.rs
+++ b/clippy_lints/src/declared_lints.rs
@@ -55,6 +55,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::attrs::INLINE_ALWAYS_INFO,
     crate::attrs::MIXED_ATTRIBUTES_STYLE_INFO,
     crate::attrs::NON_MINIMAL_CFG_INFO,
+    crate::attrs::REPR_PACKED_WITHOUT_ABI_INFO,
     crate::attrs::SHOULD_PANIC_WITHOUT_EXPECT_INFO,
     crate::attrs::UNNECESSARY_CLIPPY_CFG_INFO,
     crate::attrs::USELESS_ATTRIBUTE_INFO,
@@ -75,6 +76,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,
     crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,
     crate::cargo::WILDCARD_DEPENDENCIES_INFO,
+    crate::casts::AS_POINTER_UNDERSCORE_INFO,
     crate::casts::AS_PTR_CAST_MUT_INFO,
     crate::casts::AS_UNDERSCORE_INFO,
     crate::casts::BORROW_AS_PTR_INFO,
@@ -139,6 +141,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::doc::DOC_LAZY_CONTINUATION_INFO,
     crate::doc::DOC_LINK_WITH_QUOTES_INFO,
     crate::doc::DOC_MARKDOWN_INFO,
+    crate::doc::DOC_NESTED_REFDEFS_INFO,
     crate::doc::EMPTY_DOCS_INFO,
     crate::doc::EMPTY_LINE_AFTER_DOC_COMMENTS_INFO,
     crate::doc::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
@@ -277,6 +280,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::literal_representation::MISTYPED_LITERAL_SUFFIXES_INFO,
     crate::literal_representation::UNREADABLE_LITERAL_INFO,
     crate::literal_representation::UNUSUAL_BYTE_GROUPINGS_INFO,
+    crate::literal_string_with_formatting_args::LITERAL_STRING_WITH_FORMATTING_ARGS_INFO,
     crate::loops::EMPTY_LOOP_INFO,
     crate::loops::EXPLICIT_COUNTER_LOOP_INFO,
     crate::loops::EXPLICIT_INTO_ITER_LOOP_INFO,
diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs
index 6819ad547f87..3b3a78cb1153 100644
--- a/clippy_lints/src/default_numeric_fallback.rs
+++ b/clippy_lints/src/default_numeric_fallback.rs
@@ -26,7 +26,8 @@ declare_clippy_lint! {
     /// To ensure that every numeric type is chosen explicitly rather than implicitly.
     ///
     /// ### Known problems
-    /// This lint can only be allowed at the function level or above.
+    /// This lint is implemented using a custom algorithm independent of rustc's inference,
+    /// which results in many false positives and false negatives.
     ///
     /// ### Example
     /// ```no_run
@@ -36,8 +37,8 @@ declare_clippy_lint! {
     ///
     /// Use instead:
     /// ```no_run
-    /// let i = 10i32;
-    /// let f = 1.23f64;
+    /// let i = 10_i32;
+    /// let f = 1.23_f64;
     /// ```
     #[clippy::version = "1.52.0"]
     pub DEFAULT_NUMERIC_FALLBACK,
diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs
index 821312a9e401..653726872c64 100644
--- a/clippy_lints/src/dereference.rs
+++ b/clippy_lints/src/dereference.rs
@@ -1004,7 +1004,10 @@ fn report<'tcx>(
                     let needs_paren = match cx.tcx.parent_hir_node(data.first_expr.hir_id) {
                         Node::Expr(e) => match e.kind {
                             ExprKind::Call(callee, _) if callee.hir_id != data.first_expr.hir_id => false,
-                            ExprKind::Call(..) => expr.precedence() < ExprPrecedence::Unambiguous || matches!(expr.kind, ExprKind::Field(..)),
+                            ExprKind::Call(..) => {
+                                expr.precedence() < ExprPrecedence::Unambiguous
+                                    || matches!(expr.kind, ExprKind::Field(..))
+                            },
                             _ => expr.precedence() < e.precedence(),
                         },
                         _ => false,
@@ -1017,11 +1020,7 @@ fn report<'tcx>(
                         })
                     );
 
-                    let sugg = if !snip_is_macro
-                        && needs_paren
-                        && !has_enclosing_paren(&snip)
-                        && !is_in_tuple
-                    {
+                    let sugg = if !snip_is_macro && needs_paren && !has_enclosing_paren(&snip) && !is_in_tuple {
                         format!("({snip})")
                     } else {
                         snip.into()
diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs
index f65edd362530..7c2f5efd8dd4 100644
--- a/clippy_lints/src/derive.rs
+++ b/clippy_lints/src/derive.rs
@@ -6,9 +6,7 @@ use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, pat
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn, walk_item};
-use rustc_hir::{
-    self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource,
-};
+use rustc_hir::{self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{
@@ -453,7 +451,7 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
         && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
         && !has_non_exhaustive_attr(cx.tcx, *adt)
         && !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)
-        && let typing_env = typing_env_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
+        && let typing_env = typing_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
         && let Some(local_def_id) = adt.did().as_local()
         // If all of our fields implement `Eq`, we can implement `Eq` too
         && adt
@@ -484,7 +482,7 @@ fn ty_implements_eq_trait<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, eq_trait_id: De
 }
 
 /// Creates the `ParamEnv` used for the give type's derived `Eq` impl.
-fn typing_env_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ty::TypingEnv<'_> {
+fn typing_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ty::TypingEnv<'_> {
     // Initial map from generic index to param def.
     // Vec<(param_def, needs_eq)>
     let mut params = tcx
diff --git a/clippy_lints/src/disallowed_macros.rs b/clippy_lints/src/disallowed_macros.rs
index a0cb36f88dc0..a78c392e2086 100644
--- a/clippy_lints/src/disallowed_macros.rs
+++ b/clippy_lints/src/disallowed_macros.rs
@@ -43,7 +43,6 @@ declare_clippy_lint! {
     /// ```no_run
     /// use serde::Serialize;
     ///
-    /// // Example code where clippy issues a warning
     /// println!("warns");
     ///
     /// // The diagnostic will contain the message "no serializing"
diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs
index 1e660b1957a4..c4ed118b7c9f 100644
--- a/clippy_lints/src/disallowed_methods.rs
+++ b/clippy_lints/src/disallowed_methods.rs
@@ -35,7 +35,6 @@ declare_clippy_lint! {
     /// ```
     ///
     /// ```rust,ignore
-    /// // Example code where clippy issues a warning
     /// let xs = vec![1, 2, 3, 4];
     /// xs.leak(); // Vec::leak is disallowed in the config.
     /// // The diagnostic contains the message "no leaking memory".
@@ -47,7 +46,6 @@ declare_clippy_lint! {
     ///
     /// Use instead:
     /// ```rust,ignore
-    /// // Example code which does not raise clippy warning
     /// let mut xs = Vec::new(); // Vec::new is _not_ disallowed in the config.
     /// xs.push(123); // Vec::push is _not_ disallowed in the config.
     /// ```
diff --git a/clippy_lints/src/doc/include_in_doc_without_cfg.rs b/clippy_lints/src/doc/include_in_doc_without_cfg.rs
index 0bb16a0c77d5..4b40fc0b1ee2 100644
--- a/clippy_lints/src/doc/include_in_doc_without_cfg.rs
+++ b/clippy_lints/src/doc/include_in_doc_without_cfg.rs
@@ -1,9 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_opt;
-use rustc_ast::{AttrStyle};
+use rustc_ast::AttrStyle;
 use rustc_errors::Applicability;
+use rustc_hir::{AttrArgs, AttrKind, Attribute};
 use rustc_lint::LateContext;
-use rustc_hir::{Attribute, AttrKind, AttrArgs};
 
 use super::DOC_INCLUDE_WITHOUT_CFG;
 
diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs
index f65acd7978a7..b2135fe18bd9 100644
--- a/clippy_lints/src/doc/mod.rs
+++ b/clippy_lints/src/doc/mod.rs
@@ -5,7 +5,7 @@ mod too_long_first_doc_paragraph;
 
 use clippy_config::Conf;
 use clippy_utils::attrs::is_doc_hidden;
-use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
+use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_then};
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::Visitable;
@@ -17,6 +17,7 @@ use pulldown_cmark::Event::{
 use pulldown_cmark::Tag::{BlockQuote, CodeBlock, FootnoteDefinition, Heading, Item, Link, Paragraph};
 use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options, TagEnd};
 use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AnonConst, Attribute, Expr, ImplItemKind, ItemKind, Node, Safety, TraitItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -563,6 +564,32 @@ declare_clippy_lint! {
     "check if files included in documentation are behind `cfg(doc)`"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Warns if a link reference definition appears at the start of a
+    /// list item or quote.
+    ///
+    /// ### Why is this bad?
+    /// This is probably intended as an intra-doc link. If it is really
+    /// supposed to be a reference definition, it can be written outside
+    /// of the list item or quote.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// //! - [link]: description
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// //! - [link][]: description (for intra-doc link)
+    /// //!
+    /// //! [link]: destination (for link reference definition)
+    /// ```
+    #[clippy::version = "1.84.0"]
+    pub DOC_NESTED_REFDEFS,
+    suspicious,
+    "link reference defined in list item or quote"
+}
+
 pub struct Documentation {
     valid_idents: FxHashSet<String>,
     check_private_items: bool,
@@ -580,6 +607,7 @@ impl Documentation {
 impl_lint_pass!(Documentation => [
     DOC_LINK_WITH_QUOTES,
     DOC_MARKDOWN,
+    DOC_NESTED_REFDEFS,
     MISSING_SAFETY_DOC,
     MISSING_ERRORS_DOC,
     MISSING_PANICS_DOC,
@@ -831,6 +859,31 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
             Start(BlockQuote(_)) => {
                 blockquote_level += 1;
                 containers.push(Container::Blockquote);
+                if let Some((next_event, next_range)) = events.peek() {
+                    let next_start = match next_event {
+                        End(TagEnd::BlockQuote) => next_range.end,
+                        _ => next_range.start,
+                    };
+                    if let Some(refdefrange) = looks_like_refdef(doc, range.start..next_start) &&
+                        let Some(refdefspan) = fragments.span(cx, refdefrange.clone())
+                    {
+                        span_lint_and_then(
+                            cx,
+                            DOC_NESTED_REFDEFS,
+                            refdefspan,
+                            "link reference defined in quote",
+                            |diag| {
+                                diag.span_suggestion_short(
+                                    refdefspan.shrink_to_hi(),
+                                    "for an intra-doc link, add `[]` between the label and the colon",
+                                    "[]",
+                                    Applicability::MaybeIncorrect,
+                                );
+                                diag.help("link definitions are not shown in rendered documentation");
+                            }
+                        );
+                    }
+                }
             },
             End(TagEnd::BlockQuote) => {
                 blockquote_level -= 1;
@@ -869,11 +922,42 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                     in_heading = true;
                 }
                 if let Start(Item) = event {
-                    if let Some((_next_event, next_range)) = events.peek() {
-                        containers.push(Container::List(next_range.start - range.start));
+                    let indent = if let Some((next_event, next_range)) = events.peek() {
+                        let next_start = match next_event {
+                            End(TagEnd::Item) => next_range.end,
+                            _ => next_range.start,
+                        };
+                        if let Some(refdefrange) = looks_like_refdef(doc, range.start..next_start) &&
+                            let Some(refdefspan) = fragments.span(cx, refdefrange.clone())
+                        {
+                            span_lint_and_then(
+                                cx,
+                                DOC_NESTED_REFDEFS,
+                                refdefspan,
+                                "link reference defined in list item",
+                                |diag| {
+                                    diag.span_suggestion_short(
+                                        refdefspan.shrink_to_hi(),
+                                        "for an intra-doc link, add `[]` between the label and the colon",
+                                        "[]",
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                    diag.help("link definitions are not shown in rendered documentation");
+                                }
+                            );
+                            refdefrange.start - range.start
+                        } else {
+                            let mut start = next_range.start;
+                            if start > 0 && doc.as_bytes().get(start - 1) == Some(&b'\\') {
+                                // backslashes aren't in the event stream...
+                                start -= 1;
+                            }
+                            start - range.start
+                        }
                     } else {
-                        containers.push(Container::List(0));
-                    }
+                        0
+                    };
+                    containers.push(Container::List(indent));
                 }
                 ticks_unbalanced = false;
                 paragraph_range = range;
@@ -1045,3 +1129,25 @@ impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> {
         self.cx.tcx.hir()
     }
 }
+
+#[expect(clippy::range_plus_one)] // inclusive ranges aren't the same type
+fn looks_like_refdef(doc: &str, range: Range<usize>) -> Option<Range<usize>> {
+    let offset = range.start;
+    let mut iterator = doc.as_bytes()[range].iter().copied().enumerate();
+    let mut start = None;
+    while let Some((i, byte)) = iterator.next() {
+        match byte {
+            b'\\' => {
+                iterator.next();
+            },
+            b'[' => {
+                start = Some(i + offset);
+            },
+            b']' if let Some(start) = start => {
+                return Some(start..i + offset + 1);
+            },
+            _ => {},
+        }
+    }
+    None
+}
diff --git a/clippy_lints/src/explicit_write.rs b/clippy_lints/src/explicit_write.rs
index 0550c22761a5..a5a4e05b3a6d 100644
--- a/clippy_lints/src/explicit_write.rs
+++ b/clippy_lints/src/explicit_write.rs
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
             // match call to write_fmt
             && let ExprKind::MethodCall(write_fun, write_recv, [write_arg], _) = *look_in_block(cx, &write_call.kind)
             && let ExprKind::Call(write_recv_path, []) = write_recv.kind
-            && write_fun.ident.name.as_str() == "write_fmt"
+            && write_fun.ident.name == sym::write_fmt
             && let Some(def_id) = path_def_id(cx, write_recv_path)
         {
             // match calls to std::io::stdout() / std::io::stderr ()
diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs
index be3d0f7ad634..243eb5cbfd40 100644
--- a/clippy_lints/src/functions/mod.rs
+++ b/clippy_lints/src/functions/mod.rs
@@ -10,6 +10,7 @@ mod too_many_lines;
 
 use clippy_config::Conf;
 use clippy_utils::def_path_def_ids;
+use clippy_utils::msrvs::Msrv;
 use rustc_hir as hir;
 use rustc_hir::intravisit;
 use rustc_lint::{LateContext, LateLintPass};
@@ -455,6 +456,7 @@ pub struct Functions {
     /// A set of resolved `def_id` of traits that are configured to allow
     /// function params renaming.
     trait_ids: DefIdSet,
+    msrv: Msrv,
 }
 
 impl Functions {
@@ -469,6 +471,7 @@ impl Functions {
                 .iter()
                 .flat_map(|p| def_path_def_ids(tcx, &p.split("::").collect::<Vec<_>>()))
                 .collect(),
+            msrv: conf.msrv.clone(),
         }
     }
 }
@@ -518,12 +521,12 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
         must_use::check_item(cx, item);
-        result::check_item(cx, item, self.large_error_threshold);
+        result::check_item(cx, item, self.large_error_threshold, &self.msrv);
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
         must_use::check_impl_item(cx, item);
-        result::check_impl_item(cx, item, self.large_error_threshold);
+        result::check_impl_item(cx, item, self.large_error_threshold, &self.msrv);
         impl_trait_in_params::check_impl_item(cx, item);
         renamed_function_params::check_impl_item(cx, item, &self.trait_ids);
     }
@@ -532,8 +535,10 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
         too_many_arguments::check_trait_item(cx, item, self.too_many_arguments_threshold);
         not_unsafe_ptr_arg_deref::check_trait_item(cx, item);
         must_use::check_trait_item(cx, item);
-        result::check_trait_item(cx, item, self.large_error_threshold);
+        result::check_trait_item(cx, item, self.large_error_threshold, &self.msrv);
         impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api);
         ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api);
     }
+
+    extract_msrv_attr!(LateContext);
 }
diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs
index 2b26285429af..afdb5d5306a6 100644
--- a/clippy_lints/src/functions/must_use.rs
+++ b/clippy_lints/src/functions/must_use.rs
@@ -28,7 +28,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
         let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
         if let Some(attr) = attr {
-            check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, sig);
+            check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
         } else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) {
             check_must_use_candidate(
                 cx,
@@ -50,7 +50,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
         let attrs = cx.tcx.hir().attrs(item.hir_id());
         let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
         if let Some(attr) = attr {
-            check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, sig);
+            check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
         } else if is_public && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
             check_must_use_candidate(
                 cx,
@@ -73,7 +73,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
         let attrs = cx.tcx.hir().attrs(item.hir_id());
         let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
         if let Some(attr) = attr {
-            check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, sig);
+            check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
         } else if let hir::TraitFn::Provided(eid) = *eid {
             let body = cx.tcx.hir().body(eid);
             if attr.is_none() && is_public && !is_proc_macro(attrs) {
@@ -91,6 +91,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr
     }
 }
 
+#[allow(clippy::too_many_arguments)]
 fn check_needless_must_use(
     cx: &LateContext<'_>,
     decl: &hir::FnDecl<'_>,
@@ -98,21 +99,54 @@ fn check_needless_must_use(
     item_span: Span,
     fn_header_span: Span,
     attr: &Attribute,
+    attrs: &[Attribute],
     sig: &FnSig<'_>,
 ) {
     if in_external_macro(cx.sess(), item_span) {
         return;
     }
     if returns_unit(decl) {
-        span_lint_and_then(
-            cx,
-            MUST_USE_UNIT,
-            fn_header_span,
-            "this unit-returning function has a `#[must_use]` attribute",
-            |diag| {
-                diag.span_suggestion(attr.span, "remove the attribute", "", Applicability::MachineApplicable);
-            },
-        );
+        if attrs.len() == 1 {
+            span_lint_and_then(
+                cx,
+                MUST_USE_UNIT,
+                fn_header_span,
+                "this unit-returning function has a `#[must_use]` attribute",
+                |diag| {
+                    diag.span_suggestion(attr.span, "remove the attribute", "", Applicability::MachineApplicable);
+                },
+            );
+        } else {
+            // When there are multiple attributes, it is not sufficient to simply make `must_use` empty, see
+            // issue #12320.
+            span_lint_and_then(
+                cx,
+                MUST_USE_UNIT,
+                fn_header_span,
+                "this unit-returning function has a `#[must_use]` attribute",
+                |diag| {
+                    let mut attrs_without_must_use = attrs.to_vec();
+                    attrs_without_must_use.retain(|a| a.id != attr.id);
+                    let sugg_str = attrs_without_must_use
+                        .iter()
+                        .map(|a| {
+                            if a.value_str().is_none() {
+                                return a.name_or_empty().to_string();
+                            }
+                            format!("{} = \"{}\"", a.name_or_empty(), a.value_str().unwrap())
+                        })
+                        .collect::<Vec<_>>()
+                        .join(", ");
+
+                    diag.span_suggestion(
+                        attrs[0].span.with_hi(attrs[attrs.len() - 1].span.hi()),
+                        "change these attributes to",
+                        sugg_str,
+                        Applicability::MachineApplicable,
+                    );
+                },
+            );
+        }
     } else if attr.value_str().is_none() && is_must_use_ty(cx, return_ty(cx, item_id)) {
         // Ignore async functions unless Future::Output type is a must_use type
         if sig.header.is_async() {
diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs
index d4eaa1663208..674d78eaae76 100644
--- a/clippy_lints/src/functions/result.rs
+++ b/clippy_lints/src/functions/result.rs
@@ -1,3 +1,4 @@
+use clippy_utils::msrvs::{self, Msrv};
 use rustc_errors::Diag;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
@@ -6,8 +7,8 @@ use rustc_middle::ty::{self, Ty};
 use rustc_span::{Span, sym};
 
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
-use clippy_utils::trait_ref_of_method;
 use clippy_utils::ty::{AdtVariantInfo, approx_ty_size, is_type_diagnostic_item};
+use clippy_utils::{is_no_std_crate, trait_ref_of_method};
 
 use super::{RESULT_LARGE_ERR, RESULT_UNIT_ERR};
 
@@ -34,19 +35,24 @@ fn result_err_ty<'tcx>(
     }
 }
 
-pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64) {
+pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64, msrv: &Msrv) {
     if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind
         && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
     {
         if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
             let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
-            check_result_unit_err(cx, err_ty, fn_header_span);
+            check_result_unit_err(cx, err_ty, fn_header_span, msrv);
         }
         check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
     }
 }
 
-pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem<'tcx>, large_err_threshold: u64) {
+pub(super) fn check_impl_item<'tcx>(
+    cx: &LateContext<'tcx>,
+    item: &hir::ImplItem<'tcx>,
+    large_err_threshold: u64,
+    msrv: &Msrv,
+) {
     // Don't lint if method is a trait's implementation, we can't do anything about those
     if let hir::ImplItemKind::Fn(ref sig, _) = item.kind
         && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
@@ -54,26 +60,31 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::ImplItem
     {
         if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
             let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
-            check_result_unit_err(cx, err_ty, fn_header_span);
+            check_result_unit_err(cx, err_ty, fn_header_span, msrv);
         }
         check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
     }
 }
 
-pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::TraitItem<'tcx>, large_err_threshold: u64) {
+pub(super) fn check_trait_item<'tcx>(
+    cx: &LateContext<'tcx>,
+    item: &hir::TraitItem<'tcx>,
+    large_err_threshold: u64,
+    msrv: &Msrv,
+) {
     if let hir::TraitItemKind::Fn(ref sig, _) = item.kind {
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
         if let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span) {
             if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
-                check_result_unit_err(cx, err_ty, fn_header_span);
+                check_result_unit_err(cx, err_ty, fn_header_span, msrv);
             }
             check_result_large_err(cx, err_ty, hir_ty.span, large_err_threshold);
         }
     }
 }
 
-fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: Span) {
-    if err_ty.is_unit() {
+fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: Span, msrv: &Msrv) {
+    if err_ty.is_unit() && (!is_no_std_crate(cx) || msrv.meets(msrvs::ERROR_IN_CORE)) {
         span_lint_and_help(
             cx,
             RESULT_UNIT_ERR,
diff --git a/clippy_lints/src/if_not_else.rs b/clippy_lints/src/if_not_else.rs
index 120c5396a1cd..2806d4d0e5d6 100644
--- a/clippy_lints/src/if_not_else.rs
+++ b/clippy_lints/src/if_not_else.rs
@@ -1,9 +1,13 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::is_else_clause;
+use clippy_utils::source::{HasSession, indent_of, reindent_multiline, snippet};
+use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::Span;
+use std::borrow::Cow;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -54,7 +58,7 @@ fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
 
 impl LateLintPass<'_> for IfNotElse {
     fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {
-        if let ExprKind::If(cond, _, Some(els)) = e.kind
+        if let ExprKind::If(cond, cond_inner, Some(els)) = e.kind
             && let ExprKind::DropTemps(cond) = cond.kind
             && let ExprKind::Block(..) = els.kind
         {
@@ -79,8 +83,52 @@ impl LateLintPass<'_> for IfNotElse {
             // }
             // ```
             if !e.span.from_expansion() && !is_else_clause(cx.tcx, e) {
-                span_lint_and_help(cx, IF_NOT_ELSE, e.span, msg, None, help);
+                match cond.kind {
+                    ExprKind::Unary(UnOp::Not, _) | ExprKind::Binary(_, _, _) => span_lint_and_sugg(
+                        cx,
+                        IF_NOT_ELSE,
+                        e.span,
+                        msg,
+                        "try",
+                        make_sugg(cx, &cond.kind, cond_inner.span, els.span, "..", Some(e.span)).to_string(),
+                        Applicability::MachineApplicable,
+                    ),
+                    _ => span_lint_and_help(cx, IF_NOT_ELSE, e.span, msg, None, help),
+                }
             }
         }
     }
 }
+
+fn make_sugg<'a>(
+    sess: &impl HasSession,
+    cond_kind: &'a ExprKind<'a>,
+    cond_inner: Span,
+    els_span: Span,
+    default: &'a str,
+    indent_relative_to: Option<Span>,
+) -> Cow<'a, str> {
+    let cond_inner_snip = snippet(sess, cond_inner, default);
+    let els_snip = snippet(sess, els_span, default);
+    let indent = indent_relative_to.and_then(|s| indent_of(sess, s));
+
+    let suggestion = match cond_kind {
+        ExprKind::Unary(UnOp::Not, cond_rest) => {
+            format!(
+                "if {} {} else {}",
+                snippet(sess, cond_rest.span, default),
+                els_snip,
+                cond_inner_snip
+            )
+        },
+        ExprKind::Binary(_, lhs, rhs) => {
+            let lhs_snip = snippet(sess, lhs.span, default);
+            let rhs_snip = snippet(sess, rhs.span, default);
+
+            format!("if {lhs_snip} == {rhs_snip} {els_snip} else {cond_inner_snip}")
+        },
+        _ => String::new(),
+    };
+
+    reindent_multiline(suggestion.into(), true, indent)
+}
diff --git a/clippy_lints/src/incompatible_msrv.rs b/clippy_lints/src/incompatible_msrv.rs
index 6cee7cfaca23..b10206dcd05e 100644
--- a/clippy_lints/src/incompatible_msrv.rs
+++ b/clippy_lints/src/incompatible_msrv.rs
@@ -2,7 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_in_test;
 use clippy_utils::msrvs::Msrv;
-use rustc_attr_parsing::{StabilityLevel, StableSince, RustcVersion};
+use rustc_attr_parsing::{RustcVersion, StabilityLevel, StableSince};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{Expr, ExprKind, HirId};
 use rustc_lint::{LateContext, LateLintPass};
diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs
index c2030a5ab090..15650c4f7329 100644
--- a/clippy_lints/src/index_refutable_slice.rs
+++ b/clippy_lints/src/index_refutable_slice.rs
@@ -135,7 +135,7 @@ fn lint_slice(cx: &LateContext<'_>, slice: &SliceLintInformation) {
         .map(|(index, _)| *index)
         .collect::<FxIndexSet<_>>();
 
-    let value_name = |index| format!("{}_{index}", slice.ident.name);
+    let value_name = |index| format!("{}_{}", slice.ident.name, index);
 
     if let Some(max_index) = used_indices.iter().max() {
         let opt_ref = if slice.needs_ref { "ref " } else { "" };
@@ -150,6 +150,18 @@ fn lint_slice(cx: &LateContext<'_>, slice: &SliceLintInformation) {
             .collect::<Vec<_>>();
         let pat_sugg = format!("[{}, ..]", pat_sugg_idents.join(", "));
 
+        let mut suggestions = Vec::new();
+
+        // Add the binding pattern suggestion
+        if !slice.pattern_spans.is_empty() {
+            suggestions.extend(slice.pattern_spans.iter().map(|span| (*span, pat_sugg.clone())));
+        }
+
+        // Add the index replacement suggestions
+        if !slice.index_use.is_empty() {
+            suggestions.extend(slice.index_use.iter().map(|(index, span)| (*span, value_name(*index))));
+        }
+
         span_lint_and_then(
             cx,
             INDEX_REFUTABLE_SLICE,
@@ -157,28 +169,10 @@ fn lint_slice(cx: &LateContext<'_>, slice: &SliceLintInformation) {
             "this binding can be a slice pattern to avoid indexing",
             |diag| {
                 diag.multipart_suggestion(
-                    "try using a slice pattern here",
-                    slice
-                        .pattern_spans
-                        .iter()
-                        .map(|span| (*span, pat_sugg.clone()))
-                        .collect(),
+                    "replace the binding and indexed access with a slice pattern",
+                    suggestions,
                     Applicability::MaybeIncorrect,
                 );
-
-                diag.multipart_suggestion(
-                    "and replace the index expressions here",
-                    slice
-                        .index_use
-                        .iter()
-                        .map(|(index, span)| (*span, value_name(*index)))
-                        .collect(),
-                    Applicability::MaybeIncorrect,
-                );
-
-                // The lint message doesn't contain a warning about the removed index expression,
-                // since `filter_lintable_slices` will only return slices where all access indices
-                // are known at compile time. Therefore, they can be removed without side effects.
             },
         );
     }
diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs
index ae2c3e0491f2..f666ed0a440b 100644
--- a/clippy_lints/src/indexing_slicing.rs
+++ b/clippy_lints/src/indexing_slicing.rs
@@ -2,7 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::ty::{deref_chain, get_adt_inherent_method};
-use clippy_utils::{higher, is_from_proc_macro};
+use clippy_utils::{higher, is_from_proc_macro, is_in_test};
 use rustc_ast::ast::RangeLimits;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -42,39 +42,50 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for usage of indexing or slicing. Arrays are special cases, this lint
-    /// does report on arrays if we can tell that slicing operations are in bounds and does not
-    /// lint on constant `usize` indexing on arrays because that is handled by rustc's `const_err` lint.
+    /// Checks for usage of indexing or slicing that may panic at runtime.
+    ///
+    /// This lint does not report on indexing or slicing operations
+    /// that always panic, clippy's `out_of_bound_indexing` already
+    /// handles those cases.
     ///
     /// ### Why restrict this?
     /// To avoid implicit panics from indexing and slicing.
+    ///
     /// There are “checked” alternatives which do not panic, and can be used with `unwrap()` to make
     /// an explicit panic when it is desired.
     ///
+    /// ### Limitations
+    /// This lint does not check for the usage of indexing or slicing on strings. These are covered
+    /// by the more specific `string_slice` lint.
+    ///
     /// ### Example
     /// ```rust,no_run
     /// // Vector
-    /// let x = vec![0; 5];
+    /// let x = vec![0, 1, 2, 3];
     ///
     /// x[2];
+    /// x[100];
     /// &x[2..100];
     ///
     /// // Array
     /// let y = [0, 1, 2, 3];
     ///
-    /// &y[10..100];
-    /// &y[10..];
+    /// let i = 10; // Could be a runtime value
+    /// let j = 20;
+    /// &y[i..j];
     /// ```
     ///
     /// Use instead:
     /// ```no_run
-    /// # let x = vec![0; 5];
-    /// # let y = [0, 1, 2, 3];
+    /// # let x = vec![0, 1, 2, 3];
     /// x.get(2);
+    /// x.get(100);
     /// x.get(2..100);
     ///
-    /// y.get(10);
-    /// y.get(10..100);
+    /// # let y = [0, 1, 2, 3];
+    /// let i = 10;
+    /// let j = 20;
+    /// y.get(i..j);
     /// ```
     #[clippy::version = "pre 1.29.0"]
     pub INDEXING_SLICING,
@@ -85,12 +96,14 @@ declare_clippy_lint! {
 impl_lint_pass!(IndexingSlicing => [INDEXING_SLICING, OUT_OF_BOUNDS_INDEXING]);
 
 pub struct IndexingSlicing {
+    allow_indexing_slicing_in_tests: bool,
     suppress_restriction_lint_in_const: bool,
 }
 
 impl IndexingSlicing {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
+            allow_indexing_slicing_in_tests: conf.allow_indexing_slicing_in_tests,
             suppress_restriction_lint_in_const: conf.suppress_restriction_lint_in_const,
         }
     }
@@ -111,6 +124,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
         {
             let note = "the suggestion might not be applicable in constant blocks";
             let ty = cx.typeck_results().expr_ty(array).peel_refs();
+            let allowed_in_tests = self.allow_indexing_slicing_in_tests && is_in_test(cx.tcx, expr.hir_id);
             if let Some(range) = higher::Range::hir(index) {
                 // Ranged indexes, i.e., &x[n..m], &x[n..], &x[..n] and &x[..]
                 if let ty::Array(_, s) = ty.kind() {
@@ -160,6 +174,10 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
                     (None, None) => return, // [..] is ok.
                 };
 
+                if allowed_in_tests {
+                    return;
+                }
+
                 span_lint_and_then(cx, INDEXING_SLICING, expr.span, "slicing may panic", |diag| {
                     diag.help(help_msg);
 
@@ -198,6 +216,10 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
                     }
                 }
 
+                if allowed_in_tests {
+                    return;
+                }
+
                 span_lint_and_then(cx, INDEXING_SLICING, expr.span, "indexing may panic", |diag| {
                     diag.help("consider using `.get(n)` or `.get_mut(n)` instead");
 
diff --git a/clippy_lints/src/large_include_file.rs b/clippy_lints/src/large_include_file.rs
index 66d4c40ab5e4..f3d62b513e84 100644
--- a/clippy_lints/src/large_include_file.rs
+++ b/clippy_lints/src/large_include_file.rs
@@ -2,8 +2,8 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::source::snippet_opt;
-use rustc_ast::{LitKind};
-use rustc_hir::{Expr, ExprKind, Attribute, AttrArgs, AttrKind};
+use rustc_ast::LitKind;
+use rustc_hir::{AttrArgs, AttrKind, Attribute, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 3e8315588cc7..d33013ba6638 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -9,6 +9,7 @@
 #![feature(iter_partition_in_place)]
 #![feature(let_chains)]
 #![feature(never_type)]
+#![feature(round_char_boundary)]
 #![feature(rustc_private)]
 #![feature(stmt_expr_attributes)]
 #![feature(unwrap_infallible)]
@@ -17,7 +18,8 @@
     clippy::missing_docs_in_private_items,
     clippy::must_use_candidate,
     rustc::diagnostic_outside_of_impl,
-    rustc::untranslatable_diagnostic
+    rustc::untranslatable_diagnostic,
+    clippy::literal_string_with_formatting_args
 )]
 #![warn(
     trivial_casts,
@@ -49,6 +51,7 @@ extern crate rustc_lexer;
 extern crate rustc_lint;
 extern crate rustc_middle;
 extern crate rustc_parse;
+extern crate rustc_parse_format;
 extern crate rustc_resolve;
 extern crate rustc_session;
 extern crate rustc_span;
@@ -196,6 +199,7 @@ mod let_with_type_underscore;
 mod lifetimes;
 mod lines_filter_map_ok;
 mod literal_representation;
+mod literal_string_with_formatting_args;
 mod loops;
 mod macro_metavars_in_unsafe;
 mod macro_use;
@@ -957,6 +961,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| Box::new(manual_div_ceil::ManualDivCeil::new(conf)));
     store.register_late_pass(|_| Box::new(manual_is_power_of_two::ManualIsPowerOfTwo));
     store.register_late_pass(|_| Box::new(non_zero_suggestions::NonZeroSuggestions));
+    store.register_late_pass(|_| Box::new(literal_string_with_formatting_args::LiteralStringWithFormattingArg));
     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));
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index 35b14776e59f..8b2eee34a972 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -643,8 +643,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
 
 // An `impl` lifetime is elidable if it satisfies the following conditions:
 // - It is used exactly once.
-// - That single use is not in a bounded type or `GenericArgs` in a `WherePredicate`. (Note that
-//   `GenericArgs` are different from `GenericParam`s.)
+// - That single use is not in a `WherePredicate`.
 fn report_elidable_impl_lifetimes<'tcx>(
     cx: &LateContext<'tcx>,
     impl_: &'tcx Impl<'_>,
@@ -658,12 +657,6 @@ fn report_elidable_impl_lifetimes<'tcx>(
                     lifetime,
                     in_where_predicate: false,
                     ..
-                }
-                | Usage {
-                    lifetime,
-                    in_bounded_ty: false,
-                    in_generics_arg: false,
-                    ..
                 },
             ] = usages.as_slice()
             {
diff --git a/clippy_lints/src/literal_string_with_formatting_args.rs b/clippy_lints/src/literal_string_with_formatting_args.rs
new file mode 100644
index 000000000000..49353a1b76be
--- /dev/null
+++ b/clippy_lints/src/literal_string_with_formatting_args.rs
@@ -0,0 +1,167 @@
+use rustc_ast::{LitKind, StrStyle};
+use rustc_hir::{Expr, ExprKind};
+use rustc_lexer::is_ident;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_parse_format::{ParseMode, Parser, Piece};
+use rustc_session::declare_lint_pass;
+use rustc_span::{BytePos, Span};
+
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::mir::enclosing_mir;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks if string literals have formatting arguments outside of macros
+    /// using them (like `format!`).
+    ///
+    /// ### Why is this bad?
+    /// It will likely not generate the expected content.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let x: Option<usize> = None;
+    /// let y = "hello";
+    /// x.expect("{y:?}");
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let x: Option<usize> = None;
+    /// let y = "hello";
+    /// x.expect(&format!("{y:?}"));
+    /// ```
+    #[clippy::version = "1.83.0"]
+    pub LITERAL_STRING_WITH_FORMATTING_ARGS,
+    suspicious,
+    "Checks if string literals have formatting arguments"
+}
+
+declare_lint_pass!(LiteralStringWithFormattingArg => [LITERAL_STRING_WITH_FORMATTING_ARGS]);
+
+fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, spans: &[(Span, Option<String>)]) {
+    if !spans.is_empty()
+        && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id)
+    {
+        let spans = spans
+            .iter()
+            .filter_map(|(span, name)| {
+                if let Some(name) = name {
+                    // We need to check that the name is a local.
+                    if !mir
+                        .var_debug_info
+                        .iter()
+                        .any(|local| !local.source_info.span.from_expansion() && local.name.as_str() == name)
+                    {
+                        return None;
+                    }
+                }
+                Some(*span)
+            })
+            .collect::<Vec<_>>();
+        match spans.len() {
+            0 => {},
+            1 => {
+                span_lint(
+                    cx,
+                    LITERAL_STRING_WITH_FORMATTING_ARGS,
+                    spans,
+                    "this looks like a formatting argument but it is not part of a formatting macro",
+                );
+            },
+            _ => {
+                span_lint(
+                    cx,
+                    LITERAL_STRING_WITH_FORMATTING_ARGS,
+                    spans,
+                    "these look like formatting arguments but are not part of a formatting macro",
+                );
+            },
+        }
+    }
+}
+
+impl LateLintPass<'_> for LiteralStringWithFormattingArg {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        if expr.span.from_expansion() {
+            return;
+        }
+        if let ExprKind::Lit(lit) = expr.kind {
+            let (add, symbol) = match lit.node {
+                LitKind::Str(symbol, style) => {
+                    let add = match style {
+                        StrStyle::Cooked => 1,
+                        StrStyle::Raw(nb) => nb as usize + 2,
+                    };
+                    (add, symbol)
+                },
+                _ => return,
+            };
+            let fmt_str = symbol.as_str();
+            let lo = expr.span.lo();
+            let mut current = fmt_str;
+            let mut diff_len = 0;
+
+            let mut parser = Parser::new(current, None, None, false, ParseMode::Format);
+            let mut spans = Vec::new();
+            while let Some(piece) = parser.next() {
+                if let Some(error) = parser.errors.last() {
+                    // We simply ignore the errors and move after them.
+                    if error.span.end >= current.len() {
+                        break;
+                    }
+                    // We find the closest char to where the error location ends.
+                    let pos = current.floor_char_boundary(error.span.end);
+                    // We get the next character.
+                    current = if let Some((next_char_pos, _)) = current[pos..].char_indices().nth(1) {
+                        // We make the parser start from this new location.
+                        &current[pos + next_char_pos..]
+                    } else {
+                        break;
+                    };
+                    diff_len = fmt_str.len() - current.len();
+                    parser = Parser::new(current, None, None, false, ParseMode::Format);
+                } else if let Piece::NextArgument(arg) = piece {
+                    let mut pos = arg.position_span;
+                    pos.start += diff_len;
+                    pos.end += diff_len;
+
+                    let start = fmt_str[..pos.start].rfind('{').unwrap_or(pos.start);
+                    // If this is a unicode character escape, we don't want to lint.
+                    if start > 1 && fmt_str[..start].ends_with("\\u") {
+                        continue;
+                    }
+
+                    if fmt_str[start + 1..].trim_start().starts_with('}') {
+                        // We ignore `{}`.
+                        continue;
+                    }
+
+                    let end = fmt_str[start + 1..]
+                        .find('}')
+                        .map_or(pos.end, |found| start + 1 + found)
+                        + 1;
+                    let ident_start = start + 1;
+                    let colon_pos = fmt_str[ident_start..end].find(':');
+                    let ident_end = colon_pos.unwrap_or(end - 1);
+                    let mut name = None;
+                    if ident_start < ident_end
+                        && let arg = &fmt_str[ident_start..ident_end]
+                        && !arg.is_empty()
+                        && is_ident(arg)
+                    {
+                        name = Some(arg.to_string());
+                    } else if colon_pos.is_none() {
+                        // Not a `{:?}`.
+                        continue;
+                    }
+                    spans.push((
+                        expr.span
+                            .with_hi(lo + BytePos((start + add).try_into().unwrap()))
+                            .with_lo(lo + BytePos((end + add).try_into().unwrap())),
+                        name,
+                    ));
+                }
+            }
+            emit_lint(cx, expr, &spans);
+        }
+    }
+}
diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs
index 3c77db84a405..9f3b0957eab1 100644
--- a/clippy_lints/src/manual_async_fn.rs
+++ b/clippy_lints/src/manual_async_fn.rs
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
                     if let Some(vis_snip) = vis_span.get_source_text(cx)
                         && let Some(header_snip) = header_span.get_source_text(cx)
                         && let Some(ret_pos) = position_before_rarrow(&header_snip)
-                        && let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output)
+                        && let Some((_, ret_snip)) = suggested_ret(cx, output)
                     {
                         let header_snip = if vis_snip.is_empty() {
                             format!("async {}", &header_snip[..ret_pos])
@@ -82,19 +82,14 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
                             format!("{} async {}", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos])
                         };
 
-                        let help = format!("make the function `async` and {ret_sugg}");
-                        diag.span_suggestion(
-                            header_span,
-                            help,
-                            format!("{header_snip}{ret_snip}"),
-                            Applicability::MachineApplicable,
-                        );
+                        let body_snip = snippet_block(cx, closure_body.value.span, "..", Some(block.span)).to_string();
 
-                        let body_snip = snippet_block(cx, closure_body.value.span, "..", Some(block.span));
-                        diag.span_suggestion(
-                            block.span,
-                            "move the body of the async block to the enclosing function",
-                            body_snip,
+                        diag.multipart_suggestion(
+                            "make the function `async` and return the output of the future directly",
+                            vec![
+                                (header_span, format!("{header_snip}{ret_snip}")),
+                                (block.span, body_snip),
+                            ],
                             Applicability::MachineApplicable,
                         );
                     }
diff --git a/clippy_lints/src/manual_float_methods.rs b/clippy_lints/src/manual_float_methods.rs
index 0e08e2eb83da..a1951b9da44a 100644
--- a/clippy_lints/src/manual_float_methods.rs
+++ b/clippy_lints/src/manual_float_methods.rs
@@ -5,9 +5,9 @@ use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_from_proc_macro, path_to_local};
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
 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;
@@ -129,9 +129,7 @@ fn is_not_const(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         | DefKind::Ctor(..)
         | DefKind::AssocConst => false,
 
-        DefKind::Fn
-        | DefKind::AssocFn
-        | DefKind::Closure => tcx.constness(def_id) == Constness::NotConst,
+        DefKind::Fn | DefKind::AssocFn | DefKind::Closure => tcx.constness(def_id) == Constness::NotConst,
     }
 }
 
diff --git a/clippy_lints/src/manual_is_power_of_two.rs b/clippy_lints/src/manual_is_power_of_two.rs
index 4fee3bf7aa9f..841adfec4624 100644
--- a/clippy_lints/src/manual_is_power_of_two.rs
+++ b/clippy_lints/src/manual_is_power_of_two.rs
@@ -43,21 +43,21 @@ impl LateLintPass<'_> for ManualIsPowerOfTwo {
             && bin_op.node == BinOpKind::Eq
         {
             // a.count_ones() == 1
-            if let ExprKind::MethodCall(method_name, reciever, [], _) = left.kind
+            if let ExprKind::MethodCall(method_name, receiver, [], _) = left.kind
                 && method_name.ident.as_str() == "count_ones"
-                && let &Uint(_) = cx.typeck_results().expr_ty(reciever).kind()
+                && let &Uint(_) = cx.typeck_results().expr_ty(receiver).kind()
                 && check_lit(right, 1)
             {
-                build_sugg(cx, expr, reciever, &mut applicability);
+                build_sugg(cx, expr, receiver, &mut applicability);
             }
 
             // 1 == a.count_ones()
-            if let ExprKind::MethodCall(method_name, reciever, [], _) = right.kind
+            if let ExprKind::MethodCall(method_name, receiver, [], _) = right.kind
                 && method_name.ident.as_str() == "count_ones"
-                && let &Uint(_) = cx.typeck_results().expr_ty(reciever).kind()
+                && let &Uint(_) = cx.typeck_results().expr_ty(receiver).kind()
                 && check_lit(left, 1)
             {
-                build_sugg(cx, expr, reciever, &mut applicability);
+                build_sugg(cx, expr, receiver, &mut applicability);
             }
 
             // a & (a - 1) == 0
@@ -115,8 +115,8 @@ impl LateLintPass<'_> for ManualIsPowerOfTwo {
     }
 }
 
-fn build_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, reciever: &Expr<'_>, applicability: &mut Applicability) {
-    let snippet = snippet_with_applicability(cx, reciever.span, "..", applicability);
+fn build_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, receiver: &Expr<'_>, applicability: &mut Applicability) {
+    let snippet = snippet_with_applicability(cx, receiver.span, "..", applicability);
 
     span_lint_and_sugg(
         cx,
diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs
index 20984bc40caf..b72a61a43849 100644
--- a/clippy_lints/src/matches/match_same_arms.rs
+++ b/clippy_lints/src/matches/match_same_arms.rs
@@ -74,8 +74,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
                         // check if using the same bindings as before
                         HirIdMapEntry::Occupied(entry) => return *entry.get() == b_id,
                     }
-                // the names technically don't have to match; this makes the lint more conservative
-                && cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id)
+                    // the names technically don't have to match; this makes the lint more conservative
+                    && cx.tcx.hir().name(a_id) == cx.tcx.hir().name(b_id)
                     && cx.typeck_results().expr_ty(a) == cx.typeck_results().expr_ty(b)
                     && pat_contains_local(lhs.pat, a_id)
                     && pat_contains_local(rhs.pat, b_id)
@@ -149,16 +149,12 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
                     let move_pat_snip = snippet_with_applicability(cx, move_arm.pat.span, "<pat2>", &mut appl);
                     let keep_pat_snip = snippet_with_applicability(cx, keep_arm.pat.span, "<pat1>", &mut appl);
 
-                    diag.span_suggestion(
-                        keep_arm.pat.span,
-                        "or try merging the arm patterns",
-                        format!("{keep_pat_snip} | {move_pat_snip}"),
-                        appl,
-                    )
-                    .span_suggestion(
-                        adjusted_arm_span(cx, move_arm.span),
-                        "and remove this obsolete arm",
-                        "",
+                    diag.multipart_suggestion(
+                        "or try merging the arm patterns and removing the obsolete arm",
+                        vec![
+                            (keep_arm.pat.span, format!("{keep_pat_snip} | {move_pat_snip}")),
+                            (adjusted_arm_span(cx, move_arm.span), String::new()),
+                        ],
                         appl,
                     )
                     .help("try changing either arm body");
diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs
index 64969271764c..1fd2ebcb54a6 100644
--- a/clippy_lints/src/matches/mod.rs
+++ b/clippy_lints/src/matches/mod.rs
@@ -27,7 +27,9 @@ mod wild_in_or_pats;
 use clippy_config::Conf;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::walk_span_to_context;
-use clippy_utils::{higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg};
+use clippy_utils::{
+    higher, is_direct_expn_of, is_in_const_context, is_span_match, span_contains_cfg, span_extract_comments,
+};
 use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -1059,7 +1061,28 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
                     }
 
                     redundant_pattern_match::check_match(cx, expr, ex, arms);
-                    single_match::check(cx, ex, arms, expr);
+                    let source_map = cx.tcx.sess.source_map();
+                    let mut match_comments = span_extract_comments(source_map, expr.span);
+                    // We remove comments from inside arms block.
+                    if !match_comments.is_empty() {
+                        for arm in arms {
+                            for comment in span_extract_comments(source_map, arm.body.span) {
+                                if let Some(index) = match_comments
+                                    .iter()
+                                    .enumerate()
+                                    .find(|(_, cm)| **cm == comment)
+                                    .map(|(index, _)| index)
+                                {
+                                    match_comments.remove(index);
+                                }
+                            }
+                        }
+                    }
+                    // If there are still comments, it means they are outside of the arms, therefore
+                    // we should not lint.
+                    if match_comments.is_empty() {
+                        single_match::check(cx, ex, arms, expr);
+                    }
                     match_bool::check(cx, ex, arms, expr);
                     overlapping_arms::check(cx, ex, arms);
                     match_wild_enum::check(cx, ex, arms);
diff --git a/clippy_lints/src/matches/needless_match.rs b/clippy_lints/src/matches/needless_match.rs
index 6f7d69026404..73822314b4b4 100644
--- a/clippy_lints/src/matches/needless_match.rs
+++ b/clippy_lints/src/matches/needless_match.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::{is_type_diagnostic_item, same_type_and_consts};
 use clippy_utils::{
-    eq_expr_value, get_parent_expr_for_hir, higher, is_else_clause, is_res_lang_ctor, over, path_res,
+    SpanlessEq, eq_expr_value, get_parent_expr_for_hir, higher, is_else_clause, is_res_lang_ctor, over, path_res,
     peel_blocks_with_stmt,
 };
 use rustc_errors::Applicability;
@@ -90,7 +90,9 @@ fn check_if_let_inner(cx: &LateContext<'_>, if_let: &higher::IfLet<'_>) -> bool
         }
 
         // Recursively check for each `else if let` phrase,
-        if let Some(ref nested_if_let) = higher::IfLet::hir(cx, if_else) {
+        if let Some(ref nested_if_let) = higher::IfLet::hir(cx, if_else)
+            && SpanlessEq::new(cx).eq_expr(nested_if_let.let_expr, if_let.let_expr)
+        {
             return check_if_let_inner(cx, nested_if_let);
         }
 
diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs
index 95a4bf6f60de..3ca20479f8e0 100644
--- a/clippy_lints/src/matches/single_match.rs
+++ b/clippy_lints/src/matches/single_match.rs
@@ -129,7 +129,7 @@ fn report_single_pattern(cx: &LateContext<'_>, ex: &Expr<'_>, arm: &Arm<'_>, exp
             PatKind::Lit(Expr {
                 kind: ExprKind::Lit(lit),
                 ..
-            }) if lit.node.is_str() => pat_ref_count + 1,
+            }) if lit.node.is_str() || lit.node.is_bytestr() => pat_ref_count + 1,
             _ => pat_ref_count,
         };
         // References are only implicitly added to the pattern, so no overflow here.
diff --git a/clippy_lints/src/methods/filter_map_identity.rs b/clippy_lints/src/methods/filter_map_identity.rs
index cf7f276dabb1..b04d761d4860 100644
--- a/clippy_lints/src/methods/filter_map_identity.rs
+++ b/clippy_lints/src/methods/filter_map_identity.rs
@@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::{is_expr_identity_function, is_expr_untyped_identity_function, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_hir::ExprKind;
 use rustc_lint::LateContext;
 use rustc_span::{Span, sym};
 
@@ -21,6 +22,15 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg:
     if is_trait_method(cx, expr, sym::Iterator)
         && let Some(applicability) = is_identity(cx, filter_map_arg)
     {
+        // check if the iterator is from an empty array, see issue #12653
+        if let ExprKind::MethodCall(_, recv, ..) = expr.kind
+            && let ExprKind::MethodCall(_, recv2, ..) = recv.kind
+            && let ExprKind::Array(arr) = recv2.kind
+            && arr.is_empty()
+        {
+            return;
+        }
+
         span_lint_and_sugg(
             cx,
             FILTER_MAP_IDENTITY,
diff --git a/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
index 80703618a113..1ebb71e251ab 100644
--- a/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
+++ b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
@@ -19,7 +19,7 @@ fn extract_count_with_applicability(
 ) -> Option<String> {
     let start = range.start?;
     let end = range.end?;
-    // TODO: This doens't handle if either the start or end are negative literals, or if the start is
+    // TODO: This doesn't handle if either the start or end are negative literals, or if the start is
     // not a literal. In the first case, we need to be careful about how we handle computing the
     // count to avoid overflows. In the second, we may need to add parenthesis to make the
     // suggestion correct.
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 7d1d5d69c991..810287fa5416 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1864,7 +1864,6 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```no_run
-    /// // example code where clippy issues a warning
     /// let opt: Option<u32> = None;
     ///
     /// opt.unwrap_or_else(|| 42);
@@ -3839,13 +3838,11 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```no_run
-    /// // example code where clippy issues a warning
     /// vec![Some(1)].into_iter().filter(Option::is_some);
     ///
     /// ```
     /// Use instead:
     /// ```no_run
-    /// // example code which does not raise clippy warning
     /// vec![Some(1)].into_iter().flatten();
     /// ```
     #[clippy::version = "1.77.0"]
@@ -3865,13 +3862,11 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```no_run
-    /// // example code where clippy issues a warning
     /// vec![Ok::<i32, String>(1)].into_iter().filter(Result::is_ok);
     ///
     /// ```
     /// Use instead:
     /// ```no_run
-    /// // example code which does not raise clippy warning
     /// vec![Ok::<i32, String>(1)].into_iter().flatten();
     /// ```
     #[clippy::version = "1.77.0"]
@@ -3969,7 +3964,7 @@ declare_clippy_lint! {
     ///
     /// ### Why is this bad?
     ///
-    /// In the aformentioned cases it is not necessary to call `min()` or `max()`
+    /// In the aforementioned cases it is not necessary to call `min()` or `max()`
     /// to compare values, it may even cause confusion.
     ///
     /// ### Example
@@ -4982,6 +4977,10 @@ impl Methods {
                     }
                     map_identity::check(cx, expr, recv, m_arg, name, span);
                     manual_inspect::check(cx, expr, m_arg, name, span, &self.msrv);
+                    crate::useless_conversion::check_function_application(cx, expr, recv, m_arg);
+                },
+                ("map_break" | "map_continue", [m_arg]) => {
+                    crate::useless_conversion::check_function_application(cx, expr, recv, m_arg);
                 },
                 ("map_or", [def, map]) => {
                     option_map_or_none::check(cx, expr, recv, def, map);
diff --git a/clippy_lints/src/methods/needless_option_take.rs b/clippy_lints/src/methods/needless_option_take.rs
index 829c118d2916..c41ce2481d74 100644
--- a/clippy_lints/src/methods/needless_option_take.rs
+++ b/clippy_lints/src/methods/needless_option_take.rs
@@ -1,9 +1,6 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::match_def_path;
-use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::diagnostics::span_lint_and_note;
 use clippy_utils::ty::is_type_diagnostic_item;
-use rustc_errors::Applicability;
-use rustc_hir::Expr;
+use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_span::sym;
 
@@ -11,20 +8,17 @@ use super::NEEDLESS_OPTION_TAKE;
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
     // 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) && has_expr_as_ref_path(cx, recv) {
-        let mut applicability = Applicability::MachineApplicable;
-        span_lint_and_sugg(
-            cx,
-            NEEDLESS_OPTION_TAKE,
-            expr.span,
-            "called `Option::take()` on a temporary value",
-            "try",
-            format!(
-                "{}",
-                snippet_with_applicability(cx, recv.span, "..", &mut applicability)
-            ),
-            applicability,
-        );
+    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(
+                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"),
+            );
+        }
     }
 }
 
@@ -33,9 +27,24 @@ fn is_expr_option(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     is_type_diagnostic_item(cx, expr_type, sym::Option)
 }
 
-fn has_expr_as_ref_path(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    if let Some(ref_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
-        return match_def_path(cx, ref_id, &["core", "option", "Option", "as_ref"]);
+/// Returns the string of the function call that creates the temporary.
+/// When this function is called, we are reasonably certain that the `ExprKind` is either
+/// `Call` or `MethodCall` because we already checked that the expression is not
+/// `is_syntactic_place_expr()`.
+fn source_of_temporary_value<'a>(expr: &'a Expr<'_>) -> Option<&'a str> {
+    match expr.peel_borrows().kind {
+        ExprKind::Call(function, _) => {
+            if let ExprKind::Path(QPath::Resolved(_, func_path)) = function.kind {
+                if !func_path.segments.is_empty() {
+                    return Some(func_path.segments[0].ident.name.as_str());
+                }
+            }
+            if let ExprKind::Path(QPath::TypeRelative(_, func_path_segment)) = function.kind {
+                return Some(func_path_segment.ident.name.as_str());
+            }
+            None
+        },
+        ExprKind::MethodCall(path_segment, ..) => Some(path_segment.ident.name.as_str()),
+        _ => None,
     }
-    false
 }
diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs
index c91be33b1cd0..c6d4ef5911ee 100644
--- a/clippy_lints/src/methods/str_splitn.rs
+++ b/clippy_lints/src/methods/str_splitn.rs
@@ -129,7 +129,7 @@ fn check_manual_split_once_indirect(
     let ctxt = expr.span.ctxt();
     let mut parents = cx.tcx.hir().parent_iter(expr.hir_id);
     if let (_, Node::LetStmt(local)) = parents.next()?
-        && let PatKind::Binding(BindingMode::MUT, iter_binding_id, iter_ident, None) = local.pat.kind
+        && let PatKind::Binding(BindingMode::MUT, iter_binding_id, _, None) = local.pat.kind
         && let (iter_stmt_id, Node::Stmt(_)) = parents.next()?
         && let (_, Node::Block(enclosing_block)) = parents.next()?
         && let mut stmts = enclosing_block
@@ -162,16 +162,20 @@ fn check_manual_split_once_indirect(
                 UnwrapKind::Unwrap => ".unwrap()",
                 UnwrapKind::QuestionMark => "?",
             };
-            diag.span_suggestion_verbose(
-                local.span,
-                format!("try `{r}split_once`"),
-                format!("let ({lhs}, {rhs}) = {self_snip}.{r}split_once({pat_snip}){unwrap};"),
+
+            // Add a multipart suggestion
+            diag.multipart_suggestion(
+                format!("replace with `{r}split_once`"),
+                vec![
+                    (
+                        local.span,
+                        format!("let ({lhs}, {rhs}) = {self_snip}.{r}split_once({pat_snip}){unwrap};"),
+                    ),
+                    (first.span, String::new()),  // Remove the first usage
+                    (second.span, String::new()), // Remove the second usage
+                ],
                 app,
             );
-
-            let remove_msg = format!("remove the `{iter_ident}` usages");
-            diag.span_suggestion(first.span, remove_msg.clone(), "", app);
-            diag.span_suggestion(second.span, remove_msg, "", app);
         });
     }
 
diff --git a/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 029704882dde..671c189a98e6 100644
--- a/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -6,6 +6,7 @@ use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr, path_to_local};
 use core::ops::ControlFlow;
+use itertools::Itertools;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, Expr, ExprKind, Node, PatKind};
@@ -122,14 +123,13 @@ pub fn check_for_loop_iter(
                 } else {
                     Applicability::MachineApplicable
                 };
-                diag.span_suggestion(expr.span, "use", snippet.to_owned(), applicability);
-                if !references_to_binding.is_empty() {
-                    diag.multipart_suggestion(
-                        "remove any references to the binding",
-                        references_to_binding,
-                        applicability,
-                    );
-                }
+
+                let combined = references_to_binding
+                    .into_iter()
+                    .chain(vec![(expr.span, snippet.to_owned())])
+                    .collect_vec();
+
+                diag.multipart_suggestion("remove any references to the binding", combined, applicability);
             },
         );
         return true;
diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs
index 603916e06c95..9a45b04d1a62 100644
--- a/clippy_lints/src/methods/unnecessary_sort_by.rs
+++ b/clippy_lints/src/methods/unnecessary_sort_by.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_trait_method;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::implements_trait;
+use clippy_utils::{is_trait_method, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath};
 use rustc_lint::LateContext;
@@ -211,8 +211,10 @@ pub(super) fn check<'tcx>(
                 trigger.vec_name,
                 if is_unstable { "_unstable" } else { "" },
                 trigger.closure_arg,
-                if trigger.reverse {
-                    format!("std::cmp::Reverse({})", trigger.closure_body)
+                if let Some(std_or_core) = std_or_core(cx)
+                    && trigger.reverse
+                {
+                    format!("{}::cmp::Reverse({})", std_or_core, trigger.closure_body)
                 } else {
                     trigger.closure_body.to_string()
                 },
diff --git a/clippy_lints/src/missing_const_for_thread_local.rs b/clippy_lints/src/missing_const_for_thread_local.rs
index 9a44a3c980c0..e2ca4458edaa 100644
--- a/clippy_lints/src/missing_const_for_thread_local.rs
+++ b/clippy_lints/src/missing_const_for_thread_local.rs
@@ -27,14 +27,12 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```no_run
-    /// // example code where clippy issues a warning
     /// thread_local! {
     ///     static BUF: String = String::new();
     /// }
     /// ```
     /// Use instead:
     /// ```no_run
-    /// // example code which does not raise clippy warning
     /// thread_local! {
     ///     static BUF: String = const { String::new() };
     /// }
diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs
index 9e44bb02c56f..7feff7e4d3f1 100644
--- a/clippy_lints/src/no_effect.rs
+++ b/clippy_lints/src/no_effect.rs
@@ -8,7 +8,7 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
     BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, LocalSource, Node, PatKind, Stmt, StmtKind,
-    UnsafeSource, StructTailExpr, is_range_literal,
+    StructTailExpr, UnsafeSource, is_range_literal,
 };
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
diff --git a/clippy_lints/src/operators/numeric_arithmetic.rs b/clippy_lints/src/operators/numeric_arithmetic.rs
index d369978b8be8..2083f2bf628d 100644
--- a/clippy_lints/src/operators/numeric_arithmetic.rs
+++ b/clippy_lints/src/operators/numeric_arithmetic.rs
@@ -43,8 +43,8 @@ impl Context {
             _ => (),
         }
 
-        let (_, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r));
-        if r_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() {
+        let (l_ty, r_ty) = (cx.typeck_results().expr_ty(l), cx.typeck_results().expr_ty(r));
+        if l_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() {
             span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected");
             self.expr_id = Some(expr.hir_id);
         }
diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs
index 37f5dd5583bf..031f09310590 100644
--- a/clippy_lints/src/precedence.rs
+++ b/clippy_lints/src/precedence.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 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};
@@ -12,6 +13,7 @@ declare_clippy_lint! {
     /// 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
     ///
     /// ### Why is this bad?
     /// Not everyone knows the precedence of those operators by
@@ -20,6 +22,7 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7
+    /// * `0x2345 & 0xF000 >> 12` equals 5, while `(0x2345 & 0xF000) >> 12` equals 2
     #[clippy::version = "pre 1.29.0"]
     pub PRECEDENCE,
     complexity,
@@ -51,8 +54,13 @@ impl EarlyLintPass for Precedence {
                 return;
             }
             let mut applicability = Applicability::MachineApplicable;
-            match (is_arith_expr(left), is_arith_expr(right)) {
-                (true, true) => {
+            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),
+                )
+                | (Shl | Shr, Some(Add | Div | Mul | Rem | Sub), Some(Add | Div | Mul | Rem | Sub)) => {
                     let sugg = format!(
                         "({}) {} ({})",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
@@ -61,7 +69,8 @@ impl EarlyLintPass for Precedence {
                     );
                     span_sugg(expr, sugg, applicability);
                 },
-                (true, false) => {
+                (BitAnd | BitOr | BitXor, Some(Shl | Shr | Add | Div | Mul | Rem | Sub), _)
+                | (Shl | Shr, Some(Add | Div | Mul | Rem | Sub), _) => {
                     let sugg = format!(
                         "({}) {} {}",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
@@ -70,7 +79,8 @@ impl EarlyLintPass for Precedence {
                     );
                     span_sugg(expr, sugg, applicability);
                 },
-                (false, true) => {
+                (BitAnd | BitOr | BitXor, _, Some(Shl | Shr | Add | Div | Mul | Rem | Sub))
+                | (Shl | Shr, _, Some(Add | Div | Mul | Rem | Sub)) => {
                     let sugg = format!(
                         "{} {} ({})",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
@@ -79,27 +89,20 @@ impl EarlyLintPass for Precedence {
                     );
                     span_sugg(expr, sugg, applicability);
                 },
-                (false, false) => (),
+                _ => (),
             }
         }
     }
 }
 
-fn is_arith_expr(expr: &Expr) -> bool {
+fn get_bin_opt(expr: &Expr) -> Option<BinOpKind> {
     match expr.kind {
-        ExprKind::Binary(Spanned { node: op, .. }, _, _) => is_arith_op(op),
-        _ => false,
+        ExprKind::Binary(Spanned { node: op, .. }, _, _) => Some(op),
+        _ => None,
     }
 }
 
 #[must_use]
 fn is_bit_op(op: BinOpKind) -> bool {
-    use rustc_ast::ast::BinOpKind::{BitAnd, BitOr, BitXor, Shl, Shr};
     matches!(op, BitXor | BitAnd | BitOr | Shl | Shr)
 }
-
-#[must_use]
-fn is_arith_op(op: BinOpKind) -> bool {
-    use rustc_ast::ast::BinOpKind::{Add, Div, Mul, Rem, Sub};
-    matches!(op, Add | Sub | Mul | Div | Rem)
-}
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index 77abe7151f07..ffc3b86c502e 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -59,7 +59,7 @@ pub struct QuestionMark {
     /// As for why we need this in the first place: <https://github.com/rust-lang/rust-clippy/issues/8628>
     try_block_depth_stack: Vec<u32>,
     /// Keeps track of the number of inferred return type closures we are inside, to avoid problems
-    /// with the `Err(x.into())` expansion being ambiguious.
+    /// with the `Err(x.into())` expansion being ambiguous.
     inferred_ret_closure_stack: u16,
 }
 
diff --git a/clippy_lints/src/redundant_slicing.rs b/clippy_lints/src/redundant_slicing.rs
index 8e3472b1b5a1..7038b19d2759 100644
--- a/clippy_lints/src/redundant_slicing.rs
+++ b/clippy_lints/src/redundant_slicing.rs
@@ -85,7 +85,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
             let (expr_ty, expr_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(expr));
             let (indexed_ty, indexed_ref_count) = peel_middle_ty_refs(cx.typeck_results().expr_ty(indexed));
             let parent_expr = get_parent_expr(cx, expr);
-            let needs_parens_for_prefix = parent_expr.is_some_and(|parent| parent.precedence() > ExprPrecedence::Prefix);
+            let needs_parens_for_prefix =
+                parent_expr.is_some_and(|parent| parent.precedence() > ExprPrecedence::Prefix);
 
             if expr_ty == indexed_ty {
                 if expr_ref_count > indexed_ref_count {
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index 7ae0310b6d99..83199ba0f707 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -1,6 +1,9 @@
+use std::ops::ControlFlow;
+
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::path_to_local_id;
 use clippy_utils::source::snippet;
-use clippy_utils::visitors::is_local_used;
+use clippy_utils::visitors::{Descend, Visitable, for_each_expr};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::LocalDefId;
@@ -175,9 +178,31 @@ fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second
     false
 }
 
+/// Checks if the given local is used, except for in child expression of `except`.
+///
+/// This is a version of [`is_local_used`](clippy_utils::visitors::is_local_used), used to
+/// implement the fix for <https://github.com/rust-lang/rust-clippy/issues/10780>.
+pub fn is_local_used_except<'tcx>(
+    cx: &LateContext<'tcx>,
+    visitable: impl Visitable<'tcx>,
+    id: HirId,
+    except: Option<HirId>,
+) -> bool {
+    for_each_expr(cx, visitable, |e| {
+        if except.is_some_and(|it| it == e.hir_id) {
+            ControlFlow::Continue(Descend::No)
+        } else if path_to_local_id(e, id) {
+            ControlFlow::Break(())
+        } else {
+            ControlFlow::Continue(Descend::Yes)
+        }
+    })
+    .is_some()
+}
+
 fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span) {
     let (lint, msg) = match find_init(cx, pat.hir_id) {
-        Some(expr) if is_self_shadow(cx, pat, expr, shadowed) => {
+        Some((expr, _)) if is_self_shadow(cx, pat, expr, shadowed) => {
             let msg = format!(
                 "`{}` is shadowed by itself in `{}`",
                 snippet(cx, pat.span, "_"),
@@ -185,7 +210,7 @@ fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span)
             );
             (SHADOW_SAME, msg)
         },
-        Some(expr) if is_local_used(cx, expr, shadowed) => {
+        Some((expr, except)) if is_local_used_except(cx, expr, shadowed, except) => {
             let msg = format!("`{}` is shadowed", snippet(cx, pat.span, "_"));
             (SHADOW_REUSE, msg)
         },
@@ -232,15 +257,32 @@ fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_
 
 /// Finds the "init" expression for a pattern: `let <pat> = <init>;` (or `if let`) or
 /// `match <init> { .., <pat> => .., .. }`
-fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
-    for (_, node) in cx.tcx.hir().parent_iter(hir_id) {
+///
+/// For closure arguments passed to a method call, returns the method call, and the `HirId` of the
+/// closure (which will later be skipped). This is for <https://github.com/rust-lang/rust-clippy/issues/10780>
+fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<(&'tcx Expr<'tcx>, Option<HirId>)> {
+    for (hir_id, node) in cx.tcx.hir().parent_iter(hir_id) {
         let init = match node {
-            Node::Arm(_) | Node::Pat(_) => continue,
+            Node::Arm(_) | Node::Pat(_) | Node::PatField(_) | Node::Param(_) => continue,
             Node::Expr(expr) => match expr.kind {
-                ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some(e),
+                ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some((e, None)),
+                // If we're a closure argument, then a parent call is also an associated item.
+                ExprKind::Closure(_) => {
+                    if let Some((_, node)) = cx.tcx.hir().parent_iter(hir_id).next() {
+                        match node {
+                            Node::Expr(expr) => match expr.kind {
+                                ExprKind::MethodCall(_, _, _, _) | ExprKind::Call(_, _) => Some((expr, Some(hir_id))),
+                                _ => None,
+                            },
+                            _ => None,
+                        }
+                    } else {
+                        None
+                    }
+                },
                 _ => None,
             },
-            Node::LetStmt(local) => local.init,
+            Node::LetStmt(local) => local.init.map(|init| (init, None)),
             _ => None,
         };
         return init;
diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs
index 1a5b958e6a67..c690696aefc1 100644
--- a/clippy_lints/src/significant_drop_tightening.rs
+++ b/clippy_lints/src/significant_drop_tightening.rs
@@ -99,16 +99,10 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
                                     snippet(cx, apa.last_bind_ident.span, ".."),
                                 )
                             };
-                            diag.span_suggestion_verbose(
-                                apa.first_stmt_span,
+
+                            diag.multipart_suggestion_verbose(
                                 "merge the temporary construction with its single usage",
-                                stmt,
-                                Applicability::MaybeIncorrect,
-                            );
-                            diag.span_suggestion(
-                                apa.last_stmt_span,
-                                "remove separated single usage",
-                                "",
+                                vec![(apa.first_stmt_span, stmt), (apa.last_stmt_span, String::new())],
                                 Applicability::MaybeIncorrect,
                             );
                         },
diff --git a/clippy_lints/src/single_range_in_vec_init.rs b/clippy_lints/src/single_range_in_vec_init.rs
index bb11daecc07d..9737b84cdb9c 100644
--- a/clippy_lints/src/single_range_in_vec_init.rs
+++ b/clippy_lints/src/single_range_in_vec_init.rs
@@ -86,7 +86,8 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
             return;
         };
 
-        let ExprKind::Struct(QPath::LangItem(lang_item, ..), [start, end], StructTailExpr::None) = inner_expr.kind else {
+        let ExprKind::Struct(QPath::LangItem(lang_item, ..), [start, end], StructTailExpr::None) = inner_expr.kind
+        else {
             return;
         };
 
diff --git a/clippy_lints/src/strings.rs b/clippy_lints/src/strings.rs
index e09c07060065..2925f355d0b6 100644
--- a/clippy_lints/src/strings.rs
+++ b/clippy_lints/src/strings.rs
@@ -370,12 +370,10 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```no_run
-    /// // example code where clippy issues a warning
     /// let _ = "str".to_string();
     /// ```
     /// Use instead:
     /// ```no_run
-    /// // example code which does not raise clippy warning
     /// let _ = "str".to_owned();
     /// ```
     #[clippy::version = "pre 1.29.0"]
@@ -424,13 +422,11 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```no_run
-    /// // example code where clippy issues a warning
     /// let msg = String::from("Hello World");
     /// let _ = msg.to_string();
     /// ```
     /// Use instead:
     /// ```no_run
-    /// // example code which does not raise clippy warning
     /// let msg = String::from("Hello World");
     /// let _ = msg.clone();
     /// ```
diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs
index 0702f6d1e74b..d2727968c0c9 100644
--- a/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/clippy_lints/src/unit_types/let_unit_value.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_context;
-use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source, is_local_used};
+use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -71,25 +71,38 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
                 local.span,
                 "this let-binding has unit value",
                 |diag| {
+                    let mut suggestions = Vec::new();
+
+                    // Suggest omitting the `let` binding
                     if let Some(expr) = &local.init {
                         let mut app = Applicability::MachineApplicable;
                         let snip = snippet_with_context(cx, expr.span, local.span.ctxt(), "()", &mut app).0;
-                        diag.span_suggestion(local.span, "omit the `let` binding", format!("{snip};"), app);
+                        suggestions.push((local.span, format!("{snip};")));
                     }
 
-                    if let PatKind::Binding(_, binding_hir_id, ident, ..) = local.pat.kind
+                    // If this is a binding pattern, we need to add suggestions to remove any usages
+                    // of the variable
+                    if let PatKind::Binding(_, binding_hir_id, ..) = local.pat.kind
                         && let Some(body_id) = cx.enclosing_body.as_ref()
-                        && let body = cx.tcx.hir().body(*body_id)
-                        && is_local_used(cx, body, binding_hir_id)
                     {
-                        let identifier = ident.as_str();
+                        let body = cx.tcx.hir().body(*body_id);
+
+                        // Collect variable usages
                         let mut visitor = UnitVariableCollector::new(binding_hir_id);
                         walk_body(&mut visitor, body);
-                        visitor.spans.into_iter().for_each(|span| {
-                            let msg =
-                                format!("variable `{identifier}` of type `()` can be replaced with explicit `()`");
-                            diag.span_suggestion(span, msg, "()", Applicability::MachineApplicable);
-                        });
+
+                        // Add suggestions for replacing variable usages
+                        suggestions.extend(visitor.spans.into_iter().map(|span| (span, "()".to_string())));
+                    }
+
+                    // Emit appropriate diagnostic based on whether there are usages of the let binding
+                    if !suggestions.is_empty() {
+                        let message = if suggestions.len() == 1 {
+                            "omit the `let` binding"
+                        } else {
+                            "omit the `let` binding and replace variable usages with `()`"
+                        };
+                        diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable);
                     }
                 },
             );
diff --git a/clippy_lints/src/unit_types/unit_arg.rs b/clippy_lints/src/unit_types/unit_arg.rs
index 0f4bd286145a..47d6fe7db766 100644
--- a/clippy_lints/src/unit_types/unit_arg.rs
+++ b/clippy_lints/src/unit_types/unit_arg.rs
@@ -25,13 +25,13 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         return;
     }
 
-    let (reciever, args) = match expr.kind {
+    let (receiver, args) = match expr.kind {
         ExprKind::Call(_, args) => (None, args),
         ExprKind::MethodCall(_, receiver, args, _) => (Some(receiver), args),
         _ => return,
     };
 
-    let args_to_recover = reciever
+    let args_to_recover = receiver
         .into_iter()
         .chain(args)
         .filter(|arg| {
diff --git a/clippy_lints/src/unnecessary_literal_bound.rs b/clippy_lints/src/unnecessary_literal_bound.rs
index 80ce67111261..8165a45bc5ba 100644
--- a/clippy_lints/src/unnecessary_literal_bound.rs
+++ b/clippy_lints/src/unnecessary_literal_bound.rs
@@ -17,7 +17,7 @@ declare_clippy_lint! {
     ///
     /// ### Why is this bad?
     ///
-    /// This leaves the caller unable to use the `&str` as `&'static str`, causing unneccessary allocations or confusion.
+    /// This leaves the caller unable to use the `&str` as `&'static str`, causing unnecessary allocations or confusion.
     /// This is also most likely what you meant to write.
     ///
     /// ### Example
diff --git a/clippy_lints/src/unnecessary_struct_initialization.rs b/clippy_lints/src/unnecessary_struct_initialization.rs
index 0a90d31db7e1..1df229c330eb 100644
--- a/clippy_lints/src/unnecessary_struct_initialization.rs
+++ b/clippy_lints/src/unnecessary_struct_initialization.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_copy;
 use clippy_utils::{get_parent_expr, path_to_local};
-use rustc_hir::{BindingMode, Expr, ExprField, ExprKind, Node, PatKind, Path, QPath, UnOp, StructTailExpr};
+use rustc_hir::{BindingMode, Expr, ExprField, ExprKind, Node, PatKind, Path, QPath, StructTailExpr, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
@@ -63,7 +63,9 @@ impl LateLintPass<'_> for UnnecessaryStruct {
                 // all fields match, no base given
                 path.span
             },
-            (Some(path), StructTailExpr::Base(base)) if base_is_suitable(cx, expr, base) && path_matches_base(path, base) => {
+            (Some(path), StructTailExpr::Base(base))
+                if base_is_suitable(cx, expr, base) && path_matches_base(path, base) =>
+            {
                 // all fields match, has base: ensure that the path of the base matches
                 base.span
             },
diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs
index 3b05abc546f4..7ffab81a5444 100644
--- a/clippy_lints/src/useless_conversion.rs
+++ b/clippy_lints/src/useless_conversion.rs
@@ -1,8 +1,10 @@
 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::sugg::Sugg;
+use clippy_utils::sugg::{DiagExt as _, Sugg};
 use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts};
-use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, path_to_local};
+use clippy_utils::{
+    get_parent_expr, is_inherent_method_call, is_trait_item, is_trait_method, is_ty_alias, path_to_local,
+};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, Expr, ExprKind, HirId, MatchSource, Node, PatKind};
@@ -10,7 +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::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
+use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, sym};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
@@ -382,3 +384,50 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
         }
     }
 }
+
+/// Check if `arg` is a `Into::into` or `From::from` applied to `receiver` to give `expr`, through a
+/// higher-order mapping function.
+pub fn check_function_application(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Expr<'_>) {
+    if has_eligible_receiver(cx, recv, expr)
+        && (is_trait_item(cx, arg, sym::Into) || is_trait_item(cx, arg, sym::From))
+        && let ty::FnDef(_, args) = cx.typeck_results().expr_ty(arg).kind()
+        && let &[from_ty, to_ty] = args.into_type_list(cx.tcx).as_slice()
+        && same_type_and_consts(from_ty, to_ty)
+    {
+        span_lint_and_then(
+            cx,
+            USELESS_CONVERSION,
+            expr.span.with_lo(recv.span.hi()),
+            format!("useless conversion to the same type: `{from_ty}`"),
+            |diag| {
+                diag.suggest_remove_item(
+                    cx,
+                    expr.span.with_lo(recv.span.hi()),
+                    "consider removing",
+                    Applicability::MachineApplicable,
+                );
+            },
+        );
+    }
+}
+
+fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>) -> bool {
+    let recv_ty = cx.typeck_results().expr_ty(recv);
+    if is_inherent_method_call(cx, expr)
+        && let Some(recv_ty_defid) = recv_ty.ty_adt_def().map(AdtDef::did)
+    {
+        if let Some(diag_name) = cx.tcx.get_diagnostic_name(recv_ty_defid)
+            && matches!(diag_name, sym::Option | sym::Result)
+        {
+            return true;
+        }
+
+        if cx.tcx.is_diagnostic_item(sym::ControlFlow, recv_ty_defid) {
+            return true;
+        }
+    }
+    if is_trait_method(cx, expr, sym::Iterator) {
+        return true;
+    }
+    false
+}
diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs
index 521bf6a5fede..d2970c93f8e9 100644
--- a/clippy_lints/src/utils/author.rs
+++ b/clippy_lints/src/utils/author.rs
@@ -3,8 +3,8 @@ use rustc_ast::LitIntType;
 use rustc_ast::ast::{LitFloatType, LitKind};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::{
-    self as hir, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind,
-    ExprKind, FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, TyKind, StructTailExpr,
+    self as hir, BindingMode, CaptureBy, Closure, ClosureKind, ConstArg, ConstArgKind, CoroutineKind, ExprKind,
+    FnRetTy, HirId, Lit, PatKind, QPath, StmtKind, StructTailExpr, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::declare_lint_pass;
@@ -625,7 +625,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
             },
             ExprKind::UnsafeBinderCast(..) => {
                 unimplemented!("unsafe binders are not implemented yet");
-            }
+            },
         }
     }
 
diff --git a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
index 5483e80f932e..bfcce81c498a 100644
--- a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
+++ b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
@@ -1,8 +1,7 @@
 use crate::utils::internal_lints::lint_without_lint_pass::is_lint_ref_type;
 use clippy_utils::diagnostics::span_lint_and_help;
 use regex::Regex;
-use rustc_ast as ast;
-use rustc_hir::{Item, ItemKind, Mutability};
+use rustc_hir::{Attribute, Item, ItemKind, Mutability};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 
@@ -51,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation {
                 .hir()
                 .attrs(item.hir_id())
                 .iter()
-                .filter_map(|attr| ast::Attribute::doc_str(attr).map(|sym| (sym, attr)));
+                .filter_map(|attr| Attribute::doc_str(attr).map(|sym| (sym, attr)));
             if is_lint_ref_type(cx, ty) {
                 for (line, attr) in lines {
                     let cur_line = line.as_str().trim();
diff --git a/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
index 9e400d2391f0..e454427adde1 100644
--- a/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
+++ b/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
@@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if let ExprKind::Call(func, [arg]) = &expr.kind
             && let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(func).kind()
-            && match_def_path(cx, *def_id, &paths::SYMBOL_INTERN)
+            && cx.tcx.is_diagnostic_item(sym::SymbolIntern, *def_id)
             && let Some(Constant::Str(arg)) = ConstEvalCtxt::new(cx).eval_simple(arg)
             && let value = Symbol::intern(&arg).as_u32()
             && let Some(&def_id) = self.symbol_map.get(&value)
diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index 496343d82c8d..dac1951489ca 100644
--- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -3,6 +3,7 @@ use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::{is_lint_allowed, match_def_path, paths};
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
+use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_hir::intravisit::Visitor;
@@ -13,7 +14,6 @@ use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, sym};
-use {rustc_ast as ast, rustc_hir as hir};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -249,11 +249,11 @@ fn check_invalid_clippy_version_attribute(cx: &LateContext<'_>, item: &'_ Item<'
 pub(super) fn extract_clippy_version_value(cx: &LateContext<'_>, item: &'_ Item<'_>) -> Option<Symbol> {
     let attrs = cx.tcx.hir().attrs(item.hir_id());
     attrs.iter().find_map(|attr| {
-        if let ast::AttrKind::Normal(attr_kind) = &attr.kind
+        if let hir::AttrKind::Normal(attr_kind) = &attr.kind
             // Identify attribute
-            && let [tool_name, attr_name] = &attr_kind.item.path.segments[..]
-            && tool_name.ident.name == sym::clippy
-            && attr_name.ident.name == sym::version
+            && let [tool_name, attr_name] = &attr_kind.path.segments[..]
+            && tool_name.name == sym::clippy
+            && attr_name.name == sym::version
             && let Some(version) = attr.value_str()
         {
             Some(version)
diff --git a/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs b/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
index 3742be0e103d..49aad881994e 100644
--- a/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
+++ b/clippy_lints/src/utils/internal_lints/slow_symbol_comparisons.rs
@@ -1,29 +1,29 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::paths;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::match_type;
-use clippy_utils::{match_function_call, paths};
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::Span;
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
     ///
-    /// Detects symbol comparision using `Symbol::intern`.
+    /// Detects symbol comparison using `Symbol::intern`.
     ///
     /// ### Why is this bad?
     ///
-    /// Comparision via `Symbol::as_str()` is faster if the interned symbols are not reused.
+    /// Comparison via `Symbol::as_str()` is faster if the interned symbols are not reused.
     ///
     /// ### Example
     ///
     /// None, see suggestion.
     pub SLOW_SYMBOL_COMPARISONS,
     internal,
-    "detects slow comparisions of symbol"
+    "detects slow comparisons of symbol"
 }
 
 declare_lint_pass!(SlowSymbolComparisons => [SLOW_SYMBOL_COMPARISONS]);
@@ -34,7 +34,12 @@ fn check_slow_comparison<'tcx>(
     op2: &'tcx Expr<'tcx>,
 ) -> Option<(Span, String)> {
     if match_type(cx, cx.typeck_results().expr_ty(op1), &paths::SYMBOL)
-        && let Some([symbol_name_expr]) = match_function_call(cx, op2, &paths::SYMBOL_INTERN)
+        && let ExprKind::Call(fun, args) = op2.kind
+        && let ExprKind::Path(ref qpath) = fun.kind
+        && cx
+            .tcx
+            .is_diagnostic_item(sym::SymbolIntern, cx.qpath_res(qpath, fun.hir_id).opt_def_id()?)
+        && let [symbol_name_expr] = args
         && let Some(Constant::Str(symbol_name)) = ConstEvalCtxt::new(cx).eval_simple(symbol_name_expr)
     {
         Some((op1.span, symbol_name))
diff --git a/clippy_lints/src/zombie_processes.rs b/clippy_lints/src/zombie_processes.rs
index 4a13c10166f8..a702e0785a96 100644
--- a/clippy_lints/src/zombie_processes.rs
+++ b/clippy_lints/src/zombie_processes.rs
@@ -2,13 +2,14 @@ use ControlFlow::{Break, Continue};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{fn_def_id, get_enclosing_block, match_any_def_paths, match_def_path, path_to_local_id, paths};
 use rustc_ast::Mutability;
+use rustc_ast::visit::visit_opt;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_local};
 use rustc_hir::{Expr, ExprKind, HirId, LetStmt, Node, PatKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 use std::ops::ControlFlow;
 
 declare_clippy_lint! {
@@ -22,6 +23,17 @@ declare_clippy_lint! {
     /// which can eventually lead to resource exhaustion, so it's recommended to call `wait()` in long-running applications.
     /// Such processes are called "zombie processes".
     ///
+    /// To reduce the rate of false positives, if the spawned process is assigned to a binding, the lint actually works the other way around; it
+    /// conservatively checks that all uses of a variable definitely don't call `wait()` and only then emits a warning.
+    /// For that reason, a seemingly unrelated use can get called out as calling `wait()` in help messages.
+    ///
+    /// ### Control flow
+    /// If a `wait()` call exists in an if/then block but not in the else block (or there is no else block),
+    /// then this still gets linted as not calling `wait()` in all code paths.
+    /// Likewise, when early-returning from the function, `wait()` calls that appear after the return expression
+    /// are also not accepted.
+    /// In other words, the `wait()` call must be unconditionally reachable after the spawn expression.
+    ///
     /// ### Example
     /// ```rust
     /// use std::process::Command;
@@ -53,26 +65,47 @@ impl<'tcx> LateLintPass<'tcx> for ZombieProcesses {
                     if let PatKind::Binding(_, local_id, ..) = local.pat.kind
                         && let Some(enclosing_block) = get_enclosing_block(cx, expr.hir_id) =>
                 {
-                    let mut vis = WaitFinder::WalkUpTo(cx, local_id);
-
-                    // If it does have a `wait()` call, we're done. Don't lint.
-                    if let Break(BreakReason::WaitFound) = walk_block(&mut vis, enclosing_block) {
-                        return;
-                    }
+                    let mut vis = WaitFinder {
+                        cx,
+                        local_id,
+                        state: VisitorState::WalkUpToLocal,
+                        early_return: None,
+                        missing_wait_branch: None,
+                    };
+
+                    let res = (
+                        walk_block(&mut vis, enclosing_block),
+                        vis.missing_wait_branch,
+                        vis.early_return,
+                    );
+
+                    let cause = match res {
+                        (Break(MaybeWait(wait_span)), _, Some(return_span)) => {
+                            Cause::EarlyReturn { wait_span, return_span }
+                        },
+                        (Break(MaybeWait(_)), _, None) => return,
+                        (Continue(()), None, _) => Cause::NeverWait,
+                        (Continue(()), Some(MissingWaitBranch::MissingElse { if_span, wait_span }), _) => {
+                            Cause::MissingElse { wait_span, if_span }
+                        },
+                        (Continue(()), Some(MissingWaitBranch::MissingWaitInBranch { branch_span, wait_span }), _) => {
+                            Cause::MissingWaitInBranch { wait_span, branch_span }
+                        },
+                    };
 
                     // Don't emit a suggestion since the binding is used later
-                    check(cx, expr, false);
+                    check(cx, expr, cause, false);
                 },
                 Node::LetStmt(&LetStmt { pat, .. }) if let PatKind::Wild = pat.kind => {
                     // `let _ = child;`, also dropped immediately without `wait()`ing
-                    check(cx, expr, true);
+                    check(cx, expr, Cause::NeverWait, true);
                 },
                 Node::Stmt(&Stmt {
                     kind: StmtKind::Semi(_),
                     ..
                 }) => {
                     // Immediately dropped. E.g. `std::process::Command::new("echo").spawn().unwrap();`
-                    check(cx, expr, true);
+                    check(cx, expr, Cause::NeverWait, true);
                 },
                 _ => {},
             }
@@ -80,21 +113,10 @@ impl<'tcx> LateLintPass<'tcx> for ZombieProcesses {
     }
 }
 
-enum BreakReason {
-    WaitFound,
-    EarlyReturn,
-}
+struct MaybeWait(Span);
 
 /// A visitor responsible for finding a `wait()` call on a local variable.
 ///
-/// Conditional `wait()` calls are assumed to not call wait:
-/// ```ignore
-/// let mut c = Command::new("").spawn().unwrap();
-/// if true {
-///     c.wait();
-/// }
-/// ```
-///
 /// Note that this visitor does NOT explicitly look for `wait()` calls directly, but rather does the
 /// inverse -- checking if all uses of the local are either:
 /// - a field access (`child.{stderr,stdin,stdout}`)
@@ -104,43 +126,50 @@ enum BreakReason {
 ///
 /// None of these are sufficient to prevent zombie processes.
 /// Doing it like this means more FNs, but FNs are better than FPs.
-///
-/// `return` expressions, conditional or not, short-circuit the visitor because
-/// if a `wait()` call hadn't been found at that point, it might never reach one at a later point:
-/// ```ignore
-/// let mut c = Command::new("").spawn().unwrap();
-/// if true {
-///     return; // Break(BreakReason::EarlyReturn)
-/// }
-/// c.wait(); // this might not be reachable
-/// ```
-enum WaitFinder<'a, 'tcx> {
-    WalkUpTo(&'a LateContext<'tcx>, HirId),
-    Found(&'a LateContext<'tcx>, HirId),
+struct WaitFinder<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    local_id: HirId,
+    state: VisitorState,
+    early_return: Option<Span>,
+    // When joining two if branches where one of them doesn't call `wait()`, stores its span for more targetted help
+    // messages
+    missing_wait_branch: Option<MissingWaitBranch>,
+}
+
+#[derive(PartialEq)]
+enum VisitorState {
+    WalkUpToLocal,
+    LocalFound,
+}
+
+#[derive(Copy, Clone)]
+enum MissingWaitBranch {
+    MissingElse { if_span: Span, wait_span: Span },
+    MissingWaitInBranch { branch_span: Span, wait_span: Span },
 }
 
 impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
-    type Result = ControlFlow<BreakReason>;
+    type Result = ControlFlow<MaybeWait>;
 
     fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) -> Self::Result {
-        if let Self::WalkUpTo(cx, local_id) = *self
+        if self.state == VisitorState::WalkUpToLocal
             && let PatKind::Binding(_, pat_id, ..) = l.pat.kind
-            && local_id == pat_id
+            && self.local_id == pat_id
         {
-            *self = Self::Found(cx, local_id);
+            self.state = VisitorState::LocalFound;
         }
 
         walk_local(self, l)
     }
 
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {
-        let Self::Found(cx, local_id) = *self else {
+        if self.state != VisitorState::LocalFound {
             return walk_expr(self, ex);
-        };
+        }
 
-        if path_to_local_id(ex, local_id) {
-            match cx.tcx.parent_hir_node(ex.hir_id) {
+        if path_to_local_id(ex, self.local_id) {
+            match self.cx.tcx.parent_hir_node(ex.hir_id) {
                 Node::Stmt(Stmt {
                     kind: StmtKind::Semi(_),
                     ..
@@ -148,29 +177,33 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
                 Node::Expr(expr) if let ExprKind::Field(..) = expr.kind => {},
                 Node::Expr(expr) if let ExprKind::AddrOf(_, Mutability::Not, _) = expr.kind => {},
                 Node::Expr(expr)
-                    if let Some(fn_did) = fn_def_id(cx, expr)
-                        && match_any_def_paths(cx, fn_did, &[&paths::CHILD_ID, &paths::CHILD_KILL]).is_some() => {},
+                    if let Some(fn_did) = fn_def_id(self.cx, expr)
+                        && match_any_def_paths(self.cx, fn_did, &[&paths::CHILD_ID, &paths::CHILD_KILL]).is_some() => {
+                },
 
                 // Conservatively assume that all other kinds of nodes call `.wait()` somehow.
-                _ => return Break(BreakReason::WaitFound),
+                _ => return Break(MaybeWait(ex.span)),
             }
         } else {
             match ex.kind {
-                ExprKind::Ret(..) => return Break(BreakReason::EarlyReturn),
+                ExprKind::Ret(e) => {
+                    visit_opt!(self, visit_expr, e);
+                    if self.early_return.is_none() {
+                        self.early_return = Some(ex.span);
+                    }
+
+                    return Continue(());
+                },
                 ExprKind::If(cond, then, None) => {
                     walk_expr(self, cond)?;
 
-                    // A `wait()` call in an if expression with no else is not enough:
-                    //
-                    // let c = spawn();
-                    // if true {
-                    //   c.wait();
-                    // }
-                    //
-                    // This might not call wait(). However, early returns are propagated,
-                    // because they might lead to a later wait() not being called.
-                    if let Break(BreakReason::EarlyReturn) = walk_expr(self, then) {
-                        return Break(BreakReason::EarlyReturn);
+                    if let Break(MaybeWait(wait_span)) = walk_expr(self, then)
+                        && self.missing_wait_branch.is_none()
+                    {
+                        self.missing_wait_branch = Some(MissingWaitBranch::MissingElse {
+                            if_span: ex.span,
+                            wait_span,
+                        });
                     }
 
                     return Continue(());
@@ -179,22 +212,31 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
                 ExprKind::If(cond, then, Some(else_)) => {
                     walk_expr(self, cond)?;
 
-                    #[expect(clippy::unnested_or_patterns)]
                     match (walk_expr(self, then), walk_expr(self, else_)) {
-                        (Continue(()), Continue(()))
+                        (Continue(()), Continue(())) => {},
 
                         // `wait()` in one branch but nothing in the other does not count
-                        | (Continue(()), Break(BreakReason::WaitFound))
-                        | (Break(BreakReason::WaitFound), Continue(())) => {},
-
-                        // `wait()` in both branches is ok
-                        (Break(BreakReason::WaitFound), Break(BreakReason::WaitFound)) => {
-                            return Break(BreakReason::WaitFound);
+                        (Continue(()), Break(MaybeWait(wait_span))) => {
+                            if self.missing_wait_branch.is_none() {
+                                self.missing_wait_branch = Some(MissingWaitBranch::MissingWaitInBranch {
+                                    branch_span: ex.span.shrink_to_lo().to(then.span),
+                                    wait_span,
+                                });
+                            }
+                        },
+                        (Break(MaybeWait(wait_span)), Continue(())) => {
+                            if self.missing_wait_branch.is_none() {
+                                self.missing_wait_branch = Some(MissingWaitBranch::MissingWaitInBranch {
+                                    branch_span: then.span.shrink_to_hi().to(else_.span),
+                                    wait_span,
+                                });
+                            }
                         },
 
-                        // Propagate early returns in either branch
-                        (Break(BreakReason::EarlyReturn), _) | (_, Break(BreakReason::EarlyReturn)) => {
-                            return Break(BreakReason::EarlyReturn);
+                        // `wait()` in both branches is ok
+                        (Break(MaybeWait(wait_span)), Break(MaybeWait(_))) => {
+                            self.missing_wait_branch = None;
+                            return Break(MaybeWait(wait_span));
                         },
                     }
 
@@ -208,8 +250,40 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
     }
 
     fn nested_visit_map(&mut self) -> Self::Map {
-        let (Self::Found(cx, _) | Self::WalkUpTo(cx, _)) = self;
-        cx.tcx.hir()
+        self.cx.tcx.hir()
+    }
+}
+
+#[derive(Copy, Clone)]
+enum Cause {
+    /// No call to `wait()` at all
+    NeverWait,
+    /// `wait()` call exists, but not all code paths definitely lead to one due to
+    /// an early return
+    EarlyReturn { wait_span: Span, return_span: Span },
+    /// `wait()` call exists in some if branches but not this one
+    MissingWaitInBranch { wait_span: Span, branch_span: Span },
+    /// `wait()` call exists in an if/then branch but it is missing an else block
+    MissingElse { wait_span: Span, if_span: Span },
+}
+
+impl Cause {
+    fn message(self) -> &'static str {
+        match self {
+            Cause::NeverWait => "spawned process is never `wait()`ed on",
+            Cause::EarlyReturn { .. } | Cause::MissingWaitInBranch { .. } | Cause::MissingElse { .. } => {
+                "spawned process is not `wait()`ed on in all code paths"
+            },
+        }
+    }
+
+    fn fallback_help(self) -> &'static str {
+        match self {
+            Cause::NeverWait => "consider calling `.wait()`",
+            Cause::EarlyReturn { .. } | Cause::MissingWaitInBranch { .. } | Cause::MissingElse { .. } => {
+                "consider calling `.wait()` in all code paths"
+            },
+        }
     }
 }
 
@@ -220,7 +294,7 @@ impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
 /// `let _ = <expr that spawns child>;`.
 ///
 /// This checks if the program doesn't unconditionally exit after the spawn expression.
-fn check<'tcx>(cx: &LateContext<'tcx>, spawn_expr: &'tcx Expr<'tcx>, emit_suggestion: bool) {
+fn check<'tcx>(cx: &LateContext<'tcx>, spawn_expr: &'tcx Expr<'tcx>, cause: Cause, emit_suggestion: bool) {
     let Some(block) = get_enclosing_block(cx, spawn_expr.hir_id) else {
         return;
     };
@@ -234,27 +308,46 @@ fn check<'tcx>(cx: &LateContext<'tcx>, spawn_expr: &'tcx Expr<'tcx>, emit_sugges
         return;
     }
 
-    span_lint_and_then(
-        cx,
-        ZOMBIE_PROCESSES,
-        spawn_expr.span,
-        "spawned process is never `wait()`ed on",
-        |diag| {
-            if emit_suggestion {
-                diag.span_suggestion(
-                    spawn_expr.span.shrink_to_hi(),
-                    "try",
-                    ".wait()",
-                    Applicability::MaybeIncorrect,
+    span_lint_and_then(cx, ZOMBIE_PROCESSES, spawn_expr.span, cause.message(), |diag| {
+        match cause {
+            Cause::EarlyReturn { wait_span, return_span } => {
+                diag.span_note(
+                    return_span,
+                    "no `wait()` call exists on the code path to this early return",
                 );
-            } else {
-                diag.note("consider calling `.wait()`");
-            }
+                diag.span_note(
+                    wait_span,
+                    "`wait()` call exists, but it is unreachable due to the early return",
+                );
+            },
+            Cause::MissingWaitInBranch { wait_span, branch_span } => {
+                diag.span_note(branch_span, "`wait()` is not called in this if branch");
+                diag.span_note(wait_span, "`wait()` is called in the other branch");
+            },
+            Cause::MissingElse { if_span, wait_span } => {
+                diag.span_note(
+                    if_span,
+                    "this if expression has a `wait()` call, but it is missing an else block",
+                );
+                diag.span_note(wait_span, "`wait()` called here");
+            },
+            Cause::NeverWait => {},
+        }
+
+        if emit_suggestion {
+            diag.span_suggestion(
+                spawn_expr.span.shrink_to_hi(),
+                "try",
+                ".wait()",
+                Applicability::MaybeIncorrect,
+            );
+        } else {
+            diag.help(cause.fallback_help());
+        }
 
-            diag.note("not doing so might leave behind zombie processes")
-                .note("see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning");
-        },
-    );
+        diag.note("not doing so might leave behind zombie processes")
+            .note("see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning");
+    });
 }
 
 /// Checks if the given expression exits the process.
diff --git a/clippy_utils/README.md b/clippy_utils/README.md
index 61476a82ba00..73fefbcd5705 100644
--- a/clippy_utils/README.md
+++ b/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2024-11-28
+nightly-2024-12-26
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils/mod.rs
similarity index 100%
rename from clippy_utils/src/ast_utils.rs
rename to clippy_utils/src/ast_utils/mod.rs
diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs
index 922afffb8767..09de5c055379 100644
--- a/clippy_utils/src/attrs.rs
+++ b/clippy_utils/src/attrs.rs
@@ -133,11 +133,7 @@ fn parse_attrs<F: FnMut(u64)>(sess: &Session, attrs: &[impl AttributeExt], name:
     }
 }
 
-pub fn get_unique_attr<'a, A: AttributeExt>(
-    sess: &'a Session,
-    attrs: &'a [A],
-    name: &'static str,
-) -> Option<&'a A> {
+pub fn get_unique_attr<'a, A: AttributeExt>(sess: &'a Session, attrs: &'a [A], name: &'static str) -> Option<&'a A> {
     let mut unique_attr: Option<&A> = None;
     for attr in get_attr(sess, attrs, name) {
         if let Some(duplicate) = unique_attr {
diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs
index d216879cbd25..4e12577b6df6 100644
--- a/clippy_utils/src/higher.rs
+++ b/clippy_utils/src/higher.rs
@@ -8,7 +8,7 @@ use crate::ty::is_type_diagnostic_item;
 
 use rustc_ast::ast;
 use rustc_hir as hir;
-use rustc_hir::{Arm, Block, Expr, ExprKind, StructTailExpr, HirId, LoopSource, MatchSource, Node, Pat, QPath};
+use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, LoopSource, MatchSource, Node, Pat, QPath, StructTailExpr};
 use rustc_lint::LateContext;
 use rustc_span::{Span, sym, symbol};
 
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index 4b604f658b8d..ed52c481de12 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -7,10 +7,10 @@ use rustc_data_structures::fx::FxHasher;
 use rustc_hir::MatchSource::TryDesugar;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr,
-    ExprField, ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime,
-    LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitBoundModifiers, Ty,
-    TyKind, StructTailExpr,
+    AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
+    ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName,
+    Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr, TraitBoundModifiers, Ty,
+    TyKind,
 };
 use rustc_lexer::{TokenKind, tokenize};
 use rustc_lint::LateContext;
@@ -386,7 +386,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 self.eq_qpath(l_path, r_path)
                     && match (lo, ro) {
                         (StructTailExpr::Base(l),StructTailExpr::Base(r)) => self.eq_expr(l, r),
-                        (StructTailExpr::None, StructTailExpr::None) => true,
+                        (StructTailExpr::None, StructTailExpr::None) |
                         (StructTailExpr::DefaultFields(_), StructTailExpr::DefaultFields(_)) => true,
                         _ => false,
                     }
@@ -473,10 +473,10 @@ impl HirEqInterExpr<'_, '_, '_> {
             (ConstArgKind::Anon(l_an), ConstArgKind::Anon(r_an)) => self.eq_body(l_an.body, r_an.body),
             (ConstArgKind::Infer(..), ConstArgKind::Infer(..)) => true,
             // Use explicit match for now since ConstArg is undergoing flux.
-            (ConstArgKind::Path(..), ConstArgKind::Anon(..)) | (ConstArgKind::Anon(..), ConstArgKind::Path(..))
-            | (ConstArgKind::Infer(..), _) | (_, ConstArgKind::Infer(..)) => {
-                false
-            },
+            (ConstArgKind::Path(..), ConstArgKind::Anon(..))
+            | (ConstArgKind::Anon(..), ConstArgKind::Path(..))
+            | (ConstArgKind::Infer(..), _)
+            | (_, ConstArgKind::Infer(..)) => false,
         }
     }
 
@@ -1043,7 +1043,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 if let Some(ty) = ty {
                     self.hash_ty(ty);
                 }
-            }
+            },
             ExprKind::Err(_) => {},
         }
     }
@@ -1255,7 +1255,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             },
             TyKind::UnsafeBinder(binder) => {
                 self.hash_ty(binder.inner_ty);
-            }
+            },
             TyKind::Err(_)
             | TyKind::Infer
             | TyKind::Never
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 02bbddb413a9..77c597f85348 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -1960,43 +1960,6 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool {
         })
 }
 
-/// Matches a function call with the given path and returns the arguments.
-///
-/// Usage:
-///
-/// ```rust,ignore
-/// if let Some(args) = match_function_call(cx, cmp_max_call, &paths::CMP_MAX);
-/// ```
-/// This function is deprecated. Use [`match_function_call_with_def_id`].
-pub fn match_function_call<'tcx>(
-    cx: &LateContext<'tcx>,
-    expr: &'tcx Expr<'_>,
-    path: &[&str],
-) -> Option<&'tcx [Expr<'tcx>]> {
-    if let ExprKind::Call(fun, args) = expr.kind
-        && let ExprKind::Path(ref qpath) = fun.kind
-        && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
-        && match_def_path(cx, fun_def_id, path)
-    {
-        return Some(args);
-    };
-    None
-}
-
-pub fn match_function_call_with_def_id<'tcx>(
-    cx: &LateContext<'tcx>,
-    expr: &'tcx Expr<'_>,
-    fun_def_id: DefId,
-) -> Option<&'tcx [Expr<'tcx>]> {
-    if let ExprKind::Call(fun, args) = expr.kind
-        && let ExprKind::Path(ref qpath) = fun.kind
-        && cx.qpath_res(qpath, fun.hir_id).opt_def_id() == Some(fun_def_id)
-    {
-        return Some(args);
-    };
-    None
-}
-
 /// Checks if the given `DefId` matches any of the paths. Returns the index of matching path, if
 /// any.
 ///
@@ -2273,15 +2236,19 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
 }
 
 pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
-    cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
-        attr.name_or_empty() == sym::no_std
-    })
+    cx.tcx
+        .hir()
+        .attrs(hir::CRATE_HIR_ID)
+        .iter()
+        .any(|attr| attr.name_or_empty() == sym::no_std)
 }
 
 pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
-    cx.tcx.hir().attrs(hir::CRATE_HIR_ID).iter().any(|attr| {
-        attr.name_or_empty() == sym::no_core
-    })
+    cx.tcx
+        .hir()
+        .attrs(hir::CRATE_HIR_ID)
+        .iter()
+        .any(|attr| attr.name_or_empty() == sym::no_core)
 }
 
 /// Check if parent of a hir node is a trait implementation block.
@@ -2980,12 +2947,18 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool {
 ///
 /// Comments are returned wrapped with their relevant delimiters
 pub fn span_extract_comment(sm: &SourceMap, span: Span) -> String {
+    span_extract_comments(sm, span).join("\n")
+}
+
+/// Returns all the comments a given span contains.
+///
+/// Comments are returned wrapped with their relevant delimiters.
+pub fn span_extract_comments(sm: &SourceMap, span: Span) -> Vec<String> {
     let snippet = sm.span_to_snippet(span).unwrap_or_default();
-    let res = tokenize_with_text(&snippet)
+    tokenize_with_text(&snippet)
         .filter(|(t, ..)| matches!(t, TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }))
-        .map(|(_, s, _)| s)
-        .join("\n");
-    res
+        .map(|(_, s, _)| s.to_string())
+        .collect::<Vec<_>>()
 }
 
 pub fn span_find_starting_semi(sm: &SourceMap, span: Span) -> Span {
diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs
index 1e6368fab368..98bcedecccc6 100644
--- a/clippy_utils/src/msrvs.rs
+++ b/clippy_utils/src/msrvs.rs
@@ -1,5 +1,5 @@
 use rustc_ast::attr::AttributeExt;
-use rustc_attr_parsing::{parse_version, RustcVersion};
+use rustc_attr_parsing::{RustcVersion, parse_version};
 use rustc_session::Session;
 use rustc_span::{Symbol, sym};
 use serde::Deserialize;
@@ -19,11 +19,12 @@ macro_rules! msrv_aliases {
 // names may refer to stabilized feature flags or library items
 msrv_aliases! {
     1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY }
-    1,82,0 { IS_NONE_OR, REPEAT_N }
-    1,81,0 { LINT_REASONS_STABILIZATION }
-    1,80,0 { BOX_INTO_ITER}
+    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,77,0 { C_STR_LITERALS }
     1,76,0 { PTR_FROM_REF, OPTION_RESULT_INSPECT }
+    1,74,0 { REPR_RUST }
     1,73,0 { MANUAL_DIV_CEIL }
     1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
     1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index bb40a9430a7a..8cb8cd590140 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -23,7 +23,6 @@ pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
 pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
 pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"];
 pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"];
-pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"];
 pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"];
 pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
 pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty/mod.rs
similarity index 99%
rename from clippy_utils/src/ty.rs
rename to clippy_utils/src/ty/mod.rs
index bc3c3ca5c217..32e7c2bbf7cb 100644
--- a/clippy_utils/src/ty.rs
+++ b/clippy_utils/src/ty/mod.rs
@@ -171,7 +171,7 @@ pub fn should_call_clone_as_function(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     )
 }
 
-/// Returns true if ty has `iter` or `iter_mut` methods
+/// If `ty` is known to have a `iter` or `iter_mut` method, returns a symbol representing the type.
 pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<Symbol> {
     // FIXME: instead of this hard-coded list, we should check if `<adt>::iter`
     // exists and has the desired signature. Unfortunately FnCtxt is not exported
diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs
index afceeec22726..7a3a861a9cae 100644
--- a/clippy_utils/src/visitors.rs
+++ b/clippy_utils/src/visitors.rs
@@ -7,7 +7,7 @@ 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, UnOp, UnsafeSource, StructTailExpr,
+    Stmt, StructTailExpr, UnOp, UnsafeSource,
 };
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs
index 8c62dd3ed385..03e2a24f6f98 100644
--- a/lintcheck/src/main.rs
+++ b/lintcheck/src/main.rs
@@ -17,7 +17,8 @@
 #![allow(
     clippy::collapsible_else_if,
     clippy::needless_borrows_for_generic_args,
-    clippy::module_name_repetitions
+    clippy::module_name_repetitions,
+    clippy::literal_string_with_formatting_args
 )]
 
 mod config;
diff --git a/rust-toolchain b/rust-toolchain
index fb159ca2ae03..1000d90f52a5 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2024-11-28"
+channel = "nightly-2024-12-26"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/driver.rs b/src/driver.rs
index 32ee668cda1c..75ef60a5dc8a 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -285,7 +285,7 @@ pub fn main() {
         let cap_lints_allow = arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some()
             && arg_value(&orig_args, "--force-warn", |val| val.contains("clippy::")).is_none();
 
-        // If `--no-deps` is enabled only lint the primary pacakge
+        // If `--no-deps` is enabled only lint the primary package
         let relevant_package = !no_deps || env::var("CARGO_PRIMARY_PACKAGE").is_ok();
 
         // Do not run Clippy for Cargo's info queries so that invalid CLIPPY_ARGS are not cached
@@ -303,7 +303,7 @@ pub fn main() {
                 .set_using_internal_features(using_internal_features)
                 .run();
         }
-        return Ok(());
+        Ok(())
     }))
 }
 
diff --git a/tests/ui-internal/interning_defined_symbol.fixed b/tests/ui-internal/interning_defined_symbol.fixed
index 98591e15bec4..3bcabb4ab2d3 100644
--- a/tests/ui-internal/interning_defined_symbol.fixed
+++ b/tests/ui-internal/interning_defined_symbol.fixed
@@ -23,7 +23,7 @@ fn main() {
     let _ = rustc_span::sym::proc_dash_macro;
 
     // interning a keyword
-    let _ = rustc_span::symbol::kw::SelfLower;
+    let _ = rustc_span::kw::SelfLower;
 
     // Interning a symbol that is not defined
     let _ = Symbol::intern("xyz123");
diff --git a/tests/ui-internal/interning_defined_symbol.stderr b/tests/ui-internal/interning_defined_symbol.stderr
index 6d86768d344e..c4d0308979f6 100644
--- a/tests/ui-internal/interning_defined_symbol.stderr
+++ b/tests/ui-internal/interning_defined_symbol.stderr
@@ -27,7 +27,7 @@ error: interning a defined symbol
   --> tests/ui-internal/interning_defined_symbol.rs:26:13
    |
 LL |     let _ = Symbol::intern("self");
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::symbol::kw::SelfLower`
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `rustc_span::kw::SelfLower`
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui-internal/unnecessary_symbol_str.fixed b/tests/ui-internal/unnecessary_symbol_str.fixed
index 8e7f020c1f65..3d9deb705ace 100644
--- a/tests/ui-internal/unnecessary_symbol_str.fixed
+++ b/tests/ui-internal/unnecessary_symbol_str.fixed
@@ -14,8 +14,8 @@ use rustc_span::symbol::{Ident, Symbol};
 
 fn main() {
     Symbol::intern("foo") == rustc_span::sym::clippy;
-    Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower;
-    Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper;
+    Symbol::intern("foo") == rustc_span::kw::SelfLower;
+    Symbol::intern("foo") != rustc_span::kw::SelfUpper;
     Ident::empty().name == rustc_span::sym::clippy;
     rustc_span::sym::clippy == Ident::empty().name;
 }
diff --git a/tests/ui-internal/unnecessary_symbol_str.stderr b/tests/ui-internal/unnecessary_symbol_str.stderr
index 668c11722f91..1742603eff6d 100644
--- a/tests/ui-internal/unnecessary_symbol_str.stderr
+++ b/tests/ui-internal/unnecessary_symbol_str.stderr
@@ -15,13 +15,13 @@ error: unnecessary `Symbol` to string conversion
   --> tests/ui-internal/unnecessary_symbol_str.rs:17:5
    |
 LL |     Symbol::intern("foo").to_string() == "self";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::symbol::kw::SelfLower`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") == rustc_span::kw::SelfLower`
 
 error: unnecessary `Symbol` to string conversion
   --> tests/ui-internal/unnecessary_symbol_str.rs:18:5
    |
 LL |     Symbol::intern("foo").to_ident_string() != "Self";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::symbol::kw::SelfUpper`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Symbol::intern("foo") != rustc_span::kw::SelfUpper`
 
 error: unnecessary `Symbol` to string conversion
   --> tests/ui-internal/unnecessary_symbol_str.rs:19:5
diff --git a/tests/ui-toml/indexing_slicing/clippy.toml b/tests/ui-toml/indexing_slicing/clippy.toml
new file mode 100644
index 000000000000..7e83868332f1
--- /dev/null
+++ b/tests/ui-toml/indexing_slicing/clippy.toml
@@ -0,0 +1 @@
+allow-indexing-slicing-in-tests = true
diff --git a/tests/ui-toml/indexing_slicing/indexing_slicing.rs b/tests/ui-toml/indexing_slicing/indexing_slicing.rs
new file mode 100644
index 000000000000..0a0da88ea1fa
--- /dev/null
+++ b/tests/ui-toml/indexing_slicing/indexing_slicing.rs
@@ -0,0 +1,19 @@
+//@compile-flags: --test
+#![warn(clippy::indexing_slicing)]
+#![allow(clippy::no_effect)]
+
+fn main() {
+    let x = [1, 2, 3, 4];
+    let index: usize = 1;
+    &x[index..];
+}
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn test_fn() {
+        let x = [1, 2, 3, 4];
+        let index: usize = 1;
+        &x[index..];
+    }
+}
diff --git a/tests/ui-toml/indexing_slicing/indexing_slicing.stderr b/tests/ui-toml/indexing_slicing/indexing_slicing.stderr
new file mode 100644
index 000000000000..5a4de8337b46
--- /dev/null
+++ b/tests/ui-toml/indexing_slicing/indexing_slicing.stderr
@@ -0,0 +1,12 @@
+error: slicing may panic
+  --> tests/ui-toml/indexing_slicing/indexing_slicing.rs:8:6
+   |
+LL |     &x[index..];
+   |      ^^^^^^^^^^
+   |
+   = help: consider using `.get(n..)` or .get_mut(n..)` instead
+   = note: `-D clippy::indexing-slicing` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui-toml/large_include_file/large_include_file.rs b/tests/ui-toml/large_include_file/large_include_file.rs
index 8a6dd36501cf..184c6d17ba41 100644
--- a/tests/ui-toml/large_include_file/large_include_file.rs
+++ b/tests/ui-toml/large_include_file/large_include_file.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::large_include_file)]
+#![allow(clippy::literal_string_with_formatting_args)]
 
 // Good
 const GOOD_INCLUDE_BYTES: &[u8; 68] = include_bytes!("../../ui/author.rs");
diff --git a/tests/ui-toml/large_include_file/large_include_file.stderr b/tests/ui-toml/large_include_file/large_include_file.stderr
index 9e1494a47bba..82b926cc53ba 100644
--- a/tests/ui-toml/large_include_file/large_include_file.stderr
+++ b/tests/ui-toml/large_include_file/large_include_file.stderr
@@ -1,5 +1,5 @@
 error: attempted to include a large file
-  --> tests/ui-toml/large_include_file/large_include_file.rs:13:43
+  --> tests/ui-toml/large_include_file/large_include_file.rs:14:43
    |
 LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
    |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
    = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]`
 
 error: attempted to include a large file
-  --> tests/ui-toml/large_include_file/large_include_file.rs:15:35
+  --> tests/ui-toml/large_include_file/large_include_file.rs:16:35
    |
 LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
    = note: the configuration allows a maximum size of 600 bytes
 
 error: attempted to include a large file
-  --> tests/ui-toml/large_include_file/large_include_file.rs:18:1
+  --> tests/ui-toml/large_include_file/large_include_file.rs:19:1
    |
 LL | #[doc = include_str!("too_big.txt")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed
new file mode 100644
index 000000000000..36540bf1dcf7
--- /dev/null
+++ b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.fixed
@@ -0,0 +1,24 @@
+#![deny(clippy::index_refutable_slice)]
+
+fn below_limit() {
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+    if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
+        //~^ ERROR: binding can be a slice pattern
+        // This would usually not be linted but is included now due to the
+        // index limit in the config file
+        println!("{}", slice_7);
+    }
+}
+
+fn above_limit() {
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+    if let Some(slice) = slice {
+        // This will not be linted as 8 is above the limit
+        println!("{}", slice[8]);
+    }
+}
+
+fn main() {
+    below_limit();
+    above_limit();
+}
diff --git a/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs
index e64c8ff32900..da76bb20fd96 100644
--- a/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs
+++ b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs
@@ -1,7 +1,5 @@
 #![deny(clippy::index_refutable_slice)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 fn below_limit() {
     let slice: Option<&[u32]> = Some(&[1, 2, 3]);
     if let Some(slice) = slice {
diff --git a/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.stderr b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.stderr
index 3ea600c7d7b0..022deb330e6e 100644
--- a/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.stderr
+++ b/tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.stderr
@@ -1,5 +1,5 @@
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:7:17
+  --> tests/ui-toml/max_suggested_slice_pattern_length/index_refutable_slice.rs:5:17
    |
 LL |     if let Some(slice) = slice {
    |                 ^^^^^
@@ -9,14 +9,14 @@ note: the lint level is defined here
    |
 LL | #![deny(clippy::index_refutable_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
-   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let Some([_, _, _, _, _, _, _, slice_7, ..]) = slice {
+LL |
+LL |         // This would usually not be linted but is included now due to the
+LL |         // index limit in the config file
+LL ~         println!("{}", slice_7);
    |
-LL |         println!("{}", slice_7);
-   |                        ~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index 6fa583fc0417..200129da25f5 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -6,6 +6,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allow-comparison-to-zero
            allow-dbg-in-tests
            allow-expect-in-tests
+           allow-indexing-slicing-in-tests
            allow-mixed-uninlined-format-args
            allow-one-hash-in-raw-strings
            allow-panic-in-tests
@@ -93,6 +94,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allow-comparison-to-zero
            allow-dbg-in-tests
            allow-expect-in-tests
+           allow-indexing-slicing-in-tests
            allow-mixed-uninlined-format-args
            allow-one-hash-in-raw-strings
            allow-panic-in-tests
@@ -180,6 +182,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            allow-comparison-to-zero
            allow-dbg-in-tests
            allow-expect-in-tests
+           allow-indexing-slicing-in-tests
            allow-mixed-uninlined-format-args
            allow-one-hash-in-raw-strings
            allow-panic-in-tests
diff --git a/tests/ui/as_pointer_underscore.fixed b/tests/ui/as_pointer_underscore.fixed
new file mode 100644
index 000000000000..db06486ecb04
--- /dev/null
+++ b/tests/ui/as_pointer_underscore.fixed
@@ -0,0 +1,15 @@
+#![warn(clippy::as_pointer_underscore)]
+#![crate_type = "lib"]
+#![no_std]
+
+struct S;
+
+fn f(s: &S) -> usize {
+    &s as *const &S as usize
+    //~^ ERROR: using inferred pointer cast
+}
+
+fn g(s: &mut S) -> usize {
+    s as *mut S as usize
+    //~^ ERROR: using inferred pointer cast
+}
diff --git a/tests/ui/as_pointer_underscore.rs b/tests/ui/as_pointer_underscore.rs
new file mode 100644
index 000000000000..955c702ccc99
--- /dev/null
+++ b/tests/ui/as_pointer_underscore.rs
@@ -0,0 +1,15 @@
+#![warn(clippy::as_pointer_underscore)]
+#![crate_type = "lib"]
+#![no_std]
+
+struct S;
+
+fn f(s: &S) -> usize {
+    &s as *const _ as usize
+    //~^ ERROR: using inferred pointer cast
+}
+
+fn g(s: &mut S) -> usize {
+    s as *mut _ as usize
+    //~^ ERROR: using inferred pointer cast
+}
diff --git a/tests/ui/as_pointer_underscore.stderr b/tests/ui/as_pointer_underscore.stderr
new file mode 100644
index 000000000000..270056f36454
--- /dev/null
+++ b/tests/ui/as_pointer_underscore.stderr
@@ -0,0 +1,17 @@
+error: using inferred pointer cast
+  --> tests/ui/as_pointer_underscore.rs:8:11
+   |
+LL |     &s as *const _ as usize
+   |           ^^^^^^^^ help: use explicit type: `*const &S`
+   |
+   = note: `-D clippy::as-pointer-underscore` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::as_pointer_underscore)]`
+
+error: using inferred pointer cast
+  --> tests/ui/as_pointer_underscore.rs:13:10
+   |
+LL |     s as *mut _ as usize
+   |          ^^^^^^ help: use explicit type: `*mut S`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/auxiliary/proc_macro_derive.rs b/tests/ui/auxiliary/proc_macro_derive.rs
index fbf84337382e..1815dd58f510 100644
--- a/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/tests/ui/auxiliary/proc_macro_derive.rs
@@ -2,6 +2,7 @@
 #![allow(incomplete_features)]
 #![allow(clippy::field_reassign_with_default)]
 #![allow(clippy::eq_op)]
+#![allow(clippy::literal_string_with_formatting_args)]
 
 extern crate proc_macro;
 
diff --git a/tests/ui/borrow_and_ref_as_ptr.fixed b/tests/ui/borrow_and_ref_as_ptr.fixed
new file mode 100644
index 000000000000..2950b158deb6
--- /dev/null
+++ b/tests/ui/borrow_and_ref_as_ptr.fixed
@@ -0,0 +1,11 @@
+// Make sure that `ref_as_ptr` is not emitted when `borrow_as_ptr` is.
+
+#![warn(clippy::ref_as_ptr, clippy::borrow_as_ptr)]
+
+fn f<T>(_: T) {}
+
+fn main() {
+    let mut val = 0;
+    f(&raw const val);
+    f(&raw mut val);
+}
diff --git a/tests/ui/borrow_and_ref_as_ptr.rs b/tests/ui/borrow_and_ref_as_ptr.rs
new file mode 100644
index 000000000000..19eb8f292337
--- /dev/null
+++ b/tests/ui/borrow_and_ref_as_ptr.rs
@@ -0,0 +1,11 @@
+// Make sure that `ref_as_ptr` is not emitted when `borrow_as_ptr` is.
+
+#![warn(clippy::ref_as_ptr, clippy::borrow_as_ptr)]
+
+fn f<T>(_: T) {}
+
+fn main() {
+    let mut val = 0;
+    f(&val as *const _);
+    f(&mut val as *mut i32);
+}
diff --git a/tests/ui/borrow_and_ref_as_ptr.stderr b/tests/ui/borrow_and_ref_as_ptr.stderr
new file mode 100644
index 000000000000..82a27af303c2
--- /dev/null
+++ b/tests/ui/borrow_and_ref_as_ptr.stderr
@@ -0,0 +1,17 @@
+error: borrow as raw pointer
+  --> tests/ui/borrow_and_ref_as_ptr.rs:9:7
+   |
+LL |     f(&val as *const _);
+   |       ^^^^^^^^^^^^^^^^ help: try: `&raw const val`
+   |
+   = note: `-D clippy::borrow-as-ptr` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
+
+error: borrow as raw pointer
+  --> tests/ui/borrow_and_ref_as_ptr.rs:10:7
+   |
+LL |     f(&mut val as *mut i32);
+   |       ^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/borrow_as_ptr_raw_ref.fixed b/tests/ui/borrow_as_ptr_raw_ref.fixed
new file mode 100644
index 000000000000..d6842e60a3e9
--- /dev/null
+++ b/tests/ui/borrow_as_ptr_raw_ref.fixed
@@ -0,0 +1,19 @@
+#![warn(clippy::borrow_as_ptr)]
+#![allow(clippy::useless_vec)]
+
+fn a() -> i32 {
+    0
+}
+
+#[clippy::msrv = "1.82"]
+fn main() {
+    let val = 1;
+    let _p = &raw const val;
+    let _p = &0 as *const i32;
+    let _p = &a() as *const i32;
+    let vec = vec![1];
+    let _p = &vec.len() as *const usize;
+
+    let mut val_mut = 1;
+    let _p_mut = &raw mut val_mut;
+}
diff --git a/tests/ui/borrow_as_ptr_raw_ref.rs b/tests/ui/borrow_as_ptr_raw_ref.rs
new file mode 100644
index 000000000000..3c9daed18f15
--- /dev/null
+++ b/tests/ui/borrow_as_ptr_raw_ref.rs
@@ -0,0 +1,19 @@
+#![warn(clippy::borrow_as_ptr)]
+#![allow(clippy::useless_vec)]
+
+fn a() -> i32 {
+    0
+}
+
+#[clippy::msrv = "1.82"]
+fn main() {
+    let val = 1;
+    let _p = &val as *const i32;
+    let _p = &0 as *const i32;
+    let _p = &a() as *const i32;
+    let vec = vec![1];
+    let _p = &vec.len() as *const usize;
+
+    let mut val_mut = 1;
+    let _p_mut = &mut val_mut as *mut i32;
+}
diff --git a/tests/ui/borrow_as_ptr_raw_ref.stderr b/tests/ui/borrow_as_ptr_raw_ref.stderr
new file mode 100644
index 000000000000..5611fcae8d4b
--- /dev/null
+++ b/tests/ui/borrow_as_ptr_raw_ref.stderr
@@ -0,0 +1,17 @@
+error: borrow as raw pointer
+  --> tests/ui/borrow_as_ptr_raw_ref.rs:11:14
+   |
+LL |     let _p = &val as *const i32;
+   |              ^^^^^^^^^^^^^^^^^^ help: try: `&raw const val`
+   |
+   = note: `-D clippy::borrow-as-ptr` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
+
+error: borrow as raw pointer
+  --> tests/ui/borrow_as_ptr_raw_ref.rs:18:18
+   |
+LL |     let _p_mut = &mut val_mut as *mut i32;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&raw mut val_mut`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/comparison_chain.rs b/tests/ui/comparison_chain.rs
index 266cee4c3389..cab460d100dd 100644
--- a/tests/ui/comparison_chain.rs
+++ b/tests/ui/comparison_chain.rs
@@ -1,3 +1,4 @@
+//@no-rustfix
 #![allow(dead_code)]
 #![warn(clippy::comparison_chain)]
 
@@ -238,4 +239,16 @@ const fn sign_i8(n: i8) -> Sign {
     }
 }
 
+fn needs_parens() -> &'static str {
+    let (x, y) = (1, 2);
+    if x + 1 > y * 2 {
+        //~^ ERROR: `if` chain can be rewritten with `match`
+        "aa"
+    } else if x + 1 < y * 2 {
+        "bb"
+    } else {
+        "cc"
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/comparison_chain.stderr b/tests/ui/comparison_chain.stderr
index 96d8d819e6a5..814004e3d4b1 100644
--- a/tests/ui/comparison_chain.stderr
+++ b/tests/ui/comparison_chain.stderr
@@ -1,5 +1,5 @@
 error: `if` chain can be rewritten with `match`
-  --> tests/ui/comparison_chain.rs:14:5
+  --> tests/ui/comparison_chain.rs:15:5
    |
 LL | /     if x > y {
 LL | |
@@ -7,14 +7,13 @@ LL | |         a()
 LL | |     } else if x < y {
 LL | |         b()
 LL | |     }
-   | |_____^
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`
    |
-   = help: consider rewriting the `if` chain to use `cmp` and `match`
    = note: `-D clippy::comparison-chain` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::comparison_chain)]`
 
 error: `if` chain can be rewritten with `match`
-  --> tests/ui/comparison_chain.rs:28:5
+  --> tests/ui/comparison_chain.rs:29:5
    |
 LL | /     if x > y {
 LL | |
@@ -23,12 +22,10 @@ LL | |     } else if x < y {
 ...  |
 LL | |         c()
 LL | |     }
-   | |_____^
-   |
-   = help: consider rewriting the `if` chain to use `cmp` and `match`
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`
 
 error: `if` chain can be rewritten with `match`
-  --> tests/ui/comparison_chain.rs:37:5
+  --> tests/ui/comparison_chain.rs:38:5
    |
 LL | /     if x > y {
 LL | |
@@ -37,12 +34,10 @@ LL | |     } else if y > x {
 ...  |
 LL | |         c()
 LL | |     }
-   | |_____^
-   |
-   = help: consider rewriting the `if` chain to use `cmp` and `match`
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`
 
 error: `if` chain can be rewritten with `match`
-  --> tests/ui/comparison_chain.rs:46:5
+  --> tests/ui/comparison_chain.rs:47:5
    |
 LL | /     if x > 1 {
 LL | |
@@ -51,12 +46,10 @@ LL | |     } else if x < 1 {
 ...  |
 LL | |         c()
 LL | |     }
-   | |_____^
-   |
-   = help: consider rewriting the `if` chain to use `cmp` and `match`
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&1) {...}`
 
 error: `if` chain can be rewritten with `match`
-  --> tests/ui/comparison_chain.rs:121:5
+  --> tests/ui/comparison_chain.rs:122:5
    |
 LL | /     if x > y {
 LL | |
@@ -64,12 +57,10 @@ LL | |         a()
 LL | |     } else if x < y {
 LL | |         b()
 LL | |     }
-   | |_____^
-   |
-   = help: consider rewriting the `if` chain to use `cmp` and `match`
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`
 
 error: `if` chain can be rewritten with `match`
-  --> tests/ui/comparison_chain.rs:128:5
+  --> tests/ui/comparison_chain.rs:129:5
    |
 LL | /     if x > y {
 LL | |
@@ -78,12 +69,10 @@ LL | |     } else if x < y {
 ...  |
 LL | |         c()
 LL | |     }
-   | |_____^
-   |
-   = help: consider rewriting the `if` chain to use `cmp` and `match`
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`
 
 error: `if` chain can be rewritten with `match`
-  --> tests/ui/comparison_chain.rs:137:5
+  --> tests/ui/comparison_chain.rs:138:5
    |
 LL | /     if x > y {
 LL | |
@@ -92,9 +81,19 @@ LL | |     } else if y > x {
 ...  |
 LL | |         c()
 LL | |     }
-   | |_____^
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match x.cmp(&y) {...}`
+
+error: `if` chain can be rewritten with `match`
+  --> tests/ui/comparison_chain.rs:244:5
    |
-   = help: consider rewriting the `if` chain to use `cmp` and `match`
+LL | /     if x + 1 > y * 2 {
+LL | |
+LL | |         "aa"
+LL | |     } else if x + 1 < y * 2 {
+...  |
+LL | |         "cc"
+LL | |     }
+   | |_____^ help: consider rewriting the `if` chain with `match`: `match (x + 1).cmp(&(y * 2)) {...}`
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/tests/ui/default_union_representation.rs b/tests/ui/default_union_representation.rs
index 41308b077bac..ba63cde2fa9d 100644
--- a/tests/ui/default_union_representation.rs
+++ b/tests/ui/default_union_representation.rs
@@ -1,5 +1,6 @@
 #![feature(transparent_unions)]
 #![warn(clippy::default_union_representation)]
+#![allow(clippy::repr_packed_without_abi)]
 
 union NoAttribute {
     //~^ ERROR: this union has the default representation
diff --git a/tests/ui/default_union_representation.stderr b/tests/ui/default_union_representation.stderr
index c7ef70a0b8e7..d558a3e8de1b 100644
--- a/tests/ui/default_union_representation.stderr
+++ b/tests/ui/default_union_representation.stderr
@@ -1,5 +1,5 @@
 error: this union has the default representation
-  --> tests/ui/default_union_representation.rs:4:1
+  --> tests/ui/default_union_representation.rs:5:1
    |
 LL | / union NoAttribute {
 LL | |
@@ -13,7 +13,7 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::default_union_representation)]`
 
 error: this union has the default representation
-  --> tests/ui/default_union_representation.rs:17:1
+  --> tests/ui/default_union_representation.rs:18:1
    |
 LL | / union ReprPacked {
 LL | |
@@ -25,7 +25,7 @@ LL | | }
    = help: consider annotating `ReprPacked` with `#[repr(C)]` to explicitly specify memory layout
 
 error: this union has the default representation
-  --> tests/ui/default_union_representation.rs:36:1
+  --> tests/ui/default_union_representation.rs:37:1
    |
 LL | / union ReprAlign {
 LL | |
@@ -37,7 +37,7 @@ LL | | }
    = help: consider annotating `ReprAlign` with `#[repr(C)]` to explicitly specify memory layout
 
 error: this union has the default representation
-  --> tests/ui/default_union_representation.rs:57:1
+  --> tests/ui/default_union_representation.rs:58:1
    |
 LL | / union ZSTAndTwoFields {
 LL | |
diff --git a/tests/ui/derive.rs b/tests/ui/derive.rs
index b06dd78608fd..d03cc01a08b0 100644
--- a/tests/ui/derive.rs
+++ b/tests/ui/derive.rs
@@ -2,6 +2,7 @@
     clippy::non_canonical_clone_impl,
     clippy::non_canonical_partial_ord_impl,
     clippy::needless_lifetimes,
+    clippy::repr_packed_without_abi,
     dead_code
 )]
 #![warn(clippy::expl_impl_clone_on_copy)]
diff --git a/tests/ui/derive.stderr b/tests/ui/derive.stderr
index 0eb4b3c1adaa..d70a59855229 100644
--- a/tests/ui/derive.stderr
+++ b/tests/ui/derive.stderr
@@ -1,5 +1,5 @@
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:13:1
+  --> tests/ui/derive.rs:14:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -10,7 +10,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:13:1
+  --> tests/ui/derive.rs:14:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -23,7 +23,7 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:38:1
+  --> tests/ui/derive.rs:39:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -34,7 +34,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:38:1
+  --> tests/ui/derive.rs:39:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -45,7 +45,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:50:1
+  --> tests/ui/derive.rs:51:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -56,7 +56,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:50:1
+  --> tests/ui/derive.rs:51:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -67,7 +67,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:62:1
+  --> tests/ui/derive.rs:63:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -78,7 +78,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:62:1
+  --> tests/ui/derive.rs:63:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -89,7 +89,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:83:1
+  --> tests/ui/derive.rs:84:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |
@@ -100,7 +100,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:83:1
+  --> tests/ui/derive.rs:84:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |
diff --git a/tests/ui/doc/doc_lazy_list.fixed b/tests/ui/doc/doc_lazy_list.fixed
index da537518a2b5..0822cc7c6350 100644
--- a/tests/ui/doc/doc_lazy_list.fixed
+++ b/tests/ui/doc/doc_lazy_list.fixed
@@ -75,3 +75,9 @@ fn seven() {}
 ///   ]
 //~^ ERROR: doc list item without indentation
 fn eight() {}
+
+#[rustfmt::skip]
+// https://github.com/rust-lang/rust-clippy/issues/13705
+/// - \[text in square brackets\] with a long following description
+///   that goes over multiple lines
+pub fn backslash_escaped_square_braces() {}
diff --git a/tests/ui/doc/doc_lazy_list.rs b/tests/ui/doc/doc_lazy_list.rs
index 3cc18e35780a..068de140e00a 100644
--- a/tests/ui/doc/doc_lazy_list.rs
+++ b/tests/ui/doc/doc_lazy_list.rs
@@ -75,3 +75,9 @@ fn seven() {}
 ///  ]
 //~^ ERROR: doc list item without indentation
 fn eight() {}
+
+#[rustfmt::skip]
+// https://github.com/rust-lang/rust-clippy/issues/13705
+/// - \[text in square brackets\] with a long following description
+///   that goes over multiple lines
+pub fn backslash_escaped_square_braces() {}
diff --git a/tests/ui/doc/doc_nested_refdef_blockquote.fixed b/tests/ui/doc/doc_nested_refdef_blockquote.fixed
new file mode 100644
index 000000000000..8939a03d2e3e
--- /dev/null
+++ b/tests/ui/doc/doc_nested_refdef_blockquote.fixed
@@ -0,0 +1,133 @@
+// https://github.com/rust-lang/rust/issues/133150
+#![warn(clippy::doc_nested_refdefs)]
+#[rustfmt::skip]
+/// > [link][]: def
+//~^ ERROR: link reference defined in quote
+///
+/// > [link][]: def (title)
+//~^ ERROR: link reference defined in quote
+///
+/// > [link][]: def "title"
+//~^ ERROR: link reference defined in quote
+///
+/// > [link]: not def
+///
+/// > [link][]: notdef
+///
+/// > [link]\: notdef
+pub struct Empty;
+
+#[rustfmt::skip]
+/// > [link][]: def
+//~^ ERROR: link reference defined in quote
+/// > inner text
+///
+/// > [link][]: def (title)
+//~^ ERROR: link reference defined in quote
+/// > inner text
+///
+/// > [link][]: def "title"
+//~^ ERROR: link reference defined in quote
+/// > inner text
+///
+/// > [link]: not def
+/// > inner text
+///
+/// > [link][]: notdef
+/// > inner text
+///
+/// > [link]\: notdef
+/// > inner text
+pub struct NotEmpty;
+
+#[rustfmt::skip]
+/// > [link][]: def
+//~^ ERROR: link reference defined in quote
+/// >
+/// > inner text
+///
+/// > [link][]: def (title)
+//~^ ERROR: link reference defined in quote
+/// >
+/// > inner text
+///
+/// > [link][]: def "title"
+//~^ ERROR: link reference defined in quote
+/// >
+/// > inner text
+///
+/// > [link]: not def
+/// >
+/// > inner text
+///
+/// > [link][]: notdef
+/// >
+/// > inner text
+///
+/// > [link]\: notdef
+/// >
+/// > inner text
+pub struct NotEmptyLoose;
+
+#[rustfmt::skip]
+/// > first lines
+/// > [link]: def
+///
+/// > first lines
+/// > [link]: def (title)
+///
+/// > firs lines
+/// > [link]: def "title"
+///
+/// > firs lines
+/// > [link]: not def
+///
+/// > first lines
+/// > [link][]: notdef
+///
+/// > first lines
+/// > [link]\: notdef
+pub struct NotAtStartTight;
+
+#[rustfmt::skip]
+/// > first lines
+/// >
+/// > [link]: def
+///
+/// > first lines
+/// >
+/// > [link]: def (title)
+///
+/// > firs lines
+/// >
+/// > [link]: def "title"
+///
+/// > firs lines
+/// >
+/// > [link]: not def
+///
+/// > first lines
+/// >
+/// > [link][]: notdef
+///
+/// > first lines
+/// >
+/// > [link]\: notdef
+pub struct NotAtStartLoose;
+
+#[rustfmt::skip]
+/// > - [link][]: def
+//~^ ERROR: link reference defined in list item
+/// >
+/// > - [link][]: def (title)
+//~^ ERROR: link reference defined in list item
+/// >
+/// > - [link][]: def "title"
+//~^ ERROR: link reference defined in list item
+/// >
+/// > - [link]: not def
+/// >
+/// > - [link][]: notdef
+/// >
+/// > - [link]\: notdef
+pub struct ListNested;
diff --git a/tests/ui/doc/doc_nested_refdef_blockquote.rs b/tests/ui/doc/doc_nested_refdef_blockquote.rs
new file mode 100644
index 000000000000..f861242384ba
--- /dev/null
+++ b/tests/ui/doc/doc_nested_refdef_blockquote.rs
@@ -0,0 +1,133 @@
+// https://github.com/rust-lang/rust/issues/133150
+#![warn(clippy::doc_nested_refdefs)]
+#[rustfmt::skip]
+/// > [link]: def
+//~^ ERROR: link reference defined in quote
+///
+/// > [link]: def (title)
+//~^ ERROR: link reference defined in quote
+///
+/// > [link]: def "title"
+//~^ ERROR: link reference defined in quote
+///
+/// > [link]: not def
+///
+/// > [link][]: notdef
+///
+/// > [link]\: notdef
+pub struct Empty;
+
+#[rustfmt::skip]
+/// > [link]: def
+//~^ ERROR: link reference defined in quote
+/// > inner text
+///
+/// > [link]: def (title)
+//~^ ERROR: link reference defined in quote
+/// > inner text
+///
+/// > [link]: def "title"
+//~^ ERROR: link reference defined in quote
+/// > inner text
+///
+/// > [link]: not def
+/// > inner text
+///
+/// > [link][]: notdef
+/// > inner text
+///
+/// > [link]\: notdef
+/// > inner text
+pub struct NotEmpty;
+
+#[rustfmt::skip]
+/// > [link]: def
+//~^ ERROR: link reference defined in quote
+/// >
+/// > inner text
+///
+/// > [link]: def (title)
+//~^ ERROR: link reference defined in quote
+/// >
+/// > inner text
+///
+/// > [link]: def "title"
+//~^ ERROR: link reference defined in quote
+/// >
+/// > inner text
+///
+/// > [link]: not def
+/// >
+/// > inner text
+///
+/// > [link][]: notdef
+/// >
+/// > inner text
+///
+/// > [link]\: notdef
+/// >
+/// > inner text
+pub struct NotEmptyLoose;
+
+#[rustfmt::skip]
+/// > first lines
+/// > [link]: def
+///
+/// > first lines
+/// > [link]: def (title)
+///
+/// > firs lines
+/// > [link]: def "title"
+///
+/// > firs lines
+/// > [link]: not def
+///
+/// > first lines
+/// > [link][]: notdef
+///
+/// > first lines
+/// > [link]\: notdef
+pub struct NotAtStartTight;
+
+#[rustfmt::skip]
+/// > first lines
+/// >
+/// > [link]: def
+///
+/// > first lines
+/// >
+/// > [link]: def (title)
+///
+/// > firs lines
+/// >
+/// > [link]: def "title"
+///
+/// > firs lines
+/// >
+/// > [link]: not def
+///
+/// > first lines
+/// >
+/// > [link][]: notdef
+///
+/// > first lines
+/// >
+/// > [link]\: notdef
+pub struct NotAtStartLoose;
+
+#[rustfmt::skip]
+/// > - [link]: def
+//~^ ERROR: link reference defined in list item
+/// >
+/// > - [link]: def (title)
+//~^ ERROR: link reference defined in list item
+/// >
+/// > - [link]: def "title"
+//~^ ERROR: link reference defined in list item
+/// >
+/// > - [link]: not def
+/// >
+/// > - [link][]: notdef
+/// >
+/// > - [link]\: notdef
+pub struct ListNested;
diff --git a/tests/ui/doc/doc_nested_refdef_blockquote.stderr b/tests/ui/doc/doc_nested_refdef_blockquote.stderr
new file mode 100644
index 000000000000..448659b89410
--- /dev/null
+++ b/tests/ui/doc/doc_nested_refdef_blockquote.stderr
@@ -0,0 +1,148 @@
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:4:7
+   |
+LL | /// > [link]: def
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+   = note: `-D clippy::doc-nested-refdefs` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_nested_refdefs)]`
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:7:7
+   |
+LL | /// > [link]: def (title)
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def (title)
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:10:7
+   |
+LL | /// > [link]: def "title"
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def "title"
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:21:7
+   |
+LL | /// > [link]: def
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:25:7
+   |
+LL | /// > [link]: def (title)
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def (title)
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:29:7
+   |
+LL | /// > [link]: def "title"
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def "title"
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:44:7
+   |
+LL | /// > [link]: def
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:49:7
+   |
+LL | /// > [link]: def (title)
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def (title)
+   |             ++
+
+error: link reference defined in quote
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:54:7
+   |
+LL | /// > [link]: def "title"
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > [link][]: def "title"
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:119:9
+   |
+LL | /// > - [link]: def
+   |         ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > - [link][]: def
+   |               ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:122:9
+   |
+LL | /// > - [link]: def (title)
+   |         ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > - [link][]: def (title)
+   |               ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_blockquote.rs:125:9
+   |
+LL | /// > - [link]: def "title"
+   |         ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// > - [link][]: def "title"
+   |               ++
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/doc/doc_nested_refdef_list_item.fixed b/tests/ui/doc/doc_nested_refdef_list_item.fixed
new file mode 100644
index 000000000000..fcfcfcc40736
--- /dev/null
+++ b/tests/ui/doc/doc_nested_refdef_list_item.fixed
@@ -0,0 +1,71 @@
+// https://github.com/rust-lang/rust/issues/133150
+#![warn(clippy::doc_nested_refdefs)]
+#[rustfmt::skip]
+/// - [link][]: def
+//~^ ERROR: link reference defined in list item
+///
+/// - [link][]: def (title)
+//~^ ERROR: link reference defined in list item
+///
+/// - [link][]: def "title"
+//~^ ERROR: link reference defined in list item
+///
+/// - [link]: not def
+///
+/// - [link][]: notdef
+///
+/// - [link]\: notdef
+pub struct Empty;
+
+#[rustfmt::skip]
+/// - [link][]: def
+//~^ ERROR: link reference defined in list item
+/// - [link][]: def (title)
+//~^ ERROR: link reference defined in list item
+/// - [link][]: def "title"
+//~^ ERROR: link reference defined in list item
+/// - [link]: not def
+/// - [link][]: notdef
+/// - [link]\: notdef
+pub struct EmptyTight;
+
+#[rustfmt::skip]
+/// - [link][]: def
+//~^ ERROR: link reference defined in list item
+///   inner text
+///
+/// - [link][]: def (title)
+//~^ ERROR: link reference defined in list item
+///   inner text
+///
+/// - [link][]: def "title"
+//~^ ERROR: link reference defined in list item
+///   inner text
+///
+/// - [link]: not def
+///   inner text
+///
+/// - [link][]: notdef
+///   inner text
+///
+/// - [link]\: notdef
+///   inner text
+pub struct NotEmpty;
+
+#[rustfmt::skip]
+/// - [link][]: def
+//~^ ERROR: link reference defined in list item
+///   inner text
+/// - [link][]: def (title)
+//~^ ERROR: link reference defined in list item
+///   inner text
+/// - [link][]: def "title"
+//~^ ERROR: link reference defined in list item
+///   inner text
+/// - [link]: not def
+///   inner text
+/// - [link][]: notdef
+///   inner text
+/// - [link]\: notdef
+///   inner text
+pub struct NotEmptyTight;
diff --git a/tests/ui/doc/doc_nested_refdef_list_item.rs b/tests/ui/doc/doc_nested_refdef_list_item.rs
new file mode 100644
index 000000000000..53368de4616d
--- /dev/null
+++ b/tests/ui/doc/doc_nested_refdef_list_item.rs
@@ -0,0 +1,71 @@
+// https://github.com/rust-lang/rust/issues/133150
+#![warn(clippy::doc_nested_refdefs)]
+#[rustfmt::skip]
+/// - [link]: def
+//~^ ERROR: link reference defined in list item
+///
+/// - [link]: def (title)
+//~^ ERROR: link reference defined in list item
+///
+/// - [link]: def "title"
+//~^ ERROR: link reference defined in list item
+///
+/// - [link]: not def
+///
+/// - [link][]: notdef
+///
+/// - [link]\: notdef
+pub struct Empty;
+
+#[rustfmt::skip]
+/// - [link]: def
+//~^ ERROR: link reference defined in list item
+/// - [link]: def (title)
+//~^ ERROR: link reference defined in list item
+/// - [link]: def "title"
+//~^ ERROR: link reference defined in list item
+/// - [link]: not def
+/// - [link][]: notdef
+/// - [link]\: notdef
+pub struct EmptyTight;
+
+#[rustfmt::skip]
+/// - [link]: def
+//~^ ERROR: link reference defined in list item
+///   inner text
+///
+/// - [link]: def (title)
+//~^ ERROR: link reference defined in list item
+///   inner text
+///
+/// - [link]: def "title"
+//~^ ERROR: link reference defined in list item
+///   inner text
+///
+/// - [link]: not def
+///   inner text
+///
+/// - [link][]: notdef
+///   inner text
+///
+/// - [link]\: notdef
+///   inner text
+pub struct NotEmpty;
+
+#[rustfmt::skip]
+/// - [link]: def
+//~^ ERROR: link reference defined in list item
+///   inner text
+/// - [link]: def (title)
+//~^ ERROR: link reference defined in list item
+///   inner text
+/// - [link]: def "title"
+//~^ ERROR: link reference defined in list item
+///   inner text
+/// - [link]: not def
+///   inner text
+/// - [link][]: notdef
+///   inner text
+/// - [link]\: notdef
+///   inner text
+pub struct NotEmptyTight;
diff --git a/tests/ui/doc/doc_nested_refdef_list_item.stderr b/tests/ui/doc/doc_nested_refdef_list_item.stderr
new file mode 100644
index 000000000000..27314c7e968d
--- /dev/null
+++ b/tests/ui/doc/doc_nested_refdef_list_item.stderr
@@ -0,0 +1,148 @@
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:4:7
+   |
+LL | /// - [link]: def
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+   = note: `-D clippy::doc-nested-refdefs` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_nested_refdefs)]`
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:7:7
+   |
+LL | /// - [link]: def (title)
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def (title)
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:10:7
+   |
+LL | /// - [link]: def "title"
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def "title"
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:21:7
+   |
+LL | /// - [link]: def
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:23:7
+   |
+LL | /// - [link]: def (title)
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def (title)
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:25:7
+   |
+LL | /// - [link]: def "title"
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def "title"
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:33:7
+   |
+LL | /// - [link]: def
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:37:7
+   |
+LL | /// - [link]: def (title)
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def (title)
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:41:7
+   |
+LL | /// - [link]: def "title"
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def "title"
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:56:7
+   |
+LL | /// - [link]: def
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:59:7
+   |
+LL | /// - [link]: def (title)
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def (title)
+   |             ++
+
+error: link reference defined in list item
+  --> tests/ui/doc/doc_nested_refdef_list_item.rs:62:7
+   |
+LL | /// - [link]: def "title"
+   |       ^^^^^^
+   |
+   = help: link definitions are not shown in rendered documentation
+help: for an intra-doc link, add `[]` between the label and the colon
+   |
+LL | /// - [link][]: def "title"
+   |             ++
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/filter_map_identity.fixed b/tests/ui/filter_map_identity.fixed
index f3f6848e5f92..fdd020fcd773 100644
--- a/tests/ui/filter_map_identity.fixed
+++ b/tests/ui/filter_map_identity.fixed
@@ -81,3 +81,8 @@ fn main() {
         //~^ ERROR: use of
     }
 }
+
+fn issue12653() -> impl Iterator<Item = u8> {
+    [].into_iter().filter_map(|x| x)
+    // No lint
+}
diff --git a/tests/ui/filter_map_identity.rs b/tests/ui/filter_map_identity.rs
index b9aa9c05be89..a626de9f5bbd 100644
--- a/tests/ui/filter_map_identity.rs
+++ b/tests/ui/filter_map_identity.rs
@@ -81,3 +81,8 @@ fn main() {
         //~^ ERROR: use of
     }
 }
+
+fn issue12653() -> impl Iterator<Item = u8> {
+    [].into_iter().filter_map(|x| x)
+    // No lint
+}
diff --git a/tests/ui/format.fixed b/tests/ui/format.fixed
index 2b32fdeae2b5..3dc8eb79ba28 100644
--- a/tests/ui/format.fixed
+++ b/tests/ui/format.fixed
@@ -6,7 +6,8 @@
     clippy::needless_borrow,
     clippy::uninlined_format_args,
     clippy::needless_raw_string_hashes,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::literal_string_with_formatting_args
 )]
 
 struct Foo(pub String);
diff --git a/tests/ui/format.rs b/tests/ui/format.rs
index bad192067e93..eaf33c2a6c92 100644
--- a/tests/ui/format.rs
+++ b/tests/ui/format.rs
@@ -6,7 +6,8 @@
     clippy::needless_borrow,
     clippy::uninlined_format_args,
     clippy::needless_raw_string_hashes,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::literal_string_with_formatting_args
 )]
 
 struct Foo(pub String);
diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr
index faa80b48000f..1368c8cd77e0 100644
--- a/tests/ui/format.stderr
+++ b/tests/ui/format.stderr
@@ -1,5 +1,5 @@
 error: useless use of `format!`
-  --> tests/ui/format.rs:19:5
+  --> tests/ui/format.rs:20:5
    |
 LL |     format!("foo");
    |     ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
@@ -8,19 +8,19 @@ LL |     format!("foo");
    = help: to override `-D warnings` add `#[allow(clippy::useless_format)]`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:20:5
+  --> tests/ui/format.rs:21:5
    |
 LL |     format!("{{}}");
    |     ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:21:5
+  --> tests/ui/format.rs:22:5
    |
 LL |     format!("{{}} abc {{}}");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:22:5
+  --> tests/ui/format.rs:23:5
    |
 LL | /     format!(
 LL | |         r##"foo {{}}
@@ -35,67 +35,67 @@ LL ~ " bar"##.to_string();
    |
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:27:13
+  --> tests/ui/format.rs:28:13
    |
 LL |     let _ = format!("");
    |             ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:29:5
+  --> tests/ui/format.rs:30:5
    |
 LL |     format!("{}", "foo");
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:37:5
+  --> tests/ui/format.rs:38:5
    |
 LL |     format!("{}", arg);
    |     ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:67:5
+  --> tests/ui/format.rs:68:5
    |
 LL |     format!("{}", 42.to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:69:5
+  --> tests/ui/format.rs:70:5
    |
 LL |     format!("{}", x.display().to_string());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:73:18
+  --> tests/ui/format.rs:74:18
    |
 LL |     let _ = Some(format!("{}", a + "bar"));
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:77:22
+  --> tests/ui/format.rs:78:22
    |
 LL |     let _s: String = format!("{}", &*v.join("\n"));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("\n")).to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:83:13
+  --> tests/ui/format.rs:84:13
    |
 LL |     let _ = format!("{x}");
    |             ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:85:13
+  --> tests/ui/format.rs:86:13
    |
 LL |     let _ = format!("{y}", y = x);
    |             ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:89:13
+  --> tests/ui/format.rs:90:13
    |
 LL |     let _ = format!("{abc}");
    |             ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()`
 
 error: useless use of `format!`
-  --> tests/ui/format.rs:91:13
+  --> tests/ui/format.rs:92:13
    |
 LL |     let _ = format!("{xx}");
    |             ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()`
diff --git a/tests/ui/if_not_else.fixed b/tests/ui/if_not_else.fixed
new file mode 100644
index 000000000000..11d1e13179c4
--- /dev/null
+++ b/tests/ui/if_not_else.fixed
@@ -0,0 +1,73 @@
+#![warn(clippy::all)]
+#![warn(clippy::if_not_else)]
+
+fn foo() -> bool {
+    unimplemented!()
+}
+fn bla() -> bool {
+    unimplemented!()
+}
+
+fn main() {
+    if bla() {
+        println!("Bunny");
+    } else {
+        //~^ ERROR: unnecessary boolean `not` operation
+        println!("Bugs");
+    }
+    if 4 == 5 {
+        println!("Bunny");
+    } else {
+        //~^ ERROR: unnecessary `!=` operation
+        println!("Bugs");
+    }
+    if !foo() {
+        println!("Foo");
+    } else if !bla() {
+        println!("Bugs");
+    } else {
+        println!("Bunny");
+    }
+
+    if (foo() && bla()) {
+        println!("both true");
+    } else {
+        #[cfg(not(debug_assertions))]
+        println!("not debug");
+        #[cfg(debug_assertions)]
+        println!("debug");
+        if foo() {
+            println!("foo");
+        } else if bla() {
+            println!("bla");
+        } else {
+            println!("both false");
+        }
+    }
+}
+
+fn with_comments() {
+    if foo() {
+        println!("foo"); /* foo */
+    } else {
+        /* foo is false */
+        println!("foo is false");
+    }
+
+    if bla() {
+        println!("bla"); // bla
+    } else {
+        // bla is false
+        println!("bla");
+    }
+}
+
+fn with_annotations() {
+    #[cfg(debug_assertions)]
+    if foo() {
+        println!("foo"); /* foo */
+    } else {
+        /* foo is false */
+        println!("foo is false");
+    }
+}
diff --git a/tests/ui/if_not_else.rs b/tests/ui/if_not_else.rs
index fd30e3702a27..fcc67e163e8a 100644
--- a/tests/ui/if_not_else.rs
+++ b/tests/ui/if_not_else.rs
@@ -28,4 +28,46 @@ fn main() {
     } else {
         println!("Bunny");
     }
+
+    if !(foo() && bla()) {
+        #[cfg(not(debug_assertions))]
+        println!("not debug");
+        #[cfg(debug_assertions)]
+        println!("debug");
+        if foo() {
+            println!("foo");
+        } else if bla() {
+            println!("bla");
+        } else {
+            println!("both false");
+        }
+    } else {
+        println!("both true");
+    }
+}
+
+fn with_comments() {
+    if !foo() {
+        /* foo is false */
+        println!("foo is false");
+    } else {
+        println!("foo"); /* foo */
+    }
+
+    if !bla() {
+        // bla is false
+        println!("bla");
+    } else {
+        println!("bla"); // bla
+    }
+}
+
+fn with_annotations() {
+    #[cfg(debug_assertions)]
+    if !foo() {
+        /* foo is false */
+        println!("foo is false");
+    } else {
+        println!("foo"); /* foo */
+    }
 }
diff --git a/tests/ui/if_not_else.stderr b/tests/ui/if_not_else.stderr
index 92fed7b1bf70..b01cb5af11f7 100644
--- a/tests/ui/if_not_else.stderr
+++ b/tests/ui/if_not_else.stderr
@@ -9,9 +9,17 @@ LL | |         println!("Bunny");
 LL | |     }
    | |_____^
    |
-   = help: remove the `!` and swap the blocks of the `if`/`else`
    = note: `-D clippy::if-not-else` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::if_not_else)]`
+help: try
+   |
+LL ~     if bla() {
+LL +         println!("Bunny");
+LL +     } else {
+LL +
+LL +         println!("Bugs");
+LL +     }
+   |
 
 error: unnecessary `!=` operation
   --> tests/ui/if_not_else.rs:18:5
@@ -24,7 +32,109 @@ LL | |         println!("Bunny");
 LL | |     }
    | |_____^
    |
-   = help: change to `==` and swap the blocks of the `if`/`else`
+help: try
+   |
+LL ~     if 4 == 5 {
+LL +         println!("Bunny");
+LL +     } else {
+LL +
+LL +         println!("Bugs");
+LL +     }
+   |
+
+error: unnecessary boolean `not` operation
+  --> tests/ui/if_not_else.rs:32:5
+   |
+LL | /     if !(foo() && bla()) {
+LL | |         #[cfg(not(debug_assertions))]
+LL | |         println!("not debug");
+LL | |         #[cfg(debug_assertions)]
+...  |
+LL | |         println!("both true");
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     if (foo() && bla()) {
+LL +         println!("both true");
+LL +     } else {
+LL +         #[cfg(not(debug_assertions))]
+LL +         println!("not debug");
+LL +         #[cfg(debug_assertions)]
+LL +         println!("debug");
+LL +         if foo() {
+LL +             println!("foo");
+LL +         } else if bla() {
+LL +             println!("bla");
+LL +         } else {
+LL +             println!("both false");
+LL +         }
+LL +     }
+   |
+
+error: unnecessary boolean `not` operation
+  --> tests/ui/if_not_else.rs:50:5
+   |
+LL | /     if !foo() {
+LL | |         /* foo is false */
+LL | |         println!("foo is false");
+LL | |     } else {
+LL | |         println!("foo"); /* foo */
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     if foo() {
+LL +         println!("foo"); /* foo */
+LL +     } else {
+LL +         /* foo is false */
+LL +         println!("foo is false");
+LL +     }
+   |
+
+error: unnecessary boolean `not` operation
+  --> tests/ui/if_not_else.rs:57:5
+   |
+LL | /     if !bla() {
+LL | |         // bla is false
+LL | |         println!("bla");
+LL | |     } else {
+LL | |         println!("bla"); // bla
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     if bla() {
+LL +         println!("bla"); // bla
+LL +     } else {
+LL +         // bla is false
+LL +         println!("bla");
+LL +     }
+   |
+
+error: unnecessary boolean `not` operation
+  --> tests/ui/if_not_else.rs:67:5
+   |
+LL | /     if !foo() {
+LL | |         /* foo is false */
+LL | |         println!("foo is false");
+LL | |     } else {
+LL | |         println!("foo"); /* foo */
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     if foo() {
+LL +         println!("foo"); /* foo */
+LL +     } else {
+LL +         /* foo is false */
+LL +         println!("foo is false");
+LL +     }
+   |
 
-error: aborting due to 2 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.fixed b/tests/ui/index_refutable_slice/if_let_slice_binding.fixed
new file mode 100644
index 000000000000..ea8e56e18b08
--- /dev/null
+++ b/tests/ui/index_refutable_slice/if_let_slice_binding.fixed
@@ -0,0 +1,177 @@
+#![deny(clippy::index_refutable_slice)]
+#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes)]
+
+enum SomeEnum<T> {
+    One(T),
+    Two(T),
+    Three(T),
+    Four(T),
+}
+
+fn lintable_examples() {
+    // Try with reference
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+    if let Some([slice_0, ..]) = slice {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        println!("{}", slice_0);
+    }
+
+    // Try with copy
+    let slice: Option<[u32; 3]> = Some([1, 2, 3]);
+    if let Some([slice_0, ..]) = slice {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        println!("{}", slice_0);
+    }
+
+    // Try with long slice and small indices
+    let slice: Option<[u32; 9]> = Some([1, 2, 3, 4, 5, 6, 7, 8, 9]);
+    if let Some([slice_0, _, slice_2, ..]) = slice {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        println!("{}", slice_2);
+        println!("{}", slice_0);
+    }
+
+    // Multiple bindings
+    let slice_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([5, 6, 7]);
+    if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        println!("{}", slice_0);
+    }
+
+    // Two lintable slices in one if let
+    let a_wrapped: SomeEnum<[u32; 3]> = SomeEnum::One([9, 5, 1]);
+    let b_wrapped: Option<[u32; 2]> = Some([4, 6]);
+    if let (SomeEnum::Three([_, _, a_2, ..]), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        //~| ERROR: this binding can be a slice pattern to avoid indexing
+        println!("{} -> {}", a_2, b_1);
+    }
+
+    // This requires the slice values to be borrowed as the slice values can only be
+    // borrowed and `String` doesn't implement copy
+    let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
+    if let Some([_, ref slice_1, ..]) = slice {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        println!("{:?}", slice_1);
+    }
+    println!("{:?}", slice);
+
+    // This should not suggest using the `ref` keyword as the scrutinee is already
+    // a reference
+    let slice: Option<[String; 2]> = Some([String::from("1"), String::from("2")]);
+    if let Some([slice_0, ..]) = &slice {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        println!("{:?}", slice_0);
+    }
+    println!("{:?}", slice);
+}
+
+fn slice_index_above_limit() {
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+
+    if let Some(slice) = slice {
+        // Would cause a panic, IDK
+        println!("{}", slice[7]);
+    }
+}
+
+fn slice_is_used() {
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+    if let Some(slice) = slice {
+        println!("{:?}", slice.len());
+    }
+
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+    if let Some(slice) = slice {
+        println!("{:?}", slice.to_vec());
+    }
+
+    let opt: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
+    if let Some(slice) = opt {
+        if !slice.is_empty() {
+            println!("first: {}", slice[0]);
+        }
+    }
+}
+
+/// The slice is used by an external function and should therefore not be linted
+fn check_slice_as_arg() {
+    fn is_interesting<T>(slice: &[T; 2]) -> bool {
+        !slice.is_empty()
+    }
+
+    let slice_wrapped: Option<[String; 2]> = Some([String::from("Hello"), String::from("world")]);
+    if let Some(slice) = &slice_wrapped {
+        if is_interesting(slice) {
+            println!("This is interesting {}", slice[0]);
+        }
+    }
+    println!("{:?}", slice_wrapped);
+}
+
+fn check_slice_in_struct() {
+    #[derive(Debug)]
+    struct Wrapper<'a> {
+        inner: Option<&'a [String]>,
+        is_awesome: bool,
+    }
+
+    impl<'a> Wrapper<'a> {
+        fn is_super_awesome(&self) -> bool {
+            self.is_awesome
+        }
+    }
+
+    let inner = &[String::from("New"), String::from("World")];
+    let wrap = Wrapper {
+        inner: Some(inner),
+        is_awesome: true,
+    };
+
+    // Test 1: Field access
+    if let Some([slice_0, ..]) = wrap.inner {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        if wrap.is_awesome {
+            println!("This is awesome! {}", slice_0);
+        }
+    }
+
+    // Test 2: function access
+    if let Some([slice_0, ..]) = wrap.inner {
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        if wrap.is_super_awesome() {
+            println!("This is super awesome! {}", slice_0);
+        }
+    }
+    println!("Complete wrap: {:?}", wrap);
+}
+
+/// This would be a nice additional feature to have in the future, but adding it
+/// now would make the PR too large. This is therefore only a test that we don't
+/// lint cases we can't make a reasonable suggestion for
+fn mutable_slice_index() {
+    // Mut access
+    let mut slice: Option<[String; 1]> = Some([String::from("Penguin")]);
+    if let Some(ref mut slice) = slice {
+        slice[0] = String::from("Mr. Penguin");
+    }
+    println!("Use after modification: {:?}", slice);
+
+    // Mut access on reference
+    let mut slice: Option<[String; 1]> = Some([String::from("Cat")]);
+    if let Some(slice) = &mut slice {
+        slice[0] = String::from("Lord Meow Meow");
+    }
+    println!("Use after modification: {:?}", slice);
+}
+
+/// The lint will ignore bindings with sub patterns as it would be hard
+/// to build correct suggestions for these instances :)
+fn binding_with_sub_pattern() {
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+    if let Some(slice @ [_, _, _]) = slice {
+        println!("{:?}", slice[2]);
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.rs b/tests/ui/index_refutable_slice/if_let_slice_binding.rs
index a4cb50bd6822..1c1d1c4cbe46 100644
--- a/tests/ui/index_refutable_slice/if_let_slice_binding.rs
+++ b/tests/ui/index_refutable_slice/if_let_slice_binding.rs
@@ -1,8 +1,6 @@
 #![deny(clippy::index_refutable_slice)]
 #![allow(clippy::uninlined_format_args, clippy::needless_lifetimes)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 enum SomeEnum<T> {
     One(T),
     Two(T),
diff --git a/tests/ui/index_refutable_slice/if_let_slice_binding.stderr b/tests/ui/index_refutable_slice/if_let_slice_binding.stderr
index 8819cb0e28bf..14ee2e54cab1 100644
--- a/tests/ui/index_refutable_slice/if_let_slice_binding.stderr
+++ b/tests/ui/index_refutable_slice/if_let_slice_binding.stderr
@@ -1,5 +1,5 @@
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:16:17
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:14:17
    |
 LL |     if let Some(slice) = slice {
    |                 ^^^^^
@@ -9,150 +9,134 @@ note: the lint level is defined here
    |
 LL | #![deny(clippy::index_refutable_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let Some([slice_0, ..]) = slice {
-   |                 ~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let Some([slice_0, ..]) = slice {
+LL |
+LL ~         println!("{}", slice_0);
    |
-LL |         println!("{}", slice_0);
-   |                        ~~~~~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:23:17
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:21:17
    |
 LL |     if let Some(slice) = slice {
    |                 ^^^^^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let Some([slice_0, ..]) = slice {
-   |                 ~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let Some([slice_0, ..]) = slice {
+LL |
+LL ~         println!("{}", slice_0);
    |
-LL |         println!("{}", slice_0);
-   |                        ~~~~~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:30:17
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:28:17
    |
 LL |     if let Some(slice) = slice {
    |                 ^^^^^
    |
-help: try using a slice pattern here
-   |
-LL |     if let Some([slice_0, _, slice_2, ..]) = slice {
-   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and replace the index expressions here
+help: replace the binding and indexed access with a slice pattern
    |
+LL ~     if let Some([slice_0, _, slice_2, ..]) = slice {
+LL |
 LL ~         println!("{}", slice_2);
 LL ~         println!("{}", slice_0);
    |
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:38:26
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:36:26
    |
 LL |     if let SomeEnum::One(slice) | SomeEnum::Three(slice) = slice_wrapped {
    |                          ^^^^^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
-   |                          ~~~~~~~~~~~~~                    ~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let SomeEnum::One([slice_0, ..]) | SomeEnum::Three([slice_0, ..]) = slice_wrapped {
+LL |
+LL ~         println!("{}", slice_0);
    |
-LL |         println!("{}", slice_0);
-   |                        ~~~~~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:29
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:29
    |
 LL |     if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
    |                             ^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let (SomeEnum::Three([_, _, a_2, ..]), Some(b)) = (a_wrapped, b_wrapped) {
-   |                             ~~~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let (SomeEnum::Three([_, _, a_2, ..]), Some(b)) = (a_wrapped, b_wrapped) {
+LL |
+LL |
+LL ~         println!("{} -> {}", a_2, b[1]);
    |
-LL |         println!("{} -> {}", a_2, b[1]);
-   |                              ~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:46:38
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:44:38
    |
 LL |     if let (SomeEnum::Three(a), Some(b)) = (a_wrapped, b_wrapped) {
    |                                      ^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let (SomeEnum::Three(a), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
-   |                                      ~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let (SomeEnum::Three(a), Some([_, b_1, ..])) = (a_wrapped, b_wrapped) {
+LL |
+LL |
+LL ~         println!("{} -> {}", a[2], b_1);
    |
-LL |         println!("{} -> {}", a[2], b_1);
-   |                                    ~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:55:21
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:53:21
    |
 LL |     if let Some(ref slice) = slice {
    |                     ^^^^^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let Some([_, ref slice_1, ..]) = slice {
-   |                 ~~~~~~~~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let Some([_, ref slice_1, ..]) = slice {
+LL |
+LL ~         println!("{:?}", slice_1);
    |
-LL |         println!("{:?}", slice_1);
-   |                          ~~~~~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:64:17
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:62:17
    |
 LL |     if let Some(slice) = &slice {
    |                 ^^^^^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let Some([slice_0, ..]) = &slice {
-   |                 ~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let Some([slice_0, ..]) = &slice {
+LL |
+LL ~         println!("{:?}", slice_0);
    |
-LL |         println!("{:?}", slice_0);
-   |                          ~~~~~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:134:17
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:132:17
    |
 LL |     if let Some(slice) = wrap.inner {
    |                 ^^^^^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let Some([slice_0, ..]) = wrap.inner {
-   |                 ~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let Some([slice_0, ..]) = wrap.inner {
+LL |
+LL |         if wrap.is_awesome {
+LL ~             println!("This is awesome! {}", slice_0);
    |
-LL |             println!("This is awesome! {}", slice_0);
-   |                                             ~~~~~~~
 
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:142:17
+  --> tests/ui/index_refutable_slice/if_let_slice_binding.rs:140:17
    |
 LL |     if let Some(slice) = wrap.inner {
    |                 ^^^^^
    |
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |     if let Some([slice_0, ..]) = wrap.inner {
-   |                 ~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~     if let Some([slice_0, ..]) = wrap.inner {
+LL |
+LL |         if wrap.is_super_awesome() {
+LL ~             println!("This is super awesome! {}", slice_0);
    |
-LL |             println!("This is super awesome! {}", slice_0);
-   |                                                   ~~~~~~~
 
 error: aborting due to 10 previous errors
 
diff --git a/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed b/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
new file mode 100644
index 000000000000..72edc539f043
--- /dev/null
+++ b/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
@@ -0,0 +1,29 @@
+#![deny(clippy::index_refutable_slice)]
+
+extern crate if_chain;
+use if_chain::if_chain;
+
+macro_rules! if_let_slice_macro {
+    () => {
+        // This would normally be linted
+        let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+        if let Some(slice) = slice {
+            println!("{}", slice[0]);
+        }
+    };
+}
+
+fn main() {
+    // Don't lint this
+    if_let_slice_macro!();
+
+    // Do lint this
+    if_chain! {
+        let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+        if let Some([slice_0, ..]) = slice;
+        //~^ ERROR: this binding can be a slice pattern to avoid indexing
+        then {
+            println!("{}", slice_0);
+        }
+    }
+}
diff --git a/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs b/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
index 5d9fad488899..7b474ba423b9 100644
--- a/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
+++ b/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
@@ -1,7 +1,5 @@
 #![deny(clippy::index_refutable_slice)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 extern crate if_chain;
 use if_chain::if_chain;
 
diff --git a/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr b/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr
index 69f0aaa97778..64741abb9114 100644
--- a/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr
+++ b/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr
@@ -1,5 +1,5 @@
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:25:21
+  --> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:23:21
    |
 LL |         if let Some(slice) = slice;
    |                     ^^^^^
@@ -9,14 +9,13 @@ note: the lint level is defined here
    |
 LL | #![deny(clippy::index_refutable_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: try using a slice pattern here
+help: replace the binding and indexed access with a slice pattern
    |
-LL |         if let Some([slice_0, ..]) = slice;
-   |                     ~~~~~~~~~~~~~
-help: and replace the index expressions here
+LL ~         if let Some([slice_0, ..]) = slice;
+LL |
+LL |         then {
+LL ~             println!("{}", slice_0);
    |
-LL |             println!("{}", slice_0);
-   |                            ~~~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/let_unit.fixed b/tests/ui/let_unit.fixed
new file mode 100644
index 000000000000..3456e274f6a4
--- /dev/null
+++ b/tests/ui/let_unit.fixed
@@ -0,0 +1,196 @@
+#![warn(clippy::let_unit_value)]
+#![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
+
+macro_rules! let_and_return {
+    ($n:expr) => {{
+        let ret = $n;
+    }};
+}
+
+fn main() {
+    println!("x");
+    let _y = 1; // this is fine
+    let _z = ((), 1); // this as well
+    if true {
+        // do not lint this, since () is explicit
+        let _a = ();
+        let () = dummy();
+        let () = ();
+        () = dummy();
+        () = ();
+        let _a: () = ();
+        let _a: () = dummy();
+    }
+
+    consume_units_with_for_loop(); // should be fine as well
+
+    multiline_sugg();
+
+    let_and_return!(()) // should be fine
+}
+
+fn dummy() {}
+
+// Related to issue #1964
+fn consume_units_with_for_loop() {
+    // `for_let_unit` lint should not be triggered by consuming them using for loop.
+    let v = vec![(), (), ()];
+    let mut count = 0;
+    for _ in v {
+        count += 1;
+    }
+    assert_eq!(count, 3);
+
+    // Same for consuming from some other Iterator<Item = ()>.
+    let (tx, rx) = ::std::sync::mpsc::channel();
+    tx.send(()).unwrap();
+    drop(tx);
+
+    count = 0;
+    for _ in rx.iter() {
+        count += 1;
+    }
+    assert_eq!(count, 1);
+}
+
+fn multiline_sugg() {
+    let v: Vec<u8> = vec![2];
+
+    v
+        .into_iter()
+        .map(|i| i * 2)
+        .filter(|i| i % 2 == 0)
+        .map(|_| ())
+        .next()
+        .unwrap();
+}
+
+#[derive(Copy, Clone)]
+pub struct ContainsUnit(()); // should be fine
+
+fn _returns_generic() {
+    fn f<T>() -> T {
+        unimplemented!()
+    }
+    fn f2<T, U>(_: T) -> U {
+        unimplemented!()
+    }
+    fn f3<T>(x: T) -> T {
+        x
+    }
+    fn f5<T: Default>(x: bool) -> Option<T> {
+        x.then(|| T::default())
+    }
+
+    let _: () = f();
+    let x: () = f();
+
+    let _: () = f2(0i32);
+    let x: () = f2(0i32);
+
+    let _: () = f3(());
+    let x: () = f3(());
+
+    fn f4<T>(mut x: Vec<T>) -> T {
+        x.pop().unwrap()
+    }
+    let _: () = f4(vec![()]);
+    let x: () = f4(vec![()]);
+
+    let _: () = {
+        let x = 5;
+        f2(x)
+    };
+
+    let _: () = if true { f() } else { f2(0) };
+    let x: () = if true { f() } else { f2(0) };
+
+    match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => (),
+    };
+
+    let _: () = f5(true).unwrap();
+
+    #[allow(clippy::let_unit_value)]
+    {
+        let x = f();
+        let y;
+        let z;
+        match 0 {
+            0 => {
+                y = f();
+                z = f();
+            },
+            1 => {
+                println!("test");
+                y = f();
+                z = f3(());
+            },
+            _ => panic!(),
+        }
+
+        let x1;
+        let x2;
+        if true {
+            x1 = f();
+            x2 = x1;
+        } else {
+            x2 = f();
+            x1 = x2;
+        }
+
+        let opt;
+        match f5(true) {
+            Some(x) => opt = x,
+            None => panic!(),
+        };
+
+        #[warn(clippy::let_unit_value)]
+        {
+            let _: () = x;
+            let _: () = y;
+            let _: () = z;
+            let _: () = x1;
+            let _: () = x2;
+            let _: () = opt;
+        }
+    }
+
+    let () = f();
+}
+
+fn attributes() {
+    fn f() {}
+
+    #[allow(clippy::let_unit_value)]
+    let _ = f();
+    #[expect(clippy::let_unit_value)]
+    let _ = f();
+}
+
+async fn issue10433() {
+    let _pending: () = std::future::pending().await;
+}
+
+pub async fn issue11502(a: ()) {}
+
+pub fn issue12594() {
+    fn returns_unit() {}
+
+    fn returns_result<T>(res: T) -> Result<T, ()> {
+        Ok(res)
+    }
+
+    fn actual_test() {
+        // create first a unit value'd value
+        returns_unit();
+        returns_result(()).unwrap();
+        returns_result(()).unwrap();
+        // make sure we replace only the first variable
+        let res = 1;
+        returns_result(res).unwrap();
+    }
+}
diff --git a/tests/ui/let_unit.rs b/tests/ui/let_unit.rs
index 530103ffaf6e..e2dafbcb7714 100644
--- a/tests/ui/let_unit.rs
+++ b/tests/ui/let_unit.rs
@@ -1,8 +1,6 @@
 #![warn(clippy::let_unit_value)]
 #![allow(unused, clippy::no_effect, clippy::needless_late_init, path_statements)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 macro_rules! let_and_return {
     ($n:expr) => {{
         let ret = $n;
diff --git a/tests/ui/let_unit.stderr b/tests/ui/let_unit.stderr
index 6f149454af2d..a2f368f22e5b 100644
--- a/tests/ui/let_unit.stderr
+++ b/tests/ui/let_unit.stderr
@@ -1,5 +1,5 @@
 error: this let-binding has unit value
-  --> tests/ui/let_unit.rs:13:5
+  --> tests/ui/let_unit.rs:11:5
    |
 LL |     let _x = println!("x");
    |     ^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `println!("x");`
@@ -8,7 +8,7 @@ LL |     let _x = println!("x");
    = help: to override `-D warnings` add `#[allow(clippy::let_unit_value)]`
 
 error: this let-binding has unit value
-  --> tests/ui/let_unit.rs:61:5
+  --> tests/ui/let_unit.rs:59:5
    |
 LL | /     let _ = v
 LL | |         .into_iter()
@@ -31,7 +31,7 @@ LL +         .unwrap();
    |
 
 error: this let-binding has unit value
-  --> tests/ui/let_unit.rs:110:5
+  --> tests/ui/let_unit.rs:108:5
    |
 LL | /     let x = match Some(0) {
 LL | |         None => f2(1),
@@ -52,23 +52,17 @@ LL +     };
    |
 
 error: this let-binding has unit value
-  --> tests/ui/let_unit.rs:191:9
+  --> tests/ui/let_unit.rs:189:9
    |
 LL |         let res = returns_unit();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: omit the `let` binding
-   |
-LL |         returns_unit();
-   |
-help: variable `res` of type `()` can be replaced with explicit `()`
+help: omit the `let` binding and replace variable usages with `()`
    |
-LL |         returns_result(()).unwrap();
-   |                        ~~
-help: variable `res` of type `()` can be replaced with explicit `()`
+LL ~         returns_unit();
+LL ~         returns_result(()).unwrap();
+LL ~         returns_result(()).unwrap();
    |
-LL |         returns_result(()).unwrap();
-   |                        ~~
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/literal_string_with_formatting_arg.rs b/tests/ui/literal_string_with_formatting_arg.rs
new file mode 100644
index 000000000000..f257c66f59d3
--- /dev/null
+++ b/tests/ui/literal_string_with_formatting_arg.rs
@@ -0,0 +1,37 @@
+#![warn(clippy::literal_string_with_formatting_args)]
+#![allow(clippy::unnecessary_literal_unwrap)]
+
+fn main() {
+    let x: Option<usize> = None;
+    let y = "hello";
+    x.expect("{y} {}"); //~ literal_string_with_formatting_args
+    x.expect(" {y} bla"); //~ literal_string_with_formatting_args
+    x.expect("{:?}"); //~ literal_string_with_formatting_args
+    x.expect("{y:?}"); //~ literal_string_with_formatting_args
+    x.expect(" {y:?} {y:?} "); //~ literal_string_with_formatting_args
+    x.expect(" {y:..} {y:?} "); //~ literal_string_with_formatting_args
+    x.expect(r"{y:?}  {y:?} "); //~ literal_string_with_formatting_args
+    x.expect(r"{y:?} y:?}"); //~ literal_string_with_formatting_args
+    x.expect(r##" {y:?} {y:?} "##); //~ literal_string_with_formatting_args
+    // Ensure that it doesn't try to go in the middle of a unicode character.
+    x.expect("———{:?}"); //~ literal_string_with_formatting_args
+
+    // Should not lint!
+    format!("{y:?}");
+    println!("{y:?}");
+    x.expect(" {} "); // We ignore `{}` to limit false positives.
+    x.expect(" {   } "); // We ignore `{}` to limit false positives.
+    x.expect("{{y} {x");
+    x.expect("{{y:?}");
+    x.expect(" {0}"); // If it only contains an integer, we ignore it.
+    x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint
+    x.expect("{y:...}");
+    let _ = "fn main {\n\
+    }";
+    // Unicode characters escape should not lint either.
+    "\u{0052}".to_string();
+
+    // Regression test for <https://github.com/rust-lang/rust-clippy/issues/13838>.
+    let x: Option<usize> = Some(0);
+    x.expect("{…}");
+}
diff --git a/tests/ui/literal_string_with_formatting_arg.stderr b/tests/ui/literal_string_with_formatting_arg.stderr
new file mode 100644
index 000000000000..32a84f600da7
--- /dev/null
+++ b/tests/ui/literal_string_with_formatting_arg.stderr
@@ -0,0 +1,71 @@
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:7:15
+   |
+LL |     x.expect("{y} {}");
+   |               ^^^
+   |
+   = note: `-D clippy::literal-string-with-formatting-args` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::literal_string_with_formatting_args)]`
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:8:16
+   |
+LL |     x.expect(" {y} bla");
+   |                ^^^
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:9:15
+   |
+LL |     x.expect("{:?}");
+   |               ^^^^
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:10:15
+   |
+LL |     x.expect("{y:?}");
+   |               ^^^^^
+
+error: these look like formatting arguments but are not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:11:16
+   |
+LL |     x.expect(" {y:?} {y:?} ");
+   |                ^^^^^ ^^^^^
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:12:23
+   |
+LL |     x.expect(" {y:..} {y:?} ");
+   |                       ^^^^^
+
+error: these look like formatting arguments but are not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:13:16
+   |
+LL |     x.expect(r"{y:?}  {y:?} ");
+   |                ^^^^^  ^^^^^
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:14:16
+   |
+LL |     x.expect(r"{y:?} y:?}");
+   |                ^^^^^
+
+error: these look like formatting arguments but are not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:15:19
+   |
+LL |     x.expect(r##" {y:?} {y:?} "##);
+   |                   ^^^^^ ^^^^^
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:17:18
+   |
+LL |     x.expect("———{:?}");
+   |                  ^^^^
+
+error: this looks like a formatting argument but it is not part of a formatting macro
+  --> tests/ui/literal_string_with_formatting_arg.rs:27:19
+   |
+LL |     x.expect(r##" {x:?} "##); // `x` doesn't exist so we shoud not lint
+   |                   ^^^^^
+
+error: aborting due to 11 previous errors
+
diff --git a/tests/ui/manual_async_fn.fixed b/tests/ui/manual_async_fn.fixed
new file mode 100644
index 000000000000..dc1cb8e11fca
--- /dev/null
+++ b/tests/ui/manual_async_fn.fixed
@@ -0,0 +1,116 @@
+#![warn(clippy::manual_async_fn)]
+#![allow(clippy::needless_pub_self, unused)]
+
+use std::future::Future;
+
+async fn fut() -> i32 { 42 }
+
+#[rustfmt::skip]
+async fn fut2() -> i32 { 42 }
+
+#[rustfmt::skip]
+async fn fut3() -> i32 { 42 }
+
+async fn empty_fut() {}
+
+#[rustfmt::skip]
+async fn empty_fut2() {}
+
+#[rustfmt::skip]
+async fn empty_fut3() {}
+
+async fn core_fut() -> i32 { 42 }
+
+// should be ignored
+fn has_other_stmts() -> impl core::future::Future<Output = i32> {
+    let _ = 42;
+    async move { 42 }
+}
+
+// should be ignored
+fn not_fut() -> i32 {
+    42
+}
+
+// should be ignored
+async fn already_async() -> impl Future<Output = i32> {
+    async { 42 }
+}
+
+struct S;
+impl S {
+    async fn inh_fut() -> i32 {
+        // NOTE: this code is here just to check that the indentation is correct in the suggested fix
+        let a = 42;
+        let b = 21;
+        if a < b {
+            let c = 21;
+            let d = 42;
+            if c < d {
+                let _ = 42;
+            }
+        }
+        42
+    }
+
+    // should be ignored
+    fn not_fut(&self) -> i32 {
+        42
+    }
+
+    // should be ignored
+    fn has_other_stmts() -> impl core::future::Future<Output = i32> {
+        let _ = 42;
+        async move { 42 }
+    }
+
+    // should be ignored
+    async fn already_async(&self) -> impl Future<Output = i32> {
+        async { 42 }
+    }
+}
+
+// Tests related to lifetime capture
+
+async fn elided(_: &i32) -> i32 { 42 }
+
+// should be ignored
+fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
+    async { 42 }
+}
+
+#[allow(clippy::needless_lifetimes)]
+async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 { 42 }
+
+// should be ignored
+#[allow(clippy::needless_lifetimes)]
+fn explicit_not_bound<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> {
+    async { 42 }
+}
+
+// should be ignored
+mod issue_5765 {
+    use std::future::Future;
+
+    struct A;
+    impl A {
+        fn f(&self) -> impl Future<Output = ()> {
+            async {}
+        }
+    }
+
+    fn test() {
+        let _future = {
+            let a = A;
+            a.f()
+        };
+    }
+}
+
+pub async fn issue_10450() -> i32 { 42 }
+
+pub(crate) async fn issue_10450_2() -> i32 { 42 }
+
+pub(self) async fn issue_10450_3() -> i32 { 42 }
+
+fn main() {}
diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs
index 6b8ac5033a92..9ca7654a3688 100644
--- a/tests/ui/manual_async_fn.rs
+++ b/tests/ui/manual_async_fn.rs
@@ -1,8 +1,6 @@
 #![warn(clippy::manual_async_fn)]
 #![allow(clippy::needless_pub_self, unused)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 use std::future::Future;
 
 fn fut() -> impl Future<Output = i32> {
@@ -99,6 +97,7 @@ fn elided_not_bound(_: &i32) -> impl Future<Output = i32> {
     async { 42 }
 }
 
+#[allow(clippy::needless_lifetimes)]
 fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
     async { 42 }
 }
diff --git a/tests/ui/manual_async_fn.stderr b/tests/ui/manual_async_fn.stderr
index f88fc30b3b54..68a97243436d 100644
--- a/tests/ui/manual_async_fn.stderr
+++ b/tests/ui/manual_async_fn.stderr
@@ -1,5 +1,5 @@
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:8:1
+  --> tests/ui/manual_async_fn.rs:6:1
    |
 LL | fn fut() -> impl Future<Output = i32> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,116 +8,84 @@ 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn fut() -> impl Future<Output = i32> { 42 }
-   |                                       ~~~~~~
+LL | async fn fut() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:13:1
+  --> tests/ui/manual_async_fn.rs:11:1
    |
 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn fut2() ->impl Future<Output = i32> { 42 }
-   |                                       ~~~~~~
+LL | async fn fut2() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:18:1
+  --> tests/ui/manual_async_fn.rs:16:1
    |
 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn fut3()-> impl Future<Output = i32> { 42 }
-   |                                       ~~~~~~
+LL | async fn fut3() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:22:1
+  --> tests/ui/manual_async_fn.rs:20:1
    |
 LL | fn empty_fut() -> impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: make the function `async` and remove the return type
-   |
-LL | async fn empty_fut() {
-   | ~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
+help: make the function `async` and return the output of the future directly
    |
-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:27:1
+  --> tests/ui/manual_async_fn.rs:25:1
    |
 LL | fn empty_fut2() ->impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: make the function `async` and remove the return type
-   |
-LL | async fn empty_fut2() {
-   | ~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
+help: make the function `async` and return the output of the future directly
    |
-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:32:1
+  --> tests/ui/manual_async_fn.rs:30:1
    |
 LL | fn empty_fut3()-> impl Future<Output = ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: make the function `async` and remove the return type
-   |
-LL | async fn empty_fut3() {
-   | ~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
+help: make the function `async` and return the output of the future directly
    |
-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:36:1
+  --> tests/ui/manual_async_fn.rs:34:1
    |
 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn core_fut() -> impl core::future::Future<Output = i32> { 42 }
-   |                                                          ~~~~~~
+LL | async fn core_fut() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:58:5
+  --> tests/ui/manual_async_fn.rs:56:5
    |
 LL |     fn inh_fut() -> impl Future<Output = i32> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL |     async fn inh_fut() -> i32 {
-   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL ~     fn inh_fut() -> impl Future<Output = i32> {
+LL ~     async fn inh_fut() -> i32 {
 LL +         // NOTE: this code is here just to check that the indentation is correct in the suggested fix
 LL +         let a = 42;
 LL +         let b = 21;
@@ -133,79 +101,59 @@ LL +     }
    |
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:93:1
+  --> tests/ui/manual_async_fn.rs:91:1
    |
 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn elided(_: &i32) -> impl Future<Output = i32> + '_ { 42 }
-   |                                                      ~~~~~~
+LL | async fn elided(_: &i32) -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: this function can be simplified using the `async fn` syntax
-  --> tests/ui/manual_async_fn.rs:102:1
+  --> tests/ui/manual_async_fn.rs:101:1
    |
 LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: make the function `async` and return the output of the future directly
    |
-LL | async fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> i32 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future<Output = i32> + 'a + 'b { 42 }
-   |                                                                                    ~~~~~~
+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:131:1
+  --> tests/ui/manual_async_fn.rs:130:1
    |
 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | pub fn issue_10450() -> impl Future<Output = i32> { 42 }
-   |                                                   ~~~~~~
+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:135:1
+  --> tests/ui/manual_async_fn.rs:134:1
    |
 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | pub(crate) fn issue_10450_2() -> impl Future<Output = i32> { 42 }
-   |                                                            ~~~~~~
+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:139:1
+  --> tests/ui/manual_async_fn.rs:138:1
    |
 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 {
-   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: move the body of the async block to the enclosing function
-   |
-LL | pub(self) fn issue_10450_3() -> impl Future<Output = i32> { 42 }
-   |                                                           ~~~~~~
+LL | pub(self) async fn issue_10450_3() -> i32 { 42 }
+   | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
 
 error: aborting due to 13 previous errors
 
diff --git a/tests/ui/manual_split_once.fixed b/tests/ui/manual_split_once.fixed
new file mode 100644
index 000000000000..aaac6a048e1d
--- /dev/null
+++ b/tests/ui/manual_split_once.fixed
@@ -0,0 +1,144 @@
+#![warn(clippy::manual_split_once)]
+#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
+
+extern crate itertools;
+
+#[allow(unused_imports)]
+use itertools::Itertools;
+
+fn main() {
+    let _ = "key=value".splitn(2, '=').nth(2);
+    let _ = "key=value".split_once('=').unwrap().1;
+    let _ = "key=value".split_once('=').unwrap().1;
+    let (_, _) = "key=value".split_once('=').unwrap();
+
+    let s = String::from("key=value");
+    let _ = s.split_once('=').unwrap().1;
+
+    let s = Box::<str>::from("key=value");
+    let _ = s.split_once('=').unwrap().1;
+
+    let s = &"key=value";
+    let _ = s.split_once('=').unwrap().1;
+
+    fn _f(s: &str) -> Option<&str> {
+        let _ = s.split_once('=')?.1;
+        let _ = s.split_once('=')?.1;
+        let _ = s.rsplit_once('=')?.0;
+        let _ = s.rsplit_once('=')?.0;
+        None
+    }
+
+    // Don't lint, slices don't have `split_once`
+    let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();
+
+    // `rsplitn` gives the results in the reverse order of `rsplit_once`
+    let _ = "key=value".rsplit_once('=').unwrap().0;
+    let (_, _) = "key=value".rsplit_once('=').map(|(x, y)| (y, x)).unwrap();
+    let _ = s.rsplit_once('=').map(|x| x.0);
+}
+
+fn indirect() -> Option<()> {
+    let (l, r) = "a.b.c".split_once('.').unwrap();
+    
+    
+
+    let (l, r) = "a.b.c".split_once('.')?;
+    
+    
+
+    let (l, r) = "a.b.c".rsplit_once('.').unwrap();
+    
+    
+
+    let (l, r) = "a.b.c".rsplit_once('.')?;
+    
+    
+
+    // could lint, currently doesn't
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let other = 1;
+    let l = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let mut mut_binding = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let tuple = (iter.next()?, iter.next()?);
+
+    // should not lint
+
+    let mut missing_unwrap = "a.b.c".splitn(2, '.');
+    let l = missing_unwrap.next();
+    let r = missing_unwrap.next();
+
+    let mut mixed_unrap = "a.b.c".splitn(2, '.');
+    let unwrap = mixed_unrap.next().unwrap();
+    let question_mark = mixed_unrap.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let same_name = iter.next()?;
+    let same_name = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let shadows_existing = "d";
+    let shadows_existing = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let becomes_shadowed = iter.next()?;
+    let becomes_shadowed = "d";
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next()?;
+    let r = iter.next()?;
+    let third_usage = iter.next()?;
+
+    let mut n_three = "a.b.c".splitn(3, '.');
+    let l = n_three.next()?;
+    let r = n_three.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    {
+        let in_block = iter.next()?;
+    }
+    let r = iter.next()?;
+
+    let mut lacks_binding = "a.b.c".splitn(2, '.');
+    let _ = lacks_binding.next()?;
+    let r = lacks_binding.next()?;
+
+    let mut mapped = "a.b.c".splitn(2, '.').map(|_| "~");
+    let l = iter.next()?;
+    let r = iter.next()?;
+
+    let mut assigned = "";
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next()?;
+    assigned = iter.next()?;
+
+    None
+}
+
+#[clippy::msrv = "1.51"]
+fn _msrv_1_51() {
+    // `str::split_once` was stabilized in 1.52. Do not lint this
+    let _ = "key=value".splitn(2, '=').nth(1).unwrap();
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let a = iter.next().unwrap();
+    let b = iter.next().unwrap();
+}
+
+#[clippy::msrv = "1.52"]
+fn _msrv_1_52() {
+    let _ = "key=value".split_once('=').unwrap().1;
+
+    let (a, b) = "a.b.c".split_once('.').unwrap();
+    
+    
+}
diff --git a/tests/ui/manual_split_once.rs b/tests/ui/manual_split_once.rs
index e13c827468b8..113e1737c97d 100644
--- a/tests/ui/manual_split_once.rs
+++ b/tests/ui/manual_split_once.rs
@@ -1,8 +1,6 @@
 #![warn(clippy::manual_split_once)]
 #![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 extern crate itertools;
 
 #[allow(unused_imports)]
diff --git a/tests/ui/manual_split_once.stderr b/tests/ui/manual_split_once.stderr
index 566204ad8762..366d860f25ef 100644
--- a/tests/ui/manual_split_once.stderr
+++ b/tests/ui/manual_split_once.stderr
@@ -1,5 +1,5 @@
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:13:13
+  --> tests/ui/manual_split_once.rs:11:13
    |
 LL |     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
@@ -8,79 +8,79 @@ LL |     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
    = help: to override `-D warnings` add `#[allow(clippy::manual_split_once)]`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:14:13
+  --> tests/ui/manual_split_once.rs:12:13
    |
 LL |     let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:15:18
+  --> tests/ui/manual_split_once.rs:13:18
    |
 LL |     let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=')`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:18:13
+  --> tests/ui/manual_split_once.rs:16:13
    |
 LL |     let _ = s.splitn(2, '=').nth(1).unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:21:13
+  --> tests/ui/manual_split_once.rs:19:13
    |
 LL |     let _ = s.splitn(2, '=').nth(1).unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:24:13
+  --> tests/ui/manual_split_once.rs:22:13
    |
 LL |     let _ = s.splitn(2, '=').skip(1).next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:27:17
+  --> tests/ui/manual_split_once.rs:25:17
    |
 LL |         let _ = s.splitn(2, '=').nth(1)?;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:28:17
+  --> tests/ui/manual_split_once.rs:26:17
    |
 LL |         let _ = s.splitn(2, '=').skip(1).next()?;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.split_once('=')?.1`
 
 error: manual implementation of `rsplit_once`
-  --> tests/ui/manual_split_once.rs:29:17
+  --> tests/ui/manual_split_once.rs:27:17
    |
 LL |         let _ = s.rsplitn(2, '=').nth(1)?;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
 
 error: manual implementation of `rsplit_once`
-  --> tests/ui/manual_split_once.rs:30:17
+  --> tests/ui/manual_split_once.rs:28:17
    |
 LL |         let _ = s.rsplitn(2, '=').skip(1).next()?;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=')?.0`
 
 error: manual implementation of `rsplit_once`
-  --> tests/ui/manual_split_once.rs:38:13
+  --> tests/ui/manual_split_once.rs:36:13
    |
 LL |     let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').unwrap().0`
 
 error: manual implementation of `rsplit_once`
-  --> tests/ui/manual_split_once.rs:39:18
+  --> tests/ui/manual_split_once.rs:37:18
    |
 LL |     let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
 
 error: manual implementation of `rsplit_once`
-  --> tests/ui/manual_split_once.rs:40:13
+  --> tests/ui/manual_split_once.rs:38:13
    |
 LL |     let _ = s.rsplitn(2, '=').nth(1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `s.rsplit_once('=').map(|x| x.0)`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:44:5
+  --> tests/ui/manual_split_once.rs:42:5
    |
 LL |     let mut iter = "a.b.c".splitn(2, '.');
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -89,21 +89,15 @@ LL |     let l = iter.next().unwrap();
 LL |     let r = iter.next().unwrap();
    |     ----------------------------- second usage here
    |
-help: try `split_once`
-   |
-LL |     let (l, r) = "a.b.c".split_once('.').unwrap();
+help: replace with `split_once`
    |
-help: remove the `iter` usages
-   |
-LL -     let l = iter.next().unwrap();
-   |
-help: remove the `iter` usages
-   |
-LL -     let r = iter.next().unwrap();
+LL ~     let (l, r) = "a.b.c".split_once('.').unwrap();
+LL ~     
+LL ~     
    |
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:48:5
+  --> tests/ui/manual_split_once.rs:46:5
    |
 LL |     let mut iter = "a.b.c".splitn(2, '.');
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,21 +106,15 @@ LL |     let l = iter.next()?;
 LL |     let r = iter.next()?;
    |     --------------------- second usage here
    |
-help: try `split_once`
-   |
-LL |     let (l, r) = "a.b.c".split_once('.')?;
-   |
-help: remove the `iter` usages
-   |
-LL -     let l = iter.next()?;
+help: replace with `split_once`
    |
-help: remove the `iter` usages
-   |
-LL -     let r = iter.next()?;
+LL ~     let (l, r) = "a.b.c".split_once('.')?;
+LL ~     
+LL ~     
    |
 
 error: manual implementation of `rsplit_once`
-  --> tests/ui/manual_split_once.rs:52:5
+  --> tests/ui/manual_split_once.rs:50:5
    |
 LL |     let mut iter = "a.b.c".rsplitn(2, '.');
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -135,21 +123,15 @@ LL |     let r = iter.next().unwrap();
 LL |     let l = iter.next().unwrap();
    |     ----------------------------- second usage here
    |
-help: try `rsplit_once`
-   |
-LL |     let (l, r) = "a.b.c".rsplit_once('.').unwrap();
-   |
-help: remove the `iter` usages
-   |
-LL -     let r = iter.next().unwrap();
+help: replace with `rsplit_once`
    |
-help: remove the `iter` usages
-   |
-LL -     let l = iter.next().unwrap();
+LL ~     let (l, r) = "a.b.c".rsplit_once('.').unwrap();
+LL ~     
+LL ~     
    |
 
 error: manual implementation of `rsplit_once`
-  --> tests/ui/manual_split_once.rs:56:5
+  --> tests/ui/manual_split_once.rs:54:5
    |
 LL |     let mut iter = "a.b.c".rsplitn(2, '.');
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -158,27 +140,21 @@ LL |     let r = iter.next()?;
 LL |     let l = iter.next()?;
    |     --------------------- second usage here
    |
-help: try `rsplit_once`
-   |
-LL |     let (l, r) = "a.b.c".rsplit_once('.')?;
-   |
-help: remove the `iter` usages
+help: replace with `rsplit_once`
    |
-LL -     let r = iter.next()?;
-   |
-help: remove the `iter` usages
-   |
-LL -     let l = iter.next()?;
+LL ~     let (l, r) = "a.b.c".rsplit_once('.')?;
+LL ~     
+LL ~     
    |
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:141:13
+  --> tests/ui/manual_split_once.rs:139:13
    |
 LL |     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"key=value".split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
-  --> tests/ui/manual_split_once.rs:143:5
+  --> tests/ui/manual_split_once.rs:141:5
    |
 LL |     let mut iter = "a.b.c".splitn(2, '.');
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -187,17 +163,11 @@ LL |     let a = iter.next().unwrap();
 LL |     let b = iter.next().unwrap();
    |     ----------------------------- second usage here
    |
-help: try `split_once`
-   |
-LL |     let (a, b) = "a.b.c".split_once('.').unwrap();
-   |
-help: remove the `iter` usages
-   |
-LL -     let a = iter.next().unwrap();
-   |
-help: remove the `iter` usages
+help: replace with `split_once`
    |
-LL -     let b = iter.next().unwrap();
+LL ~     let (a, b) = "a.b.c".split_once('.').unwrap();
+LL ~     
+LL ~     
    |
 
 error: aborting due to 19 previous errors
diff --git a/tests/ui/match_same_arms.stderr b/tests/ui/match_same_arms.stderr
index 3c0382767c3f..4a4772da143a 100644
--- a/tests/ui/match_same_arms.stderr
+++ b/tests/ui/match_same_arms.stderr
@@ -20,13 +20,10 @@ LL |         (1, .., 3) => 42,
    |         ^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL |         (1, .., 3) | (.., 3) => 42,
-   |         ~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
-   |
-LL -         (.., 3) => 42,
+LL ~         (1, .., 3) | (.., 3) => 42,
+LL ~         _ => 0,
    |
 
 error: this match arm has an identical body to another arm
@@ -36,13 +33,11 @@ LL |         51 => 1,
    |         ^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         51 | 42 => 1,
-   |         ~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         42 => 1,
+LL -         51 => 1,
+LL +         51 | 42 => 1,
    |
 
 error: this match arm has an identical body to another arm
@@ -52,13 +47,10 @@ LL |         41 => 2,
    |         ^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL |         41 | 52 => 2,
-   |         ~~~~~~~
-help: and remove this obsolete arm
-   |
-LL -         52 => 2,
+LL ~         41 | 52 => 2,
+LL ~         _ => 0,
    |
 
 error: this match arm has an identical body to another arm
@@ -68,13 +60,11 @@ LL |         2 => 2,
    |         ^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         2 | 1 => 2,
-   |         ~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         1 => 2,
+LL -         2 => 2,
+LL +         2 | 1 => 2,
    |
 
 error: this match arm has an identical body to another arm
@@ -84,13 +74,11 @@ LL |         3 => 2,
    |         ^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL |         3 | 1 => 2,
-   |         ~~~~~
-help: and remove this obsolete arm
-   |
-LL -         1 => 2,
+LL ~         2 => 2,
+LL |
+LL ~         3 | 1 => 2,
    |
 
 error: this match arm has an identical body to another arm
@@ -100,14 +88,11 @@ LL |         2 => 2,
    |         ^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL |         2 | 3 => 2,
-   |         ~~~~~
-help: and remove this obsolete arm
-   |
-LL -         3 => 2,
-LL +
+LL ~         2 | 3 => 2,
+LL |
+LL ~
    |
 
 error: this match arm has an identical body to another arm
@@ -117,13 +102,11 @@ LL |                 CommandInfo::External { name, .. } => name.to_string(),
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |                 CommandInfo::External { name, .. } | CommandInfo::BuiltIn { name, .. } => name.to_string(),
-   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -                 CommandInfo::BuiltIn { name, .. } => name.to_string(),
+LL -                 CommandInfo::External { name, .. } => name.to_string(),
+LL +                 CommandInfo::External { name, .. } | CommandInfo::BuiltIn { name, .. } => name.to_string(),
    |
 
 error: aborting due to 8 previous errors
diff --git a/tests/ui/match_same_arms2.fixed b/tests/ui/match_same_arms2.fixed
new file mode 100644
index 000000000000..b7d377f1ebff
--- /dev/null
+++ b/tests/ui/match_same_arms2.fixed
@@ -0,0 +1,259 @@
+#![warn(clippy::match_same_arms)]
+#![allow(
+    clippy::disallowed_names,
+    clippy::diverging_sub_expression,
+    clippy::uninlined_format_args,
+    clippy::match_single_binding,
+    clippy::match_like_matches_macro
+)]
+
+fn bar<T>(_: T) {}
+fn foo() -> bool {
+    unimplemented!()
+}
+
+fn match_same_arms() {
+    let _ = match 42 {
+        _ => {
+            foo();
+            let mut a = 42 + [23].len() as i32;
+            if true {
+                a += 7;
+            }
+            a = -31 - a;
+            a
+        },
+    };
+    //~^^^^^^^^^^^^^^^^^^^ ERROR: this match arm has an identical body to the `_` wildcard arm
+
+    let _ = match 42 {
+        51 | 42 => foo(), //~ ERROR: this match arm has an identical body to another arm
+        _ => true,
+    };
+
+    let _ = match Some(42) {
+        None | Some(_) => 24, //~ ERROR: this match arm has an identical body to another arm
+    };
+
+    let _ = match Some(42) {
+        Some(foo) => 24,
+        None => 24,
+    };
+
+    let _ = match Some(42) {
+        Some(42) => 24,
+        Some(a) => 24, // bindings are different
+        None => 0,
+    };
+
+    let _ = match Some(42) {
+        Some(a) if a > 0 => 24,
+        Some(a) => 24, // one arm has a guard
+        None => 0,
+    };
+
+    match (Some(42), Some(42)) {
+        (None, Some(a)) | (Some(a), None) => bar(a), //~ ERROR: this match arm has an identical body to another arm
+        _ => (),
+    }
+
+    // No warning because guards are different
+    let _ = match Some(42) {
+        Some(a) if a == 42 => a,
+        Some(a) if a == 24 => a,
+        Some(_) => 24,
+        None => 0,
+    };
+
+    let _ = match (Some(42), Some(42)) {
+        (None, Some(a)) | (Some(a), None) if a == 42 => a, //~ ERROR: this match arm has an identical body to another arm
+        _ => 0,
+    };
+
+    match (Some(42), Some(42)) {
+        (Some(a), ..) | (.., Some(a)) => bar(a), //~ ERROR: this match arm has an identical body to another arm
+        _ => (),
+    }
+
+    let _ = match Some(()) {
+        Some(()) => 0.0,
+        None => -0.0,
+    };
+
+    match (Some(42), Some("")) {
+        (Some(a), None) => bar(a),
+        (None, Some(a)) => bar(a), // bindings have different types
+        _ => (),
+    }
+
+    let x: Result<i32, &str> = Ok(3);
+
+    // No warning because of the guard.
+    match x {
+        Ok(x) if x * x == 64 => println!("ok"),
+        Ok(_) => println!("ok"),
+        Err(_) => println!("err"),
+    }
+
+    // This used to be a false positive; see issue #1996.
+    match x {
+        Ok(3) => println!("ok"),
+        Ok(x) if x * x == 64 => println!("ok 64"),
+        Ok(_) => println!("ok"),
+        Err(_) => println!("err"),
+    }
+
+    match (x, Some(1i32)) {
+        (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x), //~ ERROR: this match arm has an identical body to another arm
+        _ => println!("err"),
+    }
+
+    // No warning; different types for `x`.
+    match (x, Some(1.0f64)) {
+        (Ok(x), Some(_)) => println!("ok {}", x),
+        (Ok(_), Some(x)) => println!("ok {}", x),
+        _ => println!("err"),
+    }
+
+    // False negative #2251.
+    match x {
+        Ok(_tmp) => println!("ok"),
+        Ok(_) | Ok(3) => println!("ok"), //~ ERROR: this match arm has an identical body to another arm
+        Err(_) => {
+            unreachable!();
+        },
+    }
+
+    // False positive #1390
+    macro_rules! empty {
+        ($e:expr) => {};
+    }
+    match 0 {
+        0 => {
+            empty!(0);
+        },
+        1 => {
+            empty!(1);
+        },
+        x => {
+            empty!(x);
+        },
+    };
+
+    // still lint if the tokens are the same
+    match 0 {
+        1 | 0 => {
+            empty!(0);
+        },
+        x => {
+            empty!(x);
+        },
+    }
+    //~^^^^^^^ ERROR: this match arm has an identical body to another arm
+
+    match_expr_like_matches_macro_priority();
+}
+
+fn match_expr_like_matches_macro_priority() {
+    enum E {
+        A,
+        B,
+        C,
+    }
+    let x = E::A;
+    let _ans = match x {
+        E::A => false,
+        E::B => false,
+        _ => true,
+    };
+}
+
+fn main() {
+    let _ = match Some(0) {
+        Some(0) => 0,
+        Some(1) => 1,
+        #[cfg(feature = "foo")]
+        Some(2) => 2,
+        _ => 1,
+    };
+
+    enum Foo {
+        X(u32),
+        Y(u32),
+        Z(u32),
+    }
+
+    // Don't lint. `Foo::X(0)` and `Foo::Z(_)` overlap with the arm in between.
+    let _ = match Foo::X(0) {
+        Foo::X(0) => 1,
+        Foo::X(_) | Foo::Y(_) | Foo::Z(0) => 2,
+        Foo::Z(_) => 1,
+        _ => 0,
+    };
+
+    // Suggest moving `Foo::Z(_)` up.
+    let _ = match Foo::X(0) {
+        Foo::X(0) | Foo::Z(_) => 1, //~ ERROR: this match arm has an identical body to another arm
+        Foo::X(_) | Foo::Y(_) => 2,
+        _ => 0,
+    };
+
+    // Suggest moving `Foo::X(0)` down.
+    let _ = match Foo::X(0) {
+        Foo::Y(_) | Foo::Z(0) => 2,
+        Foo::Z(_) | Foo::X(0) => 1, //~ ERROR: this match arm has an identical body to another arm
+        _ => 0,
+    };
+
+    // Don't lint.
+    let _ = match 0 {
+        -2 => 1,
+        -5..=50 => 2,
+        -150..=88 => 1,
+        _ => 3,
+    };
+
+    struct Bar {
+        x: u32,
+        y: u32,
+        z: u32,
+    }
+
+    // Lint.
+    let _ = match None {
+        Some(Bar { y: 10, z: 0, .. }) => 2,
+        None => 50,
+        Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1, //~ ERROR: this match arm has an identical body to another arm
+        _ => 200,
+    };
+
+    let _ = match 0 {
+        0 => todo!(),
+        1 => todo!(),
+        2 => core::convert::identity::<u32>(todo!()),
+        3 => core::convert::identity::<u32>(todo!()),
+        _ => 5,
+    };
+
+    let _ = match 0 {
+        1 | 0 => cfg!(not_enable),
+        _ => false,
+    };
+}
+
+// issue #8919, fixed on https://github.com/rust-lang/rust/pull/97312
+mod with_lifetime {
+    enum MaybeStaticStr<'a> {
+        Static(&'static str),
+        Borrowed(&'a str),
+    }
+
+    impl<'a> MaybeStaticStr<'a> {
+        fn get(&self) -> &'a str {
+            match *self {
+                MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
+                //~^ ERROR: this match arm has an identical body to another arm
+            }
+        }
+    }
+}
diff --git a/tests/ui/match_same_arms2.rs b/tests/ui/match_same_arms2.rs
index dedd02e78733..dfd15d10c3d3 100644
--- a/tests/ui/match_same_arms2.rs
+++ b/tests/ui/match_same_arms2.rs
@@ -7,8 +7,6 @@
     clippy::match_like_matches_macro
 )]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 fn bar<T>(_: T) {}
 fn foo() -> bool {
     unimplemented!()
diff --git a/tests/ui/match_same_arms2.stderr b/tests/ui/match_same_arms2.stderr
index 3a28b5afc2b8..525a25e9287b 100644
--- a/tests/ui/match_same_arms2.stderr
+++ b/tests/ui/match_same_arms2.stderr
@@ -1,5 +1,5 @@
 error: this match arm has an identical body to the `_` wildcard arm
-  --> tests/ui/match_same_arms2.rs:19:9
+  --> tests/ui/match_same_arms2.rs:17:9
    |
 LL | /         42 => {
 LL | |             foo();
@@ -12,7 +12,7 @@ LL | |         _ => {
    |
    = help: or try changing either arm body
 note: `_` wildcard arm here
-  --> tests/ui/match_same_arms2.rs:28:9
+  --> tests/ui/match_same_arms2.rs:26:9
    |
 LL | /         _ => {
 LL | |             foo();
@@ -26,119 +26,103 @@ LL | |         },
    = help: to override `-D warnings` add `#[allow(clippy::match_same_arms)]`
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:42:9
+  --> tests/ui/match_same_arms2.rs:40:9
    |
 LL |         51 => foo(),
    |         ^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         51 | 42 => foo(),
-   |         ~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         42 => foo(),
+LL -         51 => foo(),
+LL +         51 | 42 => foo(),
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:48:9
+  --> tests/ui/match_same_arms2.rs:46:9
    |
 LL |         None => 24,
    |         ^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         None | Some(_) => 24,
-   |         ~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         Some(_) => 24,
+LL -         None => 24,
+LL +         None | Some(_) => 24,
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:70:9
+  --> tests/ui/match_same_arms2.rs:68:9
    |
 LL |         (None, Some(a)) => bar(a),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         (None, Some(a)) | (Some(a), None) => bar(a),
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         (Some(a), None) => bar(a),
+LL -         (None, Some(a)) => bar(a),
+LL +         (None, Some(a)) | (Some(a), None) => bar(a),
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:84:9
+  --> tests/ui/match_same_arms2.rs:82:9
    |
 LL |         (None, Some(a)) if a == 42 => a,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         (None, Some(a)) | (Some(a), None) if a == 42 => a,
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         (Some(a), None) if a == 42 => a,
+LL -         (None, Some(a)) if a == 42 => a,
+LL +         (None, Some(a)) | (Some(a), None) if a == 42 => a,
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:89:9
+  --> tests/ui/match_same_arms2.rs:87:9
    |
 LL |         (Some(a), ..) => bar(a),
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL |         (Some(a), ..) | (.., Some(a)) => bar(a),
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
-   |
-LL -         (.., Some(a)) => bar(a),
+LL ~         (Some(a), ..) | (.., Some(a)) => bar(a),
+LL ~         _ => (),
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:123:9
+  --> tests/ui/match_same_arms2.rs:121:9
    |
 LL |         (Ok(x), Some(_)) => println!("ok {}", x),
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x),
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL -         (Ok(_), Some(x)) => println!("ok {}", x),
+LL ~         (Ok(x), Some(_)) | (Ok(_), Some(x)) => println!("ok {}", x),
+LL ~         _ => println!("err"),
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:139:9
+  --> tests/ui/match_same_arms2.rs:137:9
    |
 LL |         Ok(_) => println!("ok"),
    |         ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         Ok(_) | Ok(3) => println!("ok"),
-   |         ~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         Ok(3) => println!("ok"),
+LL -         Ok(_) => println!("ok"),
+LL +         Ok(_) | Ok(3) => println!("ok"),
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:166:9
+  --> tests/ui/match_same_arms2.rs:164:9
    |
 LL | /         1 => {
 LL | |             empty!(0);
@@ -146,95 +130,82 @@ LL | |         },
    | |_________^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         1 | 0 => {
-   |         ~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         0 => {
 LL -             empty!(0);
 LL -         },
+LL -         1 => {
+LL +         1 | 0 => {
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:217:9
+  --> tests/ui/match_same_arms2.rs:215:9
    |
 LL |         Foo::X(0) => 1,
    |         ^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         Foo::X(0) | Foo::Z(_) => 1,
-   |         ~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL -         Foo::Z(_) => 1,
+LL ~         Foo::X(0) | Foo::Z(_) => 1,
+LL |         Foo::X(_) | Foo::Y(_) => 2,
+LL ~         _ => 0,
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:227:9
+  --> tests/ui/match_same_arms2.rs:225:9
    |
 LL |         Foo::Z(_) => 1,
    |         ^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         Foo::Z(_) | Foo::X(0) => 1,
-   |         ~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL -         Foo::X(0) => 1,
+LL ~         Foo::Y(_) | Foo::Z(0) => 2,
+LL ~         Foo::Z(_) | Foo::X(0) => 1,
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:250:9
+  --> tests/ui/match_same_arms2.rs:248:9
    |
 LL |         Some(Bar { y: 0, x: 5, .. }) => 1,
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
+help: or try merging the arm patterns and removing the obsolete arm
    |
-LL |         Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1,
-   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
-   |
-LL -         Some(Bar { x: 0, y: 5, .. }) => 1,
+LL ~         Some(Bar { y: 10, z: 0, .. }) => 2,
+LL |         None => 50,
+LL ~         Some(Bar { y: 0, x: 5, .. }) | Some(Bar { x: 0, y: 5, .. }) => 1,
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:264:9
+  --> tests/ui/match_same_arms2.rs:262:9
    |
 LL |         1 => cfg!(not_enable),
    |         ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |         1 | 0 => cfg!(not_enable),
-   |         ~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -         0 => cfg!(not_enable),
+LL -         1 => cfg!(not_enable),
+LL +         1 | 0 => cfg!(not_enable),
    |
 
 error: this match arm has an identical body to another arm
-  --> tests/ui/match_same_arms2.rs:280:17
+  --> tests/ui/match_same_arms2.rs:278:17
    |
 LL |                 MaybeStaticStr::Borrowed(s) => s,
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: try changing either arm body
-help: or try merging the arm patterns
-   |
-LL |                 MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
-   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-help: and remove this obsolete arm
+help: or try merging the arm patterns and removing the obsolete arm
    |
 LL -                 MaybeStaticStr::Static(s) => s,
+LL -                 MaybeStaticStr::Borrowed(s) => s,
+LL +                 MaybeStaticStr::Borrowed(s) | MaybeStaticStr::Static(s) => s,
    |
 
 error: aborting due to 14 previous errors
diff --git a/tests/ui/must_use_unit.fixed b/tests/ui/must_use_unit.fixed
index f255cb666528..b92d9379c904 100644
--- a/tests/ui/must_use_unit.fixed
+++ b/tests/ui/must_use_unit.fixed
@@ -23,3 +23,9 @@ fn main() {
         fn foo() {}
     );
 }
+
+#[cfg_attr(all(), deprecated)]
+fn issue_12320() {}
+
+#[cfg_attr(all(), deprecated, doc = "foo")]
+fn issue_12320_2() {}
diff --git a/tests/ui/must_use_unit.rs b/tests/ui/must_use_unit.rs
index 1305910ed0e5..c77e72827504 100644
--- a/tests/ui/must_use_unit.rs
+++ b/tests/ui/must_use_unit.rs
@@ -26,3 +26,9 @@ fn main() {
         fn foo() {}
     );
 }
+
+#[cfg_attr(all(), must_use, deprecated)]
+fn issue_12320() {}
+
+#[cfg_attr(all(), deprecated, doc = "foo", must_use)]
+fn issue_12320_2() {}
diff --git a/tests/ui/must_use_unit.stderr b/tests/ui/must_use_unit.stderr
index c2ee2edda7dc..b435568deeab 100644
--- a/tests/ui/must_use_unit.stderr
+++ b/tests/ui/must_use_unit.stderr
@@ -25,5 +25,21 @@ LL | #[must_use = "With note"]
 LL | pub fn must_use_with_note() {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 3 previous errors
+error: this unit-returning function has a `#[must_use]` attribute
+  --> tests/ui/must_use_unit.rs:31:1
+   |
+LL | #[cfg_attr(all(), must_use, deprecated)]
+   |                   -------------------- help: change these attributes to: `deprecated`
+LL | fn issue_12320() {}
+   | ^^^^^^^^^^^^^^^^
+
+error: this unit-returning function has a `#[must_use]` attribute
+  --> tests/ui/must_use_unit.rs:34:1
+   |
+LL | #[cfg_attr(all(), deprecated, doc = "foo", must_use)]
+   |                   --------------------------------- help: change these attributes to: `deprecated, doc = "foo"`
+LL | fn issue_12320_2() {}
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/needless_lifetimes.fixed b/tests/ui/needless_lifetimes.fixed
index cfa4cf9da3c5..8196d608abd2 100644
--- a/tests/ui/needless_lifetimes.fixed
+++ b/tests/ui/needless_lifetimes.fixed
@@ -562,4 +562,18 @@ mod rayon {
     }
 }
 
+mod issue13749 {
+    pub struct Generic<T>(T);
+    // Non elidable lifetime
+    #[expect(clippy::extra_unused_lifetimes)]
+    impl<'a, T> Generic<T> where T: 'a {}
+}
+
+mod issue13749bis {
+    pub struct Generic<T>(T);
+    // Non elidable lifetime
+    #[expect(clippy::extra_unused_lifetimes)]
+    impl<'a, T: 'a> Generic<T> {}
+}
+
 fn main() {}
diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs
index 5e9d51164268..b55dd99c46d0 100644
--- a/tests/ui/needless_lifetimes.rs
+++ b/tests/ui/needless_lifetimes.rs
@@ -562,4 +562,18 @@ mod rayon {
     }
 }
 
+mod issue13749 {
+    pub struct Generic<T>(T);
+    // Non elidable lifetime
+    #[expect(clippy::extra_unused_lifetimes)]
+    impl<'a, T> Generic<T> where T: 'a {}
+}
+
+mod issue13749bis {
+    pub struct Generic<T>(T);
+    // Non elidable lifetime
+    #[expect(clippy::extra_unused_lifetimes)]
+    impl<'a, T: 'a> Generic<T> {}
+}
+
 fn main() {}
diff --git a/tests/ui/needless_match.fixed b/tests/ui/needless_match.fixed
index a936eb463f96..06c6169d0da0 100644
--- a/tests/ui/needless_match.fixed
+++ b/tests/ui/needless_match.fixed
@@ -245,4 +245,57 @@ mod issue9084 {
     }
 }
 
+fn a() -> Option<()> {
+    Some(())
+}
+fn b() -> Option<()> {
+    Some(())
+}
+fn c() -> Option<()> {
+    Some(())
+}
+
+#[allow(clippy::ifs_same_cond)]
+pub fn issue13574() -> Option<()> {
+    // Do not lint.
+    // The right hand of all these arms are different functions.
+    let _ = {
+        if let Some(a) = a() {
+            Some(a)
+        } else if let Some(b) = b() {
+            Some(b)
+        } else if let Some(c) = c() {
+            Some(c)
+        } else {
+            None
+        }
+    };
+
+    const A: Option<()> = Some(());
+    const B: Option<()> = Some(());
+    const C: Option<()> = Some(());
+    const D: Option<()> = Some(());
+
+    let _ = {
+        if let Some(num) = A {
+            Some(num)
+        } else if let Some(num) = B {
+            Some(num)
+        } else if let Some(num) = C {
+            Some(num)
+        } else if let Some(num) = D {
+            Some(num)
+        } else {
+            None
+        }
+    };
+
+    // Same const, should lint
+    let _ = {
+        A
+    };
+
+    None
+}
+
 fn main() {}
diff --git a/tests/ui/needless_match.rs b/tests/ui/needless_match.rs
index b1dd6ff075d8..6b71de68e1be 100644
--- a/tests/ui/needless_match.rs
+++ b/tests/ui/needless_match.rs
@@ -289,4 +289,65 @@ mod issue9084 {
     }
 }
 
+fn a() -> Option<()> {
+    Some(())
+}
+fn b() -> Option<()> {
+    Some(())
+}
+fn c() -> Option<()> {
+    Some(())
+}
+
+#[allow(clippy::ifs_same_cond)]
+pub fn issue13574() -> Option<()> {
+    // Do not lint.
+    // The right hand of all these arms are different functions.
+    let _ = {
+        if let Some(a) = a() {
+            Some(a)
+        } else if let Some(b) = b() {
+            Some(b)
+        } else if let Some(c) = c() {
+            Some(c)
+        } else {
+            None
+        }
+    };
+
+    const A: Option<()> = Some(());
+    const B: Option<()> = Some(());
+    const C: Option<()> = Some(());
+    const D: Option<()> = Some(());
+
+    let _ = {
+        if let Some(num) = A {
+            Some(num)
+        } else if let Some(num) = B {
+            Some(num)
+        } else if let Some(num) = C {
+            Some(num)
+        } else if let Some(num) = D {
+            Some(num)
+        } else {
+            None
+        }
+    };
+
+    // Same const, should lint
+    let _ = {
+        if let Some(num) = A {
+            Some(num)
+        } else if let Some(num) = A {
+            Some(num)
+        } else if let Some(num) = A {
+            Some(num)
+        } else {
+            None
+        }
+    };
+
+    None
+}
+
 fn main() {}
diff --git a/tests/ui/needless_match.stderr b/tests/ui/needless_match.stderr
index 5bcab467aeae..1410585cb2e3 100644
--- a/tests/ui/needless_match.stderr
+++ b/tests/ui/needless_match.stderr
@@ -131,5 +131,17 @@ LL | |             _ => e,
 LL | |         };
    | |_________^ help: replace it with: `e`
 
-error: aborting due to 13 previous errors
+error: this if-let expression is unnecessary
+  --> tests/ui/needless_match.rs:339:9
+   |
+LL | /         if let Some(num) = A {
+LL | |             Some(num)
+LL | |         } else if let Some(num) = A {
+LL | |             Some(num)
+...  |
+LL | |             None
+LL | |         }
+   | |_________^ help: replace it with: `A`
+
+error: aborting due to 14 previous errors
 
diff --git a/tests/ui/needless_option_take.fixed b/tests/ui/needless_option_take.fixed
deleted file mode 100644
index d732a2686cb9..000000000000
--- a/tests/ui/needless_option_take.fixed
+++ /dev/null
@@ -1,13 +0,0 @@
-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();
-
-    println!("Testing erroneous option_take_on_temporary");
-    let x = Some(3);
-    x.as_ref();
-}
diff --git a/tests/ui/needless_option_take.rs b/tests/ui/needless_option_take.rs
index f947d874e064..c6807718a758 100644
--- a/tests/ui/needless_option_take.rs
+++ b/tests/ui/needless_option_take.rs
@@ -1,3 +1,15 @@
+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);
@@ -7,7 +19,40 @@ fn main() {
     let x = Some(3);
     x.as_ref();
 
-    println!("Testing erroneous option_take_on_temporary");
     let x = Some(3);
     x.as_ref().take();
+    //~^ 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().take();
+    //~^ ERROR: called `Option::take()` on a temporary value
+    let y = x.replace(289).take();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let y = Some(3).as_mut().take();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let y = Option::as_mut(&mut x).take();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let x = return_option();
+    let x = return_option().take();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let x = MyStruct::get_option();
+    let x = MyStruct::get_option().take();
+    //~^ 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().take();
+    //~^ ERROR: called `Option::take()` on a temporary value
+
+    let y = my_vec.first().take();
+    //~^ ERROR: called `Option::take()` on a temporary value
 }
diff --git a/tests/ui/needless_option_take.stderr b/tests/ui/needless_option_take.stderr
index 4a73ccb86d08..e036bd53170a 100644
--- a/tests/ui/needless_option_take.stderr
+++ b/tests/ui/needless_option_take.stderr
@@ -1,11 +1,76 @@
 error: called `Option::take()` on a temporary value
-  --> tests/ui/needless_option_take.rs:12:5
+  --> tests/ui/needless_option_take.rs:23:5
    |
 LL |     x.as_ref().take();
-   |     ^^^^^^^^^^^^^^^^^ help: try: `x.as_ref()`
+   |     ^^^^^^^^^^^^^^^^^
    |
+   = note: `as_ref` creates a temporary value, so calling take() has no effect
    = note: `-D clippy::needless-option-take` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::needless_option_take)]`
 
-error: aborting due to 1 previous error
+error: called `Option::take()` on a temporary value
+  --> tests/ui/needless_option_take.rs:31:13
+   |
+LL |     let y = x.as_mut().take();
+   |             ^^^^^^^^^^^^^^^^^
+   |
+   = note: `as_mut` creates a temporary value, so calling take() has no effect
+
+error: called `Option::take()` on a temporary value
+  --> tests/ui/needless_option_take.rs:33:13
+   |
+LL |     let y = x.replace(289).take();
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `replace` creates a temporary value, so calling take() has no effect
+
+error: called `Option::take()` on a temporary value
+  --> tests/ui/needless_option_take.rs:36:13
+   |
+LL |     let y = Some(3).as_mut().take();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `as_mut` creates a temporary value, so calling take() has no effect
+
+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();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `as_mut` creates a temporary value, so calling take() has no effect
+
+error: called `Option::take()` on a temporary value
+  --> tests/ui/needless_option_take.rs:43:13
+   |
+LL |     let x = return_option().take();
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `return_option` creates a temporary value, so calling take() has no effect
+
+error: called `Option::take()` on a temporary value
+  --> tests/ui/needless_option_take.rs:47:13
+   |
+LL |     let x = MyStruct::get_option().take();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `get_option` creates a temporary value, so calling take() has no effect
+
+error: called `Option::take()` on a temporary value
+  --> tests/ui/needless_option_take.rs:53:13
+   |
+LL |     let y = my_vec.first().take();
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `first` creates a temporary value, so calling take() has no effect
+
+error: called `Option::take()` on a temporary value
+  --> tests/ui/needless_option_take.rs:56:13
+   |
+LL |     let y = my_vec.first().take();
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `first` creates a temporary value, so calling take() has no effect
+
+error: aborting due to 9 previous errors
 
diff --git a/tests/ui/precedence.fixed b/tests/ui/precedence.fixed
index c25c2062aceb..9864dd2550b6 100644
--- a/tests/ui/precedence.fixed
+++ b/tests/ui/precedence.fixed
@@ -20,6 +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;
 
     let b = 3;
     trip!(b * 8);
diff --git a/tests/ui/precedence.rs b/tests/ui/precedence.rs
index dc242ecf4c72..9ef5c43833f8 100644
--- a/tests/ui/precedence.rs
+++ b/tests/ui/precedence.rs
@@ -20,6 +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;
 
     let b = 3;
     trip!(b * 8);
diff --git a/tests/ui/precedence.stderr b/tests/ui/precedence.stderr
index 8057c25a5e49..0d63e827d66e 100644
--- a/tests/ui/precedence.stderr
+++ b/tests/ui/precedence.stderr
@@ -43,5 +43,29 @@ error: operator precedence can trip the unwary
 LL |     3 & 5 - 2;
    |     ^^^^^^^^^ help: consider parenthesizing your expression: `3 & (5 - 2)`
 
-error: aborting due to 7 previous errors
+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
 
diff --git a/tests/ui/print_literal.fixed b/tests/ui/print_literal.fixed
index a7157c07f8a9..1705a7ff01bb 100644
--- a/tests/ui/print_literal.fixed
+++ b/tests/ui/print_literal.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::print_literal)]
-#![allow(clippy::uninlined_format_args)]
+#![allow(clippy::uninlined_format_args, clippy::literal_string_with_formatting_args)]
 
 fn main() {
     // these should be fine
diff --git a/tests/ui/print_literal.rs b/tests/ui/print_literal.rs
index 4b04b42744cc..d10b26b5887c 100644
--- a/tests/ui/print_literal.rs
+++ b/tests/ui/print_literal.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::print_literal)]
-#![allow(clippy::uninlined_format_args)]
+#![allow(clippy::uninlined_format_args, clippy::literal_string_with_formatting_args)]
 
 fn main() {
     // these should be fine
diff --git a/tests/ui/rename.fixed b/tests/ui/rename.fixed
index 47149622ef7c..47d6e119543d 100644
--- a/tests/ui/rename.fixed
+++ b/tests/ui/rename.fixed
@@ -15,6 +15,7 @@
 #![allow(clippy::mixed_read_write_in_expression)]
 #![allow(clippy::manual_find_map)]
 #![allow(clippy::manual_filter_map)]
+#![allow(unpredictable_function_pointer_comparisons)]
 #![allow(clippy::useless_conversion)]
 #![allow(clippy::redundant_pattern_matching)]
 #![allow(clippy::match_result_ok)]
diff --git a/tests/ui/rename.rs b/tests/ui/rename.rs
index 7a78a5d280dd..12c7db69be2e 100644
--- a/tests/ui/rename.rs
+++ b/tests/ui/rename.rs
@@ -15,6 +15,7 @@
 #![allow(clippy::mixed_read_write_in_expression)]
 #![allow(clippy::manual_find_map)]
 #![allow(clippy::manual_filter_map)]
+#![allow(unpredictable_function_pointer_comparisons)]
 #![allow(clippy::useless_conversion)]
 #![allow(clippy::redundant_pattern_matching)]
 #![allow(clippy::match_result_ok)]
diff --git a/tests/ui/rename.stderr b/tests/ui/rename.stderr
index dc24bc16d0ea..1ec45c4f1f7b 100644
--- a/tests/ui/rename.stderr
+++ b/tests/ui/rename.stderr
@@ -1,5 +1,5 @@
 error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
-  --> tests/ui/rename.rs:64:9
+  --> tests/ui/rename.rs:65:9
    |
 LL | #![warn(clippy::almost_complete_letter_range)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
@@ -8,397 +8,397 @@ LL | #![warn(clippy::almost_complete_letter_range)]
    = help: to override `-D warnings` add `#[allow(renamed_and_removed_lints)]`
 
 error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
-  --> tests/ui/rename.rs:65:9
+  --> tests/ui/rename.rs:66:9
    |
 LL | #![warn(clippy::blacklisted_name)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
 
 error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions`
-  --> tests/ui/rename.rs:66:9
+  --> tests/ui/rename.rs:67:9
    |
 LL | #![warn(clippy::block_in_if_condition_expr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
 
 error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions`
-  --> tests/ui/rename.rs:67:9
+  --> tests/ui/rename.rs:68:9
    |
 LL | #![warn(clippy::block_in_if_condition_stmt)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
 
 error: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions`
-  --> tests/ui/rename.rs:68:9
+  --> tests/ui/rename.rs:69:9
    |
 LL | #![warn(clippy::blocks_in_if_conditions)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
 
 error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
-  --> tests/ui/rename.rs:69:9
+  --> tests/ui/rename.rs:70:9
    |
 LL | #![warn(clippy::box_vec)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
 
 error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
-  --> tests/ui/rename.rs:70:9
+  --> tests/ui/rename.rs:71:9
    |
 LL | #![warn(clippy::const_static_lifetime)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
 
 error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
-  --> tests/ui/rename.rs:71:9
+  --> tests/ui/rename.rs:72:9
    |
 LL | #![warn(clippy::cyclomatic_complexity)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
 
 error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
-  --> tests/ui/rename.rs:72:9
+  --> tests/ui/rename.rs:73:9
    |
 LL | #![warn(clippy::derive_hash_xor_eq)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
 
 error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
-  --> tests/ui/rename.rs:73:9
+  --> tests/ui/rename.rs:74:9
    |
 LL | #![warn(clippy::disallowed_method)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
 
 error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
-  --> tests/ui/rename.rs:74:9
+  --> tests/ui/rename.rs:75:9
    |
 LL | #![warn(clippy::disallowed_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
 
 error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
-  --> tests/ui/rename.rs:75:9
+  --> tests/ui/rename.rs:76:9
    |
 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:76:9
+  --> 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:77:9
+  --> tests/ui/rename.rs:78: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:78:9
+  --> tests/ui/rename.rs:79:9
    |
 LL | #![warn(clippy::fn_address_comparisons)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unpredictable_function_pointer_comparisons`
 
 error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
-  --> tests/ui/rename.rs:79:9
+  --> tests/ui/rename.rs:80: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:80:9
+  --> tests/ui/rename.rs:81: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:81:9
+  --> tests/ui/rename.rs:82: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:82:9
+  --> tests/ui/rename.rs:83: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:83:9
+  --> tests/ui/rename.rs:84: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:84:9
+  --> tests/ui/rename.rs:85: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:85:9
+  --> tests/ui/rename.rs:86: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:86:9
+  --> tests/ui/rename.rs:87: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:87:9
+  --> tests/ui/rename.rs:88: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:88:9
+  --> tests/ui/rename.rs:89: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:89:9
+  --> tests/ui/rename.rs:90: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:90:9
+  --> tests/ui/rename.rs:91: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:91:9
+  --> tests/ui/rename.rs:92: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:92:9
+  --> tests/ui/rename.rs:93: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:93:9
+  --> tests/ui/rename.rs:94: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:94:9
+  --> tests/ui/rename.rs:95: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:95:9
+  --> tests/ui/rename.rs:96: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:96:9
+  --> tests/ui/rename.rs:97:9
    |
 LL | #![warn(clippy::result_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
-  --> tests/ui/rename.rs:97:9
+  --> tests/ui/rename.rs:98:9
    |
 LL | #![warn(clippy::single_char_push_str)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
 
 error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
-  --> tests/ui/rename.rs:98:9
+  --> tests/ui/rename.rs:99:9
    |
 LL | #![warn(clippy::stutter)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
 
 error: lint `clippy::thread_local_initializer_can_be_made_const` has been renamed to `clippy::missing_const_for_thread_local`
-  --> tests/ui/rename.rs:99:9
+  --> tests/ui/rename.rs:100:9
    |
 LL | #![warn(clippy::thread_local_initializer_can_be_made_const)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::missing_const_for_thread_local`
 
 error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
-  --> tests/ui/rename.rs:100:9
+  --> tests/ui/rename.rs:101:9
    |
 LL | #![warn(clippy::to_string_in_display)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
 
 error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default`
-  --> tests/ui/rename.rs:101:9
+  --> tests/ui/rename.rs:102:9
    |
 LL | #![warn(clippy::unwrap_or_else_default)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default`
 
 error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
-  --> tests/ui/rename.rs:102:9
+  --> tests/ui/rename.rs:103:9
    |
 LL | #![warn(clippy::zero_width_space)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
 
 error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting`
-  --> tests/ui/rename.rs:103:9
+  --> tests/ui/rename.rs:104:9
    |
 LL | #![warn(clippy::cast_ref_to_mut)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting`
 
 error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
-  --> tests/ui/rename.rs:104:9
+  --> tests/ui/rename.rs:105:9
    |
 LL | #![warn(clippy::clone_double_ref)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
 
 error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`
-  --> tests/ui/rename.rs:105:9
+  --> tests/ui/rename.rs:106:9
    |
 LL | #![warn(clippy::cmp_nan)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`
 
 error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
-  --> tests/ui/rename.rs:106:9
+  --> tests/ui/rename.rs:107: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:107:9
+  --> tests/ui/rename.rs:108: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:108:9
+  --> tests/ui/rename.rs:109:9
    |
 LL | #![warn(clippy::drop_ref)]
    |         ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
 
 error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`
-  --> tests/ui/rename.rs:109:9
+  --> tests/ui/rename.rs:110: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:110:9
+  --> tests/ui/rename.rs:111: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:111:9
+  --> tests/ui/rename.rs:112: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:112:9
+  --> tests/ui/rename.rs:113: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:113:9
+  --> tests/ui/rename.rs:114: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:114:9
+  --> tests/ui/rename.rs:115: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:115:9
+  --> tests/ui/rename.rs:116: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:116:9
+  --> tests/ui/rename.rs:117: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:117:9
+  --> tests/ui/rename.rs:118: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:118:9
+  --> tests/ui/rename.rs:119: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:119:9
+  --> tests/ui/rename.rs:120: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:120:9
+  --> tests/ui/rename.rs:121: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:121:9
+  --> tests/ui/rename.rs:122: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:122:9
+  --> tests/ui/rename.rs:123: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:123:9
+  --> tests/ui/rename.rs:124: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:124:9
+  --> tests/ui/rename.rs:125: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:125:9
+  --> tests/ui/rename.rs:126: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:126:9
+  --> tests/ui/rename.rs:127: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:127:9
+  --> tests/ui/rename.rs:128: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:128:9
+  --> tests/ui/rename.rs:129: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:129:9
+  --> tests/ui/rename.rs:130: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:130:9
+  --> tests/ui/rename.rs:131:9
    |
 LL | #![warn(clippy::reverse_range_loop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::reversed_empty_ranges`
diff --git a/tests/ui/repr_packed_without_abi.rs b/tests/ui/repr_packed_without_abi.rs
new file mode 100644
index 000000000000..16b5ededee99
--- /dev/null
+++ b/tests/ui/repr_packed_without_abi.rs
@@ -0,0 +1,37 @@
+#![deny(clippy::repr_packed_without_abi)]
+
+#[repr(packed)]
+struct NetworkPacketHeader {
+    header_length: u8,
+    header_version: u16,
+}
+
+#[repr(packed)]
+union Foo {
+    a: u8,
+    b: u16,
+}
+
+#[repr(C, packed)]
+struct NoLintCNetworkPacketHeader {
+    header_length: u8,
+    header_version: u16,
+}
+
+#[repr(Rust, packed)]
+struct NoLintRustNetworkPacketHeader {
+    header_length: u8,
+    header_version: u16,
+}
+
+#[repr(packed, C)]
+union NotLintCFoo {
+    a: u8,
+    b: u16,
+}
+
+#[repr(packed, Rust)]
+union NotLintRustFoo {
+    a: u8,
+    b: u16,
+}
diff --git a/tests/ui/repr_packed_without_abi.stderr b/tests/ui/repr_packed_without_abi.stderr
new file mode 100644
index 000000000000..4f7acd00db3d
--- /dev/null
+++ b/tests/ui/repr_packed_without_abi.stderr
@@ -0,0 +1,35 @@
+error: item uses `packed` representation without ABI-qualification
+  --> tests/ui/repr_packed_without_abi.rs:4:1
+   |
+LL |   #[repr(packed)]
+   |          ------ `packed` representation set here
+LL | / struct NetworkPacketHeader {
+LL | |     header_length: u8,
+LL | |     header_version: u16,
+LL | | }
+   | |_^
+   |
+   = warning: unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI
+   = help: qualify the desired ABI explicity via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`
+note: the lint level is defined here
+  --> tests/ui/repr_packed_without_abi.rs:1:9
+   |
+LL | #![deny(clippy::repr_packed_without_abi)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: item uses `packed` representation without ABI-qualification
+  --> tests/ui/repr_packed_without_abi.rs:10:1
+   |
+LL |   #[repr(packed)]
+   |          ------ `packed` representation set here
+LL | / union Foo {
+LL | |     a: u8,
+LL | |     b: u16,
+LL | | }
+   | |_^
+   |
+   = warning: unqualified `#[repr(packed)]` defaults to `#[repr(Rust, packed)]`, which has no stable ABI
+   = help: qualify the desired ABI explicity via `#[repr(C, packed)]` or `#[repr(Rust, packed)]`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/result_unit_error_no_std.rs b/tests/ui/result_unit_error_no_std.rs
new file mode 100644
index 000000000000..1e7a028a7fc0
--- /dev/null
+++ b/tests/ui/result_unit_error_no_std.rs
@@ -0,0 +1,26 @@
+#![feature(lang_items, start, libc)]
+#![no_std]
+#![warn(clippy::result_unit_err)]
+
+#[clippy::msrv = "1.80"]
+pub fn returns_unit_error_no_lint() -> Result<u32, ()> {
+    Err(())
+}
+
+#[clippy::msrv = "1.81"]
+pub fn returns_unit_error_lint() -> Result<u32, ()> {
+    Err(())
+}
+
+#[start]
+fn main(_argc: isize, _argv: *const *const u8) -> isize {
+    0
+}
+
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+    loop {}
+}
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
diff --git a/tests/ui/result_unit_error_no_std.stderr b/tests/ui/result_unit_error_no_std.stderr
new file mode 100644
index 000000000000..33692e605543
--- /dev/null
+++ b/tests/ui/result_unit_error_no_std.stderr
@@ -0,0 +1,12 @@
+error: this returns a `Result<_, ()>`
+  --> tests/ui/result_unit_error_no_std.rs:11:1
+   |
+LL | pub fn returns_unit_error_lint() -> Result<u32, ()> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use a custom `Error` type instead
+   = note: `-D clippy::result-unit-err` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::result_unit_err)]`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs
index 258dba9dd831..31944f5ef1b1 100644
--- a/tests/ui/shadow.rs
+++ b/tests/ui/shadow.rs
@@ -119,4 +119,26 @@ fn ice_8748() {
     }];
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/10780
+fn shadow_closure() {
+    // These are not shadow_unrelated; but they are correctly shadow_reuse
+    let x = Some(1);
+    #[allow(clippy::shadow_reuse)]
+    let y = x.map(|x| x + 1);
+    let z = x.map(|x| x + 1);
+    let a: Vec<Option<u8>> = [100u8, 120, 140]
+        .iter()
+        .map(|i| i.checked_mul(2))
+        .map(|i| i.map(|i| i - 10))
+        .collect();
+}
+
+struct Issue13795 {
+    value: i32,
+}
+
+fn issue13795(value: Issue13795) {
+    let Issue13795 { value, .. } = value;
+}
+
 fn main() {}
diff --git a/tests/ui/shadow.stderr b/tests/ui/shadow.stderr
index fdd149a2216f..c8c524b3a2f5 100644
--- a/tests/ui/shadow.stderr
+++ b/tests/ui/shadow.stderr
@@ -280,5 +280,41 @@ note: previous binding is here
 LL |         let x = 1;
    |             ^
 
-error: aborting due to 23 previous errors
+error: `x` is shadowed
+  --> tests/ui/shadow.rs:128:20
+   |
+LL |     let z = x.map(|x| x + 1);
+   |                    ^
+   |
+note: previous binding is here
+  --> tests/ui/shadow.rs:125:9
+   |
+LL |     let x = Some(1);
+   |         ^
+
+error: `i` is shadowed
+  --> tests/ui/shadow.rs:132:25
+   |
+LL |         .map(|i| i.map(|i| i - 10))
+   |                         ^
+   |
+note: previous binding is here
+  --> tests/ui/shadow.rs:132:15
+   |
+LL |         .map(|i| i.map(|i| i - 10))
+   |               ^
+
+error: `value` is shadowed by itself in `value`
+  --> tests/ui/shadow.rs:141:22
+   |
+LL |     let Issue13795 { value, .. } = value;
+   |                      ^^^^^
+   |
+note: previous binding is here
+  --> tests/ui/shadow.rs:140:15
+   |
+LL | fn issue13795(value: Issue13795) {
+   |               ^^^^^
+
+error: aborting due to 26 previous errors
 
diff --git a/tests/ui/significant_drop_tightening.fixed b/tests/ui/significant_drop_tightening.fixed
new file mode 100644
index 000000000000..ed05f6e0c8d3
--- /dev/null
+++ b/tests/ui/significant_drop_tightening.fixed
@@ -0,0 +1,144 @@
+#![warn(clippy::significant_drop_tightening)]
+
+use std::sync::Mutex;
+
+pub fn complex_return_triggers_the_lint() -> i32 {
+    fn foo() -> i32 {
+        1
+    }
+    let mutex = Mutex::new(1);
+    let lock = mutex.lock().unwrap();
+    let _ = *lock;
+    let _ = *lock;
+    drop(lock);
+    foo()
+}
+
+pub fn issue_10413() {
+    let mutex = Mutex::new(Some(1));
+    let opt = Some(1);
+    if opt.is_some() {
+        let lock = mutex.lock().unwrap();
+        let _ = *lock;
+        if opt.is_some() {
+            let _ = *lock;
+        }
+    }
+}
+
+pub fn issue_11128() {
+    use std::mem::drop as unlock;
+
+    struct Foo {
+        droppable: Option<Vec<i32>>,
+        mutex: Mutex<Vec<i32>>,
+    }
+
+    impl Drop for Foo {
+        fn drop(&mut self) {
+            if let Some(droppable) = self.droppable.take() {
+                let lock = self.mutex.lock().unwrap();
+                let idx_opt = lock.iter().copied().find(|el| Some(el) == droppable.first());
+                if let Some(idx) = idx_opt {
+                    let local_droppable = vec![lock.first().copied().unwrap_or_default()];
+                    unlock(lock);
+                    drop(local_droppable);
+                }
+            }
+        }
+    }
+}
+
+pub fn issue_11160() -> bool {
+    let mutex = Mutex::new(1i32);
+    let lock = mutex.lock().unwrap();
+    let _ = lock.abs();
+    true
+}
+
+pub fn issue_11189() {
+    struct Number {
+        pub value: u32,
+    }
+
+    fn do_something() -> Result<(), ()> {
+        let number = Mutex::new(Number { value: 1 });
+        let number2 = Mutex::new(Number { value: 2 });
+        let number3 = Mutex::new(Number { value: 3 });
+        let mut lock = number.lock().unwrap();
+        let mut lock2 = number2.lock().unwrap();
+        let mut lock3 = number3.lock().unwrap();
+        lock.value += 1;
+        lock2.value += 1;
+        lock3.value += 1;
+        drop((lock, lock2, lock3));
+        Ok(())
+    }
+}
+
+pub fn path_return_can_be_ignored() -> i32 {
+    let mutex = Mutex::new(1);
+    let lock = mutex.lock().unwrap();
+    let rslt = *lock;
+    let _ = *lock;
+    rslt
+}
+
+pub fn post_bindings_can_be_ignored() {
+    let mutex = Mutex::new(1);
+    let lock = mutex.lock().unwrap();
+    let rslt = *lock;
+    let another = rslt;
+    let _ = another;
+}
+
+pub fn unnecessary_contention_with_multiple_owned_results() {
+    {
+        let mutex = Mutex::new(1i32);
+        let lock = mutex.lock().unwrap();
+        let _ = lock.abs();
+        let _ = lock.is_positive();
+    }
+
+    {
+        let mutex = Mutex::new(1i32);
+        let lock = mutex.lock().unwrap();
+        let rslt0 = lock.abs();
+        let rslt1 = lock.is_positive();
+        drop(lock);
+        do_heavy_computation_that_takes_time((rslt0, rslt1));
+    }
+}
+
+pub fn unnecessary_contention_with_single_owned_results() {
+    {
+        let mutex = Mutex::new(1i32);
+        let lock = mutex.lock().unwrap();
+        let _ = lock.abs();
+    }
+    {
+        let mutex = Mutex::new(vec![1i32]);
+        let mut lock = mutex.lock().unwrap();
+        lock.clear();
+    }
+
+    {
+        let mutex = Mutex::new(1i32);
+        
+        let rslt0 = mutex.lock().unwrap().abs();
+        
+        do_heavy_computation_that_takes_time(rslt0);
+    }
+    {
+        let mutex = Mutex::new(vec![1i32]);
+        
+        mutex.lock().unwrap().clear();
+        
+        do_heavy_computation_that_takes_time(());
+    }
+}
+
+// Marker used for illustration purposes.
+pub fn do_heavy_computation_that_takes_time<T>(_: T) {}
+
+fn main() {}
diff --git a/tests/ui/significant_drop_tightening.rs b/tests/ui/significant_drop_tightening.rs
index 77538167548e..e5f17278f0f6 100644
--- a/tests/ui/significant_drop_tightening.rs
+++ b/tests/ui/significant_drop_tightening.rs
@@ -1,7 +1,5 @@
 #![warn(clippy::significant_drop_tightening)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 use std::sync::Mutex;
 
 pub fn complex_return_triggers_the_lint() -> i32 {
diff --git a/tests/ui/significant_drop_tightening.stderr b/tests/ui/significant_drop_tightening.stderr
index 7d7e3ac7d0ae..aef774a3d360 100644
--- a/tests/ui/significant_drop_tightening.stderr
+++ b/tests/ui/significant_drop_tightening.stderr
@@ -1,5 +1,5 @@
 error: temporary with significant `Drop` can be early dropped
-  --> tests/ui/significant_drop_tightening.rs:12:9
+  --> tests/ui/significant_drop_tightening.rs:10:9
    |
 LL |   pub fn complex_return_triggers_the_lint() -> i32 {
    |  __________________________________________________-
@@ -23,7 +23,7 @@ LL +     drop(lock);
    |
 
 error: temporary with significant `Drop` can be early dropped
-  --> tests/ui/significant_drop_tightening.rs:106:13
+  --> tests/ui/significant_drop_tightening.rs:104:13
    |
 LL | /     {
 LL | |         let mutex = Mutex::new(1i32);
@@ -43,7 +43,7 @@ LL +         drop(lock);
    |
 
 error: temporary with significant `Drop` can be early dropped
-  --> tests/ui/significant_drop_tightening.rs:127:13
+  --> tests/ui/significant_drop_tightening.rs:125:13
    |
 LL | /     {
 LL | |         let mutex = Mutex::new(1i32);
@@ -59,14 +59,11 @@ help: merge the temporary construction with its single usage
    |
 LL ~         
 LL +         let rslt0 = mutex.lock().unwrap().abs();
-   |
-help: remove separated single usage
-   |
-LL -         let rslt0 = lock.abs();
+LL ~         
    |
 
 error: temporary with significant `Drop` can be early dropped
-  --> tests/ui/significant_drop_tightening.rs:133:17
+  --> tests/ui/significant_drop_tightening.rs:131:17
    |
 LL | /     {
 LL | |         let mutex = Mutex::new(vec![1i32]);
@@ -82,10 +79,7 @@ help: merge the temporary construction with its single usage
    |
 LL ~         
 LL +         mutex.lock().unwrap().clear();
-   |
-help: remove separated single usage
-   |
-LL -         lock.clear();
+LL ~         
    |
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/single_match.fixed b/tests/ui/single_match.fixed
index 4016b2699d6b..d3d5fd8b35c8 100644
--- a/tests/ui/single_match.fixed
+++ b/tests/ui/single_match.fixed
@@ -17,7 +17,13 @@ fn single_match() {
     };
 
     let x = Some(1u8);
-    if let Some(y) = x { println!("{:?}", y) }
+    match x {
+        // Note the missing block braces.
+        // We suggest `if let Some(y) = x { .. }` because the macro
+        // is expanded before we can do anything.
+        Some(y) => println!("{:?}", y),
+        _ => (),
+    }
 
     let z = (1u8, 1u8);
     if let (2..=3, 7..=9) = z { dummy() };
@@ -297,6 +303,10 @@ fn issue11365() {
     if let Some(A | B) = &Some(A) { println!() }
 }
 
+fn issue12758(s: &[u8]) {
+    if &s[0..3] == b"foo" { println!() }
+}
+
 #[derive(Eq, PartialEq)]
 pub struct Data([u8; 4]);
 
@@ -318,5 +328,25 @@ fn irrefutable_match() {
 
     
 
-    println!()
+    println!();
+
+    let mut x = vec![1i8];
+
+    // Should not lint.
+    match x.pop() {
+        // bla
+        Some(u) => println!("{u}"),
+        // more comments!
+        None => {},
+    }
+    // Should not lint.
+    match x.pop() {
+        // bla
+        Some(u) => {
+            // bla
+            println!("{u}");
+        },
+        // bla
+        None => {},
+    }
 }
diff --git a/tests/ui/single_match.rs b/tests/ui/single_match.rs
index 75edaa606053..2f3547c50639 100644
--- a/tests/ui/single_match.rs
+++ b/tests/ui/single_match.rs
@@ -361,6 +361,13 @@ fn issue11365() {
     }
 }
 
+fn issue12758(s: &[u8]) {
+    match &s[0..3] {
+        b"foo" => println!(),
+        _ => {},
+    }
+}
+
 #[derive(Eq, PartialEq)]
 pub struct Data([u8; 4]);
 
@@ -401,4 +408,24 @@ fn irrefutable_match() {
         CONST_I32 => println!(),
         _ => {},
     }
+
+    let mut x = vec![1i8];
+
+    // Should not lint.
+    match x.pop() {
+        // bla
+        Some(u) => println!("{u}"),
+        // more comments!
+        None => {},
+    }
+    // Should not lint.
+    match x.pop() {
+        // bla
+        Some(u) => {
+            // bla
+            println!("{u}");
+        },
+        // bla
+        None => {},
+    }
 }
diff --git a/tests/ui/single_match.stderr b/tests/ui/single_match.stderr
index dd03737279ad..54bbfbac093c 100644
--- a/tests/ui/single_match.stderr
+++ b/tests/ui/single_match.stderr
@@ -18,15 +18,6 @@ LL +         println!("{:?}", y);
 LL ~     };
    |
 
-error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:23:5
-   |
-LL | /     match x {
-...  |
-LL | |         _ => (),
-LL | |     }
-   | |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
-
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
   --> tests/ui/single_match.rs:32:5
    |
@@ -213,8 +204,17 @@ LL | |         None | Some(_) => {},
 LL | |     }
    | |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }`
 
+error: you seem to be trying to use `match` for an equality check. Consider using `if`
+  --> tests/ui/single_match.rs:365:5
+   |
+LL | /     match &s[0..3] {
+LL | |         b"foo" => println!(),
+LL | |         _ => {},
+LL | |     }
+   | |_____^ help: try: `if &s[0..3] == b"foo" { println!() }`
+
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:371:5
+  --> tests/ui/single_match.rs:378:5
    |
 LL | /     match DATA {
 LL | |         DATA => println!(),
@@ -223,7 +223,7 @@ LL | |     }
    | |_____^ help: try: `println!();`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:376:5
+  --> tests/ui/single_match.rs:383:5
    |
 LL | /     match CONST_I32 {
 LL | |         CONST_I32 => println!(),
@@ -232,7 +232,7 @@ LL | |     }
    | |_____^ help: try: `println!();`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:382:5
+  --> tests/ui/single_match.rs:389:5
    |
 LL | /     match i {
 LL | |         i => {
@@ -252,7 +252,7 @@ LL +     }
    |
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:390:5
+  --> tests/ui/single_match.rs:397:5
    |
 LL | /     match i {
 LL | |         i => {},
@@ -261,7 +261,7 @@ LL | |     }
    | |_____^ help: `match` expression can be removed
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:395:5
+  --> tests/ui/single_match.rs:402:5
    |
 LL | /     match i {
 LL | |         i => (),
@@ -270,13 +270,13 @@ LL | |     }
    | |_____^ help: `match` expression can be removed
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:400:5
+  --> tests/ui/single_match.rs:407:5
    |
 LL | /     match CONST_I32 {
 LL | |         CONST_I32 => println!(),
 LL | |         _ => {},
 LL | |     }
-   | |_____^ help: try: `println!()`
+   | |_____^ help: try: `println!();`
 
 error: aborting due to 26 previous errors
 
diff --git a/tests/ui/trailing_empty_array.rs b/tests/ui/trailing_empty_array.rs
index 3d06c2621681..309a5920dfde 100644
--- a/tests/ui/trailing_empty_array.rs
+++ b/tests/ui/trailing_empty_array.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::trailing_empty_array)]
+#![allow(clippy::repr_packed_without_abi)]
 
 // Do lint:
 
diff --git a/tests/ui/trailing_empty_array.stderr b/tests/ui/trailing_empty_array.stderr
index 756381478f2b..7ebff372cf75 100644
--- a/tests/ui/trailing_empty_array.stderr
+++ b/tests/ui/trailing_empty_array.stderr
@@ -1,5 +1,5 @@
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:5:1
+  --> tests/ui/trailing_empty_array.rs:6:1
    |
 LL | / struct RarelyUseful {
 LL | |
@@ -13,7 +13,7 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::trailing_empty_array)]`
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:11:1
+  --> tests/ui/trailing_empty_array.rs:12:1
    |
 LL | / struct OnlyField {
 LL | |
@@ -24,7 +24,7 @@ LL | | }
    = help: consider annotating `OnlyField` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:16:1
+  --> tests/ui/trailing_empty_array.rs:17:1
    |
 LL | / struct GenericArrayType<T> {
 LL | |
@@ -36,7 +36,7 @@ LL | | }
    = help: consider annotating `GenericArrayType` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:23:1
+  --> tests/ui/trailing_empty_array.rs:24:1
    |
 LL | / struct OnlyAnotherAttribute {
 LL | |
@@ -48,7 +48,7 @@ LL | | }
    = help: consider annotating `OnlyAnotherAttribute` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:30:1
+  --> tests/ui/trailing_empty_array.rs:31:1
    |
 LL | / struct OnlyADeriveAttribute {
 LL | |
@@ -60,7 +60,7 @@ LL | | }
    = help: consider annotating `OnlyADeriveAttribute` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:37:1
+  --> tests/ui/trailing_empty_array.rs:38:1
    |
 LL | / struct ZeroSizedWithConst {
 LL | |
@@ -72,7 +72,7 @@ LL | | }
    = help: consider annotating `ZeroSizedWithConst` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:47:1
+  --> tests/ui/trailing_empty_array.rs:48:1
    |
 LL | / struct ZeroSizedWithConstFunction {
 LL | |
@@ -84,7 +84,7 @@ LL | | }
    = help: consider annotating `ZeroSizedWithConstFunction` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:56:1
+  --> tests/ui/trailing_empty_array.rs:57:1
    |
 LL | / struct ZeroSizedWithConstFunction2 {
 LL | |
@@ -96,7 +96,7 @@ LL | | }
    = help: consider annotating `ZeroSizedWithConstFunction2` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:62:1
+  --> tests/ui/trailing_empty_array.rs:63:1
    |
 LL | struct ZeroSizedArrayWrapper([usize; 0]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -104,7 +104,7 @@ LL | struct ZeroSizedArrayWrapper([usize; 0]);
    = help: consider annotating `ZeroSizedArrayWrapper` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:65:1
+  --> tests/ui/trailing_empty_array.rs:66:1
    |
 LL | struct TupleStruct(i32, [usize; 0]);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -112,7 +112,7 @@ LL | struct TupleStruct(i32, [usize; 0]);
    = help: consider annotating `TupleStruct` with `#[repr(C)]` or another `repr` attribute
 
 error: trailing zero-sized array in a struct which is not marked with a `repr` attribute
-  --> tests/ui/trailing_empty_array.rs:68:1
+  --> tests/ui/trailing_empty_array.rs:69:1
    |
 LL | / struct LotsOfFields {
 LL | |
diff --git a/tests/ui/uninlined_format_args_panic.edition2018.fixed b/tests/ui/uninlined_format_args_panic.edition2018.fixed
index f0d570efdcee..9911d1317070 100644
--- a/tests/ui/uninlined_format_args_panic.edition2018.fixed
+++ b/tests/ui/uninlined_format_args_panic.edition2018.fixed
@@ -3,6 +3,7 @@
 //@[edition2021] edition:2021
 
 #![warn(clippy::uninlined_format_args)]
+#![allow(clippy::literal_string_with_formatting_args)]
 
 fn main() {
     let var = 1;
diff --git a/tests/ui/uninlined_format_args_panic.edition2018.stderr b/tests/ui/uninlined_format_args_panic.edition2018.stderr
index 0541dd9a7d7b..4b154abac5bc 100644
--- a/tests/ui/uninlined_format_args_panic.edition2018.stderr
+++ b/tests/ui/uninlined_format_args_panic.edition2018.stderr
@@ -1,5 +1,5 @@
 error: variables can be used directly in the `format!` string
-  --> tests/ui/uninlined_format_args_panic.rs:10:5
+  --> tests/ui/uninlined_format_args_panic.rs:11:5
    |
 LL |     println!("val='{}'", var);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/uninlined_format_args_panic.edition2021.fixed b/tests/ui/uninlined_format_args_panic.edition2021.fixed
index 7c0f28c45764..87b74670565f 100644
--- a/tests/ui/uninlined_format_args_panic.edition2021.fixed
+++ b/tests/ui/uninlined_format_args_panic.edition2021.fixed
@@ -3,6 +3,7 @@
 //@[edition2021] edition:2021
 
 #![warn(clippy::uninlined_format_args)]
+#![allow(clippy::literal_string_with_formatting_args)]
 
 fn main() {
     let var = 1;
diff --git a/tests/ui/uninlined_format_args_panic.edition2021.stderr b/tests/ui/uninlined_format_args_panic.edition2021.stderr
index 3615eaa9dee3..7638d3f8bbad 100644
--- a/tests/ui/uninlined_format_args_panic.edition2021.stderr
+++ b/tests/ui/uninlined_format_args_panic.edition2021.stderr
@@ -1,5 +1,5 @@
 error: variables can be used directly in the `format!` string
-  --> tests/ui/uninlined_format_args_panic.rs:10:5
+  --> tests/ui/uninlined_format_args_panic.rs:11:5
    |
 LL |     println!("val='{}'", var);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     println!("val='{var}'");
    |
 
 error: variables can be used directly in the `format!` string
-  --> tests/ui/uninlined_format_args_panic.rs:13:9
+  --> tests/ui/uninlined_format_args_panic.rs:14:9
    |
 LL |         panic!("p1 {}", var);
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL +         panic!("p1 {var}");
    |
 
 error: variables can be used directly in the `format!` string
-  --> tests/ui/uninlined_format_args_panic.rs:16:9
+  --> tests/ui/uninlined_format_args_panic.rs:17:9
    |
 LL |         panic!("p2 {0}", var);
    |         ^^^^^^^^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL +         panic!("p2 {var}");
    |
 
 error: variables can be used directly in the `format!` string
-  --> tests/ui/uninlined_format_args_panic.rs:19:9
+  --> tests/ui/uninlined_format_args_panic.rs:20:9
    |
 LL |         panic!("p3 {var}", var = var);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL +         panic!("p3 {var}");
    |
 
 error: variables can be used directly in the `format!` string
-  --> tests/ui/uninlined_format_args_panic.rs:29:5
+  --> tests/ui/uninlined_format_args_panic.rs:30:5
    |
 LL |     assert!(var == 1, "p5 {}", var);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL +     assert!(var == 1, "p5 {var}");
    |
 
 error: variables can be used directly in the `format!` string
-  --> tests/ui/uninlined_format_args_panic.rs:30:5
+  --> tests/ui/uninlined_format_args_panic.rs:31:5
    |
 LL |     debug_assert!(var == 1, "p6 {}", var);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/uninlined_format_args_panic.rs b/tests/ui/uninlined_format_args_panic.rs
index fa594d9a96f0..647c69bc5c41 100644
--- a/tests/ui/uninlined_format_args_panic.rs
+++ b/tests/ui/uninlined_format_args_panic.rs
@@ -3,6 +3,7 @@
 //@[edition2021] edition:2021
 
 #![warn(clippy::uninlined_format_args)]
+#![allow(clippy::literal_string_with_formatting_args)]
 
 fn main() {
     let var = 1;
diff --git a/tests/ui/unnecessary_iter_cloned.fixed b/tests/ui/unnecessary_iter_cloned.fixed
new file mode 100644
index 000000000000..dc5e163ff04e
--- /dev/null
+++ b/tests/ui/unnecessary_iter_cloned.fixed
@@ -0,0 +1,201 @@
+#![allow(unused_assignments)]
+#![warn(clippy::unnecessary_to_owned)]
+
+#[allow(dead_code)]
+#[derive(Clone, Copy)]
+enum FileType {
+    Account,
+    PrivateKey,
+    Certificate,
+}
+
+fn main() {
+    let path = std::path::Path::new("x");
+
+    let _ = check_files(&[(FileType::Account, path)]);
+    let _ = check_files_vec(vec![(FileType::Account, path)]);
+
+    // negative tests
+    let _ = check_files_ref(&[(FileType::Account, path)]);
+    let _ = check_files_mut(&[(FileType::Account, path)]);
+    let _ = check_files_ref_mut(&[(FileType::Account, path)]);
+    let _ = check_files_self_and_arg(&[(FileType::Account, path)]);
+    let _ = check_files_mut_path_buf(&[(FileType::Account, std::path::PathBuf::new())]);
+
+    check_mut_iteratee_and_modify_inner_variable();
+}
+
+// `check_files` and its variants are based on:
+// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
+fn check_files(files: &[(FileType, &std::path::Path)]) -> bool {
+    for (t, path) in files {
+        let other = match get_file_path(t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.is_file() || !other.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+fn check_files_vec(files: Vec<(FileType, &std::path::Path)>) -> bool {
+    for (t, path) in files.iter() {
+        let other = match get_file_path(t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.is_file() || !other.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+fn check_files_ref(files: &[(FileType, &std::path::Path)]) -> bool {
+    for (ref t, path) in files.iter().copied() {
+        let other = match get_file_path(t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.is_file() || !other.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+#[allow(unused_assignments)]
+fn check_files_mut(files: &[(FileType, &std::path::Path)]) -> bool {
+    for (mut t, path) in files.iter().copied() {
+        t = FileType::PrivateKey;
+        let other = match get_file_path(&t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.is_file() || !other.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+fn check_files_ref_mut(files: &[(FileType, &std::path::Path)]) -> bool {
+    for (ref mut t, path) in files.iter().copied() {
+        *t = FileType::PrivateKey;
+        let other = match get_file_path(t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.is_file() || !other.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+fn check_files_self_and_arg(files: &[(FileType, &std::path::Path)]) -> bool {
+    for (t, path) in files.iter().copied() {
+        let other = match get_file_path(&t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.join(path).is_file() || !other.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+#[allow(unused_assignments)]
+fn check_files_mut_path_buf(files: &[(FileType, std::path::PathBuf)]) -> bool {
+    for (mut t, path) in files.iter().cloned() {
+        t = FileType::PrivateKey;
+        let other = match get_file_path(&t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.is_file() || !other.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
+    Ok(std::path::PathBuf::new())
+}
+
+// Issue 12098
+// https://github.com/rust-lang/rust-clippy/issues/12098
+// no message emits
+fn check_mut_iteratee_and_modify_inner_variable() {
+    struct Test {
+        list: Vec<String>,
+        mut_this: bool,
+    }
+
+    impl Test {
+        fn list(&self) -> &[String] {
+            &self.list
+        }
+    }
+
+    let mut test = Test {
+        list: vec![String::from("foo"), String::from("bar")],
+        mut_this: false,
+    };
+
+    for _item in test.list().to_vec() {
+        println!("{}", _item);
+
+        test.mut_this = true;
+        {
+            test.mut_this = true;
+        }
+    }
+}
+
+mod issue_12821 {
+    fn foo() {
+        let v: Vec<_> = "hello".chars().collect();
+        for c in v.iter() {
+            //~^ ERROR: unnecessary use of `cloned`
+            println!("{c}"); // should not suggest to remove `&`
+        }
+    }
+
+    fn bar() {
+        let v: Vec<_> = "hello".chars().collect();
+        for c in v.iter() {
+            //~^ ERROR: unnecessary use of `cloned`
+            let ref_c = c; //~ HELP: remove any references to the binding
+            println!("{ref_c}");
+        }
+    }
+
+    fn baz() {
+        let v: Vec<_> = "hello".chars().enumerate().collect();
+        for (i, c) in v.iter() {
+            //~^ ERROR: unnecessary use of `cloned`
+            let ref_c = c; //~ HELP: remove any references to the binding
+            let ref_i = i;
+            println!("{i} {ref_c}"); // should not suggest to remove `&` from `i`
+        }
+    }
+}
diff --git a/tests/ui/unnecessary_iter_cloned.rs b/tests/ui/unnecessary_iter_cloned.rs
index 331b7b25271b..8f797ac717fb 100644
--- a/tests/ui/unnecessary_iter_cloned.rs
+++ b/tests/ui/unnecessary_iter_cloned.rs
@@ -1,8 +1,6 @@
 #![allow(unused_assignments)]
 #![warn(clippy::unnecessary_to_owned)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 #[allow(dead_code)]
 #[derive(Clone, Copy)]
 enum FileType {
diff --git a/tests/ui/unnecessary_iter_cloned.stderr b/tests/ui/unnecessary_iter_cloned.stderr
index e3592e3cbbd8..6f2ae0ab1f35 100644
--- a/tests/ui/unnecessary_iter_cloned.stderr
+++ b/tests/ui/unnecessary_iter_cloned.stderr
@@ -1,71 +1,58 @@
 error: unnecessary use of `copied`
-  --> tests/ui/unnecessary_iter_cloned.rs:33:22
+  --> tests/ui/unnecessary_iter_cloned.rs:31:22
    |
 LL |     for (t, path) in files.iter().copied() {
    |                      ^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
-help: use
-   |
-LL |     for (t, path) in files {
-   |                      ~~~~~
 help: remove any references to the binding
    |
-LL -         let other = match get_file_path(&t) {
-LL +         let other = match get_file_path(t) {
+LL ~     for (t, path) in files {
+LL ~         let other = match get_file_path(t) {
    |
 
 error: unnecessary use of `copied`
-  --> tests/ui/unnecessary_iter_cloned.rs:48:22
+  --> tests/ui/unnecessary_iter_cloned.rs:46:22
    |
 LL |     for (t, path) in files.iter().copied() {
    |                      ^^^^^^^^^^^^^^^^^^^^^
    |
-help: use
-   |
-LL |     for (t, path) in files.iter() {
-   |                      ~~~~~~~~~~~~
 help: remove any references to the binding
    |
-LL -         let other = match get_file_path(&t) {
-LL +         let other = match get_file_path(t) {
+LL ~     for (t, path) in files.iter() {
+LL ~         let other = match get_file_path(t) {
    |
 
 error: unnecessary use of `cloned`
-  --> tests/ui/unnecessary_iter_cloned.rs:179:18
+  --> tests/ui/unnecessary_iter_cloned.rs:177:18
    |
 LL |         for c in v.iter().cloned() {
-   |                  ^^^^^^^^^^^^^^^^^ help: use: `v.iter()`
+   |                  ^^^^^^^^^^^^^^^^^ help: remove any references to the binding: `v.iter()`
 
 error: unnecessary use of `cloned`
-  --> tests/ui/unnecessary_iter_cloned.rs:187:18
+  --> tests/ui/unnecessary_iter_cloned.rs:185:18
    |
 LL |         for c in v.iter().cloned() {
    |                  ^^^^^^^^^^^^^^^^^
    |
-help: use
-   |
-LL |         for c in v.iter() {
-   |                  ~~~~~~~~
 help: remove any references to the binding
    |
-LL -             let ref_c = &c;
-LL +             let ref_c = c;
+LL ~         for c in v.iter() {
+LL |
+LL ~             let ref_c = c;
    |
 
 error: unnecessary use of `cloned`
-  --> tests/ui/unnecessary_iter_cloned.rs:196:23
+  --> tests/ui/unnecessary_iter_cloned.rs:194:23
    |
 LL |         for (i, c) in v.iter().cloned() {
    |                       ^^^^^^^^^^^^^^^^^
    |
-help: use
-   |
-LL |         for (i, c) in v.iter() {
-   |                       ~~~~~~~~
 help: remove any references to the binding
    |
+LL ~         for (i, c) in v.iter() {
+LL |
 LL ~             let ref_c = c;
 LL ~             let ref_i = i;
    |
diff --git a/tests/ui/unnecessary_sort_by_no_std.fixed b/tests/ui/unnecessary_sort_by_no_std.fixed
new file mode 100644
index 000000000000..c7be000b820c
--- /dev/null
+++ b/tests/ui/unnecessary_sort_by_no_std.fixed
@@ -0,0 +1,20 @@
+#![no_std]
+extern crate alloc;
+use alloc::vec;
+use alloc::vec::Vec;
+
+fn issue_11524() -> Vec<i32> {
+    let mut vec = vec![1, 2, 3];
+
+    // Should lint and suggest `vec.sort_by_key(|a| a + 1);`
+    vec.sort_by_key(|a| a + 1);
+    vec
+}
+
+fn issue_11524_2() -> Vec<i32> {
+    let mut vec = vec![1, 2, 3];
+
+    // Should lint and suggest `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));`
+    vec.sort_by_key(|b| core::cmp::Reverse(b + 1));
+    vec
+}
diff --git a/tests/ui/unnecessary_sort_by_no_std.rs b/tests/ui/unnecessary_sort_by_no_std.rs
new file mode 100644
index 000000000000..5f44be97c61f
--- /dev/null
+++ b/tests/ui/unnecessary_sort_by_no_std.rs
@@ -0,0 +1,20 @@
+#![no_std]
+extern crate alloc;
+use alloc::vec;
+use alloc::vec::Vec;
+
+fn issue_11524() -> Vec<i32> {
+    let mut vec = vec![1, 2, 3];
+
+    // Should lint and suggest `vec.sort_by_key(|a| a + 1);`
+    vec.sort_by(|a, b| (a + 1).cmp(&(b + 1)));
+    vec
+}
+
+fn issue_11524_2() -> Vec<i32> {
+    let mut vec = vec![1, 2, 3];
+
+    // Should lint and suggest `vec.sort_by_key(|b| core::cmp::Reverse(b + 1));`
+    vec.sort_by(|a, b| (b + 1).cmp(&(a + 1)));
+    vec
+}
diff --git a/tests/ui/unnecessary_sort_by_no_std.stderr b/tests/ui/unnecessary_sort_by_no_std.stderr
new file mode 100644
index 000000000000..a57fbc7a6328
--- /dev/null
+++ b/tests/ui/unnecessary_sort_by_no_std.stderr
@@ -0,0 +1,17 @@
+error: consider using `sort_by_key`
+  --> tests/ui/unnecessary_sort_by_no_std.rs:10:5
+   |
+LL |     vec.sort_by(|a, b| (a + 1).cmp(&(b + 1)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| a + 1)`
+   |
+   = note: `-D clippy::unnecessary-sort-by` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]`
+
+error: consider using `sort_by_key`
+  --> tests/ui/unnecessary_sort_by_no_std.rs:18:5
+   |
+LL |     vec.sort_by(|a, b| (b + 1).cmp(&(a + 1)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| core::cmp::Reverse(b + 1))`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/unnecessary_to_owned.fixed b/tests/ui/unnecessary_to_owned.fixed
new file mode 100644
index 000000000000..fdcac8fb08dc
--- /dev/null
+++ b/tests/ui/unnecessary_to_owned.fixed
@@ -0,0 +1,587 @@
+#![allow(
+    clippy::needless_borrow,
+    clippy::needless_borrows_for_generic_args,
+    clippy::ptr_arg,
+    clippy::manual_async_fn,
+    clippy::needless_lifetimes
+)]
+#![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
+
+use std::borrow::Cow;
+use std::ffi::{CStr, CString, OsStr, OsString};
+use std::ops::Deref;
+
+#[derive(Clone)]
+struct X(String);
+
+impl Deref for X {
+    type Target = [u8];
+    fn deref(&self) -> &[u8] {
+        self.0.as_bytes()
+    }
+}
+
+impl AsRef<str> for X {
+    fn as_ref(&self) -> &str {
+        self.0.as_str()
+    }
+}
+
+#[allow(clippy::to_string_trait_impl)]
+impl ToString for X {
+    fn to_string(&self) -> String {
+        self.0.to_string()
+    }
+}
+
+impl X {
+    fn join(&self, other: impl AsRef<str>) -> Self {
+        let mut s = self.0.clone();
+        s.push_str(other.as_ref());
+        Self(s)
+    }
+}
+
+#[allow(dead_code)]
+#[derive(Clone)]
+enum FileType {
+    Account,
+    PrivateKey,
+    Certificate,
+}
+
+fn main() {
+    let c_str = CStr::from_bytes_with_nul(&[0]).unwrap();
+    let os_str = OsStr::new("x");
+    let path = std::path::Path::new("x");
+    let s = "x";
+    let array = ["x"];
+    let array_ref = &["x"];
+    let slice = &["x"][..];
+    let x = X(String::from("x"));
+    let x_ref = &x;
+
+    require_c_str(&Cow::from(c_str));
+    require_c_str(c_str);
+
+    require_os_str(os_str);
+    require_os_str(&Cow::from(os_str));
+    require_os_str(os_str);
+
+    require_path(path);
+    require_path(&Cow::from(path));
+    require_path(path);
+
+    require_str(s);
+    require_str(&Cow::from(s));
+    require_str(s);
+    require_str(x_ref.as_ref());
+
+    require_slice(slice);
+    require_slice(&Cow::from(slice));
+    require_slice(array.as_ref());
+    require_slice(array_ref.as_ref());
+    require_slice(slice);
+    require_slice(&x_ref.to_owned()); // No longer flagged because of #8759.
+
+    require_x(&Cow::<X>::Owned(x.clone()));
+    require_x(&x_ref.to_owned()); // No longer flagged because of #8759.
+
+    require_deref_c_str(c_str);
+    require_deref_os_str(os_str);
+    require_deref_path(path);
+    require_deref_str(s);
+    require_deref_slice(slice);
+
+    require_impl_deref_c_str(c_str);
+    require_impl_deref_os_str(os_str);
+    require_impl_deref_path(path);
+    require_impl_deref_str(s);
+    require_impl_deref_slice(slice);
+
+    require_deref_str_slice(s, slice);
+    require_deref_slice_str(slice, s);
+
+    require_as_ref_c_str(c_str);
+    require_as_ref_os_str(os_str);
+    require_as_ref_path(path);
+    require_as_ref_str(s);
+    require_as_ref_str(&x);
+    require_as_ref_slice(array);
+    require_as_ref_slice(array_ref);
+    require_as_ref_slice(slice);
+
+    require_impl_as_ref_c_str(c_str);
+    require_impl_as_ref_os_str(os_str);
+    require_impl_as_ref_path(path);
+    require_impl_as_ref_str(s);
+    require_impl_as_ref_str(&x);
+    require_impl_as_ref_slice(array);
+    require_impl_as_ref_slice(array_ref);
+    require_impl_as_ref_slice(slice);
+
+    require_as_ref_str_slice(s, array);
+    require_as_ref_str_slice(s, array_ref);
+    require_as_ref_str_slice(s, slice);
+    require_as_ref_slice_str(array, s);
+    require_as_ref_slice_str(array_ref, s);
+    require_as_ref_slice_str(slice, s);
+
+    let _ = x.join(x_ref);
+
+    let _ = slice.iter().copied();
+    let _ = slice.iter().copied();
+    let _ = [std::path::PathBuf::new()][..].iter().cloned();
+    let _ = [std::path::PathBuf::new()][..].iter().cloned();
+
+    let _ = slice.iter().copied();
+    let _ = slice.iter().copied();
+    let _ = [std::path::PathBuf::new()][..].iter().cloned();
+    let _ = [std::path::PathBuf::new()][..].iter().cloned();
+
+    let _ = check_files(&[FileType::Account]);
+
+    // negative tests
+    require_string(&s.to_string());
+    require_string(&Cow::from(s).into_owned());
+    require_string(&s.to_owned());
+    require_string(&x_ref.to_string());
+
+    // `X` isn't copy.
+    require_slice(&x.to_owned());
+    require_deref_slice(x.to_owned());
+
+    // The following should be flagged by `redundant_clone`, but not by this lint.
+    require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap());
+    require_os_str(&OsString::from("x"));
+    require_path(&std::path::PathBuf::from("x"));
+    require_str(&String::from("x"));
+    require_slice(&[String::from("x")]);
+
+    let slice = [0u8; 1024];
+    let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
+    let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
+    let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
+    // Expression is of type `&String`, can't suggest `str::from_utf8` here
+    let _ref_string = &String::from_utf8(b"foo".to_vec()).unwrap();
+    macro_rules! arg_from_macro {
+        () => {
+            b"foo".to_vec()
+        };
+    }
+    macro_rules! string_from_utf8_from_macro {
+        () => {
+            &String::from_utf8(b"foo".to_vec()).unwrap()
+        };
+    }
+    let _ref_str: &str = &String::from_utf8(arg_from_macro!()).unwrap();
+    let _ref_str: &str = string_from_utf8_from_macro!();
+}
+
+fn require_c_str(_: &CStr) {}
+fn require_os_str(_: &OsStr) {}
+fn require_path(_: &std::path::Path) {}
+fn require_str(_: &str) {}
+fn require_slice<T>(_: &[T]) {}
+fn require_x(_: &X) {}
+
+fn require_deref_c_str<T: Deref<Target = CStr>>(_: T) {}
+fn require_deref_os_str<T: Deref<Target = OsStr>>(_: T) {}
+fn require_deref_path<T: Deref<Target = std::path::Path>>(_: T) {}
+fn require_deref_str<T: Deref<Target = str>>(_: T) {}
+fn require_deref_slice<T, U: Deref<Target = [T]>>(_: U) {}
+
+fn require_impl_deref_c_str(_: impl Deref<Target = CStr>) {}
+fn require_impl_deref_os_str(_: impl Deref<Target = OsStr>) {}
+fn require_impl_deref_path(_: impl Deref<Target = std::path::Path>) {}
+fn require_impl_deref_str(_: impl Deref<Target = str>) {}
+fn require_impl_deref_slice<T>(_: impl Deref<Target = [T]>) {}
+
+fn require_deref_str_slice<T: Deref<Target = str>, U, V: Deref<Target = [U]>>(_: T, _: V) {}
+fn require_deref_slice_str<T, U: Deref<Target = [T]>, V: Deref<Target = str>>(_: U, _: V) {}
+
+fn require_as_ref_c_str<T: AsRef<CStr>>(_: T) {}
+fn require_as_ref_os_str<T: AsRef<OsStr>>(_: T) {}
+fn require_as_ref_path<T: AsRef<std::path::Path>>(_: T) {}
+fn require_as_ref_str<T: AsRef<str>>(_: T) {}
+fn require_as_ref_slice<T, U: AsRef<[T]>>(_: U) {}
+
+fn require_impl_as_ref_c_str(_: impl AsRef<CStr>) {}
+fn require_impl_as_ref_os_str(_: impl AsRef<OsStr>) {}
+fn require_impl_as_ref_path(_: impl AsRef<std::path::Path>) {}
+fn require_impl_as_ref_str(_: impl AsRef<str>) {}
+fn require_impl_as_ref_slice<T>(_: impl AsRef<[T]>) {}
+
+fn require_as_ref_str_slice<T: AsRef<str>, U, V: AsRef<[U]>>(_: T, _: V) {}
+fn require_as_ref_slice_str<T, U: AsRef<[T]>, V: AsRef<str>>(_: U, _: V) {}
+
+// `check_files` is based on:
+// https://github.com/breard-r/acmed/blob/1f0dcc32aadbc5e52de6d23b9703554c0f925113/acmed/src/storage.rs#L262
+fn check_files(file_types: &[FileType]) -> bool {
+    for t in file_types {
+        let path = match get_file_path(t) {
+            Ok(p) => p,
+            Err(_) => {
+                return false;
+            },
+        };
+        if !path.is_file() {
+            return false;
+        }
+    }
+    true
+}
+
+fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::Error> {
+    Ok(std::path::PathBuf::new())
+}
+
+fn require_string(_: &String) {}
+
+#[clippy::msrv = "1.35"]
+fn _msrv_1_35() {
+    // `copied` was stabilized in 1.36, so clippy should use `cloned`.
+    let _ = &["x"][..].iter().cloned();
+}
+
+#[clippy::msrv = "1.36"]
+fn _msrv_1_36() {
+    let _ = &["x"][..].iter().copied();
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/8507
+mod issue_8507 {
+    #![allow(dead_code)]
+
+    struct Opaque<P>(P);
+
+    pub trait Abstracted {}
+
+    impl<P> Abstracted for Opaque<P> {}
+
+    fn build<P>(p: P) -> Opaque<P>
+    where
+        P: AsRef<str>,
+    {
+        Opaque(p)
+    }
+
+    // Should not lint.
+    fn test_str(s: &str) -> Box<dyn Abstracted> {
+        Box::new(build(s.to_string()))
+    }
+
+    // Should not lint.
+    fn test_x(x: super::X) -> Box<dyn Abstracted> {
+        Box::new(build(x))
+    }
+
+    #[derive(Clone, Copy)]
+    struct Y(&'static str);
+
+    impl AsRef<str> for Y {
+        fn as_ref(&self) -> &str {
+            self.0
+        }
+    }
+
+    #[allow(clippy::to_string_trait_impl)]
+    impl ToString for Y {
+        fn to_string(&self) -> String {
+            self.0.to_string()
+        }
+    }
+
+    // Should lint because Y is copy.
+    fn test_y(y: Y) -> Box<dyn Abstracted> {
+        Box::new(build(y))
+    }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/8759
+mod issue_8759 {
+    #![allow(dead_code)]
+
+    #[derive(Default)]
+    struct View {}
+
+    impl std::borrow::ToOwned for View {
+        type Owned = View;
+        fn to_owned(&self) -> Self::Owned {
+            View {}
+        }
+    }
+
+    #[derive(Default)]
+    struct RenderWindow {
+        default_view: View,
+    }
+
+    impl RenderWindow {
+        fn default_view(&self) -> &View {
+            &self.default_view
+        }
+        fn set_view(&mut self, _view: &View) {}
+    }
+
+    fn main() {
+        let mut rw = RenderWindow::default();
+        rw.set_view(&rw.default_view().to_owned());
+    }
+}
+
+mod issue_8759_variant {
+    #![allow(dead_code)]
+
+    #[derive(Clone, Default)]
+    struct View {}
+
+    #[derive(Default)]
+    struct RenderWindow {
+        default_view: View,
+    }
+
+    impl RenderWindow {
+        fn default_view(&self) -> &View {
+            &self.default_view
+        }
+        fn set_view(&mut self, _view: &View) {}
+    }
+
+    fn main() {
+        let mut rw = RenderWindow::default();
+        rw.set_view(&rw.default_view().to_owned());
+    }
+}
+
+mod issue_9317 {
+    #![allow(dead_code)]
+
+    struct Bytes {}
+
+    #[allow(clippy::to_string_trait_impl)]
+    impl ToString for Bytes {
+        fn to_string(&self) -> String {
+            "123".to_string()
+        }
+    }
+
+    impl AsRef<[u8]> for Bytes {
+        fn as_ref(&self) -> &[u8] {
+            &[1, 2, 3]
+        }
+    }
+
+    fn consume<C: AsRef<[u8]>>(c: C) {
+        let _ = c;
+    }
+
+    pub fn main() {
+        let b = Bytes {};
+        // Should not lint.
+        consume(b.to_string());
+    }
+}
+
+mod issue_9351 {
+    #![allow(dead_code)]
+
+    use std::ops::Deref;
+    use std::path::{Path, PathBuf};
+
+    fn require_deref_path<T: Deref<Target = std::path::Path>>(x: T) -> T {
+        x
+    }
+
+    fn generic_arg_used_elsewhere<T: AsRef<Path>>(_x: T, _y: T) {}
+
+    fn id<T: AsRef<str>>(x: T) -> T {
+        x
+    }
+
+    fn predicates_are_satisfied(_x: impl std::fmt::Write) {}
+
+    // Should lint
+    fn single_return() -> impl AsRef<str> {
+        id("abc")
+    }
+
+    // Should not lint
+    fn multiple_returns(b: bool) -> impl AsRef<str> {
+        if b {
+            return String::new();
+        }
+
+        id("abc".to_string())
+    }
+
+    struct S1(String);
+
+    // Should not lint
+    fn fields1() -> S1 {
+        S1(id("abc".to_string()))
+    }
+
+    struct S2 {
+        s: String,
+    }
+
+    // Should not lint
+    fn fields2() {
+        let mut s = S2 { s: "abc".into() };
+        s.s = id("abc".to_string());
+    }
+
+    pub fn main() {
+        let path = std::path::Path::new("x");
+        let path_buf = path.to_owned();
+
+        // Should not lint.
+        let _x: PathBuf = require_deref_path(path.to_owned());
+        generic_arg_used_elsewhere(path.to_owned(), path_buf);
+        predicates_are_satisfied(id("abc".to_string()));
+    }
+}
+
+mod issue_9504 {
+    #![allow(dead_code)]
+
+    async fn foo<S: AsRef<str>>(_: S) {}
+    async fn bar() {
+        foo(std::path::PathBuf::new().to_string_lossy().to_string()).await;
+    }
+}
+
+mod issue_9771a {
+    #![allow(dead_code)]
+
+    use std::marker::PhantomData;
+
+    pub struct Key<K: AsRef<[u8]>, V: ?Sized>(K, PhantomData<V>);
+
+    impl<K: AsRef<[u8]>, V: ?Sized> Key<K, V> {
+        pub fn new(key: K) -> Key<K, V> {
+            Key(key, PhantomData)
+        }
+    }
+
+    pub fn pkh(pkh: &[u8]) -> Key<Vec<u8>, String> {
+        Key::new([b"pkh-", pkh].concat().to_vec())
+    }
+}
+
+mod issue_9771b {
+    #![allow(dead_code)]
+
+    pub struct Key<K: AsRef<[u8]>>(K);
+
+    pub fn from(c: &[u8]) -> Key<Vec<u8>> {
+        let v = [c].concat();
+        Key(v.to_vec())
+    }
+}
+
+// This is a watered down version of the code in: https://github.com/oxigraph/rio
+// The ICE is triggered by the call to `to_owned` on this line:
+// https://github.com/oxigraph/rio/blob/66635b9ff8e5423e58932353fa40d6e64e4820f7/testsuite/src/parser_evaluator.rs#L116
+mod issue_10021 {
+    #![allow(unused)]
+
+    pub struct Iri<T>(T);
+
+    impl<T: AsRef<str>> Iri<T> {
+        pub fn parse(iri: T) -> Result<Self, ()> {
+            unimplemented!()
+        }
+    }
+
+    pub fn parse_w3c_rdf_test_file(url: &str) -> Result<(), ()> {
+        let base_iri = Iri::parse(url.to_owned())?;
+        Ok(())
+    }
+}
+
+mod issue_10033 {
+    #![allow(dead_code)]
+    use std::fmt::Display;
+    use std::ops::Deref;
+
+    fn _main() {
+        let f = Foo;
+
+        // Not actually unnecessary - this calls `Foo`'s `Display` impl, not `str`'s (even though `Foo` does
+        // deref to `str`)
+        foo(&f.to_string());
+    }
+
+    fn foo(s: &str) {
+        println!("{}", s);
+    }
+
+    struct Foo;
+
+    impl Deref for Foo {
+        type Target = str;
+
+        fn deref(&self) -> &Self::Target {
+            "str"
+        }
+    }
+
+    impl Display for Foo {
+        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+            write!(f, "Foo")
+        }
+    }
+}
+
+mod issue_11952 {
+    use core::future::{Future, IntoFuture};
+
+    fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {
+        async move {
+            let _y = y;
+            Ok(())
+        }
+    }
+
+    fn bar() {
+        IntoFuture::into_future(foo([], &0));
+    }
+}
+
+fn borrow_checks() {
+    use std::borrow::Borrow;
+    use std::collections::HashSet;
+
+    fn inner(a: &[&str]) {
+        let mut s = HashSet::from([vec!["a"]]);
+        s.remove(a); //~ ERROR: unnecessary use of `to_vec`
+    }
+
+    let mut s = HashSet::from(["a".to_string()]);
+    s.remove("b"); //~ ERROR: unnecessary use of `to_owned`
+    s.remove("b"); //~ ERROR: unnecessary use of `to_string`
+    // Should not warn.
+    s.remove("b");
+
+    let mut s = HashSet::from([vec!["a"]]);
+    s.remove(["b"].as_slice()); //~ ERROR: unnecessary use of `to_vec`
+    s.remove((&["b"]).as_slice()); //~ ERROR: unnecessary use of `to_vec`
+
+    // Should not warn.
+    s.remove(&["b"].to_vec().clone());
+    s.remove(["a"].as_slice());
+
+    trait SetExt {
+        fn foo<Q: Borrow<str>>(&self, _: &String);
+    }
+
+    impl<K> SetExt for HashSet<K> {
+        fn foo<Q: Borrow<str>>(&self, _: &String) {}
+    }
+
+    // Should not lint!
+    HashSet::<i32>::new().foo::<&str>(&"".to_owned());
+    HashSet::<String>::new().get(&1.to_string());
+}
diff --git a/tests/ui/unnecessary_to_owned.rs b/tests/ui/unnecessary_to_owned.rs
index da0c761f795b..10a9727a9a79 100644
--- a/tests/ui/unnecessary_to_owned.rs
+++ b/tests/ui/unnecessary_to_owned.rs
@@ -7,8 +7,6 @@
 )]
 #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 use std::borrow::Cow;
 use std::ffi::{CStr, CString, OsStr, OsString};
 use std::ops::Deref;
diff --git a/tests/ui/unnecessary_to_owned.stderr b/tests/ui/unnecessary_to_owned.stderr
index 7ab1f667d9b5..498ac68cdaa0 100644
--- a/tests/ui/unnecessary_to_owned.stderr
+++ b/tests/ui/unnecessary_to_owned.stderr
@@ -1,11 +1,11 @@
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:157:64
+  --> tests/ui/unnecessary_to_owned.rs:155:64
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                                                                ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:157:20
+  --> tests/ui/unnecessary_to_owned.rs:155:20
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,55 +13,55 @@ LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned())
    = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:158:40
+  --> tests/ui/unnecessary_to_owned.rs:156:40
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                                        ^^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:158:21
+  --> tests/ui/unnecessary_to_owned.rs:156:21
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                     ^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:159:48
+  --> tests/ui/unnecessary_to_owned.rs:157:48
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                                                ^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:159:19
+  --> tests/ui/unnecessary_to_owned.rs:157:19
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:160:35
+  --> tests/ui/unnecessary_to_owned.rs:158:35
    |
 LL |     require_str(&String::from("x").to_string());
    |                                   ^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:160:18
+  --> tests/ui/unnecessary_to_owned.rs:158:18
    |
 LL |     require_str(&String::from("x").to_string());
    |                  ^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:161:39
+  --> tests/ui/unnecessary_to_owned.rs:159:39
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                                       ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:161:20
+  --> tests/ui/unnecessary_to_owned.rs:159:20
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^
 
 error: unnecessary use of `into_owned`
-  --> tests/ui/unnecessary_to_owned.rs:66:36
+  --> tests/ui/unnecessary_to_owned.rs:64:36
    |
 LL |     require_c_str(&Cow::from(c_str).into_owned());
    |                                    ^^^^^^^^^^^^^ help: remove this
@@ -70,415 +70,415 @@ LL |     require_c_str(&Cow::from(c_str).into_owned());
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:67:19
+  --> tests/ui/unnecessary_to_owned.rs:65:19
    |
 LL |     require_c_str(&c_str.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_os_string`
-  --> tests/ui/unnecessary_to_owned.rs:69:20
+  --> tests/ui/unnecessary_to_owned.rs:67:20
    |
 LL |     require_os_str(&os_str.to_os_string());
    |                    ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `into_owned`
-  --> tests/ui/unnecessary_to_owned.rs:70:38
+  --> tests/ui/unnecessary_to_owned.rs:68:38
    |
 LL |     require_os_str(&Cow::from(os_str).into_owned());
    |                                      ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:71:20
+  --> tests/ui/unnecessary_to_owned.rs:69:20
    |
 LL |     require_os_str(&os_str.to_owned());
    |                    ^^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_path_buf`
-  --> tests/ui/unnecessary_to_owned.rs:73:18
+  --> tests/ui/unnecessary_to_owned.rs:71:18
    |
 LL |     require_path(&path.to_path_buf());
    |                  ^^^^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `into_owned`
-  --> tests/ui/unnecessary_to_owned.rs:74:34
+  --> tests/ui/unnecessary_to_owned.rs:72:34
    |
 LL |     require_path(&Cow::from(path).into_owned());
    |                                  ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:75:18
+  --> tests/ui/unnecessary_to_owned.rs:73:18
    |
 LL |     require_path(&path.to_owned());
    |                  ^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:77:17
+  --> tests/ui/unnecessary_to_owned.rs:75:17
    |
 LL |     require_str(&s.to_string());
    |                 ^^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `into_owned`
-  --> tests/ui/unnecessary_to_owned.rs:78:30
+  --> tests/ui/unnecessary_to_owned.rs:76:30
    |
 LL |     require_str(&Cow::from(s).into_owned());
    |                              ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:79:17
+  --> tests/ui/unnecessary_to_owned.rs:77:17
    |
 LL |     require_str(&s.to_owned());
    |                 ^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:80:17
+  --> tests/ui/unnecessary_to_owned.rs:78:17
    |
 LL |     require_str(&x_ref.to_string());
    |                 ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:82:19
+  --> tests/ui/unnecessary_to_owned.rs:80:19
    |
 LL |     require_slice(&slice.to_vec());
    |                   ^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `into_owned`
-  --> tests/ui/unnecessary_to_owned.rs:83:36
+  --> tests/ui/unnecessary_to_owned.rs:81:36
    |
 LL |     require_slice(&Cow::from(slice).into_owned());
    |                                    ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:84:19
+  --> tests/ui/unnecessary_to_owned.rs:82:19
    |
 LL |     require_slice(&array.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:85:19
+  --> tests/ui/unnecessary_to_owned.rs:83:19
    |
 LL |     require_slice(&array_ref.to_owned());
    |                   ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:86:19
+  --> tests/ui/unnecessary_to_owned.rs:84:19
    |
 LL |     require_slice(&slice.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `into_owned`
-  --> tests/ui/unnecessary_to_owned.rs:89:42
+  --> tests/ui/unnecessary_to_owned.rs:87:42
    |
 LL |     require_x(&Cow::<X>::Owned(x.clone()).into_owned());
    |                                          ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:92:25
+  --> tests/ui/unnecessary_to_owned.rs:90:25
    |
 LL |     require_deref_c_str(c_str.to_owned());
    |                         ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:93:26
+  --> tests/ui/unnecessary_to_owned.rs:91:26
    |
 LL |     require_deref_os_str(os_str.to_owned());
    |                          ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:94:24
+  --> tests/ui/unnecessary_to_owned.rs:92:24
    |
 LL |     require_deref_path(path.to_owned());
    |                        ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:95:23
+  --> tests/ui/unnecessary_to_owned.rs:93:23
    |
 LL |     require_deref_str(s.to_owned());
    |                       ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:96:25
+  --> tests/ui/unnecessary_to_owned.rs:94:25
    |
 LL |     require_deref_slice(slice.to_owned());
    |                         ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:98:30
+  --> tests/ui/unnecessary_to_owned.rs:96:30
    |
 LL |     require_impl_deref_c_str(c_str.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:99:31
+  --> tests/ui/unnecessary_to_owned.rs:97:31
    |
 LL |     require_impl_deref_os_str(os_str.to_owned());
    |                               ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:100:29
+  --> tests/ui/unnecessary_to_owned.rs:98:29
    |
 LL |     require_impl_deref_path(path.to_owned());
    |                             ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:101:28
+  --> tests/ui/unnecessary_to_owned.rs:99:28
    |
 LL |     require_impl_deref_str(s.to_owned());
    |                            ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:102:30
+  --> tests/ui/unnecessary_to_owned.rs:100:30
    |
 LL |     require_impl_deref_slice(slice.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:104:29
+  --> tests/ui/unnecessary_to_owned.rs:102:29
    |
 LL |     require_deref_str_slice(s.to_owned(), slice.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:104:43
+  --> tests/ui/unnecessary_to_owned.rs:102:43
    |
 LL |     require_deref_str_slice(s.to_owned(), slice.to_owned());
    |                                           ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:105:29
+  --> tests/ui/unnecessary_to_owned.rs:103:29
    |
 LL |     require_deref_slice_str(slice.to_owned(), s.to_owned());
    |                             ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:105:47
+  --> tests/ui/unnecessary_to_owned.rs:103:47
    |
 LL |     require_deref_slice_str(slice.to_owned(), s.to_owned());
    |                                               ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:107:26
+  --> tests/ui/unnecessary_to_owned.rs:105:26
    |
 LL |     require_as_ref_c_str(c_str.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:108:27
+  --> tests/ui/unnecessary_to_owned.rs:106:27
    |
 LL |     require_as_ref_os_str(os_str.to_owned());
    |                           ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:109:25
+  --> tests/ui/unnecessary_to_owned.rs:107:25
    |
 LL |     require_as_ref_path(path.to_owned());
    |                         ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:110:24
+  --> tests/ui/unnecessary_to_owned.rs:108:24
    |
 LL |     require_as_ref_str(s.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:111:24
+  --> tests/ui/unnecessary_to_owned.rs:109:24
    |
 LL |     require_as_ref_str(x.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:112:26
+  --> tests/ui/unnecessary_to_owned.rs:110:26
    |
 LL |     require_as_ref_slice(array.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:113:26
+  --> tests/ui/unnecessary_to_owned.rs:111:26
    |
 LL |     require_as_ref_slice(array_ref.to_owned());
    |                          ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:114:26
+  --> tests/ui/unnecessary_to_owned.rs:112:26
    |
 LL |     require_as_ref_slice(slice.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:116:31
+  --> tests/ui/unnecessary_to_owned.rs:114:31
    |
 LL |     require_impl_as_ref_c_str(c_str.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:117:32
+  --> tests/ui/unnecessary_to_owned.rs:115:32
    |
 LL |     require_impl_as_ref_os_str(os_str.to_owned());
    |                                ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:118:30
+  --> tests/ui/unnecessary_to_owned.rs:116:30
    |
 LL |     require_impl_as_ref_path(path.to_owned());
    |                              ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:119:29
+  --> tests/ui/unnecessary_to_owned.rs:117:29
    |
 LL |     require_impl_as_ref_str(s.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:120:29
+  --> tests/ui/unnecessary_to_owned.rs:118:29
    |
 LL |     require_impl_as_ref_str(x.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:121:31
+  --> tests/ui/unnecessary_to_owned.rs:119:31
    |
 LL |     require_impl_as_ref_slice(array.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:122:31
+  --> tests/ui/unnecessary_to_owned.rs:120:31
    |
 LL |     require_impl_as_ref_slice(array_ref.to_owned());
    |                               ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:123:31
+  --> tests/ui/unnecessary_to_owned.rs:121:31
    |
 LL |     require_impl_as_ref_slice(slice.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:125:30
+  --> tests/ui/unnecessary_to_owned.rs:123:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:125:44
+  --> tests/ui/unnecessary_to_owned.rs:123:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());
    |                                            ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:126:30
+  --> tests/ui/unnecessary_to_owned.rs:124:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:126:44
+  --> tests/ui/unnecessary_to_owned.rs:124:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
    |                                            ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:127:30
+  --> tests/ui/unnecessary_to_owned.rs:125:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:127:44
+  --> tests/ui/unnecessary_to_owned.rs:125:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());
    |                                            ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:128:30
+  --> tests/ui/unnecessary_to_owned.rs:126:30
    |
 LL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:128:48
+  --> tests/ui/unnecessary_to_owned.rs:126:48
    |
 LL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());
    |                                                ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:129:30
+  --> tests/ui/unnecessary_to_owned.rs:127:30
    |
 LL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:129:52
+  --> tests/ui/unnecessary_to_owned.rs:127:52
    |
 LL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
    |                                                    ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:130:30
+  --> tests/ui/unnecessary_to_owned.rs:128:30
    |
 LL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:130:48
+  --> tests/ui/unnecessary_to_owned.rs:128:48
    |
 LL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());
    |                                                ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:132:20
+  --> tests/ui/unnecessary_to_owned.rs:130:20
    |
 LL |     let _ = x.join(&x_ref.to_string());
    |                    ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:134:13
+  --> tests/ui/unnecessary_to_owned.rs:132:13
    |
 LL |     let _ = slice.to_vec().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:135:13
+  --> tests/ui/unnecessary_to_owned.rs:133:13
    |
 LL |     let _ = slice.to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:136:13
+  --> tests/ui/unnecessary_to_owned.rs:134:13
    |
 LL |     let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:137:13
+  --> tests/ui/unnecessary_to_owned.rs:135:13
    |
 LL |     let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:139:13
+  --> tests/ui/unnecessary_to_owned.rs:137:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:140:13
+  --> tests/ui/unnecessary_to_owned.rs:138:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:141:13
+  --> tests/ui/unnecessary_to_owned.rs:139:13
    |
 LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:142:13
+  --> tests/ui/unnecessary_to_owned.rs:140:13
    |
 LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:164:26
+  --> tests/ui/unnecessary_to_owned.rs:162:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8");
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -490,7 +490,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
    |
 
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:165:26
+  --> tests/ui/unnecessary_to_owned.rs:163:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -502,7 +502,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
    |
 
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:166:26
+  --> tests/ui/unnecessary_to_owned.rs:164:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -514,77 +514,73 @@ LL +     let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
    |
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:223:14
+  --> tests/ui/unnecessary_to_owned.rs:221:14
    |
 LL |     for t in file_types.to_vec() {
    |              ^^^^^^^^^^^^^^^^^^^
    |
-help: use
-   |
-LL |     for t in file_types {
-   |              ~~~~~~~~~~
 help: remove any references to the binding
    |
-LL -         let path = match get_file_path(&t) {
-LL +         let path = match get_file_path(t) {
+LL ~     for t in file_types {
+LL ~         let path = match get_file_path(t) {
    |
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:246:14
+  --> tests/ui/unnecessary_to_owned.rs:244:14
    |
 LL |     let _ = &["x"][..].to_vec().into_iter();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:251:14
+  --> tests/ui/unnecessary_to_owned.rs:249:14
    |
 LL |     let _ = &["x"][..].to_vec().into_iter();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:299:24
+  --> tests/ui/unnecessary_to_owned.rs:297:24
    |
 LL |         Box::new(build(y.to_string()))
    |                        ^^^^^^^^^^^^^ help: use: `y`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:408:12
+  --> tests/ui/unnecessary_to_owned.rs:406:12
    |
 LL |         id("abc".to_string())
    |            ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:551:37
+  --> tests/ui/unnecessary_to_owned.rs:549:37
    |
 LL |         IntoFuture::into_future(foo([].to_vec(), &0));
    |                                     ^^^^^^^^^^^ help: use: `[]`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:561:18
+  --> tests/ui/unnecessary_to_owned.rs:559:18
    |
 LL |         s.remove(&a.to_vec());
    |                  ^^^^^^^^^^^ help: replace it with: `a`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:565:14
+  --> tests/ui/unnecessary_to_owned.rs:563:14
    |
 LL |     s.remove(&"b".to_owned());
    |              ^^^^^^^^^^^^^^^ help: replace it with: `"b"`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:566:14
+  --> tests/ui/unnecessary_to_owned.rs:564:14
    |
 LL |     s.remove(&"b".to_string());
    |              ^^^^^^^^^^^^^^^^ help: replace it with: `"b"`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:571:14
+  --> tests/ui/unnecessary_to_owned.rs:569:14
    |
 LL |     s.remove(&["b"].to_vec());
    |              ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:572:14
+  --> tests/ui/unnecessary_to_owned.rs:570:14
    |
 LL |     s.remove(&(&["b"]).to_vec());
    |              ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()`
diff --git a/tests/ui/useless_attribute.fixed b/tests/ui/useless_attribute.fixed
index 231fc0a892ad..de1062f123b7 100644
--- a/tests/ui/useless_attribute.fixed
+++ b/tests/ui/useless_attribute.fixed
@@ -134,3 +134,12 @@ pub mod ambiguous_glob_exports {
     pub use my_prelude::*;
     pub use my_type::*;
 }
+
+// Regression test for https://github.com/rust-lang/rust-clippy/issues/13764
+pub mod unknown_namespace {
+    pub mod some_module {
+        pub struct SomeType;
+    }
+    #[allow(rustc::non_glob_import_of_type_ir_inherent)]
+    use some_module::SomeType;
+}
diff --git a/tests/ui/useless_attribute.rs b/tests/ui/useless_attribute.rs
index 8dfcd2110a4b..94657dd1ca37 100644
--- a/tests/ui/useless_attribute.rs
+++ b/tests/ui/useless_attribute.rs
@@ -134,3 +134,12 @@ pub mod ambiguous_glob_exports {
     pub use my_prelude::*;
     pub use my_type::*;
 }
+
+// Regression test for https://github.com/rust-lang/rust-clippy/issues/13764
+pub mod unknown_namespace {
+    pub mod some_module {
+        pub struct SomeType;
+    }
+    #[allow(rustc::non_glob_import_of_type_ir_inherent)]
+    use some_module::SomeType;
+}
diff --git a/tests/ui/useless_conversion.fixed b/tests/ui/useless_conversion.fixed
index eff617a80168..2f7edd92bb7c 100644
--- a/tests/ui/useless_conversion.fixed
+++ b/tests/ui/useless_conversion.fixed
@@ -3,6 +3,8 @@
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
 #![allow(static_mut_refs)]
 
+use std::ops::ControlFlow;
+
 fn test_generic<T: Copy>(val: T) -> T {
     let _ = val;
     val
@@ -297,3 +299,46 @@ impl From<Foo<'a'>> for Foo<'b'> {
         Foo
     }
 }
+
+fn direct_application() {
+    let _: Result<(), std::io::Error> = test_issue_3913();
+    //~^ useless_conversion
+    let _: Result<(), std::io::Error> = test_issue_3913();
+    //~^ useless_conversion
+    let _: Result<(), std::io::Error> = test_issue_3913();
+    //~^ useless_conversion
+    let _: Result<(), std::io::Error> = test_issue_3913();
+    //~^ useless_conversion
+
+    let c: ControlFlow<()> = ControlFlow::Continue(());
+    let _: ControlFlow<()> = c;
+    //~^ useless_conversion
+    let c: ControlFlow<()> = ControlFlow::Continue(());
+    let _: ControlFlow<()> = c;
+    //~^ useless_conversion
+
+    struct Absorb;
+    impl From<()> for Absorb {
+        fn from(_: ()) -> Self {
+            Self
+        }
+    }
+    impl From<std::io::Error> for Absorb {
+        fn from(_: std::io::Error) -> Self {
+            Self
+        }
+    }
+    let _: Vec<u32> = [1u32].into_iter().collect();
+    //~^ useless_conversion
+
+    // No lint for those
+    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(Into::into);
+    let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into);
+    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(From::from);
+    let _: Result<(), Absorb> = test_issue_3913().map_err(From::from);
+}
+
+fn gen_identity<T>(x: [T; 3]) -> Vec<T> {
+    x.into_iter().collect()
+    //~^ useless_conversion
+}
diff --git a/tests/ui/useless_conversion.rs b/tests/ui/useless_conversion.rs
index 64b066207891..eacdf77f9052 100644
--- a/tests/ui/useless_conversion.rs
+++ b/tests/ui/useless_conversion.rs
@@ -3,6 +3,8 @@
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
 #![allow(static_mut_refs)]
 
+use std::ops::ControlFlow;
+
 fn test_generic<T: Copy>(val: T) -> T {
     let _ = T::from(val);
     val.into()
@@ -297,3 +299,46 @@ impl From<Foo<'a'>> for Foo<'b'> {
         Foo
     }
 }
+
+fn direct_application() {
+    let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into);
+    //~^ useless_conversion
+    let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into);
+    //~^ useless_conversion
+    let _: Result<(), std::io::Error> = test_issue_3913().map(From::from);
+    //~^ useless_conversion
+    let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from);
+    //~^ useless_conversion
+
+    let c: ControlFlow<()> = ControlFlow::Continue(());
+    let _: ControlFlow<()> = c.map_break(Into::into);
+    //~^ useless_conversion
+    let c: ControlFlow<()> = ControlFlow::Continue(());
+    let _: ControlFlow<()> = c.map_continue(Into::into);
+    //~^ useless_conversion
+
+    struct Absorb;
+    impl From<()> for Absorb {
+        fn from(_: ()) -> Self {
+            Self
+        }
+    }
+    impl From<std::io::Error> for Absorb {
+        fn from(_: std::io::Error) -> Self {
+            Self
+        }
+    }
+    let _: Vec<u32> = [1u32].into_iter().map(Into::into).collect();
+    //~^ useless_conversion
+
+    // No lint for those
+    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(Into::into);
+    let _: Result<(), Absorb> = test_issue_3913().map_err(Into::into);
+    let _: Result<Absorb, std::io::Error> = test_issue_3913().map(From::from);
+    let _: Result<(), Absorb> = test_issue_3913().map_err(From::from);
+}
+
+fn gen_identity<T>(x: [T; 3]) -> Vec<T> {
+    x.into_iter().map(Into::into).collect()
+    //~^ useless_conversion
+}
diff --git a/tests/ui/useless_conversion.stderr b/tests/ui/useless_conversion.stderr
index b149357bcf4f..6aeb382902ba 100644
--- a/tests/ui/useless_conversion.stderr
+++ b/tests/ui/useless_conversion.stderr
@@ -1,5 +1,5 @@
 error: useless conversion to the same type: `T`
-  --> tests/ui/useless_conversion.rs:7:13
+  --> tests/ui/useless_conversion.rs:9:13
    |
 LL |     let _ = T::from(val);
    |             ^^^^^^^^^^^^ help: consider removing `T::from()`: `val`
@@ -11,220 +11,268 @@ LL | #![deny(clippy::useless_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: useless conversion to the same type: `T`
-  --> tests/ui/useless_conversion.rs:8:5
+  --> tests/ui/useless_conversion.rs:10:5
    |
 LL |     val.into()
    |     ^^^^^^^^^^ help: consider removing `.into()`: `val`
 
 error: useless conversion to the same type: `i32`
-  --> tests/ui/useless_conversion.rs:20:22
+  --> tests/ui/useless_conversion.rs:22:22
    |
 LL |         let _: i32 = 0i32.into();
    |                      ^^^^^^^^^^^ help: consider removing `.into()`: `0i32`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:50:22
+  --> tests/ui/useless_conversion.rs:52:22
    |
 LL |     if Some("ok") == lines.into_iter().next() {}
    |                      ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:55:21
+  --> tests/ui/useless_conversion.rs:57:21
    |
 LL |     let mut lines = text.lines().into_iter();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:61:22
+  --> tests/ui/useless_conversion.rs:63:22
    |
 LL |     if Some("ok") == text.lines().into_iter().next() {}
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
 
 error: useless conversion to the same type: `std::ops::Range<i32>`
-  --> tests/ui/useless_conversion.rs:67:13
+  --> tests/ui/useless_conversion.rs:69:13
    |
 LL |     let _ = NUMBERS.into_iter().next();
    |             ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
 
 error: useless conversion to the same type: `std::ops::Range<i32>`
-  --> tests/ui/useless_conversion.rs:72:17
+  --> tests/ui/useless_conversion.rs:74:17
    |
 LL |     let mut n = NUMBERS.into_iter();
    |                 ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:134:21
+  --> tests/ui/useless_conversion.rs:136:21
    |
 LL |     let _: String = "foo".to_string().into();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:135:21
+  --> tests/ui/useless_conversion.rs:137:21
    |
 LL |     let _: String = From::from("foo".to_string());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:136:13
+  --> tests/ui/useless_conversion.rs:138:13
    |
 LL |     let _ = String::from("foo".to_string());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:137:13
+  --> tests/ui/useless_conversion.rs:139:13
    |
 LL |     let _ = String::from(format!("A: {:04}", 123));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:138:13
+  --> tests/ui/useless_conversion.rs:140:13
    |
 LL |     let _ = "".lines().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()`
 
 error: useless conversion to the same type: `std::vec::IntoIter<i32>`
-  --> tests/ui/useless_conversion.rs:139:13
+  --> tests/ui/useless_conversion.rs:141:13
    |
 LL |     let _ = vec![1, 2, 3].into_iter().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:140:21
+  --> tests/ui/useless_conversion.rs:142:21
    |
 LL |     let _: String = format!("Hello {}", "world").into();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
 
 error: useless conversion to the same type: `i32`
-  --> tests/ui/useless_conversion.rs:145:13
+  --> tests/ui/useless_conversion.rs:147:13
    |
 LL |     let _ = i32::from(a + b) * 3;
    |             ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)`
 
 error: useless conversion to the same type: `Foo<'a'>`
-  --> tests/ui/useless_conversion.rs:151:23
+  --> tests/ui/useless_conversion.rs:153:23
    |
 LL |     let _: Foo<'a'> = s2.into();
    |                       ^^^^^^^^^ help: consider removing `.into()`: `s2`
 
 error: useless conversion to the same type: `Foo<'a'>`
-  --> tests/ui/useless_conversion.rs:153:13
+  --> tests/ui/useless_conversion.rs:155:13
    |
 LL |     let _ = Foo::<'a'>::from(s3);
    |             ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3`
 
 error: useless conversion to the same type: `std::vec::IntoIter<Foo<'a'>>`
-  --> tests/ui/useless_conversion.rs:155:13
+  --> tests/ui/useless_conversion.rs:157:13
    |
 LL |     let _ = vec![s4, s4, s4].into_iter().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()`
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:187:7
+  --> tests/ui/useless_conversion.rs:189:7
    |
 LL |     b(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:177:13
+  --> tests/ui/useless_conversion.rs:179:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:188:7
+  --> tests/ui/useless_conversion.rs:190:7
    |
 LL |     c(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:178:18
+  --> tests/ui/useless_conversion.rs:180:18
    |
 LL |     fn c(_: impl IntoIterator<Item = i32>) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:189:7
+  --> tests/ui/useless_conversion.rs:191:7
    |
 LL |     d(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:181:12
+  --> tests/ui/useless_conversion.rs:183:12
    |
 LL |         T: IntoIterator<Item = i32>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:192:7
+  --> 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]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:177:13
+  --> tests/ui/useless_conversion.rs:179:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:193:7
+  --> 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]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:177:13
+  --> tests/ui/useless_conversion.rs:179:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:239:24
+  --> tests/ui/useless_conversion.rs:241:24
    |
 LL |         foo2::<i32, _>([1, 2, 3].into_iter());
    |                        ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:218:12
+  --> tests/ui/useless_conversion.rs:220:12
    |
 LL |         I: IntoIterator<Item = i32> + Helper<X>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:247:14
+  --> tests/ui/useless_conversion.rs:249:14
    |
 LL |         foo3([1, 2, 3].into_iter());
    |              ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:227:12
+  --> tests/ui/useless_conversion.rs:229:12
    |
 LL |         I: IntoIterator<Item = i32>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:256:16
+  --> tests/ui/useless_conversion.rs:258:16
    |
 LL |         S1.foo([1, 2].into_iter());
    |                ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:253:27
+  --> tests/ui/useless_conversion.rs:255:27
    |
 LL |             pub fn foo<I: IntoIterator>(&self, _: I) {}
    |                           ^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:275:44
+  --> tests/ui/useless_conversion.rs:277:44
    |
 LL |         v0.into_iter().interleave_shortest(v1.into_iter());
    |                                            ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:262:20
+  --> tests/ui/useless_conversion.rs:264:20
    |
 LL |                 J: IntoIterator,
    |                    ^^^^^^^^^^^^
 
-error: aborting due to 28 previous errors
+error: useless conversion to the same type: `()`
+  --> tests/ui/useless_conversion.rs:304:58
+   |
+LL |     let _: Result<(), std::io::Error> = test_issue_3913().map(Into::into);
+   |                                                          ^^^^^^^^^^^^^^^^ help: consider removing
+
+error: useless conversion to the same type: `std::io::Error`
+  --> tests/ui/useless_conversion.rs:306:58
+   |
+LL |     let _: Result<(), std::io::Error> = test_issue_3913().map_err(Into::into);
+   |                                                          ^^^^^^^^^^^^^^^^^^^^ help: consider removing
+
+error: useless conversion to the same type: `()`
+  --> tests/ui/useless_conversion.rs:308:58
+   |
+LL |     let _: Result<(), std::io::Error> = test_issue_3913().map(From::from);
+   |                                                          ^^^^^^^^^^^^^^^^ help: consider removing
+
+error: useless conversion to the same type: `std::io::Error`
+  --> tests/ui/useless_conversion.rs:310:58
+   |
+LL |     let _: Result<(), std::io::Error> = test_issue_3913().map_err(From::from);
+   |                                                          ^^^^^^^^^^^^^^^^^^^^ help: consider removing
+
+error: useless conversion to the same type: `()`
+  --> tests/ui/useless_conversion.rs:314:31
+   |
+LL |     let _: ControlFlow<()> = c.map_break(Into::into);
+   |                               ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing
+
+error: useless conversion to the same type: `()`
+  --> tests/ui/useless_conversion.rs:317:31
+   |
+LL |     let _: ControlFlow<()> = c.map_continue(Into::into);
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing
+
+error: useless conversion to the same type: `u32`
+  --> tests/ui/useless_conversion.rs:331:41
+   |
+LL |     let _: Vec<u32> = [1u32].into_iter().map(Into::into).collect();
+   |                                         ^^^^^^^^^^^^^^^^ help: consider removing
+
+error: useless conversion to the same type: `T`
+  --> tests/ui/useless_conversion.rs:342:18
+   |
+LL |     x.into_iter().map(Into::into).collect()
+   |                  ^^^^^^^^^^^^^^^^ help: consider removing
+
+error: aborting due to 36 previous errors
 
diff --git a/tests/ui/zombie_processes.rs b/tests/ui/zombie_processes.rs
index b41bcce3f7f7..6f0d2760a860 100644
--- a/tests/ui/zombie_processes.rs
+++ b/tests/ui/zombie_processes.rs
@@ -1,7 +1,7 @@
 #![warn(clippy::zombie_processes)]
-#![allow(clippy::if_same_then_else, clippy::ifs_same_cond)]
+#![allow(clippy::if_same_then_else, clippy::ifs_same_cond, clippy::needless_return)]
 
-use std::process::{Child, Command};
+use std::process::{Child, Command, ExitStatus};
 
 fn main() {
     {
@@ -12,7 +12,7 @@ fn main() {
 
     {
         let mut x = Command::new("").spawn().unwrap();
-        //~^ ERROR: spawned process is never `wait()`ed on
+        //~^ zombie_processes
         x.kill();
         x.id();
     }
@@ -39,7 +39,7 @@ fn main() {
     }
     {
         let mut x = Command::new("").spawn().unwrap();
-        //~^ ERROR: spawned process is never `wait()`ed on
+        //~^ zombie_processes
         let v = &x;
         // (allow shared refs is fine because one cannot call `.wait()` through that)
     }
@@ -64,14 +64,14 @@ fn main() {
     // It should assume that it might not exit and still lint
     {
         let mut x = Command::new("").spawn().unwrap();
-        //~^ ERROR: spawned process is never `wait()`ed on
+        //~^ zombie_processes
         if true {
             std::process::exit(0);
         }
     }
     {
         let mut x = Command::new("").spawn().unwrap();
-        //~^ ERROR: spawned process is never `wait()`ed on
+        //~^ zombie_processes
         if true {
             while false {}
             // Calling `exit()` after leaving a while loop should still be linted.
@@ -97,7 +97,7 @@ fn main() {
 
     {
         let mut x = Command::new("").spawn().unwrap();
-        //~^ ERROR: spawned process is never `wait()`ed on
+        //~^ zombie_processes
         if true {
             return;
         }
@@ -106,12 +106,32 @@ fn main() {
 
     {
         let mut x = Command::new("").spawn().unwrap();
-        //~^ ERROR: spawned process is never `wait()`ed on
+        //~^ zombie_processes
         if true {
             x.wait().unwrap();
         }
     }
 
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ zombie_processes
+        if true {
+            x.wait().unwrap();
+        } else {
+            // this else block exists to test the other help message
+        }
+    }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        //~^ zombie_processes
+        if true {
+            // this else block exists to test the other help message
+        } else {
+            x.wait().unwrap();
+        }
+    }
+
     {
         let mut x = Command::new("").spawn().unwrap();
         if true {
@@ -143,3 +163,8 @@ fn main() {
 fn process_child(c: Child) {
     todo!()
 }
+
+fn return_wait() -> ExitStatus {
+    let mut x = Command::new("").spawn().unwrap();
+    return x.wait().unwrap();
+}
diff --git a/tests/ui/zombie_processes.stderr b/tests/ui/zombie_processes.stderr
index eec821a4c8f1..afc518c60db2 100644
--- a/tests/ui/zombie_processes.stderr
+++ b/tests/ui/zombie_processes.stderr
@@ -4,7 +4,7 @@ error: spawned process is never `wait()`ed on
 LL |         let mut x = Command::new("").spawn().unwrap();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consider calling `.wait()`
+   = help: consider calling `.wait()`
    = note: not doing so might leave behind zombie processes
    = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
    = note: `-D clippy::zombie-processes` implied by `-D warnings`
@@ -16,7 +16,7 @@ error: spawned process is never `wait()`ed on
 LL |         let mut x = Command::new("").spawn().unwrap();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consider calling `.wait()`
+   = help: consider calling `.wait()`
    = note: not doing so might leave behind zombie processes
    = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
 
@@ -26,7 +26,7 @@ error: spawned process is never `wait()`ed on
 LL |         let mut x = Command::new("").spawn().unwrap();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consider calling `.wait()`
+   = help: consider calling `.wait()`
    = note: not doing so might leave behind zombie processes
    = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
 
@@ -36,29 +36,96 @@ error: spawned process is never `wait()`ed on
 LL |         let mut x = Command::new("").spawn().unwrap();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consider calling `.wait()`
+   = help: consider calling `.wait()`
    = note: not doing so might leave behind zombie processes
    = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
 
-error: spawned process is never `wait()`ed on
+error: spawned process is not `wait()`ed on in all code paths
   --> tests/ui/zombie_processes.rs:99:21
    |
 LL |         let mut x = Command::new("").spawn().unwrap();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consider calling `.wait()`
+note: no `wait()` call exists on the code path to this early return
+  --> tests/ui/zombie_processes.rs:102:13
+   |
+LL |             return;
+   |             ^^^^^^
+note: `wait()` call exists, but it is unreachable due to the early return
+  --> tests/ui/zombie_processes.rs:104:9
+   |
+LL |         x.wait().unwrap();
+   |         ^
+   = help: consider calling `.wait()` in all code paths
    = note: not doing so might leave behind zombie processes
    = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
 
-error: spawned process is never `wait()`ed on
+error: spawned process is not `wait()`ed on in all code paths
   --> tests/ui/zombie_processes.rs:108:21
    |
 LL |         let mut x = Command::new("").spawn().unwrap();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: consider calling `.wait()`
+note: this if expression has a `wait()` call, but it is missing an else block
+  --> tests/ui/zombie_processes.rs:110:9
+   |
+LL | /         if true {
+LL | |             x.wait().unwrap();
+LL | |         }
+   | |_________^
+note: `wait()` called here
+  --> tests/ui/zombie_processes.rs:111:13
+   |
+LL |             x.wait().unwrap();
+   |             ^
+   = help: consider calling `.wait()` in all code paths
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is not `wait()`ed on in all code paths
+  --> tests/ui/zombie_processes.rs:116:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: `wait()` is not called in this if branch
+  --> tests/ui/zombie_processes.rs:120:10
+   |
+LL |           } else {
+   |  __________^
+LL | |             // this else block exists to test the other help message
+LL | |         }
+   | |_________^
+note: `wait()` is called in the other branch
+  --> tests/ui/zombie_processes.rs:119:13
+   |
+LL |             x.wait().unwrap();
+   |             ^
+   = help: consider calling `.wait()` in all code paths
+   = note: not doing so might leave behind zombie processes
+   = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
+
+error: spawned process is not `wait()`ed on in all code paths
+  --> tests/ui/zombie_processes.rs:126:21
+   |
+LL |         let mut x = Command::new("").spawn().unwrap();
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: `wait()` is not called in this if branch
+  --> tests/ui/zombie_processes.rs:128:9
+   |
+LL | /         if true {
+LL | |             // this else block exists to test the other help message
+LL | |         } else {
+   | |_________^
+note: `wait()` is called in the other branch
+  --> tests/ui/zombie_processes.rs:131:13
+   |
+LL |             x.wait().unwrap();
+   |             ^
+   = help: consider calling `.wait()` in all code paths
    = note: not doing so might leave behind zombie processes
    = note: see https://doc.rust-lang.org/stable/std/process/struct.Child.html#warning
 
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/util/gh-pages/script.js b/util/gh-pages/script.js
index 9a5365b2158b..c2197b89c566 100644
--- a/util/gh-pages/script.js
+++ b/util/gh-pages/script.js
@@ -232,13 +232,13 @@ const APPLICABILITIES_FILTER_DEFAULT = {
     MaybeIncorrect: true,
     HasPlaceholders: true,
 };
-const URL_PARAMS_CORRESPONDANCE = {
+const URL_PARAMS_CORRESPONDENCE = {
     "groups_filter": "groups",
     "levels_filter": "levels",
     "applicabilities_filter": "applicabilities",
     "version_filter": "versions",
 };
-const VERSIONS_CORRESPONDANCE = {
+const VERSIONS_CORRESPONDENCE = {
     "lte": "≤",
     "gte": "≥",
     "eq": "=",
@@ -285,7 +285,7 @@ window.filters = {
         }
         function updateIfNeeded(filterName, obj2) {
             const obj1 = filters[filterName];
-            const name = URL_PARAMS_CORRESPONDANCE[filterName];
+            const name = URL_PARAMS_CORRESPONDENCE[filterName];
             if (!compareObjects(obj1, obj2)) {
                 urlParams.set(
                     name,
@@ -316,9 +316,9 @@ window.filters = {
             versions.push(`lte:${filters.version_filter["≤"]}`);
         }
         if (versions.length !== 0) {
-            urlParams.set(URL_PARAMS_CORRESPONDANCE["version_filter"], versions.join(","));
+            urlParams.set(URL_PARAMS_CORRESPONDENCE["version_filter"], versions.join(","));
         } else {
-            urlParams.delete(URL_PARAMS_CORRESPONDANCE["version_filter"]);
+            urlParams.delete(URL_PARAMS_CORRESPONDENCE["version_filter"]);
         }
 
         let params = urlParams.toString();
@@ -532,7 +532,7 @@ function parseURLFilters() {
     const urlParams = new URLSearchParams(window.location.search);
 
     for (const [key, value] of urlParams.entries()) {
-        for (const [corres_key, corres_value] of Object.entries(URL_PARAMS_CORRESPONDANCE)) {
+        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(","));
@@ -545,7 +545,7 @@ function parseURLFilters() {
 
                     for (const [kind, value] of settings) {
                         const elem = document.querySelector(
-                            `#version-filter input[data-value="${VERSIONS_CORRESPONDANCE[kind]}"]`);
+                            `#version-filter input[data-value="${VERSIONS_CORRESPONDENCE[kind]}"]`);
                         elem.value = value;
                         updateVersionFilters(elem, true);
                     }

From 54e5116b44a1096467991ac7c2851d4c0b7d7361 Mon Sep 17 00:00:00 2001
From: Max Niederman <max@maxniederman.com>
Date: Sat, 5 Oct 2024 22:09:20 -0700
Subject: [PATCH 2/6] cover guard patterns in clippy lints

---
 clippy_lints/src/equatable_if_let.rs        | 2 +-
 clippy_lints/src/matches/match_same_arms.rs | 8 +++++---
 clippy_lints/src/matches/single_match.rs    | 4 ++++
 clippy_lints/src/utils/author.rs            | 6 ++++++
 clippy_utils/src/hir_utils.rs               | 4 ++++
 clippy_utils/src/lib.rs                     | 2 +-
 6 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
index fb9f2b1526e3..9c8edfd6113f 100644
--- a/clippy_lints/src/equatable_if_let.rs
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -55,7 +55,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
         | PatKind::Err(_) => false,
         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) => unary_pattern(x),
+        PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) | PatKind::Guard(x, _) => unary_pattern(x),
         PatKind::Path(_) | PatKind::Lit(_) => true,
     }
 }
diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs
index b72a61a43849..4b731d759723 100644
--- a/clippy_lints/src/matches/match_same_arms.rs
+++ b/clippy_lints/src/matches/match_same_arms.rs
@@ -254,9 +254,11 @@ impl<'a> NormalizedPat<'a> {
     fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self {
         match pat.kind {
             PatKind::Wild | PatKind::Binding(.., None) => Self::Wild,
-            PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) | PatKind::Deref(pat) | PatKind::Ref(pat, _) => {
-                Self::from_pat(cx, arena, pat)
-            },
+            PatKind::Binding(.., Some(pat))
+            | PatKind::Box(pat)
+            | PatKind::Deref(pat)
+            | PatKind::Ref(pat, _)
+            | PatKind::Guard(pat, _) => Self::from_pat(cx, arena, pat),
             PatKind::Never => Self::Never,
             PatKind::Struct(ref path, fields, _) => {
                 let fields =
diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs
index 3ca20479f8e0..10ca6832d9c1 100644
--- a/clippy_lints/src/matches/single_match.rs
+++ b/clippy_lints/src/matches/single_match.rs
@@ -343,6 +343,10 @@ impl<'a> PatState<'a> {
                 matches!(self, Self::Wild)
             },
 
+            PatKind::Guard(..) => {
+                matches!(self, Self::Wild)
+            }
+
             // Patterns for things which can only contain a single sub-pattern.
             PatKind::Binding(_, _, _, Some(pat)) | PatKind::Ref(pat, _) | PatKind::Box(pat) | PatKind::Deref(pat) => {
                 self.add_pat(cx, pat)
diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs
index d2970c93f8e9..c2dcb5ae1f9e 100644
--- a/clippy_lints/src/utils/author.rs
+++ b/clippy_lints/src/utils/author.rs
@@ -712,6 +712,12 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 kind!("Ref({pat}, Mutability::{muta:?})");
                 self.pat(pat);
             },
+            PatKind::Guard(pat, cond) => {
+                bind!(self, pat, cond);
+                kind!("Guard({pat}, {cond})");
+                self.pat(pat);
+                self.expr(cond);
+            }
             PatKind::Lit(lit_expr) => {
                 bind!(self, lit_expr);
                 kind!("Lit({lit_expr})");
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index ed52c481de12..7c4e834f8416 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -1104,6 +1104,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                 self.hash_pat(pat);
                 std::mem::discriminant(&mu).hash(&mut self.s);
             },
+            PatKind::Guard(pat, guard) => {
+                self.hash_pat(pat);
+                self.hash_expr(guard);
+            },
             PatKind::Slice(l, m, r) => {
                 for pat in l {
                     self.hash_pat(pat);
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 77c597f85348..4c4e942b2792 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -1777,7 +1777,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
                 },
             }
         },
-        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) | PatKind::Deref(_) => true,
+        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) | PatKind::Deref(_) | PatKind::Guard(..) => true,
     }
 }
 

From ad36f2b0539464e2c529f9d7da3f3f4f150282c3 Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Thu, 2 Jan 2025 21:22:42 +0100
Subject: [PATCH 3/6] turn rustc_box into an intrinsic

---
 .../disallowed_macros/disallowed_macros.stderr  | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/tests/ui-toml/disallowed_macros/disallowed_macros.stderr b/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
index 2e3386628b4d..6a6c6168a1f5 100644
--- a/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
+++ b/tests/ui-toml/disallowed_macros/disallowed_macros.stderr
@@ -1,12 +1,3 @@
-error: use of a disallowed macro `std::vec`
-  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:16:5
-   |
-LL |     vec![1, 2, 3];
-   |     ^^^^^^^^^^^^^
-   |
-   = note: `-D clippy::disallowed-macros` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`
-
 error: use of a disallowed macro `serde::Serialize`
   --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:18:14
    |
@@ -14,6 +5,8 @@ LL |     #[derive(Serialize)]
    |              ^^^^^^^^^
    |
    = note: no serializing
+   = note: `-D clippy::disallowed-macros` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::disallowed_macros)]`
 
 error: use of a disallowed macro `macros::attr`
   --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:31:1
@@ -47,6 +40,12 @@ error: use of a disallowed macro `std::cfg`
 LL |     cfg!(unix);
    |     ^^^^^^^^^^
 
+error: use of a disallowed macro `std::vec`
+  --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:16:5
+   |
+LL |     vec![1, 2, 3];
+   |     ^^^^^^^^^^^^^
+
 error: use of a disallowed macro `macros::expr`
   --> tests/ui-toml/disallowed_macros/disallowed_macros.rs:21:13
    |

From f416f266b0fcd957b7c7dd939ebed15a5ebd939b Mon Sep 17 00:00:00 2001
From: Ralf Jung <post@ralfj.de>
Date: Sat, 4 Jan 2025 11:30:31 +0100
Subject: [PATCH 4/6] turn hir::ItemKind::Fn into a named-field variant

---
 clippy_lints/src/arbitrary_source_item_ordering.rs   | 2 +-
 clippy_lints/src/attrs/utils.rs                      | 2 +-
 clippy_lints/src/doc/mod.rs                          | 2 +-
 clippy_lints/src/doc/too_long_first_doc_paragraph.rs | 2 +-
 clippy_lints/src/exit.rs                             | 2 +-
 clippy_lints/src/extra_unused_type_parameters.rs     | 6 +++++-
 clippy_lints/src/functions/must_use.rs               | 7 ++++++-
 clippy_lints/src/functions/result.rs                 | 2 +-
 clippy_lints/src/implicit_hasher.rs                  | 7 ++++++-
 clippy_lints/src/lifetimes.rs                        | 8 +++++++-
 clippy_lints/src/loops/infinite_loop.rs              | 6 +++++-
 clippy_lints/src/matches/needless_match.rs           | 2 +-
 clippy_lints/src/methods/unnecessary_to_owned.rs     | 2 +-
 clippy_lints/src/missing_doc.rs                      | 2 +-
 clippy_lints/src/missing_inline.rs                   | 2 +-
 clippy_lints/src/mut_key.rs                          | 2 +-
 clippy_lints/src/no_effect.rs                        | 2 +-
 clippy_lints/src/no_mangle_with_rust_abi.rs          | 2 +-
 clippy_lints/src/ptr.rs                              | 2 +-
 clippy_lints/src/returns.rs                          | 2 +-
 clippy_lints/src/unnecessary_box_returns.rs          | 4 ++--
 clippy_utils/src/check_proc_macro.rs                 | 2 +-
 clippy_utils/src/lib.rs                              | 6 +++---
 23 files changed, 50 insertions(+), 26 deletions(-)

diff --git a/clippy_lints/src/arbitrary_source_item_ordering.rs b/clippy_lints/src/arbitrary_source_item_ordering.rs
index cf33e1444e47..741539902662 100644
--- a/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -464,7 +464,7 @@ fn convert_module_item_kind(value: &ItemKind<'_>) -> SourceItemOrderingModuleIte
         ItemKind::Use(..) => Use,
         ItemKind::Static(..) => Static,
         ItemKind::Const(..) => Const,
-        ItemKind::Fn(..) => Fn,
+        ItemKind::Fn{ .. } => Fn,
         ItemKind::Macro(..) => Macro,
         ItemKind::Mod(..) => Mod,
         ItemKind::ForeignMod { .. } => ForeignMod,
diff --git a/clippy_lints/src/attrs/utils.rs b/clippy_lints/src/attrs/utils.rs
index 96de06429040..152e6ec70a18 100644
--- a/clippy_lints/src/attrs/utils.rs
+++ b/clippy_lints/src/attrs/utils.rs
@@ -21,7 +21,7 @@ pub(super) fn is_lint_level(symbol: Symbol, attr_id: AttrId) -> bool {
 }
 
 pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
-    if let ItemKind::Fn(_, _, eid) = item.kind {
+    if let ItemKind::Fn { body: eid, .. } = item.kind {
         is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
     } else {
         true
diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs
index b2135fe18bd9..c835b81679b5 100644
--- a/clippy_lints/src/doc/mod.rs
+++ b/clippy_lints/src/doc/mod.rs
@@ -639,7 +639,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
                     self.check_private_items,
                 );
                 match item.kind {
-                    ItemKind::Fn(sig, _, body_id) => {
+                    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))
                         {
diff --git a/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
index 0f9ff5508532..2327da0ccff7 100644
--- a/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
+++ b/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
@@ -25,7 +25,7 @@ pub(super) fn check(
             // page. So associated items or impl blocks are not part of this list.
             ItemKind::Static(..)
                 | ItemKind::Const(..)
-                | ItemKind::Fn(..)
+                | ItemKind::Fn{ .. }
                 | ItemKind::Macro(..)
                 | ItemKind::Mod(..)
                 | ItemKind::TyAlias(..)
diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs
index 3c235fab0098..e6ddcd107d9d 100644
--- a/clippy_lints/src/exit.rs
+++ b/clippy_lints/src/exit.rs
@@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for Exit {
             && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id()
             && cx.tcx.is_diagnostic_item(sym::process_exit, def_id)
             && let parent = cx.tcx.hir().get_parent_item(e.hir_id)
-            && let OwnerNode::Item(Item{kind: ItemKind::Fn(..), ..}) = cx.tcx.hir_owner_node(parent)
+            && let OwnerNode::Item(Item{kind: ItemKind::Fn{ .. }, ..}) = cx.tcx.hir_owner_node(parent)
             // If the next item up is a function we check if it is an entry point
             // and only then emit a linter warning
             && !is_entrypoint_fn(cx, parent.to_def_id())
diff --git a/clippy_lints/src/extra_unused_type_parameters.rs b/clippy_lints/src/extra_unused_type_parameters.rs
index ae4b66800652..d0159ab89e10 100644
--- a/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/clippy_lints/src/extra_unused_type_parameters.rs
@@ -253,7 +253,11 @@ fn is_empty_body(cx: &LateContext<'_>, body: BodyId) -> bool {
 
 impl<'tcx> LateLintPass<'tcx> for ExtraUnusedTypeParameters {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
-        if let ItemKind::Fn(_, generics, body_id) = item.kind
+        if let ItemKind::Fn {
+            generics,
+            body: body_id,
+            ..
+        } = item.kind
             && !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))
diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs
index afdb5d5306a6..1a01f5f885c3 100644
--- a/clippy_lints/src/functions/must_use.rs
+++ b/clippy_lints/src/functions/must_use.rs
@@ -24,7 +24,12 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT};
 pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
     let attrs = cx.tcx.hir().attrs(item.hir_id());
     let attr = cx.tcx.get_attr(item.owner_id, sym::must_use);
-    if let hir::ItemKind::Fn(ref sig, _generics, ref body_id) = item.kind {
+    if let hir::ItemKind::Fn {
+        ref sig,
+        body: ref body_id,
+        ..
+    } = item.kind
+    {
         let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id);
         let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
         if let Some(attr) = attr {
diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs
index 674d78eaae76..9c396986f62a 100644
--- a/clippy_lints/src/functions/result.rs
+++ b/clippy_lints/src/functions/result.rs
@@ -36,7 +36,7 @@ fn result_err_ty<'tcx>(
 }
 
 pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &hir::Item<'tcx>, large_err_threshold: u64, msrv: &Msrv) {
-    if let hir::ItemKind::Fn(ref sig, _generics, _) = item.kind
+    if let hir::ItemKind::Fn { ref sig, .. } = item.kind
         && let Some((hir_ty, err_ty)) = result_err_ty(cx, sig.decl, item.owner_id.def_id, item.span)
     {
         if cx.effective_visibilities.is_exported(item.owner_id.def_id) {
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index c370f206c8f8..ad2da3c7fcd1 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -149,7 +149,12 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                     );
                 }
             },
-            ItemKind::Fn(ref sig, generics, body_id) => {
+            ItemKind::Fn {
+                ref sig,
+                generics,
+                body: body_id,
+                ..
+            } => {
                 let body = cx.tcx.hir().body(body_id);
 
                 for ty in sig.decl.inputs {
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index 8b2eee34a972..239822f40856 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -95,7 +95,13 @@ declare_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<'_>) {
-        if let ItemKind::Fn(ref sig, generics, id) = item.kind {
+        if let ItemKind::Fn {
+            ref sig,
+            generics,
+            body: id,
+            ..
+        } = item.kind
+        {
             check_fn_inner(cx, sig, Some(id), None, generics, item.span, true);
         } else if let ItemKind::Impl(impl_) = item.kind {
             if !item.span.from_expansion() {
diff --git a/clippy_lints/src/loops/infinite_loop.rs b/clippy_lints/src/loops/infinite_loop.rs
index 9f543b79bac4..f88605fbea0d 100644
--- a/clippy_lints/src/loops/infinite_loop.rs
+++ b/clippy_lints/src/loops/infinite_loop.rs
@@ -75,7 +75,11 @@ fn get_parent_fn_ret_ty<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option
                 ..
             }) => (),
             Node::Item(hir::Item {
-                kind: hir::ItemKind::Fn(FnSig { decl, .. }, _, _),
+                kind:
+                    hir::ItemKind::Fn {
+                        sig: FnSig { decl, .. },
+                        ..
+                    },
                 ..
             })
             | Node::TraitItem(hir::TraitItem {
diff --git a/clippy_lints/src/matches/needless_match.rs b/clippy_lints/src/matches/needless_match.rs
index 73822314b4b4..63bea586caf6 100644
--- a/clippy_lints/src/matches/needless_match.rs
+++ b/clippy_lints/src/matches/needless_match.rs
@@ -133,7 +133,7 @@ fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>
         },
         // compare match_expr ty with RetTy in `fn foo() -> RetTy`
         Node::Item(item) => {
-            if let ItemKind::Fn(..) = item.kind {
+            if let ItemKind::Fn{ .. } = item.kind {
                 let output = cx
                     .tcx
                     .fn_sig(item.owner_id)
diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs
index d19064fd57e3..42107581ab46 100644
--- a/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -496,7 +496,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
             Node::Stmt(_) => return true,
             Node::Block(..) => continue,
             Node::Item(item) => {
-                if let ItemKind::Fn(_, _, body_id) = &item.kind
+                if let ItemKind::Fn { body: body_id, .. } = &item.kind
                     && let output_ty = return_ty(cx, item.owner_id)
                     && rustc_hir_typeck::can_coerce(cx.tcx, cx.param_env, item.owner_id.def_id, ty, output_ty)
                 {
diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs
index b6f49dcc163f..1141728640d4 100644
--- a/clippy_lints/src/missing_doc.rs
+++ b/clippy_lints/src/missing_doc.rs
@@ -192,7 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
         match it.kind {
-            hir::ItemKind::Fn(..) => {
+            hir::ItemKind::Fn{ .. } => {
                 // ignore main()
                 if it.ident.name == sym::main {
                     let at_root = cx.tcx.local_parent(it.owner_id.def_id) == CRATE_DEF_ID;
diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs
index 11ff779d5316..b18f18d89e56 100644
--- a/clippy_lints/src/missing_inline.rs
+++ b/clippy_lints/src/missing_inline.rs
@@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
             return;
         }
         match it.kind {
-            hir::ItemKind::Fn(..) => {
+            hir::ItemKind::Fn{ .. } => {
                 let desc = "a function";
                 let attrs = cx.tcx.hir().attrs(it.hir_id());
                 check_missing_inline_attrs(cx, attrs, it.span, desc);
diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs
index 745f81d1c51a..7abc5870d00e 100644
--- a/clippy_lints/src/mut_key.rs
+++ b/clippy_lints/src/mut_key.rs
@@ -76,7 +76,7 @@ impl_lint_pass!(MutableKeyType<'_> => [ MUTABLE_KEY_TYPE ]);
 
 impl<'tcx> LateLintPass<'tcx> for MutableKeyType<'tcx> {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
-        if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
+        if let hir::ItemKind::Fn { ref sig, .. } = item.kind {
             self.check_sig(cx, item.owner_id.def_id, sig.decl);
         }
     }
diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs
index 7feff7e4d3f1..92644456f63d 100644
--- a/clippy_lints/src/no_effect.rs
+++ b/clippy_lints/src/no_effect.rs
@@ -144,7 +144,7 @@ impl NoEffect {
                     |diag| {
                         for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
                             if let Node::Item(item) = parent.1
-                                && let ItemKind::Fn(..) = item.kind
+                                && let ItemKind::Fn{ .. } = item.kind
                                 && let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id)
                                 && let [.., final_stmt] = block.stmts
                                 && final_stmt.hir_id == stmt.hir_id
diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs
index 64587e08ddc6..9ee4e4932777 100644
--- a/clippy_lints/src/no_mangle_with_rust_abi.rs
+++ b/clippy_lints/src/no_mangle_with_rust_abi.rs
@@ -37,7 +37,7 @@ 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(fn_sig, _, _) = &item.kind {
+        if let ItemKind::Fn { sig: fn_sig, .. } = &item.kind {
             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);
diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs
index b674b01406d3..a86926d8416c 100644
--- a/clippy_lints/src/ptr.rs
+++ b/clippy_lints/src/ptr.rs
@@ -189,7 +189,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
         let mut parents = hir.parent_iter(body.value.hir_id);
         let (item_id, sig, is_trait_item) = match parents.next() {
             Some((_, Node::Item(i))) => {
-                if let ItemKind::Fn(sig, ..) = &i.kind {
+                if let ItemKind::Fn { sig, .. } = &i.kind {
                     (i.owner_id, sig, false)
                 } else {
                     return;
diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs
index aeff31d02d26..dfaee8cc3054 100644
--- a/clippy_lints/src/returns.rs
+++ b/clippy_lints/src/returns.rs
@@ -204,7 +204,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
 
             // Ensure this is not the final stmt, otherwise removing it would cause a compile error
             && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id))
-            && let ItemKind::Fn(_, _, body) = item.kind
+            && let ItemKind::Fn { body, .. } = item.kind
             && let block = cx.tcx.hir().body(body).value
             && let ExprKind::Block(block, _) = block.kind
             && !is_inside_let_else(cx.tcx, expr)
diff --git a/clippy_lints/src/unnecessary_box_returns.rs b/clippy_lints/src/unnecessary_box_returns.rs
index 34df1d5560a1..4158050f969a 100644
--- a/clippy_lints/src/unnecessary_box_returns.rs
+++ b/clippy_lints/src/unnecessary_box_returns.rs
@@ -130,9 +130,9 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns {
     }
 
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
-        let ItemKind::Fn(signature, ..) = &item.kind else {
+        let ItemKind::Fn { sig, .. } = &item.kind else {
             return;
         };
-        self.check_fn_item(cx, signature.decl, item.owner_id.def_id, item.ident.name);
+        self.check_fn_item(cx, sig.decl, item.owner_id.def_id, item.ident.name);
     }
 }
diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs
index b71b53ea3bbf..68e7f807bf51 100644
--- a/clippy_utils/src/check_proc_macro.rs
+++ b/clippy_utils/src/check_proc_macro.rs
@@ -245,7 +245,7 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
         ItemKind::ExternCrate(_) => (Pat::Str("extern"), Pat::Str(";")),
         ItemKind::Static(..) => (Pat::Str("static"), Pat::Str(";")),
         ItemKind::Const(..) => (Pat::Str("const"), Pat::Str(";")),
-        ItemKind::Fn(sig, ..) => (fn_header_search_pat(sig.header), Pat::Str("")),
+        ItemKind::Fn { sig, .. } => (fn_header_search_pat(sig.header), Pat::Str("")),
         ItemKind::ForeignMod { .. } => (Pat::Str("extern"), Pat::Str("}")),
         ItemKind::TyAlias(..) => (Pat::Str("type"), Pat::Str(";")),
         ItemKind::Enum(..) => (Pat::Str("enum"), Pat::Str("}")),
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 77c597f85348..30e7471dd925 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -1397,7 +1397,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
     enclosing_node.and_then(|node| match node {
         Node::Block(block) => Some(block),
         Node::Item(&Item {
-            kind: ItemKind::Fn(_, _, eid),
+            kind: ItemKind::Fn { body: eid, .. },
             ..
         })
         | Node::ImplItem(&ImplItem {
@@ -2565,7 +2565,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool {
             // function scope
             .any(|(_id, node)| {
                 if let Node::Item(item) = node {
-                    if let ItemKind::Fn(_, _, _) = item.kind {
+                    if let ItemKind::Fn { .. } = item.kind {
                         // Note that we have sorted the item names in the visitor,
                         // so the binary_search gets the same as `contains`, but faster.
                         return names.binary_search(&item.ident.name).is_ok();
@@ -2722,7 +2722,7 @@ impl<'tcx> ExprUseCtxt<'tcx> {
             }) => ExprUseNode::ConstStatic(owner_id),
 
             Node::Item(&Item {
-                kind: ItemKind::Fn(..),
+                kind: ItemKind::Fn { .. },
                 owner_id,
                 ..
             })

From bb4a2599082c2666470c4e53f14bd536d4fcd62f Mon Sep 17 00:00:00 2001
From: Philipp Krones <hello@philkrones.com>
Date: Thu, 9 Jan 2025 18:01:20 +0100
Subject: [PATCH 5/6] Bump nightly version -> 2024-01-09

---
 clippy_utils/README.md | 2 +-
 rust-toolchain         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/clippy_utils/README.md b/clippy_utils/README.md
index 73fefbcd5705..c267b804124a 100644
--- a/clippy_utils/README.md
+++ b/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2024-12-26
+nightly-2025-01-09
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/rust-toolchain b/rust-toolchain
index 1000d90f52a5..b1f0a82b1f47 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2024-12-26"
+channel = "nightly-2025-01-09"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"

From 663892bea721cc6eb6364556ce4c2e1da19007aa Mon Sep 17 00:00:00 2001
From: Philipp Krones <hello@philkrones.com>
Date: Thu, 9 Jan 2025 18:01:44 +0100
Subject: [PATCH 6/6] Bump Clippy version -> 0.1.86

---
 Cargo.toml               | 2 +-
 clippy_config/Cargo.toml | 2 +-
 clippy_lints/Cargo.toml  | 2 +-
 clippy_utils/Cargo.toml  | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index bb259c77ee37..e9b11d5df2f2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "clippy"
 # begin autogenerated version
-version = "0.1.85"
+version = "0.1.86"
 # end autogenerated version
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
diff --git a/clippy_config/Cargo.toml b/clippy_config/Cargo.toml
index 3f18a0bc7d25..c761e207c6b6 100644
--- a/clippy_config/Cargo.toml
+++ b/clippy_config/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "clippy_config"
 # begin autogenerated version
-version = "0.1.85"
+version = "0.1.86"
 # end autogenerated version
 edition = "2021"
 publish = false
diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml
index c1f8e82f6988..b575ac1bf4cc 100644
--- a/clippy_lints/Cargo.toml
+++ b/clippy_lints/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "clippy_lints"
 # begin autogenerated version
-version = "0.1.85"
+version = "0.1.86"
 # end autogenerated version
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml
index 945827c98c17..7fa070cd226b 100644
--- a/clippy_utils/Cargo.toml
+++ b/clippy_utils/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "clippy_utils"
 # begin autogenerated version
-version = "0.1.85"
+version = "0.1.86"
 # end autogenerated version
 edition = "2021"
 description = "Helpful tools for writing lints, provided as they are used in Clippy"