about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2025-08-07 17:05:15 +0200
committerPhilipp Krones <hello@philkrones.com>2025-08-07 17:05:15 +0200
commitd9385437c20f4f7fb60fced9dd2d2d37a004dcf4 (patch)
tree08fd28c71182d9feb5b970b582050022513c0a90 /src
parentcd434309efcf5dc68b253e5ef6ba40c1c43711c9 (diff)
parent334fb906aef13d20050987b13448f37391bb97a2 (diff)
downloadrust-d9385437c20f4f7fb60fced9dd2d2d37a004dcf4.tar.gz
rust-d9385437c20f4f7fb60fced9dd2d2d37a004dcf4.zip
Merge commit '334fb906aef13d20050987b13448f37391bb97a2' into clippy-subtree-update
Diffstat (limited to 'src')
-rw-r--r--src/tools/clippy/.github/ISSUE_TEMPLATE/new_lint.yml21
-rwxr-xr-xsrc/tools/clippy/.github/driver.sh6
-rw-r--r--src/tools/clippy/CHANGELOG.md101
-rw-r--r--src/tools/clippy/CONTRIBUTING.md44
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md2
-rw-r--r--src/tools/clippy/clippy_config/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs2
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/inline_always.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cloned_ref_to_slice_refs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/collapsible_if.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/copies.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default_union_representation.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/deprecated_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/broken_link.rs76
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_with_brackets.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/exhaustive_items.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/formatting.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/four_forward_slashes.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/if_not_else.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/infallible_try_from.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/macro_use.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_assert.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_async_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs246
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/single_match.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/ip_constant.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs69
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs78
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs79
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/option_if_let_else.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_else.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/semicolon_block.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs121
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs109
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/mod.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs2
-rw-r--r--src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs5
-rw-r--r--src/tools/clippy/clippy_test_deps/Cargo.lock7
-rw-r--r--src/tools/clippy/clippy_test_deps/Cargo.toml1
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/README.md2
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs116
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs127
-rw-r--r--src/tools/clippy/clippy_utils/src/sym.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs7
-rw-r--r--src/tools/clippy/declare_clippy_lint/Cargo.toml2
-rw-r--r--src/tools/clippy/lintcheck/src/input.rs2
-rw-r--r--src/tools/clippy/lintcheck/src/json.rs2
-rw-r--r--src/tools/clippy/lintcheck/src/output.rs2
-rw-r--r--src/tools/clippy/rust-toolchain.toml2
-rw-r--r--src/tools/clippy/tests/compile-test.rs11
-rw-r--r--src/tools/clippy/tests/symbols-used.rs2
-rw-r--r--src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr2
-rw-r--r--src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr10
-rw-r--r--src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr6
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr6
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer_unfixable.rs17
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.fixed22
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.rs24
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.stderr11
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.fixed18
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.rs19
-rw-r--r--src/tools/clippy/tests/ui/collapsible_if.stderr20
-rw-r--r--src/tools/clippy/tests/ui/deprecated.rs1
-rw-r--r--src/tools/clippy/tests/ui/deprecated.stderr18
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/duplicated_attributes.rs2
-rw-r--r--src/tools/clippy/tests/ui/duplicated_attributes.stderr23
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed14
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.rs14
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr10
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.rs6
-rw-r--r--src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.stderr14
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.fixed6
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.rs6
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.stderr14
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed12
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs12
-rw-r--r--src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr11
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_slice.rs1
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_slice.stderr38
-rw-r--r--src/tools/clippy/tests/ui/infallible_try_from.stderr4
-rw-r--r--src/tools/clippy/tests/ui/ip_constant.fixed14
-rw-r--r--src/tools/clippy/tests/ui/ip_constant.rs14
-rw-r--r--src/tools/clippy/tests/ui/ip_constant.stderr80
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.fixed24
-rw-r--r--src/tools/clippy/tests/ui/iter_on_single_items.rs24
-rw-r--r--src/tools/clippy/tests/ui/let_unit.fixed11
-rw-r--r--src/tools/clippy/tests/ui/let_unit.rs10
-rw-r--r--src/tools/clippy/tests/ui/let_unit.stderr16
-rw-r--r--src/tools/clippy/tests/ui/let_with_type_underscore.fixed12
-rw-r--r--src/tools/clippy/tests/ui/let_with_type_underscore.rs12
-rw-r--r--src/tools/clippy/tests/ui/let_with_type_underscore.stderr50
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2018.stderr4
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2021.stderr4
-rw-r--r--src/tools/clippy/tests/ui/manual_strip.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or_default.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_identity.fixed64
-rw-r--r--src/tools/clippy/tests/ui/map_identity.rs64
-rw-r--r--src/tools/clippy/tests/ui/map_identity.stderr38
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.fixed62
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.rs76
-rw-r--r--src/tools/clippy/tests/ui/match_single_binding.stderr116
-rw-r--r--src/tools/clippy/tests/ui/min_ident_chars.rs49
-rw-r--r--src/tools/clippy/tests/ui/min_ident_chars.stderr80
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_collect_indirect.stderr32
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.rs18
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.stderr18
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed12
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs16
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.stderr19
-rw-r--r--src/tools/clippy/tests/ui/search_is_some.rs15
-rw-r--r--src/tools/clippy/tests/ui/search_is_some.stderr17
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed7
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_some.rs7
-rw-r--r--src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr8
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.rs21
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.stderr28
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.fixed20
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.rs20
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.stderr38
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.rs10
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.stderr6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_clippy_cfg.rs3
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_clippy_cfg.stderr46
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.fixed20
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.rs20
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.stderr30
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_sort_by.stderr12
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/clippy/util/gh-pages/index_template.html37
-rw-r--r--src/tools/clippy/util/gh-pages/script.js13
-rw-r--r--src/tools/clippy/util/gh-pages/style.css369
181 files changed, 2802 insertions, 1026 deletions
diff --git a/src/tools/clippy/.github/ISSUE_TEMPLATE/new_lint.yml b/src/tools/clippy/.github/ISSUE_TEMPLATE/new_lint.yml
index 464740640e0..a8202f6378f 100644
--- a/src/tools/clippy/.github/ISSUE_TEMPLATE/new_lint.yml
+++ b/src/tools/clippy/.github/ISSUE_TEMPLATE/new_lint.yml
@@ -48,3 +48,24 @@ body:
         ```
     validations:
       required: true
+  - type: textarea
+    id: comparison
+    attributes:
+      label: Comparison with existing lints
+      description: |
+        What makes this lint different from any existing lints that are similar, and how are those differences useful?
+
+        You can [use this playground template to see what existing lints are triggered by the bad code][playground]
+        (make sure to use "Tools > Clippy" and not "Build").
+        You can also look through the list of [rustc's allowed-by-default lints][allowed-by-default],
+        as those won't show up in the playground above.
+
+        [allowed-by-default]: https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html
+
+        [playground]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&code=%23%21%5Bwarn%28clippy%3A%3Apedantic%29%5D%0A%23%21%5Bwarn%28clippy%3A%3Anursery%29%5D%0A%23%21%5Bwarn%28clippy%3A%3Arestriction%29%5D%0A%23%21%5Bwarn%28clippy%3A%3Aall%29%5D%0A%23%21%5Ballow%28clippy%3A%3Ablanket_clippy_restriction_lints%2C+reason+%3D+%22testing+to+see+if+any+restriction+lints+match+given+code%22%29%5D%0A%0A%2F%2F%21+Template+that+can+be+used+to+see+what+clippy+lints+a+given+piece+of+code+would+trigger
+      placeholder: Unlike `clippy::...`, the proposed lint would...
+  - type: textarea
+    id: context
+    attributes:
+      label: Additional Context
+      description: Any additional context that you believe may be relevant.
diff --git a/src/tools/clippy/.github/driver.sh b/src/tools/clippy/.github/driver.sh
index 5a81b411291..2874aaf2110 100755
--- a/src/tools/clippy/.github/driver.sh
+++ b/src/tools/clippy/.github/driver.sh
@@ -47,9 +47,9 @@ unset CARGO_MANIFEST_DIR
 
 # Run a lint and make sure it produces the expected output. It's also expected to exit with code 1
 # FIXME: How to match the clippy invocation in compile-test.rs?
-./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/string_to_string.rs 2>string_to_string.stderr && exit 1
-sed -e "/= help: for/d" string_to_string.stderr > normalized.stderr
-diff -u normalized.stderr tests/ui/string_to_string.stderr
+./target/debug/clippy-driver -Dwarnings -Aunused -Zui-testing --emit metadata --crate-type bin tests/ui/char_lit_as_u8.rs 2>char_lit_as_u8.stderr && exit 1
+sed -e "/= help: for/d" char_lit_as_u8.stderr > normalized.stderr
+diff -u normalized.stderr tests/ui/char_lit_as_u8.stderr
 
 # make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
 SYSROOT=$(rustc --print sysroot)
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index a92fbdc767b..bc60b1c57f7 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,7 +6,105 @@ document.
 
 ## Unreleased / Beta / In Rust Nightly
 
-[03a5b6b9...master](https://github.com/rust-lang/rust-clippy/compare/03a5b6b9...master)
+[4ef75291...master](https://github.com/rust-lang/rust-clippy/compare/4ef75291...master)
+
+## Rust 1.89
+
+Current stable, released 2025-08-07
+
+[View all 137 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2025-05-01T16%3A52%3A57Z..2025-06-13T08%3A33%3A27Z+base%3Amaster)
+
+### New Lints
+
+* Added [`coerce_container_to_any`] to `nursery` [#14812](https://github.com/rust-lang/rust-clippy/pull/14812)
+* Added [`ip_constant`] to `pedantic` [#14878](https://github.com/rust-lang/rust-clippy/pull/14878)
+* Added [`infallible_try_from`] to `suspicious` [#14813](https://github.com/rust-lang/rust-clippy/pull/14813)
+* Added [`doc_suspicious_footnotes`] to `suspicious` [#14708](https://github.com/rust-lang/rust-clippy/pull/14708)
+* Added [`pointer_format`] to `restriction` [#14792](https://github.com/rust-lang/rust-clippy/pull/14792)
+* Added [`useless_concat`] to `complexity` [#13829](https://github.com/rust-lang/rust-clippy/pull/13829)
+* Added [`cloned_ref_to_slice_refs`] to `perf` [#14284](https://github.com/rust-lang/rust-clippy/pull/14284)
+* Added [`confusing_method_to_numeric_cast`] to `suspicious` [#13979](https://github.com/rust-lang/rust-clippy/pull/13979)
+
+### Moves and Deprecations
+
+* Removed superseded lints: `transmute_float_to_int`, `transmute_int_to_char`,
+  `transmute_int_to_float`, `transmute_num_to_bytes` (now in rustc)
+  [#14703](https://github.com/rust-lang/rust-clippy/pull/14703)
+
+### Enhancements
+
+* [`module_name_repetitions`] added `allow_exact_repetitions` configuration option
+  [#14261](https://github.com/rust-lang/rust-clippy/pull/14261)
+* [`missing_docs_in_private_items`] added `allow_unused` config for underscored fields
+  [#14453](https://github.com/rust-lang/rust-clippy/pull/14453)
+* [`unnecessary_unwrap`] fixed being emitted twice in closure
+  [#14763](https://github.com/rust-lang/rust-clippy/pull/14763)
+* [`needless_return`] lint span no longer wraps to previous line
+  [#14790](https://github.com/rust-lang/rust-clippy/pull/14790)
+* [`trivial-copy-size-limit`] now defaults to `target_pointer_width`
+  [#13319](https://github.com/rust-lang/rust-clippy/pull/13319)
+* [`integer_division`] fixed false negative for NonZero denominators
+  [#14664](https://github.com/rust-lang/rust-clippy/pull/14664)
+* [`arbitrary_source_item_ordering`] no longer lints inside items with `#[repr]` attribute
+  [#14610](https://github.com/rust-lang/rust-clippy/pull/14610)
+* [`excessive_precision`] no longer triggers on exponent with leading zeros
+  [#14824](https://github.com/rust-lang/rust-clippy/pull/14824)
+* [`to_digit_is_some`] no longer lints in const contexts when MSRV is below 1.87
+  [#14771](https://github.com/rust-lang/rust-clippy/pull/14771)
+
+### False Positive Fixes
+
+* [`std_instead_of_core`] fixed FP when part of the `use` cannot be replaced
+  [#15016](https://github.com/rust-lang/rust-clippy/pull/15016)
+* [`unused_unit`] fixed FP for `Fn` bounds
+  [#14962](https://github.com/rust-lang/rust-clippy/pull/14962)
+* [`unnecessary_debug_formatting`] fixed FP inside `Debug` impl
+  [#14955](https://github.com/rust-lang/rust-clippy/pull/14955)
+* [`assign_op_pattern`] fixed FP on unstable const trait
+  [#14886](https://github.com/rust-lang/rust-clippy/pull/14886)
+* [`useless_conversion`] fixed FP when using `.into_iter().any()`
+  [#14800](https://github.com/rust-lang/rust-clippy/pull/14800)
+* [`collapsible_if`] fixed FP on block stmt before expr
+  [#14730](https://github.com/rust-lang/rust-clippy/pull/14730)
+* [`manual_unwrap_or_default`] fixed FP on ref binding
+  [#14731](https://github.com/rust-lang/rust-clippy/pull/14731)
+* [`unused_async`] fixed FP on default impl
+  [#14720](https://github.com/rust-lang/rust-clippy/pull/14720)
+* [`manual_slice_fill`] fixed FP on `IndexMut` overload
+  [#14719](https://github.com/rust-lang/rust-clippy/pull/14719)
+* [`unnecessary_to_owned`] fixed FP when map key is a reference
+  [#14834](https://github.com/rust-lang/rust-clippy/pull/14834)
+
+### ICE Fixes
+
+* [`mutable_key_type`] fixed ICE when infinitely associated generic types are used
+  [#14965](https://github.com/rust-lang/rust-clippy/pull/14965)
+* [`zero_sized_map_values`] fixed ICE while computing type layout
+  [#14837](https://github.com/rust-lang/rust-clippy/pull/14837)
+* [`useless_asref`] fixed ICE on trait method
+  [#14830](https://github.com/rust-lang/rust-clippy/pull/14830)
+* [`manual_slice_size_calculation`] fixed ICE in suggestion and triggers in `const` context
+  [#14804](https://github.com/rust-lang/rust-clippy/pull/14804)
+* [`missing_const_for_fn`]: fix ICE with some compilation options
+  [#14776](https://github.com/rust-lang/rust-clippy/pull/14776)
+
+### Documentation Improvements
+
+* [`manual_contains`] improved documentation wording
+  [#14917](https://github.com/rust-lang/rust-clippy/pull/14917)
+
+### Performance improvements
+
+* [`strlen_on_c_strings`] optimized by 99.75% (31M → 76k instructions)
+  [#15043](https://github.com/rust-lang/rust-clippy/pull/15043)
+* Reduced documentation lints execution time by 85% (7.5% → 1% of total runtime)
+  [#14870](https://github.com/rust-lang/rust-clippy/pull/14870)
+* [`unit_return_expecting_ord`] optimized to reduce binder instantiation from 95k to 10k calls
+  [#14905](https://github.com/rust-lang/rust-clippy/pull/14905)
+* [`doc_markdown`] optimized by 50%
+  [#14693](https://github.com/rust-lang/rust-clippy/pull/14693)
+* Refactor and speed up `cargo dev fmt`
+  [#14638](https://github.com/rust-lang/rust-clippy/pull/14638)
 
 ## Rust 1.88
 
@@ -6260,6 +6358,7 @@ Released 2018-09-13
 [`pointers_in_nomem_asm_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#pointers_in_nomem_asm_block
 [`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters
 [`possible_missing_comma`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_comma
+[`possible_missing_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#possible_missing_else
 [`precedence`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence
 [`precedence_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#precedence_bits
 [`print_in_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#print_in_format_impl
diff --git a/src/tools/clippy/CONTRIBUTING.md b/src/tools/clippy/CONTRIBUTING.md
index 72ab08792d3..42ed624ec21 100644
--- a/src/tools/clippy/CONTRIBUTING.md
+++ b/src/tools/clippy/CONTRIBUTING.md
@@ -199,26 +199,34 @@ currently. Between writing new lints, fixing issues, reviewing pull requests and
 responding to issues there may not always be enough time to stay on top of it
 all.
 
-Our highest priority is fixing [ICEs][I-ICE] and [bugs][C-bug], for example
-an ICE in a popular crate that many other crates depend on. We don't
-want Clippy to crash on your code and we want it to be as reliable as the
-suggestions from Rust compiler errors.
-
-We have prioritization labels and a sync-blocker label, which are described below.
-- [P-low][p-low]: Requires attention (fix/response/evaluation) by a team member but isn't urgent.
-- [P-medium][p-medium]: Should be addressed by a team member until the next sync.
-- [P-high][p-high]: Should be immediately addressed and will require an out-of-cycle sync or a backport.
-- [L-sync-blocker][l-sync-blocker]: An issue that "blocks" a sync.
-Or rather: before the sync this should be addressed,
-e.g. by removing a lint again, so it doesn't hit beta/stable.
+To find things to fix, go to the [tracking issue][tracking_issue], find an issue that you like, 
+and claim it with `@rustbot claim`.
+
+As a general metric and always taking into account your skill and knowledge level, you can use this guide:
+
+- 🟥 [ICEs][search_ice], these are compiler errors that causes Clippy to panic and crash. Usually involves high-level
+debugging, sometimes interacting directly with the upstream compiler. Difficult to fix but a great challenge that
+improves a lot developer workflows!
+
+- 🟧 [Suggestion causes bug][sugg_causes_bug], Clippy suggested code that changed logic in some silent way.
+Unacceptable, as this may have disastrous consequences. Easier to fix than ICEs
+
+- 🟨 [Suggestion causes error][sugg_causes_error], Clippy suggested code snippet that caused a compiler error
+when applied. We need to make sure that Clippy doesn't suggest using a variable twice at the same time or similar
+easy-to-happen occurrences.
+
+- 🟩 [False positives][false_positive], a lint should not have fired, the easiest of them all, as this is "just"
+identifying the root of a false positive and making an exception for those cases.
+
+Note that false negatives do not have priority unless the case is very clear, as they are a feature-request in a
+trench coat.
 
 [triage]: https://forge.rust-lang.org/release/triage-procedure.html
-[I-ICE]: https://github.com/rust-lang/rust-clippy/labels/I-ICE
-[C-bug]: https://github.com/rust-lang/rust-clippy/labels/C-bug
-[p-low]: https://github.com/rust-lang/rust-clippy/labels/P-low
-[p-medium]: https://github.com/rust-lang/rust-clippy/labels/P-medium
-[p-high]: https://github.com/rust-lang/rust-clippy/labels/P-high
-[l-sync-blocker]: https://github.com/rust-lang/rust-clippy/labels/L-sync-blocker
+[search_ice]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc+state%3Aopen+label%3A%22I-ICE%22
+[sugg_causes_bug]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc%20state%3Aopen%20label%3AI-suggestion-causes-bug
+[sugg_causes_error]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc%20state%3Aopen%20label%3AI-suggestion-causes-error%20
+[false_positive]: https://github.com/rust-lang/rust-clippy/issues?q=sort%3Aupdated-desc%20state%3Aopen%20label%3AI-false-positive
+[tracking_issue]: https://github.com/rust-lang/rust-clippy/issues/15086
 
 ## Contributions
 
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index f25f9ab54dd..daf1c98cdc9 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.1.90"
+version = "0.1.91"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 992ed2c6aaa..7f16f3a9810 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -555,7 +555,7 @@ default configuration of Clippy. By default, any configuration will replace the
 * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
 * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "NixOS", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml
index 858366c8a5c..6ad2cf0d0b1 100644
--- a/src/tools/clippy/clippy_config/Cargo.toml
+++ b/src/tools/clippy/clippy_config/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_config"
-version = "0.1.90"
+version = "0.1.91"
 edition = "2024"
 publish = false
 
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 555f54bcfb8..8167d75583e 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -44,7 +44,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
     "WebP", "OpenExr", "YCbCr", "sRGB",
     "TensorFlow",
     "TrueType",
-    "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD",
+    "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "NixOS",
     "TeX", "LaTeX", "BibTeX", "BibLaTeX",
     "MinGW",
     "CamelCase",
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index c03cc99b581..b9e6de79cc0 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_lints"
-version = "0.1.90"
+version = "0.1.91"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index ab47e309752..a3710ca5165 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -2,8 +2,7 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::msrvs::{self, Msrv};
 use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
-use rustc_hir::RustcVersion;
-use rustc_hir::{HirId, Lit};
+use rustc_hir::{HirId, Lit, RustcVersion};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, symbol};
diff --git a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
index c2406bcfb64..c956738edf0 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
@@ -2,6 +2,7 @@ use super::DUPLICATED_ATTRIBUTES;
 use clippy_utils::diagnostics::span_lint_and_then;
 use itertools::Itertools;
 use rustc_ast::{Attribute, MetaItem};
+use rustc_ast_pretty::pprust::path_to_string;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_lint::EarlyContext;
 use rustc_span::{Span, Symbol, sym};
@@ -35,31 +36,38 @@ fn check_duplicated_attr(
     if attr.span.from_expansion() {
         return;
     }
-    let Some(ident) = attr.ident() else { return };
-    let name = ident.name;
-    if name == sym::doc || name == sym::cfg_attr_trace || name == sym::rustc_on_unimplemented || name == sym::reason {
-        // FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg
-        // conditions are the same.
-        // `#[rustc_on_unimplemented]` contains duplicated subattributes, that's expected.
-        return;
-    }
-    if let Some(direct_parent) = parent.last()
-        && *direct_parent == sym::cfg_trace
-        && [sym::all, sym::not, sym::any].contains(&name)
-    {
-        // FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one
-        // level `cfg`, we leave.
-        return;
+    let attr_path = if let Some(ident) = attr.ident() {
+        ident.name
+    } else {
+        Symbol::intern(&path_to_string(&attr.path))
+    };
+    if let Some(ident) = attr.ident() {
+        let name = ident.name;
+        if name == sym::doc || name == sym::cfg_attr_trace || name == sym::rustc_on_unimplemented || name == sym::reason
+        {
+            // FIXME: Would be nice to handle `cfg_attr` as well. Only problem is to check that cfg
+            // conditions are the same.
+            // `#[rustc_on_unimplemented]` contains duplicated subattributes, that's expected.
+            return;
+        }
+        if let Some(direct_parent) = parent.last()
+            && *direct_parent == sym::cfg_trace
+            && [sym::all, sym::not, sym::any].contains(&name)
+        {
+            // FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one
+            // level `cfg`, we leave.
+            return;
+        }
     }
     if let Some(value) = attr.value_str() {
         emit_if_duplicated(
             cx,
             attr,
             attr_paths,
-            format!("{}:{name}={value}", parent.iter().join(":")),
+            format!("{}:{attr_path}={value}", parent.iter().join(":")),
         );
     } else if let Some(sub_attrs) = attr.meta_item_list() {
-        parent.push(name);
+        parent.push(attr_path);
         for sub_attr in sub_attrs {
             if let Some(meta) = sub_attr.meta_item() {
                 check_duplicated_attr(cx, meta, attr_paths, parent);
@@ -67,7 +75,7 @@ fn check_duplicated_attr(
         }
         parent.pop();
     } else {
-        emit_if_duplicated(cx, attr, attr_paths, format!("{}:{name}", parent.iter().join(":")));
+        emit_if_duplicated(cx, attr, attr_paths, format!("{}:{attr_path}", parent.iter().join(":")));
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
index 409bb698665..fb86ae8da9d 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
@@ -1,8 +1,7 @@
 use super::INLINE_ALWAYS;
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir::attrs::{AttributeKind, InlineAttr};
-use rustc_hir::find_attr;
-use rustc_hir::Attribute;
+use rustc_hir::{Attribute, find_attr};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
diff --git a/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs
index 4ece3ed44fd..8a530e8cff2 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/repr_attributes.rs
@@ -1,6 +1,5 @@
 use rustc_hir::attrs::{AttributeKind, ReprAttr};
-use rustc_hir::find_attr;
-use rustc_hir::Attribute;
+use rustc_hir::{Attribute, find_attr};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
index 011962846cb..10fe1a4174f 100644
--- a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
@@ -100,8 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
                             cond.span,
                             BRACED_EXPR_MESSAGE,
                             "try",
-                            snippet_block_with_applicability(cx, ex.span, "..", Some(expr.span), &mut applicability)
-                                .to_string(),
+                            snippet_block_with_applicability(cx, ex.span, "..", Some(expr.span), &mut applicability),
                             applicability,
                         );
                     }
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index ba1135d745a..64aeb27df69 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -7,10 +7,9 @@ use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{eq_expr_value, sym};
 use rustc_ast::ast::LitKind;
-use rustc_hir::RustcVersion;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
-use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
+use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, RustcVersion, UnOp};
 use rustc_lint::{LateContext, LateLintPass, Level};
 use rustc_session::impl_lint_pass;
 use rustc_span::def_id::LocalDefId;
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
index c1d6cec1b62..c924fba6b5c 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -25,6 +25,12 @@ pub(super) fn check(
         return;
     }
 
+    // If the `as` is from a macro and the casting type is from macro input, whether it is lossless is
+    // dependent on the input
+    if expr.span.from_expansion() && !cast_to_hir.span.eq_ctxt(expr.span) {
+        return;
+    }
+
     span_lint_and_then(
         cx,
         CAST_LOSSLESS,
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index 37accff5eaa..dcc439a272c 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -807,7 +807,7 @@ declare_clippy_lint! {
     /// ```no_run
     /// let _ = u16::MAX as usize;
     /// ```
-    #[clippy::version = "1.86.0"]
+    #[clippy::version = "1.89.0"]
     pub CONFUSING_METHOD_TO_NUMERIC_CAST,
     suspicious,
     "casting a primitive method pointer to any integer type"
diff --git a/src/tools/clippy/clippy_lints/src/cloned_ref_to_slice_refs.rs b/src/tools/clippy/clippy_lints/src/cloned_ref_to_slice_refs.rs
index e33a8e0fb74..72ab292ee3c 100644
--- a/src/tools/clippy/clippy_lints/src/cloned_ref_to_slice_refs.rs
+++ b/src/tools/clippy/clippy_lints/src/cloned_ref_to_slice_refs.rs
@@ -37,7 +37,7 @@ declare_clippy_lint! {
     /// let data_ref = &data;
     /// take_slice(slice::from_ref(data_ref));
     /// ```
-    #[clippy::version = "1.87.0"]
+    #[clippy::version = "1.89.0"]
     pub CLONED_REF_TO_SLICE_REFS,
     perf,
     "cloning a reference for slice references"
diff --git a/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs b/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
index 6217fc4c897..2e3acb7748e 100644
--- a/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
+++ b/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
@@ -41,7 +41,7 @@ declare_clippy_lint! {
     /// // Succeeds since we have a &dyn Any to the inner u32!
     /// assert_eq!(dyn_any_of_u32.downcast_ref::<u32>(), Some(&0u32));
     /// ```
-    #[clippy::version = "1.88.0"]
+    #[clippy::version = "1.89.0"]
     pub COERCE_CONTAINER_TO_ANY,
     nursery,
     "coercing to `&dyn Any` when dereferencing could produce a `dyn Any` without coercion is usually not intended"
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 518535e8c8b..8f1c0296524 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -35,7 +35,7 @@ declare_clippy_lint! {
     /// * [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
     #[clippy::version = "1.35.0"]
     pub COGNITIVE_COMPLEXITY,
-    nursery,
+    restriction,
     "functions that should be split up into multiple functions",
     @eval_always = true
 }
diff --git a/src/tools/clippy/clippy_lints/src/collapsible_if.rs b/src/tools/clippy/clippy_lints/src/collapsible_if.rs
index 1854d86c53b..e3103e2d301 100644
--- a/src/tools/clippy/clippy_lints/src/collapsible_if.rs
+++ b/src/tools/clippy/clippy_lints/src/collapsible_if.rs
@@ -136,6 +136,9 @@ impl CollapsibleIf {
                         return;
                     }
 
+                    // Peel off any parentheses.
+                    let (_, else_block_span, _) = peel_parens(cx.tcx.sess.source_map(), else_.span);
+
                     // Prevent "elseif"
                     // Check that the "else" is followed by whitespace
                     let requires_space = if let Some(c) = snippet(cx, up_to_else, "..").chars().last() {
@@ -152,7 +155,7 @@ impl CollapsibleIf {
                             if requires_space { " " } else { "" },
                             snippet_block_with_applicability(
                                 cx,
-                                else_.span,
+                                else_block_span,
                                 "..",
                                 Some(else_block.span),
                                 &mut applicability
@@ -187,7 +190,8 @@ impl CollapsibleIf {
                             .with_leading_whitespace(cx)
                             .into_span()
                     };
-                    let inner_if = inner.span.split_at(2).0;
+                    let (paren_start, inner_if_span, paren_end) = peel_parens(cx.tcx.sess.source_map(), inner.span);
+                    let inner_if = inner_if_span.split_at(2).0;
                     let mut sugg = vec![
                         // Remove the outer then block `{`
                         (then_open_bracket, String::new()),
@@ -196,6 +200,17 @@ impl CollapsibleIf {
                         // Replace inner `if` by `&&`
                         (inner_if, String::from("&&")),
                     ];
+
+                    if !paren_start.is_empty() {
+                        // Remove any leading parentheses '('
+                        sugg.push((paren_start, String::new()));
+                    }
+
+                    if !paren_end.is_empty() {
+                        // Remove any trailing parentheses ')'
+                        sugg.push((paren_end, String::new()));
+                    }
+
                     sugg.extend(parens_around(check));
                     sugg.extend(parens_around(check_inner));
 
@@ -285,3 +300,37 @@ fn span_extract_keyword(sm: &SourceMap, span: Span, keyword: &str) -> Option<Spa
         })
         .next()
 }
+
+/// Peel the parentheses from an `if` expression, e.g. `((if true {} else {}))`.
+fn peel_parens(sm: &SourceMap, mut span: Span) -> (Span, Span, Span) {
+    use crate::rustc_span::Pos;
+
+    let start = span.shrink_to_lo();
+    let end = span.shrink_to_hi();
+
+    let snippet = sm.span_to_snippet(span).unwrap();
+    if let Some((trim_start, _, trim_end)) = peel_parens_str(&snippet) {
+        let mut data = span.data();
+        data.lo = data.lo + BytePos::from_usize(trim_start);
+        data.hi = data.hi - BytePos::from_usize(trim_end);
+        span = data.span();
+    }
+
+    (start.with_hi(span.lo()), span, end.with_lo(span.hi()))
+}
+
+fn peel_parens_str(snippet: &str) -> Option<(usize, &str, usize)> {
+    let trimmed = snippet.trim();
+    if !(trimmed.starts_with('(') && trimmed.ends_with(')')) {
+        return None;
+    }
+
+    let trim_start = (snippet.len() - snippet.trim_start().len()) + 1;
+    let trim_end = (snippet.len() - snippet.trim_end().len()) + 1;
+
+    let inner = snippet.get(trim_start..snippet.len() - trim_end)?;
+    Some(match peel_parens_str(inner) {
+        None => (trim_start, inner, trim_end),
+        Some((start, inner, end)) => (trim_start + start, inner, trim_end + end),
+    })
+}
diff --git a/src/tools/clippy/clippy_lints/src/copies.rs b/src/tools/clippy/clippy_lints/src/copies.rs
index 4bd34527d21..4fdb497950f 100644
--- a/src/tools/clippy/clippy_lints/src/copies.rs
+++ b/src/tools/clippy/clippy_lints/src/copies.rs
@@ -235,9 +235,9 @@ fn lint_branches_sharing_code<'tcx>(
         let cond_snippet = reindent_multiline(&snippet(cx, cond_span, "_"), false, None);
         let cond_indent = indent_of(cx, cond_span);
         let moved_snippet = reindent_multiline(&snippet(cx, span, "_"), true, None);
-        let suggestion = moved_snippet.to_string() + "\n" + &cond_snippet + "{";
+        let suggestion = moved_snippet + "\n" + &cond_snippet + "{";
         let suggestion = reindent_multiline(&suggestion, true, cond_indent);
-        (replace_span, suggestion.to_string())
+        (replace_span, suggestion)
     });
     let end_suggestion = res.end_span(last_block, sm).map(|span| {
         let moved_snipped = reindent_multiline(&snippet(cx, span, "_"), true, None);
@@ -253,7 +253,7 @@ fn lint_branches_sharing_code<'tcx>(
                     .then_some(range.start - 4..range.end)
             })
             .map_or(span, |range| range.with_ctxt(span.ctxt()));
-        (span, suggestion.to_string())
+        (span, suggestion.clone())
     });
 
     let (span, msg, end_span) = match (&start_suggestion, &end_suggestion) {
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index c3f8e02b4c0..e1cb08e361c 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -178,6 +178,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
     crate::format_impl::RECURSIVE_FORMAT_IMPL_INFO,
     crate::format_push_string::FORMAT_PUSH_STRING_INFO,
     crate::formatting::POSSIBLE_MISSING_COMMA_INFO,
+    crate::formatting::POSSIBLE_MISSING_ELSE_INFO,
     crate::formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING_INFO,
     crate::formatting::SUSPICIOUS_ELSE_FORMATTING_INFO,
     crate::formatting::SUSPICIOUS_UNARY_OP_FORMATTING_INFO,
@@ -690,7 +691,6 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
     crate::strings::STRING_FROM_UTF8_AS_BYTES_INFO,
     crate::strings::STRING_LIT_AS_BYTES_INFO,
     crate::strings::STRING_SLICE_INFO,
-    crate::strings::STRING_TO_STRING_INFO,
     crate::strings::STR_TO_STRING_INFO,
     crate::strings::TRIM_SPLIT_WHITESPACE_INFO,
     crate::strlen_on_c_strings::STRLEN_ON_C_STRINGS_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
index f41255e54db..df6525ce040 100644
--- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_hir::attrs::{AttributeKind, ReprAttr};
-use rustc_hir::find_attr;
-use rustc_hir::{HirId, Item, ItemKind};
+use rustc_hir::{HirId, Item, ItemKind, find_attr};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, FieldDef};
diff --git a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
index 5204f73ea0a..88aebc3e6a1 100644
--- a/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/deprecated_lints.rs
@@ -34,6 +34,8 @@ declare_with_version! { DEPRECATED(DEPRECATED_VERSION) = [
     ("clippy::replace_consts", "`min_value` and `max_value` are now deprecated"),
     #[clippy::version = "pre 1.29.0"]
     ("clippy::should_assert_eq", "`assert!(a == b)` can now print the values the same way `assert_eq!(a, b) can"),
+    #[clippy::version = "1.90.0"]
+    ("clippy::string_to_string", "`clippy:implicit_clone` covers those cases"),
     #[clippy::version = "pre 1.29.0"]
     ("clippy::unsafe_vector_initialization", "the suggested alternative could be substantially slower"),
     #[clippy::version = "pre 1.29.0"]
diff --git a/src/tools/clippy/clippy_lints/src/doc/broken_link.rs b/src/tools/clippy/clippy_lints/src/doc/broken_link.rs
index 4af10510023..8878fa9180f 100644
--- a/src/tools/clippy/clippy_lints/src/doc/broken_link.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/broken_link.rs
@@ -19,52 +19,52 @@ pub fn check(cx: &LateContext<'_>, bl: &PullDownBrokenLink<'_>, doc: &str, fragm
 }
 
 fn warn_if_broken_link(cx: &LateContext<'_>, bl: &PullDownBrokenLink<'_>, doc: &str, fragments: &[DocFragment]) {
-    if let Some((span, _)) = source_span_for_markdown_range(cx.tcx, doc, &bl.span, fragments) {
-        let mut len = 0;
+    let mut len = 0;
 
-        // grab raw link data
-        let (_, raw_link) = doc.split_at(bl.span.start);
+    // grab raw link data
+    let (_, raw_link) = doc.split_at(bl.span.start);
 
-        // strip off link text part
-        let raw_link = match raw_link.split_once(']') {
-            None => return,
-            Some((prefix, suffix)) => {
-                len += prefix.len() + 1;
-                suffix
-            },
-        };
+    // strip off link text part
+    let raw_link = match raw_link.split_once(']') {
+        None => return,
+        Some((prefix, suffix)) => {
+            len += prefix.len() + 1;
+            suffix
+        },
+    };
 
-        let raw_link = match raw_link.split_once('(') {
-            None => return,
-            Some((prefix, suffix)) => {
-                if !prefix.is_empty() {
-                    // there is text between ']' and '(' chars, so it is not a valid link
-                    return;
-                }
-                len += prefix.len() + 1;
-                suffix
-            },
-        };
-
-        if raw_link.starts_with("(http") {
-            // reduce chances of false positive reports
-            // by limiting this checking only to http/https links.
-            return;
-        }
-
-        for c in raw_link.chars() {
-            if c == ')' {
-                // it is a valid link
+    let raw_link = match raw_link.split_once('(') {
+        None => return,
+        Some((prefix, suffix)) => {
+            if !prefix.is_empty() {
+                // there is text between ']' and '(' chars, so it is not a valid link
                 return;
             }
+            len += prefix.len() + 1;
+            suffix
+        },
+    };
 
-            if c == '\n' {
-                report_broken_link(cx, span, len);
-                break;
-            }
+    if raw_link.starts_with("(http") {
+        // reduce chances of false positive reports
+        // by limiting this checking only to http/https links.
+        return;
+    }
 
-            len += 1;
+    for c in raw_link.chars() {
+        if c == ')' {
+            // it is a valid link
+            return;
         }
+
+        if c == '\n'
+            && let Some((span, _)) = source_span_for_markdown_range(cx.tcx, doc, &bl.span, fragments)
+        {
+            report_broken_link(cx, span, len);
+            break;
+        }
+
+        len += 1;
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index ea0da0d2467..d27d68d3866 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -662,7 +662,7 @@ declare_clippy_lint! {
     /// /// [^1]: defined here
     /// fn my_fn() {}
     /// ```
-    #[clippy::version = "1.88.0"]
+    #[clippy::version = "1.89.0"]
     pub DOC_SUSPICIOUS_FOOTNOTES,
     suspicious,
     "looks like a link or footnote ref, but with no definition"
diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
index 1e7d1f92fa3..47d91b80e7e 100644
--- a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs
@@ -1,9 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_ast::AttrStyle;
 use rustc_ast::token::CommentKind;
-use rustc_hir::attrs::AttributeKind;
 use rustc_errors::Applicability;
 use rustc_hir::Attribute;
+use rustc_hir::attrs::AttributeKind;
 use rustc_lint::LateContext;
 use rustc_span::Span;
 
diff --git a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
index 32ba696b3ec..674690e7e31 100644
--- a/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/too_long_first_doc_paragraph.rs
@@ -1,5 +1,5 @@
-use rustc_hir::attrs::AttributeKind;
 use rustc_errors::Applicability;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::{Attribute, Item, ItemKind};
 use rustc_lint::LateContext;
 
diff --git a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
index f2757407ba5..e7230ebf8cb 100644
--- a/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_with_brackets.rs
@@ -93,11 +93,11 @@ impl_lint_pass!(EmptyWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS, EMPTY_ENUM_VA
 impl LateLintPass<'_> for EmptyWithBrackets {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         // FIXME: handle `struct $name {}`
-        if let ItemKind::Struct(ident, _, var_data) = &item.kind
+        if let ItemKind::Struct(ident, generics, var_data) = &item.kind
             && !item.span.from_expansion()
             && !ident.span.from_expansion()
             && has_brackets(var_data)
-            && let span_after_ident = item.span.with_lo(ident.span.hi())
+            && let span_after_ident = item.span.with_lo(generics.span.hi())
             && has_no_fields(cx, var_data, span_after_ident)
         {
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index ba539d05b6b..e467246741c 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -7,10 +7,9 @@ use clippy_utils::{
     get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate, path_to_local, path_to_local_id,
 };
 use rustc_abi::ExternAbi;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_errors::Applicability;
-use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind};
+use rustc_hir::attrs::AttributeKind;
+use rustc_hir::{BindingMode, Expr, ExprKind, FnRetTy, GenericArgs, Param, PatKind, QPath, Safety, TyKind, find_attr};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{
diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
index 5f40e576443..ac61ce705eb 100644
--- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
+++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
@@ -1,9 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::indent_of;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_errors::Applicability;
-use rustc_hir::{Item, ItemKind};
+use rustc_hir::attrs::AttributeKind;
+use rustc_hir::{Item, ItemKind, find_attr};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
index d5abaa547e8..84d39dd81c9 100644
--- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
@@ -148,7 +148,7 @@ fn prepare_receiver_sugg<'a>(cx: &LateContext<'_>, mut expr: &'a Expr<'a>) -> Su
         .into();
 
         suggestion = match suggestion {
-            Sugg::MaybeParen(_) => Sugg::MaybeParen(op),
+            Sugg::MaybeParen(_) | Sugg::UnOp(UnOp::Neg, _) => Sugg::MaybeParen(op),
             _ => Sugg::NonParen(op),
         };
     }
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index af4202422e4..3359aa60323 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -17,12 +17,11 @@ use rustc_ast::{
     FormatArgPosition, FormatArgPositionKind, FormatArgsPiece, FormatArgumentKind, FormatCount, FormatOptions,
     FormatPlaceholder, FormatTrait,
 };
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::{find_attr,RustcVersion};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
 use rustc_errors::SuggestionStyle::{CompletelyHidden, ShowCode};
-use rustc_hir::{Expr, ExprKind, LangItem};
+use rustc_hir::attrs::AttributeKind;
+use rustc_hir::{Expr, ExprKind, LangItem, RustcVersion, find_attr};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment};
 use rustc_middle::ty::{self, GenericArg, List, TraitRef, Ty, TyCtxt, Upcast};
@@ -223,7 +222,7 @@ declare_clippy_lint! {
     /// ```
     ///
     /// [pointer format]: https://doc.rust-lang.org/std/fmt/index.html#formatting-traits
-    #[clippy::version = "1.88.0"]
+    #[clippy::version = "1.89.0"]
     pub POINTER_FORMAT,
     restriction,
     "formatting a pointer"
diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs
index 4b482f7b233..1c751643bec 100644
--- a/src/tools/clippy/clippy_lints/src/formatting.rs
+++ b/src/tools/clippy/clippy_lints/src/formatting.rs
@@ -93,6 +93,31 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
+    /// Checks for an `if` expression followed by either a block or another `if` that
+    /// looks like it should have an `else` between them.
+    ///
+    /// ### Why is this bad?
+    /// This is probably some refactoring remnant, even if the code is correct, it
+    /// might look confusing.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// if foo {
+    /// } { // looks like an `else` is missing here
+    /// }
+    ///
+    /// if foo {
+    /// } if bar { // looks like an `else` is missing here
+    /// }
+    /// ```
+    #[clippy::version = "1.90.0"]
+    pub POSSIBLE_MISSING_ELSE,
+    suspicious,
+    "possibly missing `else`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     /// Checks for possible missing comma in an array. It lints if
     /// an array element is a binary operator expression and it lies on two lines.
     ///
@@ -116,6 +141,7 @@ declare_lint_pass!(Formatting => [
     SUSPICIOUS_ASSIGNMENT_FORMATTING,
     SUSPICIOUS_UNARY_OP_FORMATTING,
     SUSPICIOUS_ELSE_FORMATTING,
+    POSSIBLE_MISSING_ELSE,
     POSSIBLE_MISSING_COMMA
 ]);
 
@@ -307,7 +333,7 @@ fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {
 
         span_lint_and_note(
             cx,
-            SUSPICIOUS_ELSE_FORMATTING,
+            POSSIBLE_MISSING_ELSE,
             else_span,
             format!("this looks like {looks_like} but the `else` is missing"),
             None,
diff --git a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs
index 8822b87f92f..a7b0edeb799 100644
--- a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs
+++ b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs
@@ -1,4 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::SpanRangeExt as _;
+use itertools::Itertools;
 use rustc_errors::Applicability;
 use rustc_hir::Item;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -81,6 +83,14 @@ impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes {
                         "turn these into doc comments by removing one `/`"
                     };
 
+                    // If the comment contains a bare CR (not followed by a LF), do not propose an auto-fix
+                    // as bare CR are not allowed in doc comments.
+                    if span.check_source_text(cx, contains_bare_cr) {
+                        diag.help(msg)
+                            .note("bare CR characters are not allowed in doc comments");
+                        return;
+                    }
+
                     diag.multipart_suggestion(
                         msg,
                         bad_comments
@@ -97,3 +107,8 @@ impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes {
         }
     }
 }
+
+/// Checks if `text` contains any CR not followed by a LF
+fn contains_bare_cr(text: &str) -> bool {
+    text.bytes().tuple_windows().any(|(a, b)| a == b'\r' && b != b'\n')
+}
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index 55ca0d9ecb7..8de68bfcb51 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -14,7 +14,7 @@ use clippy_utils::source::snippet_indent;
 use clippy_utils::ty::is_must_use_ty;
 use clippy_utils::visitors::for_each_expr_without_closures;
 use clippy_utils::{return_ty, trait_ref_of_method};
-use rustc_hir::attrs::{AttributeKind};
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::find_attr;
 use rustc_span::Symbol;
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
diff --git a/src/tools/clippy/clippy_lints/src/if_not_else.rs b/src/tools/clippy/clippy_lints/src/if_not_else.rs
index 25fed0d4dd1..e8afa69b537 100644
--- a/src/tools/clippy/clippy_lints/src/if_not_else.rs
+++ b/src/tools/clippy/clippy_lints/src/if_not_else.rs
@@ -81,7 +81,7 @@ impl LateLintPass<'_> for IfNotElse {
                         e.span,
                         msg,
                         "try",
-                        make_sugg(cx, &cond.kind, cond_inner.span, els.span, "..", Some(e.span)).to_string(),
+                        make_sugg(cx, &cond.kind, cond_inner.span, els.span, "..", Some(e.span)),
                         Applicability::MachineApplicable,
                     ),
                     _ => span_lint_and_help(cx, IF_NOT_ELSE, e.span, msg, None, help),
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index 85ebc830d3b..89988be5875 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -2,14 +2,13 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::msrvs::Msrv;
 use clippy_utils::{is_in_const_context, is_in_test};
-use rustc_hir::{RustcVersion, StabilityLevel, StableSince};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::DefKind;
-use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, QPath};
+use rustc_hir::{self as hir, AmbigArg, Expr, ExprKind, HirId, QPath, RustcVersion, StabilityLevel, StableSince};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::DefId;
+use rustc_span::def_id::{CrateNum, DefId};
 use rustc_span::{ExpnKind, Span, sym};
 
 declare_clippy_lint! {
@@ -83,16 +82,22 @@ pub struct IncompatibleMsrv {
     msrv: Msrv,
     availability_cache: FxHashMap<(DefId, bool), Availability>,
     check_in_tests: bool,
+    core_crate: Option<CrateNum>,
 }
 
 impl_lint_pass!(IncompatibleMsrv => [INCOMPATIBLE_MSRV]);
 
 impl IncompatibleMsrv {
-    pub fn new(conf: &'static Conf) -> Self {
+    pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
         Self {
             msrv: conf.msrv,
             availability_cache: FxHashMap::default(),
             check_in_tests: conf.check_incompatible_msrv_in_tests,
+            core_crate: tcx
+                .crates(())
+                .iter()
+                .find(|krate| tcx.crate_name(**krate) == sym::core)
+                .copied(),
         }
     }
 
@@ -140,23 +145,16 @@ impl IncompatibleMsrv {
             // We don't check local items since their MSRV is supposed to always be valid.
             return;
         }
-        if let ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) = span.ctxt().outer_expn_data().kind {
+        let expn_data = span.ctxt().outer_expn_data();
+        if let ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) = expn_data.kind {
             // Desugared expressions get to cheat and stability is ignored.
             // Intentionally not using `.from_expansion()`, since we do still care about macro expansions
             return;
         }
-
         // Functions coming from `core` while expanding a macro such as `assert*!()` get to cheat too: the
         // macros may have existed prior to the checked MSRV, but their expansion with a recent compiler
         // might use recent functions or methods. Compiling with an older compiler would not use those.
-        if span.from_expansion()
-            && cx.tcx.crate_name(def_id.krate) == sym::core
-            && span
-                .ctxt()
-                .outer_expn_data()
-                .macro_def_id
-                .is_some_and(|def_id| cx.tcx.crate_name(def_id.krate) == sym::core)
-        {
+        if Some(def_id.krate) == self.core_crate && expn_data.macro_def_id.map(|did| did.krate) == self.core_crate {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index 3d131a7825a..8f9f71a1476 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::IfLet;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::is_copy;
-use clippy_utils::{is_expn_of, is_lint_allowed, path_to_local, sym};
+use clippy_utils::{is_lint_allowed, path_to_local};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -71,7 +71,7 @@ impl_lint_pass!(IndexRefutableSlice => [INDEX_REFUTABLE_SLICE]);
 impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
         if let Some(IfLet { let_pat, if_then, .. }) = IfLet::hir(cx, expr)
-            && (!expr.span.from_expansion() || is_expn_of(expr.span, sym::if_chain).is_some())
+            && !expr.span.from_expansion()
             && !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id)
             && let found_slices = find_slice_values(cx, let_pat)
             && !found_slices.is_empty()
diff --git a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
index f7cdf05359a..589c294a678 100644
--- a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
+++ b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
@@ -13,7 +13,7 @@ declare_clippy_lint! {
     ///
     /// ### Why is this bad?
     ///
-    /// Infalliable conversions should be implemented via `From` with the blanket conversion.
+    /// Infallible conversions should be implemented via `From` with the blanket conversion.
     ///
     /// ### Example
     /// ```no_run
@@ -35,7 +35,7 @@ declare_clippy_lint! {
     ///     }
     /// }
     /// ```
-    #[clippy::version = "1.88.0"]
+    #[clippy::version = "1.89.0"]
     pub INFALLIBLE_TRY_FROM,
     suspicious,
     "TryFrom with infallible Error type"
@@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom {
                     cx,
                     INFALLIBLE_TRY_FROM,
                     span,
-                    "infallible TryFrom impl; consider implementing From, instead",
+                    "infallible TryFrom impl; consider implementing From instead",
                 );
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
index ee59a4cc8cb..e416ac079d6 100644
--- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
+++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
@@ -1,9 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::sugg::DiagExt;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_errors::Applicability;
-use rustc_hir::{TraitFn, TraitItem, TraitItemKind};
+use rustc_hir::attrs::AttributeKind;
+use rustc_hir::{TraitFn, TraitItem, TraitItemKind, find_attr};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
diff --git a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
index 1917ca24a05..5b0f95ffc37 100644
--- a/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_with_type_underscore.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
+use clippy_utils::source::{IntoSpan, SpanRangeExt};
 use rustc_errors::Applicability;
 use rustc_hir::{LetStmt, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -30,9 +31,15 @@ impl<'tcx> LateLintPass<'tcx> for UnderscoreTyped {
         if let Some(ty) = local.ty // Ensure that it has a type defined
             && let TyKind::Infer(()) = &ty.kind // that type is '_'
             && local.span.eq_ctxt(ty.span)
-            && !local.span.in_external_macro(cx.tcx.sess.source_map())
+            && let sm = cx.tcx.sess.source_map()
+            && !local.span.in_external_macro(sm)
             && !is_from_proc_macro(cx, ty)
         {
+            let span_to_remove = sm
+                .span_extend_to_prev_char_before(ty.span, ':', true)
+                .with_leading_whitespace(cx)
+                .into_span();
+
             span_lint_and_then(
                 cx,
                 LET_WITH_TYPE_UNDERSCORE,
@@ -40,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for UnderscoreTyped {
                 "variable declared with type underscore",
                 |diag| {
                     diag.span_suggestion_verbose(
-                        ty.span.with_lo(local.pat.span.hi()),
+                        span_to_remove,
                         "remove the explicit type `_` declaration",
                         "",
                         Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 914aa6b9b80..844bc1b0e39 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -522,7 +522,8 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
     store.register_late_pass(|_| Box::new(same_name_method::SameNameMethod));
     store.register_late_pass(move |_| Box::new(index_refutable_slice::IndexRefutableSlice::new(conf)));
     store.register_late_pass(|_| Box::<shadow::Shadow>::default());
-    store.register_late_pass(|_| Box::new(unit_types::UnitTypes));
+    let format_args = format_args_storage.clone();
+    store.register_late_pass(move |_| Box::new(unit_types::UnitTypes::new(format_args.clone())));
     store.register_late_pass(move |_| Box::new(loops::Loops::new(conf)));
     store.register_late_pass(|_| Box::<main_recursion::MainRecursion>::default());
     store.register_late_pass(move |_| Box::new(lifetimes::Lifetimes::new(conf)));
@@ -663,7 +664,6 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
     store.register_early_pass(|| Box::new(asm_syntax::InlineAsmX86IntelSyntax));
     store.register_late_pass(|_| Box::new(empty_drop::EmptyDrop));
     store.register_late_pass(|_| Box::new(strings::StrToString));
-    store.register_late_pass(|_| Box::new(strings::StringToString));
     store.register_late_pass(|_| Box::new(zero_sized_map_values::ZeroSizedMapValues));
     store.register_late_pass(|_| Box::<vec_init_then_push::VecInitThenPush>::default());
     store.register_late_pass(|_| Box::new(redundant_slicing::RedundantSlicing));
@@ -796,7 +796,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
     store.register_late_pass(|_| Box::<unconditional_recursion::UnconditionalRecursion>::default());
     store.register_late_pass(move |_| Box::new(pub_underscore_fields::PubUnderscoreFields::new(conf)));
     store.register_late_pass(move |_| Box::new(missing_const_for_thread_local::MissingConstForThreadLocal::new(conf)));
-    store.register_late_pass(move |_| Box::new(incompatible_msrv::IncompatibleMsrv::new(conf)));
+    store.register_late_pass(move |tcx| Box::new(incompatible_msrv::IncompatibleMsrv::new(tcx, conf)));
     store.register_late_pass(|_| Box::new(to_string_trait_impl::ToStringTraitImpl));
     store.register_early_pass(|| Box::new(multiple_bound_locations::MultipleBoundLocations));
     store.register_late_pass(move |_| Box::new(assigning_clones::AssigningClones::new(conf)));
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 8a253ae5810..2ccff768097 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -202,7 +202,7 @@ fn all_spans_after_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> Vec<Span> {
                 .iter()
                 .skip_while(|inner| inner.hir_id != stmt.hir_id)
                 .map(stmt_source_span)
-                .chain(if let Some(e) = block.expr { vec![e.span] } else { vec![] })
+                .chain(block.expr.map(|e| e.span))
                 .collect();
         }
 
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index bf89556fbb6..8989793625a 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -1,11 +1,10 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet;
 use hir::def::{DefKind, Res};
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_hir::{self as hir, AmbigArg};
+use rustc_hir::attrs::AttributeKind;
+use rustc_hir::{self as hir, AmbigArg, find_attr};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs
index ea6b01a053a..76cb2286477 100644
--- a/src/tools/clippy/clippy_lints/src/manual_assert.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_assert.rs
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::{is_panic, root_macro_call};
-use clippy_utils::{is_else_clause, is_parent_stmt, peel_blocks_with_stmt, span_extract_comment, sugg};
+use clippy_utils::{higher, is_else_clause, is_parent_stmt, peel_blocks_with_stmt, span_extract_comment, sugg};
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, UnOp};
+use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::declare_lint_pass;
 
@@ -35,7 +35,7 @@ declare_lint_pass!(ManualAssert => [MANUAL_ASSERT]);
 
 impl<'tcx> LateLintPass<'tcx> for ManualAssert {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
-        if let ExprKind::If(cond, then, None) = expr.kind
+        if let Some(higher::If { cond, then, r#else: None }) = higher::If::hir(expr)
             && !matches!(cond.kind, ExprKind::Let(_))
             && !expr.span.from_expansion()
             && let then = peel_blocks_with_stmt(then)
@@ -51,19 +51,13 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert {
             && !is_else_clause(cx.tcx, expr)
         {
             let mut applicability = Applicability::MachineApplicable;
-            let cond = cond.peel_drop_temps();
             let mut comments = span_extract_comment(cx.sess().source_map(), expr.span);
             if !comments.is_empty() {
                 comments += "\n";
             }
-            let (cond, not) = match cond.kind {
-                ExprKind::Unary(UnOp::Not, e) => (e, ""),
-                _ => (cond, "!"),
-            };
-            let cond_sugg =
-                sugg::Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "..", &mut applicability).maybe_paren();
+            let cond_sugg = !sugg::Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "..", &mut applicability);
             let semicolon = if is_parent_stmt(cx, expr.hir_id) { ";" } else { "" };
-            let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip}){semicolon}");
+            let sugg = format!("assert!({cond_sugg}, {format_args_snip}){semicolon}");
             // we show to the user the suggestion without the comments, but when applying the fix, include the
             // comments in the block
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
index abd1ac954cd..ba1ad599e11 100644
--- a/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_async_fn.rs
@@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
                             format!("{} async {}", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos])
                         };
 
-                        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.multipart_suggestion(
                             "make the function `async` and return the output of the future directly",
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 6b0f7446849..0d783fde331 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -4,12 +4,11 @@ use clippy_utils::is_doc_hidden;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_indent;
 use itertools::Itertools;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
-use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData};
+use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData, find_attr};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs
index 6a76c6cedd0..82d5310663e 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs
@@ -1,11 +1,16 @@
+use std::ops::ControlFlow;
+
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::macros::HirNode;
-use clippy_utils::source::{indent_of, snippet, snippet_block_with_context, snippet_with_context};
-use clippy_utils::{is_refutable, peel_blocks};
+use clippy_utils::source::{indent_of, reindent_multiline, snippet, snippet_block_with_context, snippet_with_context};
+use clippy_utils::{is_expr_identity_of_pat, is_refutable, peel_blocks};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_hir::{Arm, Expr, ExprKind, Node, PatKind, StmtKind};
+use rustc_hir::def::Res;
+use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_path, walk_stmt};
+use rustc_hir::{Arm, Block, Expr, ExprKind, HirId, Node, PatKind, Path, Stmt, StmtKind};
 use rustc_lint::LateContext;
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 
 use super::MATCH_SINGLE_BINDING;
 
@@ -26,9 +31,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
     let match_body = peel_blocks(arms[0].body);
     let mut app = Applicability::MaybeIncorrect;
     let ctxt = expr.span.ctxt();
-    let mut snippet_body = snippet_block_with_context(cx, match_body.span, ctxt, "..", Some(expr.span), &mut app)
-        .0
-        .to_string();
+    let mut snippet_body = snippet_block_with_context(cx, match_body.span, ctxt, "..", Some(expr.span), &mut app).0;
 
     // Do we need to add ';' to suggestion ?
     if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id)
@@ -50,10 +53,11 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
                         cx,
                         (ex, expr),
                         (bind_names, matched_vars),
-                        &snippet_body,
+                        snippet_body,
                         &mut app,
                         Some(span),
                         true,
+                        is_var_binding_used_later(cx, expr, &arms[0]),
                     );
 
                     span_lint_and_sugg(
@@ -78,15 +82,28 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
                         snippet_with_context(cx, pat_span, ctxt, "..", &mut app).0
                     ),
                 ),
+                None if is_expr_identity_of_pat(cx, arms[0].pat, ex, false) => {
+                    span_lint_and_sugg(
+                        cx,
+                        MATCH_SINGLE_BINDING,
+                        expr.span,
+                        "this match could be replaced by its body itself",
+                        "consider using the match body instead",
+                        snippet_body,
+                        Applicability::MachineApplicable,
+                    );
+                    return;
+                },
                 None => {
                     let sugg = sugg_with_curlies(
                         cx,
                         (ex, expr),
                         (bind_names, matched_vars),
-                        &snippet_body,
+                        snippet_body,
                         &mut app,
                         None,
                         true,
+                        is_var_binding_used_later(cx, expr, &arms[0]),
                     );
                     (expr.span, sugg)
                 },
@@ -108,10 +125,11 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
                     cx,
                     (ex, expr),
                     (bind_names, matched_vars),
-                    &snippet_body,
+                    snippet_body,
                     &mut app,
                     None,
                     false,
+                    true,
                 );
 
                 span_lint_and_sugg(
@@ -139,6 +157,125 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
     }
 }
 
+struct VarBindingVisitor<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    identifiers: FxHashSet<Symbol>,
+}
+
+impl<'tcx> Visitor<'tcx> for VarBindingVisitor<'_, 'tcx> {
+    type Result = ControlFlow<()>;
+
+    fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) -> Self::Result {
+        if let Res::Local(_) = path.res
+            && let [segment] = path.segments
+            && self.identifiers.contains(&segment.ident.name)
+        {
+            return ControlFlow::Break(());
+        }
+
+        walk_path(self, path)
+    }
+
+    fn visit_block(&mut self, block: &'tcx Block<'tcx>) -> Self::Result {
+        let before = self.identifiers.clone();
+        walk_block(self, block)?;
+        self.identifiers = before;
+        ControlFlow::Continue(())
+    }
+
+    fn visit_stmt(&mut self, stmt: &'tcx Stmt<'tcx>) -> Self::Result {
+        if let StmtKind::Let(let_stmt) = stmt.kind {
+            if let Some(init) = let_stmt.init {
+                self.visit_expr(init)?;
+            }
+
+            let_stmt.pat.each_binding(|_, _, _, ident| {
+                self.identifiers.remove(&ident.name);
+            });
+        }
+        walk_stmt(self, stmt)
+    }
+
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {
+        match expr.kind {
+            ExprKind::If(
+                Expr {
+                    kind: ExprKind::Let(let_expr),
+                    ..
+                },
+                then,
+                else_,
+            ) => {
+                self.visit_expr(let_expr.init)?;
+                let before = self.identifiers.clone();
+                let_expr.pat.each_binding(|_, _, _, ident| {
+                    self.identifiers.remove(&ident.name);
+                });
+
+                self.visit_expr(then)?;
+                self.identifiers = before;
+                if let Some(else_) = else_ {
+                    self.visit_expr(else_)?;
+                }
+                ControlFlow::Continue(())
+            },
+            ExprKind::Closure(closure) => {
+                let body = self.cx.tcx.hir_body(closure.body);
+                let before = self.identifiers.clone();
+                for param in body.params {
+                    param.pat.each_binding(|_, _, _, ident| {
+                        self.identifiers.remove(&ident.name);
+                    });
+                }
+                self.visit_expr(body.value)?;
+                self.identifiers = before;
+                ControlFlow::Continue(())
+            },
+            ExprKind::Match(expr, arms, _) => {
+                self.visit_expr(expr)?;
+                for arm in arms {
+                    let before = self.identifiers.clone();
+                    arm.pat.each_binding(|_, _, _, ident| {
+                        self.identifiers.remove(&ident.name);
+                    });
+                    if let Some(guard) = arm.guard {
+                        self.visit_expr(guard)?;
+                    }
+                    self.visit_expr(arm.body)?;
+                    self.identifiers = before;
+                }
+                ControlFlow::Continue(())
+            },
+            _ => walk_expr(self, expr),
+        }
+    }
+}
+
+fn is_var_binding_used_later(cx: &LateContext<'_>, expr: &Expr<'_>, arm: &Arm<'_>) -> bool {
+    let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id) else {
+        return false;
+    };
+    let Node::Block(block) = cx.tcx.parent_hir_node(stmt.hir_id) else {
+        return false;
+    };
+
+    let mut identifiers = FxHashSet::default();
+    arm.pat.each_binding(|_, _, _, ident| {
+        identifiers.insert(ident.name);
+    });
+
+    let mut visitor = VarBindingVisitor { cx, identifiers };
+    block
+        .stmts
+        .iter()
+        .skip_while(|s| s.hir_id != stmt.hir_id)
+        .skip(1)
+        .any(|stmt| matches!(visitor.visit_stmt(stmt), ControlFlow::Break(())))
+        || block
+            .expr
+            .is_some_and(|expr| matches!(visitor.visit_expr(expr), ControlFlow::Break(())))
+}
+
 /// Returns true if the `ex` match expression is in a local (`let`) or assign expression
 fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> {
     if let Node::Expr(parent_arm_expr) = cx.tcx.parent_hir_node(ex.hir_id) {
@@ -161,47 +298,66 @@ fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<Ass
     None
 }
 
-fn expr_parent_requires_curlies<'a>(cx: &LateContext<'a>, match_expr: &Expr<'a>) -> bool {
+fn expr_in_nested_block(cx: &LateContext<'_>, match_expr: &Expr<'_>) -> bool {
+    if let Node::Block(block) = cx.tcx.parent_hir_node(match_expr.hir_id) {
+        return block
+            .expr
+            .map_or_else(|| matches!(block.stmts, [_]), |_| block.stmts.is_empty());
+    }
+    false
+}
+
+fn expr_must_have_curlies(cx: &LateContext<'_>, match_expr: &Expr<'_>) -> bool {
     let parent = cx.tcx.parent_hir_node(match_expr.hir_id);
-    matches!(
-        parent,
-        Node::Expr(Expr {
-            kind: ExprKind::Closure { .. },
-            ..
-        }) | Node::AnonConst(..)
+    if let Node::Expr(Expr {
+        kind: ExprKind::Closure(..) | ExprKind::Binary(..),
+        ..
+    })
+    | Node::AnonConst(..) = parent
+    {
+        return true;
+    }
+
+    if let Node::Arm(arm) = &cx.tcx.parent_hir_node(match_expr.hir_id)
+        && let ExprKind::Match(..) = arm.body.kind
+    {
+        return true;
+    }
+
+    false
+}
+
+fn indent_of_nth_line(snippet: &str, nth: usize) -> Option<usize> {
+    snippet
+        .lines()
+        .nth(nth)
+        .and_then(|s| s.find(|c: char| !c.is_whitespace()))
+}
+
+fn reindent_snippet_if_in_block(snippet_body: &str, has_assignment: bool) -> String {
+    if has_assignment || !snippet_body.starts_with('{') {
+        return reindent_multiline(snippet_body, true, indent_of_nth_line(snippet_body, 1));
+    }
+
+    let snippet_body = snippet_body.trim_start_matches('{').trim_end_matches('}').trim();
+    reindent_multiline(
+        snippet_body,
+        false,
+        indent_of_nth_line(snippet_body, 0).map(|indent| indent.saturating_sub(4)),
     )
 }
 
+#[expect(clippy::too_many_arguments)]
 fn sugg_with_curlies<'a>(
     cx: &LateContext<'a>,
     (ex, match_expr): (&Expr<'a>, &Expr<'a>),
     (bind_names, matched_vars): (Span, Span),
-    snippet_body: &str,
+    mut snippet_body: String,
     applicability: &mut Applicability,
     assignment: Option<Span>,
     needs_var_binding: bool,
+    is_var_binding_used_later: bool,
 ) -> String {
-    let mut indent = " ".repeat(indent_of(cx, ex.span).unwrap_or(0));
-
-    let (mut cbrace_start, mut cbrace_end) = (String::new(), String::new());
-    if expr_parent_requires_curlies(cx, match_expr) {
-        cbrace_end = format!("\n{indent}}}");
-        // Fix body indent due to the closure
-        indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
-        cbrace_start = format!("{{\n{indent}");
-    }
-
-    // If the parent is already an arm, and the body is another match statement,
-    // we need curly braces around suggestion
-    if let Node::Arm(arm) = &cx.tcx.parent_hir_node(match_expr.hir_id)
-        && let ExprKind::Match(..) = arm.body.kind
-    {
-        cbrace_end = format!("\n{indent}}}");
-        // Fix body indent due to the match
-        indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
-        cbrace_start = format!("{{\n{indent}");
-    }
-
     let assignment_str = assignment.map_or_else(String::new, |span| {
         let mut s = snippet(cx, span, "..").to_string();
         s.push_str(" = ");
@@ -221,5 +377,17 @@ fn sugg_with_curlies<'a>(
             .to_string()
     };
 
+    let mut indent = " ".repeat(indent_of(cx, ex.span).unwrap_or(0));
+    let (mut cbrace_start, mut cbrace_end) = (String::new(), String::new());
+    if !expr_in_nested_block(cx, match_expr)
+        && ((needs_var_binding && is_var_binding_used_later) || expr_must_have_curlies(cx, match_expr))
+    {
+        cbrace_end = format!("\n{indent}}}");
+        // Fix body indent due to the closure
+        indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
+        cbrace_start = format!("{{\n{indent}");
+        snippet_body = reindent_snippet_if_in_block(&snippet_body, !assignment_str.is_empty());
+    }
+
     format!("{cbrace_start}{scrutinee};\n{indent}{assignment_str}{snippet_body}{cbrace_end}")
 }
diff --git a/src/tools/clippy/clippy_lints/src/matches/single_match.rs b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
index 7e530e98ac4..bcf079b7007 100644
--- a/src/tools/clippy/clippy_lints/src/matches/single_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/single_match.rs
@@ -112,9 +112,7 @@ fn report_single_pattern(
         let (sugg, help) = if is_unit_expr(arm.body) {
             (String::new(), "`match` expression can be removed")
         } else {
-            let mut sugg = snippet_block_with_context(cx, arm.body.span, ctxt, "..", Some(expr.span), &mut app)
-                .0
-                .to_string();
+            let mut sugg = snippet_block_with_context(cx, arm.body.span, ctxt, "..", Some(expr.span), &mut app).0;
             if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id)
                 && let StmtKind::Expr(_) = stmt.kind
                 && match arm.body.kind {
@@ -127,7 +125,7 @@ fn report_single_pattern(
             (sugg, "try")
         };
         span_lint_and_then(cx, lint, expr.span, msg, |diag| {
-            diag.span_suggestion(expr.span, help, sugg.to_string(), app);
+            diag.span_suggestion(expr.span, help, sugg, app);
             note(diag);
         });
         return;
@@ -188,7 +186,7 @@ fn report_single_pattern(
     };
 
     span_lint_and_then(cx, lint, expr.span, msg, |diag| {
-        diag.span_suggestion(expr.span, "try", sugg.to_string(), app);
+        diag.span_suggestion(expr.span, "try", sugg, app);
         note(diag);
     });
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
index efa8cee58df..8a976d1b4dc 100644
--- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
@@ -40,14 +40,12 @@ pub fn check(cx: &LateContext<'_>, method_name: Symbol, expr: &hir::Expr<'_>, re
 }
 
 /// Returns true if the named method can be used to clone the receiver.
-/// Note that `to_string` is not flagged by `implicit_clone`. So other lints that call
-/// `is_clone_like` and that do flag `to_string` must handle it separately. See, e.g.,
-/// `is_to_owned_like` in `unnecessary_to_owned.rs`.
 pub fn is_clone_like(cx: &LateContext<'_>, method_name: Symbol, method_def_id: hir::def_id::DefId) -> bool {
     match method_name {
         sym::to_os_string => is_diag_item_method(cx, method_def_id, sym::OsStr),
         sym::to_owned => is_diag_trait_item(cx, method_def_id, sym::ToOwned),
         sym::to_path_buf => is_diag_item_method(cx, method_def_id, sym::Path),
+        sym::to_string => is_diag_trait_item(cx, method_def_id, sym::ToString),
         sym::to_vec => cx
             .tcx
             .impl_of_assoc(method_def_id)
diff --git a/src/tools/clippy/clippy_lints/src/methods/ip_constant.rs b/src/tools/clippy/clippy_lints/src/methods/ip_constant.rs
index 83803fba6a1..a2ac4e54334 100644
--- a/src/tools/clippy/clippy_lints/src/methods/ip_constant.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/ip_constant.rs
@@ -1,7 +1,7 @@
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, QPath, Ty, TyKind};
+use rustc_hir::{Expr, ExprKind, QPath, TyKind};
 use rustc_lint::LateContext;
 use rustc_span::sym;
 use smallvec::SmallVec;
@@ -9,13 +9,8 @@ use smallvec::SmallVec;
 use super::IP_CONSTANT;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>]) {
-    if let ExprKind::Path(QPath::TypeRelative(
-        Ty {
-            kind: TyKind::Path(QPath::Resolved(_, func_path)),
-            ..
-        },
-        p,
-    )) = func.kind
+    if let ExprKind::Path(QPath::TypeRelative(ty, p)) = func.kind
+        && let TyKind::Path(QPath::Resolved(_, func_path)) = ty.kind
         && p.ident.name == sym::new
         && let Some(func_def_id) = func_path.res.opt_def_id()
         && matches!(
@@ -40,13 +35,15 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args
             _ => return,
         };
 
+        let mut sugg = vec![(expr.span.with_lo(p.ident.span.lo()), constant_name.to_owned())];
+        let before_span = expr.span.shrink_to_lo().until(ty.span);
+        if !before_span.is_empty() {
+            // Remove everything before the type name
+            sugg.push((before_span, String::new()));
+        }
+
         span_lint_and_then(cx, IP_CONSTANT, expr.span, "hand-coded well-known IP address", |diag| {
-            diag.span_suggestion_verbose(
-                expr.span.with_lo(p.ident.span.lo()),
-                "use",
-                constant_name,
-                Applicability::MachineApplicable,
-            );
+            diag.multipart_suggestion_verbose("use", sugg, Applicability::MachineApplicable);
         });
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index c0366765234..83e565562af 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -2,14 +2,15 @@ use std::iter::once;
 
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
+use clippy_utils::ty::{ExprFnSig, expr_sig, ty_sig};
 use clippy_utils::{get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core, sym};
 
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
-use rustc_hir::def_id::DefId;
 use rustc_hir::hir_id::HirId;
 use rustc_hir::{Expr, ExprKind, Node};
 use rustc_lint::LateContext;
+use rustc_middle::ty::Binder;
 use rustc_span::Symbol;
 
 use super::{ITER_ON_EMPTY_COLLECTIONS, ITER_ON_SINGLE_ITEMS};
@@ -32,24 +33,34 @@ impl IterType {
 
 fn is_arg_ty_unified_in_fn<'tcx>(
     cx: &LateContext<'tcx>,
-    fn_id: DefId,
+    fn_sig: ExprFnSig<'tcx>,
     arg_id: HirId,
     args: impl IntoIterator<Item = &'tcx Expr<'tcx>>,
+    is_method: bool,
 ) -> bool {
-    let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity();
     let arg_id_in_args = args.into_iter().position(|e| e.hir_id == arg_id).unwrap();
-    let arg_ty_in_args = fn_sig.input(arg_id_in_args).skip_binder();
+    let Some(arg_ty_in_args) = fn_sig.input(arg_id_in_args).map(Binder::skip_binder) else {
+        return false;
+    };
 
-    cx.tcx.predicates_of(fn_id).predicates.iter().any(|(clause, _)| {
-        clause
-            .as_projection_clause()
-            .and_then(|p| p.map_bound(|p| p.term.as_type()).transpose())
-            .is_some_and(|ty| ty.skip_binder() == arg_ty_in_args)
-    }) || fn_sig
-        .inputs()
-        .iter()
-        .enumerate()
-        .any(|(i, ty)| i != arg_id_in_args && ty.skip_binder().walk().any(|arg| arg.as_type() == Some(arg_ty_in_args)))
+    fn_sig
+        .predicates_id()
+        .map(|def_id| cx.tcx.predicates_of(def_id))
+        .is_some_and(|generics| {
+            generics.predicates.iter().any(|(clause, _)| {
+                clause
+                    .as_projection_clause()
+                    .and_then(|p| p.map_bound(|p| p.term.as_type()).transpose())
+                    .is_some_and(|ty| ty.skip_binder() == arg_ty_in_args)
+            })
+        })
+        || (!is_method
+            && fn_sig.input(arg_id_in_args).is_some_and(|binder| {
+                binder
+                    .skip_binder()
+                    .walk()
+                    .any(|arg| arg.as_type() == Some(arg_ty_in_args))
+            }))
 }
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method_name: Symbol, recv: &'tcx Expr<'tcx>) {
@@ -70,25 +81,16 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method
     let is_unified = match get_expr_use_or_unification_node(cx.tcx, expr) {
         Some((Node::Expr(parent), child_id)) => match parent.kind {
             ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id == child_id => false,
-            ExprKind::Call(
-                Expr {
-                    kind: ExprKind::Path(path),
-                    hir_id,
-                    ..
-                },
-                args,
-            ) => cx
+            ExprKind::Call(recv, args) => {
+                expr_sig(cx, recv).is_some_and(|fn_sig| is_arg_ty_unified_in_fn(cx, fn_sig, child_id, args, false))
+            },
+            ExprKind::MethodCall(_name, recv, args, _span) => cx
                 .typeck_results()
-                .qpath_res(path, *hir_id)
-                .opt_def_id()
-                .filter(|fn_id| cx.tcx.def_kind(fn_id).is_fn_like())
-                .is_some_and(|fn_id| is_arg_ty_unified_in_fn(cx, fn_id, child_id, args)),
-            ExprKind::MethodCall(_name, recv, args, _span) => is_arg_ty_unified_in_fn(
-                cx,
-                cx.typeck_results().type_dependent_def_id(parent.hir_id).unwrap(),
-                child_id,
-                once(recv).chain(args.iter()),
-            ),
+                .type_dependent_def_id(parent.hir_id)
+                .and_then(|def_id| ty_sig(cx, cx.tcx.type_of(def_id).instantiate_identity()))
+                .is_some_and(|fn_sig| {
+                    is_arg_ty_unified_in_fn(cx, fn_sig, child_id, once(recv).chain(args.iter()), true)
+                }),
             ExprKind::If(_, _, _)
             | ExprKind::Match(_, _, _)
             | ExprKind::Closure(_)
@@ -96,7 +98,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, method
             | ExprKind::Break(_, _) => true,
             _ => false,
         },
-        Some((Node::Stmt(_) | Node::LetStmt(_), _)) => false,
+        Some((Node::LetStmt(let_stmt), _)) => let_stmt.ty.is_some(),
+        Some((Node::Stmt(_), _)) => false,
         _ => true,
     };
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index bcd54557331..49ca81dafc2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -5450,7 +5450,7 @@ impl Methods {
                         implicit_clone::check(cx, name, expr, recv);
                     }
                 },
-                (sym::to_os_string | sym::to_path_buf | sym::to_vec, []) => {
+                (sym::to_os_string | sym::to_path_buf | sym::to_string | sym::to_vec, []) => {
                     implicit_clone::check(cx, name, expr, recv);
                 },
                 (sym::type_id, []) => {
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
index 4a9007c607c..1f5e3de6e7a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
@@ -109,10 +109,16 @@ pub(super) fn check<'a>(
         );
 
         let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) {
-            match parent_expr.kind {
-                ExprKind::Binary(..) | ExprKind::Unary(..) | ExprKind::Cast(..) => binop.maybe_paren(),
-                ExprKind::MethodCall(_, receiver, _, _) if receiver.hir_id == expr.hir_id => binop.maybe_paren(),
-                _ => binop,
+            if parent_expr.span.eq_ctxt(expr.span) {
+                match parent_expr.kind {
+                    ExprKind::Binary(..) | ExprKind::Unary(..) | ExprKind::Cast(..) => binop.maybe_paren(),
+                    ExprKind::MethodCall(_, receiver, _, _) if receiver.hir_id == expr.hir_id => binop.maybe_paren(),
+                    _ => binop,
+                }
+            } else {
+                // if our parent expr is created by a macro, then it should be the one taking care of
+                // parenthesising us if necessary
+                binop
             }
         } else {
             binop
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
index 1de9f6ab497..fa9d5332ff4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs
@@ -199,44 +199,50 @@ pub(super) fn check<'tcx>(
     is_unstable: bool,
 ) {
     match detect_lint(cx, expr, recv, arg) {
-        Some(LintTrigger::SortByKey(trigger)) => span_lint_and_sugg(
-            cx,
-            UNNECESSARY_SORT_BY,
-            expr.span,
-            "consider using `sort_by_key`",
-            "try",
-            format!(
-                "{}.sort{}_by_key(|{}| {})",
-                trigger.vec_name,
-                if is_unstable { "_unstable" } else { "" },
-                trigger.closure_arg,
-                if let Some(std_or_core) = std_or_core(cx)
-                    && trigger.reverse
-                {
-                    format!("{}::cmp::Reverse({})", std_or_core, trigger.closure_body)
+        Some(LintTrigger::SortByKey(trigger)) => {
+            let method = if is_unstable {
+                "sort_unstable_by_key"
+            } else {
+                "sort_by_key"
+            };
+            span_lint_and_sugg(
+                cx,
+                UNNECESSARY_SORT_BY,
+                expr.span,
+                format!("consider using `{method}`"),
+                "try",
+                format!(
+                    "{}.{}(|{}| {})",
+                    trigger.vec_name,
+                    method,
+                    trigger.closure_arg,
+                    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
+                    },
+                ),
+                if trigger.reverse {
+                    Applicability::MaybeIncorrect
                 } else {
-                    trigger.closure_body.to_string()
+                    Applicability::MachineApplicable
                 },
-            ),
-            if trigger.reverse {
-                Applicability::MaybeIncorrect
-            } else {
-                Applicability::MachineApplicable
-            },
-        ),
-        Some(LintTrigger::Sort(trigger)) => span_lint_and_sugg(
-            cx,
-            UNNECESSARY_SORT_BY,
-            expr.span,
-            "consider using `sort`",
-            "try",
-            format!(
-                "{}.sort{}()",
-                trigger.vec_name,
-                if is_unstable { "_unstable" } else { "" },
-            ),
-            Applicability::MachineApplicable,
-        ),
+            );
+        },
+        Some(LintTrigger::Sort(trigger)) => {
+            let method = if is_unstable { "sort_unstable" } else { "sort" };
+            span_lint_and_sugg(
+                cx,
+                UNNECESSARY_SORT_BY,
+                expr.span,
+                format!("consider using `{method}`"),
+                "try",
+                format!("{}.{}()", trigger.vec_name, method),
+                Applicability::MachineApplicable,
+            );
+        },
         None => {},
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 54f45263275..c1f4904af7c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -621,8 +621,8 @@ fn is_cloned_or_copied(cx: &LateContext<'_>, method_name: Symbol, method_def_id:
 /// Returns true if the named method can be used to convert the receiver to its "owned"
 /// representation.
 fn is_to_owned_like<'a>(cx: &LateContext<'a>, call_expr: &Expr<'a>, method_name: Symbol, method_def_id: DefId) -> bool {
-    is_clone_like(cx, method_name, method_def_id)
-        || is_cow_into_owned(cx, method_name, method_def_id)
+    is_cow_into_owned(cx, method_name, method_def_id)
+        || (method_name != sym::to_string && is_clone_like(cx, method_name, method_def_id))
         || is_to_string_on_string_like(cx, call_expr, method_name, method_def_id)
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index 99f01c8001a..dbce29a8631 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -4,10 +4,14 @@ use clippy_utils::is_from_proc_macro;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{Visitor, walk_item, walk_trait_item};
-use rustc_hir::{GenericParamKind, HirId, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem, UsePath};
+use rustc_hir::{
+    GenericParamKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, ItemLocalId, Node, Pat, PatKind, TraitItem,
+    UsePath,
+};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
-use rustc_span::Span;
+use rustc_span::symbol::Ident;
+use rustc_span::{Span, Symbol};
 use std::borrow::Cow;
 
 declare_clippy_lint! {
@@ -32,6 +36,10 @@ declare_clippy_lint! {
     ///     let title = movie.title;
     /// }
     /// ```
+    ///
+    /// ### Limitations
+    /// Trait implementations which use the same function or parameter name as the trait declaration will
+    /// not be warned about, even if the name is below the configured limit.
     #[clippy::version = "1.72.0"]
     pub MIN_IDENT_CHARS,
     restriction,
@@ -76,6 +84,18 @@ impl LateLintPass<'_> for MinIdentChars {
             return;
         }
 
+        // If the function is declared but not defined in a trait, check_pat isn't called so we need to
+        // check this explicitly
+        if matches!(&item.kind, rustc_hir::TraitItemKind::Fn(_, _)) {
+            let param_names = cx.tcx.fn_arg_idents(item.owner_id.to_def_id());
+            for ident in param_names.iter().flatten() {
+                let str = ident.as_str();
+                if self.is_ident_too_short(cx, str, ident.span) {
+                    emit_min_ident_chars(self, cx, str, ident.span);
+                }
+            }
+        }
+
         walk_trait_item(&mut IdentVisitor { conf: self, cx }, item);
     }
 
@@ -84,6 +104,7 @@ impl LateLintPass<'_> for MinIdentChars {
         if let PatKind::Binding(_, _, ident, ..) = pat.kind
             && let str = ident.as_str()
             && self.is_ident_too_short(cx, str, ident.span)
+            && is_not_in_trait_impl(cx, pat, ident)
         {
             emit_min_ident_chars(self, cx, str, ident.span);
         }
@@ -118,6 +139,11 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
 
         let str = ident.as_str();
         if conf.is_ident_too_short(cx, str, ident.span) {
+            // Check whether the node is part of a `impl` for a trait.
+            if matches!(cx.tcx.parent_hir_node(hir_id), Node::TraitRef(_)) {
+                return;
+            }
+
             // Check whether the node is part of a `use` statement. We don't want to emit a warning if the user
             // has no control over the type.
             let usenode = opt_as_use_node(node).or_else(|| {
@@ -201,3 +227,52 @@ fn opt_as_use_node(node: Node<'_>) -> Option<&'_ UsePath<'_>> {
         None
     }
 }
+
+/// Check if a pattern is a function param in an impl block for a trait and that the param name is
+/// the same than in the trait definition.
+fn is_not_in_trait_impl(cx: &LateContext<'_>, pat: &Pat<'_>, ident: Ident) -> bool {
+    let parent_node = cx.tcx.parent_hir_node(pat.hir_id);
+    if !matches!(parent_node, Node::Param(_)) {
+        return true;
+    }
+
+    for (_, parent_node) in cx.tcx.hir_parent_iter(pat.hir_id) {
+        if let Node::ImplItem(impl_item) = parent_node
+            && matches!(impl_item.kind, ImplItemKind::Fn(_, _))
+        {
+            let impl_parent_node = cx.tcx.parent_hir_node(impl_item.hir_id());
+            if let Node::Item(parent_item) = impl_parent_node
+                && let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = &parent_item.kind
+                && let Some(name) = get_param_name(impl_item, cx, ident)
+            {
+                return name != ident.name;
+            }
+
+            return true;
+        }
+    }
+
+    true
+}
+
+fn get_param_name(impl_item: &ImplItem<'_>, cx: &LateContext<'_>, ident: Ident) -> Option<Symbol> {
+    if let Some(trait_item_def_id) = impl_item.trait_item_def_id {
+        let trait_param_names = cx.tcx.fn_arg_idents(trait_item_def_id);
+
+        let ImplItemKind::Fn(_, body_id) = impl_item.kind else {
+            return None;
+        };
+
+        if let Some(param_index) = cx
+            .tcx
+            .hir_body_param_idents(body_id)
+            .position(|param_ident| param_ident.is_some_and(|param_ident| param_ident.span == ident.span))
+            && let Some(trait_param_name) = trait_param_names.get(param_index)
+            && let Some(trait_param_ident) = trait_param_name
+        {
+            return Some(trait_param_ident.name);
+        }
+    }
+
+    None
+}
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index c637fb247ff..d02952eb487 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -1,8 +1,7 @@
 use clippy_utils::diagnostics::span_lint;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{self as hir, Attribute};
+use rustc_hir::{self as hir, Attribute, find_attr};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::AssocItemContainer;
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index b3aa1a7286a..fa5afcc0087 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
     SpanlessEq, get_parent_expr, higher, is_block_like, is_else_clause, is_expn_of, is_parent_stmt,
-    is_receiver_of_method_call, peel_blocks, peel_blocks_with_stmt, span_extract_comment, sym,
+    is_receiver_of_method_call, peel_blocks, peel_blocks_with_stmt, span_contains_comment, sym,
 };
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -128,14 +128,13 @@ fn condition_needs_parentheses(e: &Expr<'_>) -> bool {
 impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         use self::Expression::{Bool, RetBool};
-        if e.span.from_expansion() || !span_extract_comment(cx.tcx.sess.source_map(), e.span).is_empty() {
-            return;
-        }
-        if let Some(higher::If {
-            cond,
-            then,
-            r#else: Some(r#else),
-        }) = higher::If::hir(e)
+        if !e.span.from_expansion()
+            && let Some(higher::If {
+                cond,
+                then,
+                r#else: Some(else_expr),
+            }) = higher::If::hir(e)
+            && !span_contains_comment(cx.tcx.sess.source_map(), e.span)
         {
             let reduce = |ret, not| {
                 let mut applicability = Applicability::MachineApplicable;
@@ -167,7 +166,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
                     applicability,
                 );
             };
-            if let Some((a, b)) = fetch_bool_block(then).and_then(|a| Some((a, fetch_bool_block(r#else)?))) {
+            if let Some((a, b)) = fetch_bool_block(then).and_then(|a| Some((a, fetch_bool_block(else_expr)?))) {
                 match (a, b) {
                     (RetBool(true), RetBool(true)) | (Bool(true), Bool(true)) => {
                         span_lint(
@@ -193,7 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
                 }
             }
             if let Some((lhs_a, a)) = fetch_assign(then)
-                && let Some((lhs_b, b)) = fetch_assign(r#else)
+                && let Some((lhs_b, b)) = fetch_assign(else_expr)
                 && SpanlessEq::new(cx).eq_expr(lhs_a, lhs_b)
             {
                 let mut applicability = Applicability::MachineApplicable;
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 7b057998063..32ded96c123 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -311,9 +311,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
 
 /// Functions marked with these attributes must have the exact signature.
 pub(crate) fn requires_exact_signature(attrs: &[Attribute]) -> bool {
-    attrs.iter().any(|attr| {
-        attr.is_proc_macro_attr()
-    })
+    attrs.iter().any(Attribute::is_proc_macro_attr)
 }
 
 #[derive(Default)]
diff --git a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
index 791bbbe30a8..daa2c287794 100644
--- a/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
+++ b/src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use rustc_abi::ExternAbi;
-use rustc_hir::attrs::AttributeKind;
 use rustc_errors::Applicability;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::{Attribute, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
diff --git a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
index abee3c44c5a..7ecde40aee0 100644
--- a/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
+++ b/src/tools/clippy/clippy_lints/src/non_std_lazy_statics.rs
@@ -49,7 +49,7 @@ declare_clippy_lint! {
 /// Some functions could be replaced as well if we have replaced `Lazy` to `LazyLock`,
 /// therefore after suggesting replace the type, we need to make sure the function calls can be
 /// replaced, otherwise the suggestions cannot be applied thus the applicability should be
-/// `Unspecified` or `MaybeIncorret`.
+/// [`Applicability::Unspecified`] or [`Applicability::MaybeIncorrect`].
 static FUNCTION_REPLACEMENTS: &[(&str, Option<&str>)] = &[
     ("once_cell::sync::Lazy::force", Some("std::sync::LazyLock::force")),
     ("once_cell::sync::Lazy::get", None), // `std::sync::LazyLock::get` is experimental
diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
index 9487cec87ef..3483f3081a5 100644
--- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
@@ -127,7 +127,8 @@ fn try_get_option_occurrence<'tcx>(
     if_else: &'tcx Expr<'_>,
 ) -> Option<OptionOccurrence> {
     let cond_expr = match expr.kind {
-        ExprKind::Unary(UnOp::Deref, inner_expr) | ExprKind::AddrOf(_, _, inner_expr) => inner_expr,
+        ExprKind::AddrOf(_, _, inner_expr) => inner_expr,
+        ExprKind::Unary(UnOp::Deref, inner_expr) if !cx.typeck_results().expr_ty(inner_expr).is_raw_ptr() => inner_expr,
         _ => expr,
     };
     let (inner_pat, is_result) = try_get_inner_pat_and_is_result(cx, pat)?;
@@ -223,8 +224,8 @@ fn try_get_option_occurrence<'tcx>(
 
         let mut app = Applicability::Unspecified;
 
-        let (none_body, is_argless_call) = match none_body.kind {
-            ExprKind::Call(call_expr, []) if !none_body.span.from_expansion() => (call_expr, true),
+        let (none_body, can_omit_arg) = match none_body.kind {
+            ExprKind::Call(call_expr, []) if !none_body.span.from_expansion() && !is_result => (call_expr, true),
             _ => (none_body, false),
         };
 
@@ -241,7 +242,7 @@ fn try_get_option_occurrence<'tcx>(
             ),
             none_expr: format!(
                 "{}{}",
-                if method_sugg == "map_or" || is_argless_call {
+                if method_sugg == "map_or" || can_omit_arg {
                     ""
                 } else if is_result {
                     "|_| "
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 303c5dfed89..d7b4a03aa53 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -5,13 +5,12 @@ use clippy_utils::ty::{for_each_top_level_late_bound_region, is_copy};
 use clippy_utils::{is_self, is_self_ty};
 use core::ops::ControlFlow;
 use rustc_abi::ExternAbi;
-use rustc_hir::attrs::{AttributeKind, InlineAttr};
-use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_hir::attrs::{AttributeKind, InlineAttr};
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{BindingMode, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind};
+use rustc_hir::{BindingMode, Body, FnDecl, Impl, ItemKind, MutTy, Mutability, Node, PatKind, find_attr};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
 use rustc_middle::ty::layout::LayoutOf;
diff --git a/src/tools/clippy/clippy_lints/src/redundant_else.rs b/src/tools/clippy/clippy_lints/src/redundant_else.rs
index a3be16ed858..79353dc9247 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_else.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_else.rs
@@ -97,7 +97,7 @@ impl EarlyLintPass for RedundantElse {
             els.span.with_lo(then.span.hi()),
             "redundant else block",
             "remove the `else` block and move the contents out",
-            make_sugg(cx, els.span, "..", Some(expr.span)).to_string(),
+            make_sugg(cx, els.span, "..", Some(expr.span)),
             app,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
index 2cdb8ef3a65..b057396034c 100644
--- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs
@@ -1,11 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::is_must_use_ty;
 use clippy_utils::{nth_arg, return_ty};
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind};
+use rustc_hir::{Body, FnDecl, OwnerId, TraitItem, TraitItemKind, find_attr};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
diff --git a/src/tools/clippy/clippy_lints/src/semicolon_block.rs b/src/tools/clippy/clippy_lints/src/semicolon_block.rs
index f6c128d4c52..db91c57b181 100644
--- a/src/tools/clippy/clippy_lints/src/semicolon_block.rs
+++ b/src/tools/clippy/clippy_lints/src/semicolon_block.rs
@@ -102,7 +102,7 @@ impl SemicolonBlock {
     }
 
     fn semicolon_outside_block(&self, cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>) {
-        let insert_span = block.span.with_lo(block.span.hi());
+        let insert_span = block.span.shrink_to_hi();
 
         // For macro call semicolon statements (`mac!();`), the statement's span does not actually
         // include the semicolon itself, so use `mac_call_stmt_semi_span`, which finds the semicolon
@@ -144,28 +144,20 @@ impl LateLintPass<'_> for SemicolonBlock {
                 kind: ExprKind::Block(block, _),
                 ..
             }) if !block.span.from_expansion() && stmt.span.contains(block.span) => {
-                let Block {
-                    expr: None,
-                    stmts: [.., stmt],
-                    ..
-                } = block
-                else {
-                    return;
-                };
-                let &Stmt {
-                    kind: StmtKind::Semi(expr),
-                    ..
-                } = stmt
-                else {
-                    return;
-                };
-                self.semicolon_outside_block(cx, block, expr);
+                if block.expr.is_none()
+                    && let [.., stmt] = block.stmts
+                    && let StmtKind::Semi(expr) = stmt.kind
+                {
+                    self.semicolon_outside_block(cx, block, expr);
+                }
             },
             StmtKind::Semi(Expr {
-                kind: ExprKind::Block(block @ Block { expr: Some(tail), .. }, _),
+                kind: ExprKind::Block(block, _),
                 ..
             }) if !block.span.from_expansion() => {
-                self.semicolon_inside_block(cx, block, tail, stmt.span);
+                if let Some(tail) = block.expr {
+                    self.semicolon_inside_block(cx, block, tail, stmt.span);
+                }
             },
             _ => (),
         }
@@ -173,9 +165,5 @@ impl LateLintPass<'_> for SemicolonBlock {
 }
 
 fn get_line(cx: &LateContext<'_>, span: Span) -> Option<usize> {
-    if let Ok(line) = cx.sess().source_map().lookup_line(span.lo()) {
-        return Some(line.line);
-    }
-
-    None
+    cx.sess().source_map().lookup_line(span.lo()).ok().map(|line| line.line)
 }
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 50c44a8e75c..e9534bc63a6 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -2,11 +2,10 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::msrvs::Msrv;
-use rustc_hir::{StabilityLevel, StableSince};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::{Block, Body, HirId, Path, PathSegment};
+use rustc_hir::{Block, Body, HirId, Path, PathSegment, StabilityLevel, StableSince};
 use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::kw;
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 1cda6f596f4..490e6c974ae 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -13,8 +13,6 @@ use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
 
-use std::ops::ControlFlow;
-
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for string appends of the form `x = x + y` (without
@@ -413,125 +411,6 @@ impl<'tcx> LateLintPass<'tcx> for StrToString {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// This lint checks for `.to_string()` method calls on values of type `String`.
-    ///
-    /// ### Why restrict this?
-    /// The `to_string` method is also used on other types to convert them to a string.
-    /// When called on a `String` it only clones the `String`, which can be more specifically
-    /// expressed with `.clone()`.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// let msg = String::from("Hello World");
-    /// let _ = msg.to_string();
-    /// ```
-    /// Use instead:
-    /// ```no_run
-    /// let msg = String::from("Hello World");
-    /// let _ = msg.clone();
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub STRING_TO_STRING,
-    restriction,
-    "using `to_string()` on a `String`, which should be `clone()`"
-}
-
-declare_lint_pass!(StringToString => [STRING_TO_STRING]);
-
-fn is_parent_map_like(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<rustc_span::Span> {
-    if let Some(parent_expr) = get_parent_expr(cx, expr)
-        && let ExprKind::MethodCall(name, _, _, parent_span) = parent_expr.kind
-        && name.ident.name == sym::map
-        && let Some(caller_def_id) = cx.typeck_results().type_dependent_def_id(parent_expr.hir_id)
-        && (clippy_utils::is_diag_item_method(cx, caller_def_id, sym::Result)
-            || clippy_utils::is_diag_item_method(cx, caller_def_id, sym::Option)
-            || clippy_utils::is_diag_trait_item(cx, caller_def_id, sym::Iterator))
-    {
-        Some(parent_span)
-    } else {
-        None
-    }
-}
-
-fn is_called_from_map_like(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<rustc_span::Span> {
-    // Look for a closure as parent of `expr`, discarding simple blocks
-    let parent_closure = cx
-        .tcx
-        .hir_parent_iter(expr.hir_id)
-        .try_fold(expr.hir_id, |child_hir_id, (_, node)| match node {
-            // Check that the child expression is the only expression in the block
-            Node::Block(block) if block.stmts.is_empty() && block.expr.map(|e| e.hir_id) == Some(child_hir_id) => {
-                ControlFlow::Continue(block.hir_id)
-            },
-            Node::Expr(expr) if matches!(expr.kind, ExprKind::Block(..)) => ControlFlow::Continue(expr.hir_id),
-            Node::Expr(expr) if matches!(expr.kind, ExprKind::Closure(_)) => ControlFlow::Break(Some(expr)),
-            _ => ControlFlow::Break(None),
-        })
-        .break_value()?;
-    is_parent_map_like(cx, parent_closure?)
-}
-
-fn suggest_cloned_string_to_string(cx: &LateContext<'_>, span: rustc_span::Span) {
-    span_lint_and_sugg(
-        cx,
-        STRING_TO_STRING,
-        span,
-        "`to_string()` called on a `String`",
-        "try",
-        "cloned()".to_string(),
-        Applicability::MachineApplicable,
-    );
-}
-
-impl<'tcx> LateLintPass<'tcx> for StringToString {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
-        if expr.span.from_expansion() {
-            return;
-        }
-
-        match &expr.kind {
-            ExprKind::MethodCall(path, self_arg, [], _) => {
-                if path.ident.name == sym::to_string
-                    && let ty = cx.typeck_results().expr_ty(self_arg)
-                    && is_type_lang_item(cx, ty.peel_refs(), LangItem::String)
-                {
-                    if let Some(parent_span) = is_called_from_map_like(cx, expr) {
-                        suggest_cloned_string_to_string(cx, parent_span);
-                    } else {
-                        #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
-                        span_lint_and_then(
-                            cx,
-                            STRING_TO_STRING,
-                            expr.span,
-                            "`to_string()` called on a `String`",
-                            |diag| {
-                                diag.help("consider using `.clone()`");
-                            },
-                        );
-                    }
-                }
-            },
-            ExprKind::Path(QPath::TypeRelative(ty, segment)) => {
-                if segment.ident.name == sym::to_string
-                    && let rustc_hir::TyKind::Path(QPath::Resolved(_, path)) = ty.peel_refs().kind
-                    && let rustc_hir::def::Res::Def(_, def_id) = path.res
-                    && cx
-                        .tcx
-                        .lang_items()
-                        .get(LangItem::String)
-                        .is_some_and(|lang_id| lang_id == def_id)
-                    && let Some(parent_span) = is_parent_map_like(cx, expr)
-                {
-                    suggest_cloned_string_to_string(cx, parent_span);
-                }
-            },
-            _ => {},
-        }
-    }
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Warns about calling `str::trim` (or variants) before `str::split_whitespace`.
     ///
     /// ### Why is this bad?
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index 87f184e13ce..d5b6c175854 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -1,17 +1,20 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_with_context;
+use clippy_utils::macros::{FormatArgsStorage, find_format_arg_expr, is_format_macro, root_macro_call_first_node};
+use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_context};
 use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source};
 use core::ops::ControlFlow;
+use rustc_ast::{FormatArgs, FormatArgumentKind};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
-use rustc_hir::intravisit::{Visitor, walk_body};
+use rustc_hir::intravisit::{Visitor, walk_body, walk_expr};
 use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, LetStmt, MatchSource, Node, PatKind, QPath, TyKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty;
+use rustc_span::Span;
 
 use super::LET_UNIT_VALUE;
 
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, format_args: &FormatArgsStorage, local: &'tcx LetStmt<'_>) {
     // skip `let () = { ... }`
     if let PatKind::Tuple(fields, ..) = local.pat.kind
         && fields.is_empty()
@@ -73,11 +76,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
                     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;
-                        suggestions.push((local.span, format!("{snip};")));
-                    }
+                    let mut app = Applicability::MachineApplicable;
+                    let snip = snippet_with_context(cx, init.span, local.span.ctxt(), "()", &mut app).0;
 
                     // If this is a binding pattern, we need to add suggestions to remove any usages
                     // of the variable
@@ -85,53 +85,102 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
                         && let Some(body_id) = cx.enclosing_body.as_ref()
                     {
                         let body = cx.tcx.hir_body(*body_id);
-
-                        // Collect variable usages
-                        let mut visitor = UnitVariableCollector::new(binding_hir_id);
+                        let mut visitor = UnitVariableCollector::new(cx, format_args, binding_hir_id);
                         walk_body(&mut visitor, body);
 
-                        // Add suggestions for replacing variable usages
-                        suggestions.extend(visitor.spans.into_iter().map(|span| (span, "()".to_string())));
-                    }
+                        let mut has_in_format_capture = false;
+                        suggestions.extend(visitor.spans.iter().filter_map(|span| match span {
+                            MaybeInFormatCapture::Yes => {
+                                has_in_format_capture = true;
+                                None
+                            },
+                            MaybeInFormatCapture::No(span) => Some((*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);
+                        if has_in_format_capture {
+                            suggestions.push((
+                                init.span,
+                                format!("();\n{}", reindent_multiline(&snip, false, indent_of(cx, local.span))),
+                            ));
+                            diag.multipart_suggestion(
+                                "replace variable usages with `()`",
+                                suggestions,
+                                Applicability::MachineApplicable,
+                            );
+                            return;
+                        }
                     }
+
+                    suggestions.push((local.span, format!("{snip};")));
+                    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);
                 },
             );
         }
     }
 }
 
-struct UnitVariableCollector {
+struct UnitVariableCollector<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    format_args: &'a FormatArgsStorage,
     id: HirId,
-    spans: Vec<rustc_span::Span>,
+    spans: Vec<MaybeInFormatCapture>,
+    macro_call: Option<&'a FormatArgs>,
 }
 
-impl UnitVariableCollector {
-    fn new(id: HirId) -> Self {
-        Self { id, spans: vec![] }
+enum MaybeInFormatCapture {
+    Yes,
+    No(Span),
+}
+
+impl<'a, 'tcx> UnitVariableCollector<'a, 'tcx> {
+    fn new(cx: &'a LateContext<'tcx>, format_args: &'a FormatArgsStorage, id: HirId) -> Self {
+        Self {
+            cx,
+            format_args,
+            id,
+            spans: Vec::new(),
+            macro_call: None,
+        }
     }
 }
 
 /**
  * Collect all instances where a variable is used based on its `HirId`.
  */
-impl<'tcx> Visitor<'tcx> for UnitVariableCollector {
+impl<'tcx> Visitor<'tcx> for UnitVariableCollector<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {
+        if let Some(macro_call) = root_macro_call_first_node(self.cx, ex)
+            && is_format_macro(self.cx, macro_call.def_id)
+            && let Some(format_args) = self.format_args.get(self.cx, ex, macro_call.expn)
+        {
+            let parent_macro_call = self.macro_call;
+            self.macro_call = Some(format_args);
+            walk_expr(self, ex);
+            self.macro_call = parent_macro_call;
+            return;
+        }
+
         if let ExprKind::Path(QPath::Resolved(None, path)) = ex.kind
             && let Res::Local(id) = path.res
             && id == self.id
         {
-            self.spans.push(path.span);
+            if let Some(macro_call) = self.macro_call
+                && macro_call.arguments.all_args().iter().any(|arg| {
+                    matches!(arg.kind, FormatArgumentKind::Captured(_)) && find_format_arg_expr(ex, arg).is_some()
+                })
+            {
+                self.spans.push(MaybeInFormatCapture::Yes);
+            } else {
+                self.spans.push(MaybeInFormatCapture::No(path.span));
+            }
         }
-        rustc_hir::intravisit::walk_expr(self, ex);
+
+        walk_expr(self, ex);
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/mod.rs b/src/tools/clippy/clippy_lints/src/unit_types/mod.rs
index e016bd3434b..4ffcc247acf 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/mod.rs
@@ -3,9 +3,10 @@ mod unit_arg;
 mod unit_cmp;
 mod utils;
 
+use clippy_utils::macros::FormatArgsStorage;
 use rustc_hir::{Expr, LetStmt};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::declare_lint_pass;
+use rustc_session::impl_lint_pass;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -96,11 +97,21 @@ declare_clippy_lint! {
     "passing unit to a function"
 }
 
-declare_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
+pub struct UnitTypes {
+    format_args: FormatArgsStorage,
+}
+
+impl_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
+
+impl UnitTypes {
+    pub fn new(format_args: FormatArgsStorage) -> Self {
+        Self { format_args }
+    }
+}
 
 impl<'tcx> LateLintPass<'tcx> for UnitTypes {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
-        let_unit_value::check(cx, local);
+        let_unit_value::check(cx, &self.format_args, local);
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 29931738412..2113cb92137 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -348,7 +348,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                             IntTy::I128 => "I128",
                         };
                         format!("LitIntType::Signed(IntTy::{t})")
-                    }
+                    },
                     LitIntType::Unsigned(uint_ty) => {
                         let t = match uint_ty {
                             UintTy::Usize => "Usize",
@@ -359,7 +359,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                             UintTy::U128 => "U128",
                         };
                         format!("LitIntType::Unsigned(UintTy::{t})")
-                    }
+                    },
                     LitIntType::Unsuffixed => String::from("LitIntType::Unsuffixed"),
                 };
                 kind!("Int({i}, {int_ty})");
@@ -374,7 +374,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                             FloatTy::F128 => "F128",
                         };
                         format!("LitFloatType::Suffixed(FloatTy::{t})")
-                    }
+                    },
                     LitFloatType::Unsuffixed => String::from("LitFloatType::Unsuffixed"),
                 };
                 kind!("Float(_, {float_ty})");
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index 22fd15d153a..a2523b5fb07 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -118,7 +118,7 @@ impl_lint_pass!(WildcardImports => [ENUM_GLOB_USE, WILDCARD_IMPORTS]);
 
 impl LateLintPass<'_> for WildcardImports {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
-        if cx.sess().is_test_crate() {
+        if cx.sess().is_test_crate() || item.span.in_external_macro(cx.sess().source_map()) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
index e0ae0c11cc2..5e6a40ac2eb 100644
--- a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
@@ -2,12 +2,11 @@ use clippy_utils::diagnostics::span_lint;
 use clippy_utils::paths;
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_ast::{AttrStyle, DelimArgs};
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{
-    AttrArgs, AttrItem, AttrPath, Attribute, HirId, Impl, Item, ItemKind, Path, QPath, TraitRef, Ty, TyKind,
+    AttrArgs, AttrItem, AttrPath, Attribute, HirId, Impl, Item, ItemKind, Path, QPath, TraitRef, Ty, TyKind, find_attr,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_lint_defs::declare_tool_lint;
diff --git a/src/tools/clippy/clippy_test_deps/Cargo.lock b/src/tools/clippy/clippy_test_deps/Cargo.lock
index 5be404f24e6..2f987c0137c 100644
--- a/src/tools/clippy/clippy_test_deps/Cargo.lock
+++ b/src/tools/clippy/clippy_test_deps/Cargo.lock
@@ -70,7 +70,6 @@ name = "clippy_test_deps"
 version = "0.1.0"
 dependencies = [
  "futures",
- "if_chain",
  "itertools",
  "libc",
  "parking_lot",
@@ -183,12 +182,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
 
 [[package]]
-name = "if_chain"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
-
-[[package]]
 name = "io-uring"
 version = "0.7.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/clippy/clippy_test_deps/Cargo.toml b/src/tools/clippy/clippy_test_deps/Cargo.toml
index fcedc5d4843..e449b48bc46 100644
--- a/src/tools/clippy/clippy_test_deps/Cargo.toml
+++ b/src/tools/clippy/clippy_test_deps/Cargo.toml
@@ -9,7 +9,6 @@ edition = "2021"
 libc = "0.2"
 regex = "1.5.5"
 serde = { version = "1.0.145", features = ["derive"] }
-if_chain = "1.0"
 quote = "1.0.25"
 syn = { version = "2.0", features = ["full"] }
 futures = "0.3"
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 73291aa8cdf..bdf7431f29f 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_utils"
-version = "0.1.90"
+version = "0.1.91"
 edition = "2024"
 description = "Helpful tools for writing lints, provided as they are used in Clippy"
 repository = "https://github.com/rust-lang/rust-clippy"
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
index 19e71f6af1d..6d8dd92d55d 100644
--- a/src/tools/clippy/clippy_utils/README.md
+++ b/src/tools/clippy/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2025-07-25
+nightly-2025-08-07
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 4ccd9c5300b..2d42e76dcbc 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -2,9 +2,9 @@ use crate::source::SpanRangeExt;
 use crate::{sym, tokenize_with_text};
 use rustc_ast::attr;
 use rustc_ast::attr::AttributeExt;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_errors::Applicability;
+use rustc_hir::attrs::AttributeKind;
+use rustc_hir::find_attr;
 use rustc_lexer::TokenKind;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{AdtDef, TyCtxt};
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 5b9b0ef3001..fc716d86fc6 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -83,19 +83,18 @@ pub use self::hir_utils::{
 use core::mem;
 use core::ops::ControlFlow;
 use std::collections::hash_map::Entry;
-use std::iter::{once, repeat_n};
+use std::iter::{once, repeat_n, zip};
 use std::sync::{Mutex, MutexGuard, OnceLock};
 
 use itertools::Itertools;
 use rustc_abi::Integer;
 use rustc_ast::ast::{self, LitKind, RangeLimits};
 use rustc_ast::join_path_syms;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::unhash::UnindexMap;
 use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::definitions::{DefPath, DefPathData};
@@ -106,7 +105,7 @@ use rustc_hir::{
     CoroutineKind, Destination, Expr, ExprField, ExprKind, FnDecl, FnRetTy, GenericArg, GenericArgs, HirId, Impl,
     ImplItem, ImplItemKind, Item, ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, OwnerNode,
     Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem,
-    TraitItemKind, TraitRef, TyKind, UnOp, def,
+    TraitItemKind, TraitRef, TyKind, UnOp, def, find_attr,
 };
 use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
@@ -582,7 +581,7 @@ pub fn can_mut_borrow_both(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>) -
         return false;
     }
 
-    for (x1, x2) in s1.iter().zip(s2.iter()) {
+    for (x1, x2) in zip(&s1, &s2) {
         if expr_custom_deref_adjustment(cx, x1).is_some() || expr_custom_deref_adjustment(cx, x2).is_some() {
             return false;
         }
@@ -1898,42 +1897,11 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 /// * `|x| { return x; }`
 /// * `|(x, y)| (x, y)`
 /// * `|[x, y]| [x, y]`
+/// * `|Foo(bar, baz)| Foo(bar, baz)`
+/// * `|Foo { bar, baz }| Foo { bar, baz }`
 ///
 /// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead.
 fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
-    fn check_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
-        if cx
-            .typeck_results()
-            .pat_binding_modes()
-            .get(pat.hir_id)
-            .is_some_and(|mode| matches!(mode.0, ByRef::Yes(_)))
-        {
-            // If the parameter is `(x, y)` of type `&(T, T)`, or `[x, y]` of type `&[T; 2]`, then
-            // due to match ergonomics, the inner patterns become references. Don't consider this
-            // the identity function as that changes types.
-            return false;
-        }
-
-        match (pat.kind, expr.kind) {
-            (PatKind::Binding(_, id, _, _), _) => {
-                path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty()
-            },
-            (PatKind::Tuple(pats, dotdot), ExprKind::Tup(tup))
-                if dotdot.as_opt_usize().is_none() && pats.len() == tup.len() =>
-            {
-                pats.iter().zip(tup).all(|(pat, expr)| check_pat(cx, pat, expr))
-            },
-            (PatKind::Slice(before, slice, after), ExprKind::Array(arr))
-                if slice.is_none() && before.len() + after.len() == arr.len() =>
-            {
-                (before.iter().chain(after))
-                    .zip(arr)
-                    .all(|(pat, expr)| check_pat(cx, pat, expr))
-            },
-            _ => false,
-        }
-    }
-
     let [param] = func.params else {
         return false;
     };
@@ -1966,11 +1934,81 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
                     return false;
                 }
             },
-            _ => return check_pat(cx, param.pat, expr),
+            _ => return is_expr_identity_of_pat(cx, param.pat, expr, true),
         }
     }
 }
 
+/// Checks if the given expression is an identity representation of the given pattern:
+/// * `x` is the identity representation of `x`
+/// * `(x, y)` is the identity representation of `(x, y)`
+/// * `[x, y]` is the identity representation of `[x, y]`
+/// * `Foo(bar, baz)` is the identity representation of `Foo(bar, baz)`
+/// * `Foo { bar, baz }` is the identity representation of `Foo { bar, baz }`
+///
+/// Note that `by_hir` is used to determine bindings are checked by their `HirId` or by their name.
+/// This can be useful when checking patterns in `let` bindings or `match` arms.
+pub fn is_expr_identity_of_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>, by_hir: bool) -> bool {
+    if cx
+        .typeck_results()
+        .pat_binding_modes()
+        .get(pat.hir_id)
+        .is_some_and(|mode| matches!(mode.0, ByRef::Yes(_)))
+    {
+        // If the parameter is `(x, y)` of type `&(T, T)`, or `[x, y]` of type `&[T; 2]`, then
+        // due to match ergonomics, the inner patterns become references. Don't consider this
+        // the identity function as that changes types.
+        return false;
+    }
+
+    // NOTE: we're inside a (function) body, so this won't ICE
+    let qpath_res = |qpath, hir| cx.typeck_results().qpath_res(qpath, hir);
+
+    match (pat.kind, expr.kind) {
+        (PatKind::Binding(_, id, _, _), _) if by_hir => {
+            path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty()
+        },
+        (PatKind::Binding(_, _, ident, _), ExprKind::Path(QPath::Resolved(_, path))) => {
+            matches!(path.segments, [ segment] if segment.ident.name == ident.name)
+        },
+        (PatKind::Tuple(pats, dotdot), ExprKind::Tup(tup))
+            if dotdot.as_opt_usize().is_none() && pats.len() == tup.len() =>
+        {
+            zip(pats, tup).all(|(pat, expr)| is_expr_identity_of_pat(cx, pat, expr, by_hir))
+        },
+        (PatKind::Slice(before, None, after), ExprKind::Array(arr)) if before.len() + after.len() == arr.len() => {
+            zip(before.iter().chain(after), arr).all(|(pat, expr)| is_expr_identity_of_pat(cx, pat, expr, by_hir))
+        },
+        (PatKind::TupleStruct(pat_ident, field_pats, dotdot), ExprKind::Call(ident, fields))
+            if dotdot.as_opt_usize().is_none() && field_pats.len() == fields.len() =>
+        {
+            // check ident
+            if let ExprKind::Path(ident) = &ident.kind
+                && qpath_res(&pat_ident, pat.hir_id) == qpath_res(ident, expr.hir_id)
+                // check fields
+                && zip(field_pats, fields).all(|(pat, expr)| is_expr_identity_of_pat(cx, pat, expr,by_hir))
+            {
+                true
+            } else {
+                false
+            }
+        },
+        (PatKind::Struct(pat_ident, field_pats, false), ExprKind::Struct(ident, fields, hir::StructTailExpr::None))
+            if field_pats.len() == fields.len() =>
+        {
+            // check ident
+            qpath_res(&pat_ident, pat.hir_id) == qpath_res(ident, expr.hir_id)
+                // check fields
+                && field_pats.iter().all(|field_pat| {
+                    fields.iter().any(|field| {
+                        field_pat.ident == field.ident && is_expr_identity_of_pat(cx, field_pat.pat, field.expr, by_hir)
+                    })
+                })
+        },
+        _ => false,
+    }
+}
+
 /// This is the same as [`is_expr_identity_function`], but does not consider closures
 /// with type annotations for its bindings (or similar) as identity functions:
 /// * `|x: u8| x`
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 480e0687756..89a83e2c48f 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -1,8 +1,8 @@
 use crate::sym;
 use rustc_ast::Attribute;
 use rustc_ast::attr::AttributeExt;
-use rustc_hir::RustcVersion;
 use rustc_attr_parsing::parse_version;
+use rustc_hir::RustcVersion;
 use rustc_lint::LateContext;
 use rustc_session::Session;
 use rustc_span::Symbol;
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 79116eba971..68f0b5ea255 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -5,10 +5,10 @@
 
 use crate::msrvs::{self, Msrv};
 use hir::LangItem;
-use rustc_hir::{RustcVersion, StableSince};
 use rustc_const_eval::check_consts::ConstCx;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::{RustcVersion, StableSince};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::Obligation;
 use rustc_lint::LateContext;
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index 7d21336be1c..e675291b6f3 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -342,11 +342,8 @@ impl SourceFileRange {
     /// Attempts to get the text from the source file. This can fail if the source text isn't
     /// loaded.
     pub fn as_str(&self) -> Option<&str> {
-        self.sf
-            .src
-            .as_ref()
-            .map(|src| src.as_str())
-            .or_else(|| self.sf.external_src.get().and_then(|src| src.get_source()))
+        (self.sf.src.as_ref().map(|src| src.as_str()))
+            .or_else(|| self.sf.external_src.get()?.get_source())
             .and_then(|x| x.get(self.range.clone()))
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 7a24d07fa1d..a63333c9b48 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -4,11 +4,11 @@
 use crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_with_context};
 use crate::ty::expr_sig;
 use crate::{get_parent_expr_for_hir, higher};
-use rustc_ast::ast;
 use rustc_ast::util::parser::AssocOp;
+use rustc_ast::{UnOp, ast};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_hir as hir;
-use rustc_hir::{Closure, ExprKind, HirId, MutTy, TyKind};
+use rustc_hir::{self as hir, Closure, ExprKind, HirId, MutTy, Node, TyKind};
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
 use rustc_lint::{EarlyContext, LateContext, LintContext};
 use rustc_middle::hir::place::ProjectionKind;
@@ -29,6 +29,11 @@ pub enum Sugg<'a> {
     /// A binary operator expression, including `as`-casts and explicit type
     /// coercion.
     BinOp(AssocOp, Cow<'a, str>, Cow<'a, str>),
+    /// A unary operator expression. This is used to sometimes represent `!`
+    /// or `-`, but only if the type with and without the operator is kept identical.
+    /// It means that doubling the operator can be used to remove it instead, in
+    /// order to provide better suggestions.
+    UnOp(UnOp, Box<Sugg<'a>>),
 }
 
 /// Literal constant `0`, for convenience.
@@ -40,9 +45,10 @@ pub const EMPTY: Sugg<'static> = Sugg::NonParen(Cow::Borrowed(""));
 
 impl Display for Sugg<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
-        match *self {
-            Sugg::NonParen(ref s) | Sugg::MaybeParen(ref s) => s.fmt(f),
-            Sugg::BinOp(op, ref lhs, ref rhs) => binop_to_string(op, lhs, rhs).fmt(f),
+        match self {
+            Sugg::NonParen(s) | Sugg::MaybeParen(s) => s.fmt(f),
+            Sugg::BinOp(op, lhs, rhs) => binop_to_string(*op, lhs, rhs).fmt(f),
+            Sugg::UnOp(op, inner) => write!(f, "{}{}", op.as_str(), inner.clone().maybe_inner_paren()),
         }
     }
 }
@@ -100,9 +106,19 @@ impl<'a> Sugg<'a> {
         applicability: &mut Applicability,
     ) -> Self {
         if expr.span.ctxt() == ctxt {
-            Self::hir_from_snippet(expr, |span| {
-                snippet_with_context(cx, span, ctxt, default, applicability).0
-            })
+            if let ExprKind::Unary(op, inner) = expr.kind
+                && matches!(op, UnOp::Neg | UnOp::Not)
+                && cx.typeck_results().expr_ty(expr) == cx.typeck_results().expr_ty(inner)
+            {
+                Sugg::UnOp(
+                    op,
+                    Box::new(Self::hir_with_context(cx, inner, ctxt, default, applicability)),
+                )
+            } else {
+                Self::hir_from_snippet(expr, |span| {
+                    snippet_with_context(cx, span, ctxt, default, applicability).0
+                })
+            }
         } else {
             let (snip, _) = snippet_with_context(cx, expr.span, ctxt, default, applicability);
             Sugg::NonParen(snip)
@@ -341,6 +357,7 @@ impl<'a> Sugg<'a> {
                 let sugg = binop_to_string(op, &lhs, &rhs);
                 Sugg::NonParen(format!("({sugg})").into())
             },
+            Sugg::UnOp(op, inner) => Sugg::NonParen(format!("({}{})", op.as_str(), inner.maybe_inner_paren()).into()),
         }
     }
 
@@ -348,6 +365,26 @@ impl<'a> Sugg<'a> {
         match self {
             Sugg::NonParen(p) | Sugg::MaybeParen(p) => p.into_owned(),
             Sugg::BinOp(b, l, r) => binop_to_string(b, &l, &r),
+            Sugg::UnOp(op, inner) => format!("{}{}", op.as_str(), inner.maybe_inner_paren()),
+        }
+    }
+
+    /// Checks if `self` starts with a unary operator.
+    fn starts_with_unary_op(&self) -> bool {
+        match self {
+            Sugg::UnOp(..) => true,
+            Sugg::BinOp(..) => false,
+            Sugg::MaybeParen(s) | Sugg::NonParen(s) => s.starts_with(['*', '!', '-', '&']),
+        }
+    }
+
+    /// Call `maybe_paren` on `self` if it doesn't start with a unary operator,
+    /// don't touch it otherwise.
+    fn maybe_inner_paren(self) -> Self {
+        if self.starts_with_unary_op() {
+            self
+        } else {
+            self.maybe_paren()
         }
     }
 }
@@ -430,10 +467,11 @@ impl Sub for &Sugg<'_> {
 forward_binop_impls_to_ref!(impl Add, add for Sugg<'_>, type Output = Sugg<'static>);
 forward_binop_impls_to_ref!(impl Sub, sub for Sugg<'_>, type Output = Sugg<'static>);
 
-impl Neg for Sugg<'_> {
-    type Output = Sugg<'static>;
-    fn neg(self) -> Sugg<'static> {
-        match &self {
+impl<'a> Neg for Sugg<'a> {
+    type Output = Sugg<'a>;
+    fn neg(self) -> Self::Output {
+        match self {
+            Self::UnOp(UnOp::Neg, sugg) => *sugg,
             Self::BinOp(AssocOp::Cast, ..) => Sugg::MaybeParen(format!("-({self})").into()),
             _ => make_unop("-", self),
         }
@@ -446,19 +484,21 @@ impl<'a> Not for Sugg<'a> {
         use AssocOp::Binary;
         use ast::BinOpKind::{Eq, Ge, Gt, Le, Lt, Ne};
 
-        if let Sugg::BinOp(op, lhs, rhs) = self {
-            let to_op = match op {
-                Binary(Eq) => Binary(Ne),
-                Binary(Ne) => Binary(Eq),
-                Binary(Lt) => Binary(Ge),
-                Binary(Ge) => Binary(Lt),
-                Binary(Gt) => Binary(Le),
-                Binary(Le) => Binary(Gt),
-                _ => return make_unop("!", Sugg::BinOp(op, lhs, rhs)),
-            };
-            Sugg::BinOp(to_op, lhs, rhs)
-        } else {
-            make_unop("!", self)
+        match self {
+            Sugg::BinOp(op, lhs, rhs) => {
+                let to_op = match op {
+                    Binary(Eq) => Binary(Ne),
+                    Binary(Ne) => Binary(Eq),
+                    Binary(Lt) => Binary(Ge),
+                    Binary(Ge) => Binary(Lt),
+                    Binary(Gt) => Binary(Le),
+                    Binary(Le) => Binary(Gt),
+                    _ => return make_unop("!", Sugg::BinOp(op, lhs, rhs)),
+                };
+                Sugg::BinOp(to_op, lhs, rhs)
+            },
+            Sugg::UnOp(UnOp::Not, expr) => *expr,
+            _ => make_unop("!", self),
         }
     }
 }
@@ -491,20 +531,11 @@ impl<T: Display> Display for ParenHelper<T> {
 /// Builds the string for `<op><expr>` adding parenthesis when necessary.
 ///
 /// For convenience, the operator is taken as a string because all unary
-/// operators have the same
-/// precedence.
+/// operators have the same precedence.
 pub fn make_unop(op: &str, expr: Sugg<'_>) -> Sugg<'static> {
-    // If the `expr` starts with `op` already, do not add wrap it in
+    // If the `expr` starts with a unary operator already, do not wrap it in
     // parentheses.
-    let expr = if let Sugg::MaybeParen(ref sugg) = expr
-        && !has_enclosing_paren(sugg)
-        && sugg.starts_with(op)
-    {
-        expr
-    } else {
-        expr.maybe_paren()
-    };
-    Sugg::MaybeParen(format!("{op}{expr}").into())
+    Sugg::MaybeParen(format!("{op}{}", expr.maybe_inner_paren()).into())
 }
 
 /// Builds the string for `<lhs> <op> <rhs>` adding parenthesis when necessary.
@@ -753,8 +784,10 @@ pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Opti
         let mut visitor = DerefDelegate {
             cx,
             closure_span: closure.span,
+            closure_arg_id: closure_body.params[0].pat.hir_id,
             closure_arg_is_type_annotated_double_ref,
             next_pos: closure.span.lo(),
+            checked_borrows: FxHashSet::default(),
             suggestion_start: String::new(),
             applicability: Applicability::MachineApplicable,
         };
@@ -780,10 +813,15 @@ struct DerefDelegate<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     /// The span of the input closure to adapt
     closure_span: Span,
+    /// The `hir_id` of the closure argument being checked
+    closure_arg_id: HirId,
     /// Indicates if the arg of the closure is a type annotated double reference
     closure_arg_is_type_annotated_double_ref: bool,
     /// last position of the span to gradually build the suggestion
     next_pos: BytePos,
+    /// `hir_id`s that has been checked. This is used to avoid checking the same `hir_id` multiple
+    /// times when inside macro expansions.
+    checked_borrows: FxHashSet<HirId>,
     /// starting part of the gradually built suggestion
     suggestion_start: String,
     /// confidence on the built suggestion
@@ -847,9 +885,15 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
 
     fn use_cloned(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
 
+    #[expect(clippy::too_many_lines)]
     fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, _: ty::BorrowKind) {
         if let PlaceBase::Local(id) = cmt.place.base {
             let span = self.cx.tcx.hir_span(cmt.hir_id);
+            if !self.checked_borrows.insert(cmt.hir_id) {
+                // already checked this span and hir_id, skip
+                return;
+            }
+
             let start_span = Span::new(self.next_pos, span.lo(), span.ctxt(), None);
             let mut start_snip = snippet_with_applicability(self.cx, start_span, "..", &mut self.applicability);
 
@@ -858,7 +902,12 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
             // full identifier that includes projection (i.e.: `fp.field`)
             let ident_str_with_proj = snippet(self.cx, span, "..").to_string();
 
-            if cmt.place.projections.is_empty() {
+            // Make sure to get in all projections if we're on a `matches!`
+            if let Node::Pat(pat) = self.cx.tcx.hir_node(id)
+                && pat.hir_id != self.closure_arg_id
+            {
+                let _ = write!(self.suggestion_start, "{start_snip}{ident_str_with_proj}");
+            } else if cmt.place.projections.is_empty() {
                 // handle item without any projection, that needs an explicit borrowing
                 // i.e.: suggest `&x` instead of `x`
                 let _: fmt::Result = write!(self.suggestion_start, "{start_snip}&{ident_str}");
diff --git a/src/tools/clippy/clippy_utils/src/sym.rs b/src/tools/clippy/clippy_utils/src/sym.rs
index 934be97d94e..ce7cc9348fb 100644
--- a/src/tools/clippy/clippy_utils/src/sym.rs
+++ b/src/tools/clippy/clippy_utils/src/sym.rs
@@ -171,7 +171,6 @@ generate! {
     has_significant_drop,
     hidden_glob_reexports,
     hygiene,
-    if_chain,
     insert,
     inspect,
     int_roundings,
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index 02a8eda5893..d79773f8321 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -6,13 +6,12 @@ use core::ops::ControlFlow;
 use itertools::Itertools;
 use rustc_abi::VariantIdx;
 use rustc_ast::ast::Mutability;
-use rustc_hir::attrs::{AttributeKind};
-use rustc_hir::find_attr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir as hir;
+use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::{Expr, FnDecl, LangItem, TyKind};
+use rustc_hir::{Expr, FnDecl, LangItem, TyKind, find_attr};
 use rustc_hir_analysis::lower_ty;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
@@ -583,7 +582,7 @@ pub fn all_predicates_of(tcx: TyCtxt<'_>, id: DefId) -> impl Iterator<Item = &(t
 }
 
 /// A signature for a function like type.
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
 pub enum ExprFnSig<'tcx> {
     Sig(Binder<'tcx, FnSig<'tcx>>, Option<DefId>),
     Closure(Option<&'tcx FnDecl<'tcx>>, Binder<'tcx, FnSig<'tcx>>),
diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml
index bd6b4dfdee4..ec0e59e7054 100644
--- a/src/tools/clippy/declare_clippy_lint/Cargo.toml
+++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "declare_clippy_lint"
-version = "0.1.90"
+version = "0.1.91"
 edition = "2024"
 repository = "https://github.com/rust-lang/rust-clippy"
 license = "MIT OR Apache-2.0"
diff --git a/src/tools/clippy/lintcheck/src/input.rs b/src/tools/clippy/lintcheck/src/input.rs
index 408a2e087af..1ed059d2fb1 100644
--- a/src/tools/clippy/lintcheck/src/input.rs
+++ b/src/tools/clippy/lintcheck/src/input.rs
@@ -117,7 +117,7 @@ pub fn read_crates(toml_path: &Path) -> (Vec<CrateWithSource>, RecursiveOptions)
             crate_sources.push(CrateWithSource {
                 name: tk.name.clone(),
                 source: CrateSource::CratesIo {
-                    version: version.to_string(),
+                    version: version.clone(),
                 },
                 file_link: tk.file_link(DEFAULT_DOCS_LINK),
                 options: tk.options.clone(),
diff --git a/src/tools/clippy/lintcheck/src/json.rs b/src/tools/clippy/lintcheck/src/json.rs
index 808997ff022..79c1255c5ff 100644
--- a/src/tools/clippy/lintcheck/src/json.rs
+++ b/src/tools/clippy/lintcheck/src/json.rs
@@ -66,7 +66,7 @@ impl fmt::Display for Summary {
         } in &self.0
         {
             let html_id = to_html_id(name);
-            writeln!(f, "| [`{name}`](#{html_id}) | {added} | {changed} | {removed} |")?;
+            writeln!(f, "| [`{name}`](#{html_id}) | {added} | {removed} | {changed} |")?;
         }
 
         Ok(())
diff --git a/src/tools/clippy/lintcheck/src/output.rs b/src/tools/clippy/lintcheck/src/output.rs
index d7fe0915121..1ecc3f7c249 100644
--- a/src/tools/clippy/lintcheck/src/output.rs
+++ b/src/tools/clippy/lintcheck/src/output.rs
@@ -220,7 +220,7 @@ fn print_stats(old_stats: HashMap<String, usize>, new_stats: HashMap<&String, us
     let same_in_both_hashmaps = old_stats
         .iter()
         .filter(|(old_key, old_val)| new_stats.get::<&String>(old_key) == Some(old_val))
-        .map(|(k, v)| (k.to_string(), *v))
+        .map(|(k, v)| (k.clone(), *v))
         .collect::<Vec<(String, usize)>>();
 
     let mut old_stats_deduped = old_stats;
diff --git a/src/tools/clippy/rust-toolchain.toml b/src/tools/clippy/rust-toolchain.toml
index 0edb80edd04..ac51ec2d61b 100644
--- a/src/tools/clippy/rust-toolchain.toml
+++ b/src/tools/clippy/rust-toolchain.toml
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2025-07-25"
+channel = "nightly-2025-08-07"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 464efc45c6b..6b6dfd7b81e 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -73,8 +73,7 @@ fn internal_extern_flags() -> Vec<String> {
             && INTERNAL_TEST_DEPENDENCIES.contains(&name)
         {
             // A dependency may be listed twice if it is available in sysroot,
-            // and the sysroot dependencies are listed first. As of the writing,
-            // this only seems to apply to if_chain.
+            // and the sysroot dependencies are listed first.
             crates.insert(name, path);
         }
     }
@@ -434,6 +433,7 @@ fn ui_cargo_toml_metadata() {
 #[derive(Template)]
 #[template(path = "index_template.html")]
 struct Renderer<'a> {
+    count: usize,
     lints: &'a Vec<LintMetadata>,
 }
 
@@ -513,7 +513,12 @@ impl DiagnosticCollector {
 
             fs::write(
                 "util/gh-pages/index.html",
-                Renderer { lints: &metadata }.render().unwrap(),
+                Renderer {
+                    count: LINTS.len(),
+                    lints: &metadata,
+                }
+                .render()
+                .unwrap(),
             )
             .unwrap();
         });
diff --git a/src/tools/clippy/tests/symbols-used.rs b/src/tools/clippy/tests/symbols-used.rs
index bc0456711fb..a1049ba64d5 100644
--- a/src/tools/clippy/tests/symbols-used.rs
+++ b/src/tools/clippy/tests/symbols-used.rs
@@ -75,7 +75,7 @@ fn all_symbols_are_used() -> Result<()> {
         for sym in extra {
             eprintln!("  - {sym}");
         }
-        Err(format!("extra symbols found — remove them {SYM_FILE}"))?;
+        Err(format!("extra symbols found — remove them from {SYM_FILE}"))?;
     }
     Ok(())
 }
diff --git a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr
index 14a6b5047b1..666b842bf80 100644
--- a/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/cargo_rust_version/fail_file_attr/Cargo.stderr
@@ -7,7 +7,7 @@ error: unnecessary structure name repetition
 note: the lint level is defined here
   --> src/main.rs:6:9
    |
-6  | #![deny(clippy::use_self)]
+ 6 | #![deny(clippy::use_self)]
    |         ^^^^^^^^^^^^^^^^
 
 error: unnecessary structure name repetition
diff --git a/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr
index b626551e35b..8db52c47ad5 100644
--- a/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/duplicate_mod/fail/Cargo.stderr
@@ -14,10 +14,10 @@ error: file is loaded as a module multiple times: `src/b.rs`
 error: file is loaded as a module multiple times: `src/c.rs`
   --> src/main.rs:7:1
    |
-7  |   mod c;
+ 7 |   mod c;
    |   ^^^^^^ first loaded here
-8  | / #[path = "c.rs"]
-9  | | mod c2;
+ 8 | / #[path = "c.rs"]
+ 9 | | mod c2;
    | |_______^ loaded again here
 10 | / #[path = "c.rs"]
 11 | | mod c3;
@@ -44,8 +44,8 @@ error: file is loaded as a module multiple times: `src/from_other_module.rs`
    |
   ::: src/other_module/mod.rs:1:1
    |
-1  | / #[path = "../from_other_module.rs"]
-2  | | mod m;
+ 1 | / #[path = "../from_other_module.rs"]
+ 2 | | mod m;
    | |______^ loaded again here
    |
    = help: replace all but one `mod` item with `use` items
diff --git a/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr
index 059427d8ee0..a87339a9a30 100644
--- a/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr
@@ -1,7 +1,7 @@
 error: lint group `rust_2018_idioms` has the same priority (0) as a lint
   --> Cargo.toml:7:1
    |
-7  | rust_2018_idioms = "warn"
+ 7 | rust_2018_idioms = "warn"
    | ^^^^^^^^^^^^^^^^   ------ has an implicit priority of 0
 ...
 12 | unused_attributes = { level = "allow" }
@@ -11,8 +11,8 @@ error: lint group `rust_2018_idioms` has the same priority (0) as a lint
    = note: `#[deny(clippy::lint_groups_priority)]` on by default
 help: to have lints override the group set `rust_2018_idioms` to a lower priority
    |
-7  - rust_2018_idioms = "warn"
-7  + rust_2018_idioms = { level = "warn", priority = -1 }
+ 7 - rust_2018_idioms = "warn"
+ 7 + rust_2018_idioms = { level = "warn", priority = -1 }
    |
 
 error: lint group `unused` has the same priority (0) as a lint
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
index 20511cbed16..ec9fbcfd4a3 100644
--- a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
@@ -1,3 +1,4 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
 #![warn(clippy::wildcard_imports)]
 
 mod prelude {
@@ -13,6 +14,10 @@ mod my_crate {
     pub mod utils {
         pub fn my_util_fn() {}
     }
+
+    pub mod utils2 {
+        pub const SOME_CONST: u32 = 1;
+    }
 }
 
 pub use utils::{BAR, print};
@@ -22,6 +27,12 @@ use my_crate::utils::my_util_fn;
 use prelude::FOO;
 //~^ ERROR: usage of wildcard import
 
+proc_macros::external! {
+    use my_crate::utils2::*;
+
+    static SOME_STATIC: u32 = SOME_CONST;
+}
+
 fn main() {
     let _ = FOO;
     let _ = BAR;
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
index 8d05910f471..233ee19f89b 100644
--- a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
@@ -1,3 +1,4 @@
+//@aux-build:../../ui/auxiliary/proc_macros.rs
 #![warn(clippy::wildcard_imports)]
 
 mod prelude {
@@ -13,6 +14,10 @@ mod my_crate {
     pub mod utils {
         pub fn my_util_fn() {}
     }
+
+    pub mod utils2 {
+        pub const SOME_CONST: u32 = 1;
+    }
 }
 
 pub use utils::*;
@@ -22,6 +27,12 @@ use my_crate::utils::*;
 use prelude::*;
 //~^ ERROR: usage of wildcard import
 
+proc_macros::external! {
+    use my_crate::utils2::*;
+
+    static SOME_STATIC: u32 = SOME_CONST;
+}
+
 fn main() {
     let _ = FOO;
     let _ = BAR;
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
index 5e624dd6c3c..5d37cb705f5 100644
--- a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
@@ -1,5 +1,5 @@
 error: usage of wildcard import
-  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:18:9
+  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:23:9
    |
 LL | pub use utils::*;
    |         ^^^^^^^^ help: try: `utils::{BAR, print}`
@@ -8,13 +8,13 @@ LL | pub use utils::*;
    = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
 
 error: usage of wildcard import
-  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:20:5
+  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:25:5
    |
 LL | use my_crate::utils::*;
    |     ^^^^^^^^^^^^^^^^^^ help: try: `my_crate::utils::my_util_fn`
 
 error: usage of wildcard import
-  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:22:5
+  --> tests/ui-toml/wildcard_imports/wildcard_imports.rs:27:5
    |
 LL | use prelude::*;
    |     ^^^^^^^^^^ help: try: `prelude::FOO`
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer_unfixable.rs b/src/tools/clippy/tests/ui/cast_lossless_integer_unfixable.rs
new file mode 100644
index 00000000000..db9cbbb5b66
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer_unfixable.rs
@@ -0,0 +1,17 @@
+//@check-pass
+#![warn(clippy::cast_lossless)]
+
+fn issue15348() {
+    macro_rules! zero {
+        ($int:ty) => {{
+            let data: [u8; 3] = [0, 0, 0];
+            data[0] as $int
+        }};
+    }
+
+    let _ = zero!(u8);
+    let _ = zero!(u16);
+    let _ = zero!(u32);
+    let _ = zero!(u64);
+    let _ = zero!(u128);
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.fixed b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
index fed75244c6f..3d709fe9b8e 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
@@ -104,3 +104,25 @@ fn issue14799() {
         }
     }
 }
+
+fn in_parens() {
+    let x = "hello";
+    let y = "world";
+
+    if x == "hello" {
+        print!("Hello ");
+    } else if y == "world" { println!("world") } else { println!("!") }
+    //~^^^ collapsible_else_if
+}
+
+fn in_brackets() {
+    let x = "hello";
+    let y = "world";
+
+    // There is no lint when the inner `if` is in a block.
+    if x == "hello" {
+        print!("Hello ");
+    } else {
+        { if y == "world" { println!("world") } else { println!("!") } }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.rs b/src/tools/clippy/tests/ui/collapsible_else_if.rs
index e50e781fb69..51868e03908 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.rs
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.rs
@@ -120,3 +120,27 @@ fn issue14799() {
         }
     }
 }
+
+fn in_parens() {
+    let x = "hello";
+    let y = "world";
+
+    if x == "hello" {
+        print!("Hello ");
+    } else {
+        (if y == "world" { println!("world") } else { println!("!") })
+    }
+    //~^^^ collapsible_else_if
+}
+
+fn in_brackets() {
+    let x = "hello";
+    let y = "world";
+
+    // There is no lint when the inner `if` is in a block.
+    if x == "hello" {
+        print!("Hello ");
+    } else {
+        { if y == "world" { println!("world") } else { println!("!") } }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.stderr b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
index 7d80894cadb..1a7bcec7fd5 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
@@ -150,5 +150,14 @@ LL | |         if false {}
 LL | |     }
    | |_____^ help: collapse nested if block: `if false {}`
 
-error: aborting due to 8 previous errors
+error: this `else { if .. }` block can be collapsed
+  --> tests/ui/collapsible_else_if.rs:130:12
+   |
+LL |       } else {
+   |  ____________^
+LL | |         (if y == "world" { println!("world") } else { println!("!") })
+LL | |     }
+   | |_____^ help: collapse nested if block: `if y == "world" { println!("world") } else { println!("!") }`
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/collapsible_if.fixed b/src/tools/clippy/tests/ui/collapsible_if.fixed
index 77bc791ea8e..78354c2d7cf 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_if.fixed
@@ -163,3 +163,21 @@ fn issue14799() {
         if true {}
     };
 }
+
+fn in_parens() {
+    if true
+        && true {
+            println!("In parens, linted");
+        }
+    //~^^^^^ collapsible_if
+}
+
+fn in_brackets() {
+    if true {
+        {
+            if true {
+                println!("In brackets, not linted");
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_if.rs b/src/tools/clippy/tests/ui/collapsible_if.rs
index d30df157d5e..5d9afa10956 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.rs
+++ b/src/tools/clippy/tests/ui/collapsible_if.rs
@@ -173,3 +173,22 @@ fn issue14799() {
         if true {}
     };
 }
+
+fn in_parens() {
+    if true {
+        (if true {
+            println!("In parens, linted");
+        })
+    }
+    //~^^^^^ collapsible_if
+}
+
+fn in_brackets() {
+    if true {
+        {
+            if true {
+                println!("In brackets, not linted");
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_if.stderr b/src/tools/clippy/tests/ui/collapsible_if.stderr
index 32c6b019403..a685cc2e929 100644
--- a/src/tools/clippy/tests/ui/collapsible_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_if.stderr
@@ -190,5 +190,23 @@ LL |         // This is a comment, do not collapse code to it
 LL ~     ; 3
    |
 
-error: aborting due to 11 previous errors
+error: this `if` statement can be collapsed
+  --> tests/ui/collapsible_if.rs:178:5
+   |
+LL | /     if true {
+LL | |         (if true {
+LL | |             println!("In parens, linted");
+LL | |         })
+LL | |     }
+   | |_____^
+   |
+help: collapse nested if block
+   |
+LL ~     if true
+LL ~         && true {
+LL |             println!("In parens, linted");
+LL ~         }
+   |
+
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/deprecated.rs b/src/tools/clippy/tests/ui/deprecated.rs
index 6b69bdd29ce..9743a83fb93 100644
--- a/src/tools/clippy/tests/ui/deprecated.rs
+++ b/src/tools/clippy/tests/ui/deprecated.rs
@@ -12,6 +12,7 @@
 #![warn(clippy::regex_macro)] //~ ERROR: lint `clippy::regex_macro`
 #![warn(clippy::replace_consts)] //~ ERROR: lint `clippy::replace_consts`
 #![warn(clippy::should_assert_eq)] //~ ERROR: lint `clippy::should_assert_eq`
+#![warn(clippy::string_to_string)] //~ ERROR: lint `clippy::string_to_string`
 #![warn(clippy::unsafe_vector_initialization)] //~ ERROR: lint `clippy::unsafe_vector_initialization`
 #![warn(clippy::unstable_as_mut_slice)] //~ ERROR: lint `clippy::unstable_as_mut_slice`
 #![warn(clippy::unstable_as_slice)] //~ ERROR: lint `clippy::unstable_as_slice`
diff --git a/src/tools/clippy/tests/ui/deprecated.stderr b/src/tools/clippy/tests/ui/deprecated.stderr
index 07e59d33d60..cd225da611c 100644
--- a/src/tools/clippy/tests/ui/deprecated.stderr
+++ b/src/tools/clippy/tests/ui/deprecated.stderr
@@ -61,35 +61,41 @@ error: lint `clippy::should_assert_eq` has been removed: `assert!(a == b)` can n
 LL | #![warn(clippy::should_assert_eq)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: lint `clippy::unsafe_vector_initialization` has been removed: the suggested alternative could be substantially slower
+error: lint `clippy::string_to_string` has been removed: `clippy:implicit_clone` covers those cases
   --> tests/ui/deprecated.rs:15:9
    |
+LL | #![warn(clippy::string_to_string)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: lint `clippy::unsafe_vector_initialization` has been removed: the suggested alternative could be substantially slower
+  --> tests/ui/deprecated.rs:16:9
+   |
 LL | #![warn(clippy::unsafe_vector_initialization)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` is now stable
-  --> tests/ui/deprecated.rs:16:9
+  --> tests/ui/deprecated.rs:17:9
    |
 LL | #![warn(clippy::unstable_as_mut_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unstable_as_slice` has been removed: `Vec::as_slice` is now stable
-  --> tests/ui/deprecated.rs:17:9
+  --> tests/ui/deprecated.rs:18:9
    |
 LL | #![warn(clippy::unstable_as_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unused_collect` has been removed: `Iterator::collect` is now marked as `#[must_use]`
-  --> tests/ui/deprecated.rs:18:9
+  --> tests/ui/deprecated.rs:19:9
    |
 LL | #![warn(clippy::unused_collect)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::wrong_pub_self_convention` has been removed: `clippy::wrong_self_convention` now covers this case via the `avoid-breaking-exported-api` config
-  --> tests/ui/deprecated.rs:19:9
+  --> tests/ui/deprecated.rs:20:9
    |
 LL | #![warn(clippy::wrong_pub_self_convention)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 15 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index 8cf20d8b1a1..bbbd5973036 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -83,7 +83,7 @@ fn test_units() {
 /// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport
 /// TensorFlow
 /// TrueType
-/// iOS macOS FreeBSD NetBSD OpenBSD
+/// iOS macOS FreeBSD NetBSD OpenBSD NixOS
 /// TeX LaTeX BibTeX BibLaTeX
 /// MinGW
 /// CamelCase (see also #2395)
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 5b6f2bd8330..1077d3580d3 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -83,7 +83,7 @@ fn test_units() {
 /// WebGL WebGL2 WebGPU WebRTC WebSocket WebTransport
 /// TensorFlow
 /// TrueType
-/// iOS macOS FreeBSD NetBSD OpenBSD
+/// iOS macOS FreeBSD NetBSD OpenBSD NixOS
 /// TeX LaTeX BibTeX BibLaTeX
 /// MinGW
 /// CamelCase (see also #2395)
diff --git a/src/tools/clippy/tests/ui/duplicated_attributes.rs b/src/tools/clippy/tests/ui/duplicated_attributes.rs
index 3ca91d6f182..9a671499505 100644
--- a/src/tools/clippy/tests/ui/duplicated_attributes.rs
+++ b/src/tools/clippy/tests/ui/duplicated_attributes.rs
@@ -1,6 +1,6 @@
 //@aux-build:proc_macro_attr.rs
+#![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)] //~ ERROR: duplicated attribute
 #![feature(rustc_attrs)]
-#![warn(clippy::duplicated_attributes)]
 #![cfg(any(unix, windows))]
 #![allow(dead_code)]
 #![allow(dead_code)] //~ ERROR: duplicated attribute
diff --git a/src/tools/clippy/tests/ui/duplicated_attributes.stderr b/src/tools/clippy/tests/ui/duplicated_attributes.stderr
index 0903617a8d1..922939d60dd 100644
--- a/src/tools/clippy/tests/ui/duplicated_attributes.stderr
+++ b/src/tools/clippy/tests/ui/duplicated_attributes.stderr
@@ -1,4 +1,23 @@
 error: duplicated attribute
+  --> tests/ui/duplicated_attributes.rs:2:40
+   |
+LL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first defined here
+  --> tests/ui/duplicated_attributes.rs:2:9
+   |
+LL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: remove this attribute
+  --> tests/ui/duplicated_attributes.rs:2:40
+   |
+LL | #![warn(clippy::duplicated_attributes, clippy::duplicated_attributes)]
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: `-D clippy::duplicated-attributes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
+
+error: duplicated attribute
   --> tests/ui/duplicated_attributes.rs:6:10
    |
 LL | #![allow(dead_code)]
@@ -14,8 +33,6 @@ help: remove this attribute
    |
 LL | #![allow(dead_code)]
    |          ^^^^^^^^^
-   = note: `-D clippy::duplicated-attributes` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
 
 error: duplicated attribute
   --> tests/ui/duplicated_attributes.rs:14:9
@@ -34,5 +51,5 @@ help: remove this attribute
 LL | #[allow(dead_code)]
    |         ^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
index 419cf2354f8..22386245ffe 100644
--- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
@@ -32,3 +32,17 @@ macro_rules! empty_struct {
 empty_struct!(FromMacro);
 
 fn main() {}
+
+mod issue15349 {
+    trait Bar<T> {}
+    impl<T> Bar<T> for [u8; 7] {}
+
+    struct Foo<const N: usize>;
+    //~^ empty_structs_with_brackets
+    impl<const N: usize> Foo<N>
+    where
+        [u8; N]: Bar<[(); N]>,
+    {
+        fn foo() {}
+    }
+}
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
index 90c415c1220..5cb54b66134 100644
--- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
@@ -32,3 +32,17 @@ macro_rules! empty_struct {
 empty_struct!(FromMacro);
 
 fn main() {}
+
+mod issue15349 {
+    trait Bar<T> {}
+    impl<T> Bar<T> for [u8; 7] {}
+
+    struct Foo<const N: usize> {}
+    //~^ empty_structs_with_brackets
+    impl<const N: usize> Foo<N>
+    where
+        [u8; N]: Bar<[(); N]>,
+    {
+        fn foo() {}
+    }
+}
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
index 86ef43aa960..f662bb9423e 100644
--- a/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
@@ -16,5 +16,13 @@ LL | struct MyEmptyTupleStruct(); // should trigger lint
    |
    = help: remove the brackets
 
-error: aborting due to 2 previous errors
+error: found empty brackets on struct declaration
+  --> tests/ui/empty_structs_with_brackets.rs:40:31
+   |
+LL |     struct Foo<const N: usize> {}
+   |                               ^^^
+   |
+   = help: remove the brackets
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.rs b/src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.rs
new file mode 100644
index 00000000000..19123cd206e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.rs
@@ -0,0 +1,6 @@
+//@no-rustfix
+#![warn(clippy::four_forward_slashes)]
+
+//~v four_forward_slashes
+//// nondoc comment with bare CR: '
'
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.stderr b/src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.stderr
new file mode 100644
index 00000000000..64e70b97db9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/four_forward_slashes_bare_cr.stderr
@@ -0,0 +1,14 @@
+error: this item has comments with 4 forward slashes (`////`). These look like doc comments, but they aren't
+  --> tests/ui/four_forward_slashes_bare_cr.rs:5:1
+   |
+LL | / //// nondoc comment with bare CR: '␍'
+LL | | fn main() {}
+   | |_^
+   |
+   = help: make this a doc comment by removing one `/`
+   = note: bare CR characters are not allowed in doc comments
+   = note: `-D clippy::four-forward-slashes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::four_forward_slashes)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/implicit_clone.fixed b/src/tools/clippy/tests/ui/implicit_clone.fixed
index d60d1cb0ec0..267514c5f3d 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.fixed
+++ b/src/tools/clippy/tests/ui/implicit_clone.fixed
@@ -135,4 +135,10 @@ fn main() {
     }
     let no_clone = &NoClone;
     let _ = no_clone.to_owned();
+
+    let s = String::from("foo");
+    let _ = s.clone();
+    //~^ implicit_clone
+    let _ = s.clone();
+    //~^ implicit_clone
 }
diff --git a/src/tools/clippy/tests/ui/implicit_clone.rs b/src/tools/clippy/tests/ui/implicit_clone.rs
index b96828f28c8..fba954026e7 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.rs
+++ b/src/tools/clippy/tests/ui/implicit_clone.rs
@@ -135,4 +135,10 @@ fn main() {
     }
     let no_clone = &NoClone;
     let _ = no_clone.to_owned();
+
+    let s = String::from("foo");
+    let _ = s.to_owned();
+    //~^ implicit_clone
+    let _ = s.to_string();
+    //~^ implicit_clone
 }
diff --git a/src/tools/clippy/tests/ui/implicit_clone.stderr b/src/tools/clippy/tests/ui/implicit_clone.stderr
index 1eb6ff1fe42..4cca9b0d0c0 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.stderr
+++ b/src/tools/clippy/tests/ui/implicit_clone.stderr
@@ -67,5 +67,17 @@ error: implicitly cloning a `PathBuf` by calling `to_path_buf` on its dereferenc
 LL |     let _ = pathbuf_ref.to_path_buf();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(**pathbuf_ref).clone()`
 
-error: aborting due to 11 previous errors
+error: implicitly cloning a `String` by calling `to_owned` on its dereferenced type
+  --> tests/ui/implicit_clone.rs:140:13
+   |
+LL |     let _ = s.to_owned();
+   |             ^^^^^^^^^^^^ help: consider using: `s.clone()`
+
+error: implicitly cloning a `String` by calling `to_string` on its dereferenced type
+  --> tests/ui/implicit_clone.rs:142:13
+   |
+LL |     let _ = s.to_string();
+   |             ^^^^^^^^^^^^^ help: consider using: `s.clone()`
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
index 72edc539f04..edf6f014d3d 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.fixed
@@ -1,8 +1,5 @@
 #![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
@@ -18,12 +15,9 @@ fn main() {
     if_let_slice_macro!();
 
     // Do lint this
-    if_chain! {
-        let slice: Option<&[u32]> = Some(&[1, 2, 3]);
-        if let Some([slice_0, ..]) = slice;
+    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);
-        }
+        println!("{}", slice_0);
     }
 }
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
index 7b474ba423b..76d4a2350f5 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.rs
@@ -1,8 +1,5 @@
 #![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
@@ -18,12 +15,9 @@ fn main() {
     if_let_slice_macro!();
 
     // Do lint this
-    if_chain! {
-        let slice: Option<&[u32]> = Some(&[1, 2, 3]);
-        if let Some(slice) = slice;
+    let slice: Option<&[u32]> = Some(&[1, 2, 3]);
+    if let Some(slice) = slice {
         //~^ ERROR: this binding can be a slice pattern to avoid indexing
-        then {
-            println!("{}", slice[0]);
-        }
+        println!("{}", slice[0]);
     }
 }
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr
index 64741abb911..635e6d19aef 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/slice_indexing_in_macro.stderr
@@ -1,8 +1,8 @@
 error: this binding can be a slice pattern to avoid indexing
-  --> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:23:21
+  --> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:19:17
    |
-LL |         if let Some(slice) = slice;
-   |                     ^^^^^
+LL |     if let Some(slice) = slice {
+   |                 ^^^^^
    |
 note: the lint level is defined here
   --> tests/ui/index_refutable_slice/slice_indexing_in_macro.rs:1:9
@@ -11,10 +11,9 @@ LL | #![deny(clippy::index_refutable_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: replace the binding and indexed access with a slice pattern
    |
-LL ~         if let Some([slice_0, ..]) = slice;
+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/src/tools/clippy/tests/ui/indexing_slicing_slice.rs b/src/tools/clippy/tests/ui/indexing_slicing_slice.rs
index cad77f56d03..dea31530a0b 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_slice.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_slice.rs
@@ -1,6 +1,5 @@
 //@aux-build: proc_macros.rs
 
-#![warn(clippy::indexing_slicing)]
 // We also check the out_of_bounds_indexing lint here, because it lints similar things and
 // we want to avoid false positives.
 #![warn(clippy::out_of_bounds_indexing)]
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
index e3ef89823e3..e3d6086544d 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_slice.stderr
@@ -1,5 +1,5 @@
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:115:6
+  --> tests/ui/indexing_slicing_slice.rs:114:6
    |
 LL |     &x[index..];
    |      ^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     &x[index..];
    = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:117:6
+  --> tests/ui/indexing_slicing_slice.rs:116:6
    |
 LL |     &x[..index];
    |      ^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     &x[..index];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:119:6
+  --> tests/ui/indexing_slicing_slice.rs:118:6
    |
 LL |     &x[index_from..index_to];
    |      ^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     &x[index_from..index_to];
    = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:121:6
+  --> tests/ui/indexing_slicing_slice.rs:120:6
    |
 LL |     &x[index_from..][..index_to];
    |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     &x[index_from..][..index_to];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:121:6
+  --> tests/ui/indexing_slicing_slice.rs:120:6
    |
 LL |     &x[index_from..][..index_to];
    |      ^^^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     &x[index_from..][..index_to];
    = help: consider using `.get(n..)` or .get_mut(n..)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:124:6
+  --> tests/ui/indexing_slicing_slice.rs:123:6
    |
 LL |     &x[5..][..10];
    |      ^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     &x[5..][..10];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:124:8
+  --> tests/ui/indexing_slicing_slice.rs:123:8
    |
 LL |     &x[5..][..10];
    |        ^
@@ -58,7 +58,7 @@ LL |     &x[5..][..10];
    = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:127:6
+  --> tests/ui/indexing_slicing_slice.rs:126:6
    |
 LL |     &x[0..][..3];
    |      ^^^^^^^^^^^
@@ -66,7 +66,7 @@ LL |     &x[0..][..3];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:129:6
+  --> tests/ui/indexing_slicing_slice.rs:128:6
    |
 LL |     &x[1..][..5];
    |      ^^^^^^^^^^^
@@ -74,19 +74,19 @@ LL |     &x[1..][..5];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:137:12
+  --> tests/ui/indexing_slicing_slice.rs:136:12
    |
 LL |     &y[0..=4];
    |            ^
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:139:11
+  --> tests/ui/indexing_slicing_slice.rs:138:11
    |
 LL |     &y[..=4];
    |           ^
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:145:6
+  --> tests/ui/indexing_slicing_slice.rs:144:6
    |
 LL |     &v[10..100];
    |      ^^^^^^^^^^
@@ -94,7 +94,7 @@ LL |     &v[10..100];
    = help: consider using `.get(n..m)` or `.get_mut(n..m)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:147:6
+  --> tests/ui/indexing_slicing_slice.rs:146:6
    |
 LL |     &x[10..][..100];
    |      ^^^^^^^^^^^^^^
@@ -102,13 +102,13 @@ LL |     &x[10..][..100];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: range is out of bounds
-  --> tests/ui/indexing_slicing_slice.rs:147:8
+  --> tests/ui/indexing_slicing_slice.rs:146:8
    |
 LL |     &x[10..][..100];
    |        ^^
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:150:6
+  --> tests/ui/indexing_slicing_slice.rs:149:6
    |
 LL |     &v[10..];
    |      ^^^^^^^
@@ -116,7 +116,7 @@ LL |     &v[10..];
    = help: consider using `.get(n..)` or .get_mut(n..)` instead
 
 error: slicing may panic
-  --> tests/ui/indexing_slicing_slice.rs:152:6
+  --> tests/ui/indexing_slicing_slice.rs:151:6
    |
 LL |     &v[..100];
    |      ^^^^^^^^
@@ -124,7 +124,7 @@ LL |     &v[..100];
    = help: consider using `.get(..n)`or `.get_mut(..n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_slice.rs:170:5
+  --> tests/ui/indexing_slicing_slice.rs:169:5
    |
 LL |     map_with_get[true];
    |     ^^^^^^^^^^^^^^^^^^
@@ -132,7 +132,7 @@ LL |     map_with_get[true];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_slice.rs:174:5
+  --> tests/ui/indexing_slicing_slice.rs:173:5
    |
 LL |     s[0];
    |     ^^^^
@@ -140,7 +140,7 @@ LL |     s[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_slice.rs:178:5
+  --> tests/ui/indexing_slicing_slice.rs:177:5
    |
 LL |     y[0];
    |     ^^^^
diff --git a/src/tools/clippy/tests/ui/infallible_try_from.stderr b/src/tools/clippy/tests/ui/infallible_try_from.stderr
index 705b1188489..d1e0d9e7d3b 100644
--- a/src/tools/clippy/tests/ui/infallible_try_from.stderr
+++ b/src/tools/clippy/tests/ui/infallible_try_from.stderr
@@ -1,4 +1,4 @@
-error: infallible TryFrom impl; consider implementing From, instead
+error: infallible TryFrom impl; consider implementing From instead
   --> tests/ui/infallible_try_from.rs:8:1
    |
 LL | impl TryFrom<i8> for MyStruct {
@@ -10,7 +10,7 @@ LL |     type Error = !;
    = note: `-D clippy::infallible-try-from` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::infallible_try_from)]`
 
-error: infallible TryFrom impl; consider implementing From, instead
+error: infallible TryFrom impl; consider implementing From instead
   --> tests/ui/infallible_try_from.rs:16:1
    |
 LL | impl TryFrom<i16> for MyStruct {
diff --git a/src/tools/clippy/tests/ui/ip_constant.fixed b/src/tools/clippy/tests/ui/ip_constant.fixed
index 2e3389c1193..c9479682139 100644
--- a/src/tools/clippy/tests/ui/ip_constant.fixed
+++ b/src/tools/clippy/tests/ui/ip_constant.fixed
@@ -48,6 +48,20 @@ fn literal_test3() {
     //~^ ip_constant
 }
 
+fn wrapped_in_parens() {
+    let _ = std::net::Ipv4Addr::LOCALHOST;
+    //~^ ip_constant
+    let _ = std::net::Ipv4Addr::BROADCAST;
+    //~^ ip_constant
+    let _ = std::net::Ipv4Addr::UNSPECIFIED;
+    //~^ ip_constant
+
+    let _ = std::net::Ipv6Addr::LOCALHOST;
+    //~^ ip_constant
+    let _ = std::net::Ipv6Addr::UNSPECIFIED;
+    //~^ ip_constant
+}
+
 const CONST_U8_0: u8 = 0;
 const CONST_U8_1: u8 = 1;
 const CONST_U8_127: u8 = 127;
diff --git a/src/tools/clippy/tests/ui/ip_constant.rs b/src/tools/clippy/tests/ui/ip_constant.rs
index 15e0b0551ba..69a5c3b4e92 100644
--- a/src/tools/clippy/tests/ui/ip_constant.rs
+++ b/src/tools/clippy/tests/ui/ip_constant.rs
@@ -48,6 +48,20 @@ fn literal_test3() {
     //~^ ip_constant
 }
 
+fn wrapped_in_parens() {
+    let _ = (std::net::Ipv4Addr::new(127, 0, 0, 1));
+    //~^ ip_constant
+    let _ = (std::net::Ipv4Addr::new(255, 255, 255, 255));
+    //~^ ip_constant
+    let _ = (std::net::Ipv4Addr::new(0, 0, 0, 0));
+    //~^ ip_constant
+
+    let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+    //~^ ip_constant
+    let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
+    //~^ ip_constant
+}
+
 const CONST_U8_0: u8 = 0;
 const CONST_U8_1: u8 = 1;
 const CONST_U8_127: u8 = 127;
diff --git a/src/tools/clippy/tests/ui/ip_constant.stderr b/src/tools/clippy/tests/ui/ip_constant.stderr
index 3e984c6cb3b..07d912b18a5 100644
--- a/src/tools/clippy/tests/ui/ip_constant.stderr
+++ b/src/tools/clippy/tests/ui/ip_constant.stderr
@@ -181,8 +181,68 @@ LL +     let _ = std::net::Ipv6Addr::UNSPECIFIED;
    |
 
 error: hand-coded well-known IP address
+  --> tests/ui/ip_constant.rs:52:13
+   |
+LL |     let _ = (std::net::Ipv4Addr::new(127, 0, 0, 1));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use
+   |
+LL -     let _ = (std::net::Ipv4Addr::new(127, 0, 0, 1));
+LL +     let _ = std::net::Ipv4Addr::LOCALHOST;
+   |
+
+error: hand-coded well-known IP address
+  --> tests/ui/ip_constant.rs:54:13
+   |
+LL |     let _ = (std::net::Ipv4Addr::new(255, 255, 255, 255));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use
+   |
+LL -     let _ = (std::net::Ipv4Addr::new(255, 255, 255, 255));
+LL +     let _ = std::net::Ipv4Addr::BROADCAST;
+   |
+
+error: hand-coded well-known IP address
+  --> tests/ui/ip_constant.rs:56:13
+   |
+LL |     let _ = (std::net::Ipv4Addr::new(0, 0, 0, 0));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use
+   |
+LL -     let _ = (std::net::Ipv4Addr::new(0, 0, 0, 0));
+LL +     let _ = std::net::Ipv4Addr::UNSPECIFIED;
+   |
+
+error: hand-coded well-known IP address
+  --> tests/ui/ip_constant.rs:59:13
+   |
+LL |     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use
+   |
+LL -     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
+LL +     let _ = std::net::Ipv6Addr::LOCALHOST;
+   |
+
+error: hand-coded well-known IP address
   --> tests/ui/ip_constant.rs:61:13
    |
+LL |     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use
+   |
+LL -     let _ = (std::net::Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0));
+LL +     let _ = std::net::Ipv6Addr::UNSPECIFIED;
+   |
+
+error: hand-coded well-known IP address
+  --> tests/ui/ip_constant.rs:75:13
+   |
 LL |     let _ = Ipv4Addr::new(CONST_U8_127, CONST_U8_0, CONST_U8_0, CONST_U8_1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
@@ -193,7 +253,7 @@ LL +     let _ = Ipv4Addr::LOCALHOST;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:63:13
+  --> tests/ui/ip_constant.rs:77:13
    |
 LL |     let _ = Ipv4Addr::new(CONST_U8_255, CONST_U8_255, CONST_U8_255, CONST_U8_255);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -205,7 +265,7 @@ LL +     let _ = Ipv4Addr::BROADCAST;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:65:13
+  --> tests/ui/ip_constant.rs:79:13
    |
 LL |     let _ = Ipv4Addr::new(CONST_U8_0, CONST_U8_0, CONST_U8_0, CONST_U8_0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +277,7 @@ LL +     let _ = Ipv4Addr::UNSPECIFIED;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:69:13
+  --> tests/ui/ip_constant.rs:83:13
    |
 LL |       let _ = Ipv6Addr::new(
    |  _____________^
@@ -246,7 +306,7 @@ LL +     let _ = Ipv6Addr::LOCALHOST;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:81:13
+  --> tests/ui/ip_constant.rs:95:13
    |
 LL |       let _ = Ipv6Addr::new(
    |  _____________^
@@ -275,7 +335,7 @@ LL +     let _ = Ipv6Addr::UNSPECIFIED;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:96:13
+  --> tests/ui/ip_constant.rs:110:13
    |
 LL |     let _ = Ipv4Addr::new(126 + 1, 0, 0, 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -287,7 +347,7 @@ LL +     let _ = Ipv4Addr::LOCALHOST;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:98:13
+  --> tests/ui/ip_constant.rs:112:13
    |
 LL |     let _ = Ipv4Addr::new(254 + CONST_U8_1, 255, { 255 - CONST_U8_0 }, CONST_U8_255);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -299,7 +359,7 @@ LL +     let _ = Ipv4Addr::BROADCAST;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:100:13
+  --> tests/ui/ip_constant.rs:114:13
    |
 LL |     let _ = Ipv4Addr::new(0, CONST_U8_255 - 255, 0, { 1 + 0 - 1 });
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -311,7 +371,7 @@ LL +     let _ = Ipv4Addr::UNSPECIFIED;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:104:13
+  --> tests/ui/ip_constant.rs:118:13
    |
 LL |     let _ = Ipv6Addr::new(0 + CONST_U16_0, 0, 0, 0, 0, 0, 0, 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -323,7 +383,7 @@ LL +     let _ = Ipv6Addr::LOCALHOST;
    |
 
 error: hand-coded well-known IP address
-  --> tests/ui/ip_constant.rs:106:13
+  --> tests/ui/ip_constant.rs:120:13
    |
 LL |     let _ = Ipv6Addr::new(0 + 0, 0, 0, 0, 0, { 2 - 1 - CONST_U16_1 }, 0, 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -334,5 +394,5 @@ LL -     let _ = Ipv6Addr::new(0 + 0, 0, 0, 0, 0, { 2 - 1 - CONST_U16_1 }, 0, 1)
 LL +     let _ = Ipv6Addr::LOCALHOST;
    |
 
-error: aborting due to 25 previous errors
+error: aborting due to 30 previous errors
 
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.fixed b/src/tools/clippy/tests/ui/iter_on_single_items.fixed
index b43fad6449c..044037aac2e 100644
--- a/src/tools/clippy/tests/ui/iter_on_single_items.fixed
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.fixed
@@ -66,3 +66,27 @@ fn main() {
     custom_option::custom_option();
     in_macros!();
 }
+
+mod issue14981 {
+    use std::option::IntoIter;
+    fn takes_into_iter(_: impl IntoIterator<Item = i32>) {}
+
+    fn let_stmt() {
+        macro_rules! x {
+            ($e:expr) => {
+                let _: IntoIter<i32> = $e;
+            };
+        }
+        x!(Some(5).into_iter());
+    }
+
+    fn fn_ptr() {
+        fn some_func(_: IntoIter<i32>) -> IntoIter<i32> {
+            todo!()
+        }
+        some_func(Some(5).into_iter());
+
+        const C: fn(IntoIter<i32>) -> IntoIter<i32> = <IntoIter<i32> as IntoIterator>::into_iter;
+        C(Some(5).into_iter());
+    }
+}
diff --git a/src/tools/clippy/tests/ui/iter_on_single_items.rs b/src/tools/clippy/tests/ui/iter_on_single_items.rs
index 625c96d3ef1..c925d0e480f 100644
--- a/src/tools/clippy/tests/ui/iter_on_single_items.rs
+++ b/src/tools/clippy/tests/ui/iter_on_single_items.rs
@@ -66,3 +66,27 @@ fn main() {
     custom_option::custom_option();
     in_macros!();
 }
+
+mod issue14981 {
+    use std::option::IntoIter;
+    fn takes_into_iter(_: impl IntoIterator<Item = i32>) {}
+
+    fn let_stmt() {
+        macro_rules! x {
+            ($e:expr) => {
+                let _: IntoIter<i32> = $e;
+            };
+        }
+        x!(Some(5).into_iter());
+    }
+
+    fn fn_ptr() {
+        fn some_func(_: IntoIter<i32>) -> IntoIter<i32> {
+            todo!()
+        }
+        some_func(Some(5).into_iter());
+
+        const C: fn(IntoIter<i32>) -> IntoIter<i32> = <IntoIter<i32> as IntoIterator>::into_iter;
+        C(Some(5).into_iter());
+    }
+}
diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed
index 304eacecd94..381d4cac462 100644
--- a/src/tools/clippy/tests/ui/let_unit.fixed
+++ b/src/tools/clippy/tests/ui/let_unit.fixed
@@ -198,3 +198,14 @@ pub fn issue12594() {
         returns_result(res).unwrap();
     }
 }
+
+fn issue15061() {
+    fn return_unit() {}
+    fn do_something(x: ()) {}
+
+    let res = ();
+    return_unit();
+    //~^ let_unit_value
+    do_something(());
+    println!("{res:?}");
+}
diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs
index a02cb346ff9..cdfc74991c4 100644
--- a/src/tools/clippy/tests/ui/let_unit.rs
+++ b/src/tools/clippy/tests/ui/let_unit.rs
@@ -198,3 +198,13 @@ pub fn issue12594() {
         returns_result(res).unwrap();
     }
 }
+
+fn issue15061() {
+    fn return_unit() {}
+    fn do_something(x: ()) {}
+
+    let res = return_unit();
+    //~^ let_unit_value
+    do_something(res);
+    println!("{res:?}");
+}
diff --git a/src/tools/clippy/tests/ui/let_unit.stderr b/src/tools/clippy/tests/ui/let_unit.stderr
index d743110c99d..637c9ff686b 100644
--- a/src/tools/clippy/tests/ui/let_unit.stderr
+++ b/src/tools/clippy/tests/ui/let_unit.stderr
@@ -68,5 +68,19 @@ LL ~         returns_result(()).unwrap();
 LL ~         returns_result(()).unwrap();
    |
 
-error: aborting due to 4 previous errors
+error: this let-binding has unit value
+  --> tests/ui/let_unit.rs:206:5
+   |
+LL |     let res = return_unit();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: replace variable usages with `()`
+   |
+LL ~     let res = ();
+LL ~     return_unit();
+LL |
+LL ~     do_something(());
+   |
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.fixed b/src/tools/clippy/tests/ui/let_with_type_underscore.fixed
index 7a4af4e3d1e..6339fe595c2 100644
--- a/src/tools/clippy/tests/ui/let_with_type_underscore.fixed
+++ b/src/tools/clippy/tests/ui/let_with_type_underscore.fixed
@@ -45,3 +45,15 @@ fn main() {
         x = ();
     };
 }
+
+fn issue15377() {
+    let (a) = 0;
+    //~^ let_with_type_underscore
+    let ((a)) = 0;
+    //~^ let_with_type_underscore
+    let ((a,)) = (0,);
+    //~^ let_with_type_underscore
+    #[rustfmt::skip]
+    let (   (a   )   ) = 0;
+    //~^ let_with_type_underscore
+}
diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.rs b/src/tools/clippy/tests/ui/let_with_type_underscore.rs
index a7c2f598b56..bd85346cf01 100644
--- a/src/tools/clippy/tests/ui/let_with_type_underscore.rs
+++ b/src/tools/clippy/tests/ui/let_with_type_underscore.rs
@@ -45,3 +45,15 @@ fn main() {
         x = ();
     };
 }
+
+fn issue15377() {
+    let (a): _ = 0;
+    //~^ let_with_type_underscore
+    let ((a)): _ = 0;
+    //~^ let_with_type_underscore
+    let ((a,)): _ = (0,);
+    //~^ let_with_type_underscore
+    #[rustfmt::skip]
+    let (   (a   )   ):  _ = 0;
+    //~^ let_with_type_underscore
+}
diff --git a/src/tools/clippy/tests/ui/let_with_type_underscore.stderr b/src/tools/clippy/tests/ui/let_with_type_underscore.stderr
index 9179f992207..c3f6c82397b 100644
--- a/src/tools/clippy/tests/ui/let_with_type_underscore.stderr
+++ b/src/tools/clippy/tests/ui/let_with_type_underscore.stderr
@@ -60,5 +60,53 @@ LL -     let x : _ = 1;
 LL +     let x = 1;
    |
 
-error: aborting due to 5 previous errors
+error: variable declared with type underscore
+  --> tests/ui/let_with_type_underscore.rs:50:5
+   |
+LL |     let (a): _ = 0;
+   |     ^^^^^^^^^^^^^^^
+   |
+help: remove the explicit type `_` declaration
+   |
+LL -     let (a): _ = 0;
+LL +     let (a) = 0;
+   |
+
+error: variable declared with type underscore
+  --> tests/ui/let_with_type_underscore.rs:52:5
+   |
+LL |     let ((a)): _ = 0;
+   |     ^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit type `_` declaration
+   |
+LL -     let ((a)): _ = 0;
+LL +     let ((a)) = 0;
+   |
+
+error: variable declared with type underscore
+  --> tests/ui/let_with_type_underscore.rs:54:5
+   |
+LL |     let ((a,)): _ = (0,);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit type `_` declaration
+   |
+LL -     let ((a,)): _ = (0,);
+LL +     let ((a,)) = (0,);
+   |
+
+error: variable declared with type underscore
+  --> tests/ui/let_with_type_underscore.rs:57:5
+   |
+LL |     let (   (a   )   ):  _ = 0;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit type `_` declaration
+   |
+LL -     let (   (a   )   ):  _ = 0;
+LL +     let (   (a   )   ) = 0;
+   |
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
index 221cddf069d..2e9c9045caa 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
@@ -167,7 +167,7 @@ LL -         comment */
 LL -         /// Doc comment
 LL -         panic!("panic with comment") // comment after `panic!`
 LL -     }
-LL +     assert!(!(a > 2), "panic with comment");
+LL +     assert!(a <= 2, "panic with comment");
    |
 
 error: only a `panic!` in `if`-then statement
@@ -186,7 +186,7 @@ LL -         const BAR: () = if N == 0 {
 LL -
 LL -             panic!()
 LL -         };
-LL +         const BAR: () = assert!(!(N == 0), );
+LL +         const BAR: () = assert!(N != 0, );
    |
 
 error: only a `panic!` in `if`-then statement
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
index 221cddf069d..2e9c9045caa 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
@@ -167,7 +167,7 @@ LL -         comment */
 LL -         /// Doc comment
 LL -         panic!("panic with comment") // comment after `panic!`
 LL -     }
-LL +     assert!(!(a > 2), "panic with comment");
+LL +     assert!(a <= 2, "panic with comment");
    |
 
 error: only a `panic!` in `if`-then statement
@@ -186,7 +186,7 @@ LL -         const BAR: () = if N == 0 {
 LL -
 LL -             panic!()
 LL -         };
-LL +         const BAR: () = assert!(!(N == 0), );
+LL +         const BAR: () = assert!(N != 0, );
    |
 
 error: only a `panic!` in `if`-then statement
diff --git a/src/tools/clippy/tests/ui/manual_strip.rs b/src/tools/clippy/tests/ui/manual_strip.rs
index 086b75a3987..0fdaa1c045e 100644
--- a/src/tools/clippy/tests/ui/manual_strip.rs
+++ b/src/tools/clippy/tests/ui/manual_strip.rs
@@ -75,7 +75,7 @@ fn main() {
         s4[2..].to_string();
     }
 
-    // Don't propose to reuse the `stripped` identifier as it is overriden
+    // Don't propose to reuse the `stripped` identifier as it is overridden
     if s.starts_with("ab") {
         let stripped = &s["ab".len()..];
         //~^ ERROR: stripping a prefix manually
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed b/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed
index 41ca44ceef4..189fe876aa5 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed
@@ -102,7 +102,7 @@ fn issue_12928() {
     let y = if let Some(Y(a, ..)) = x { a } else { 0 };
 }
 
-// For symetry with `manual_unwrap_or` test
+// For symmetry with `manual_unwrap_or` test
 fn allowed_manual_unwrap_or_zero() -> u32 {
     Some(42).unwrap_or_default()
 }
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs b/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs
index 343fbc4879c..ca87926763c 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs
@@ -138,7 +138,7 @@ fn issue_12928() {
     let y = if let Some(Y(a, ..)) = x { a } else { 0 };
 }
 
-// For symetry with `manual_unwrap_or` test
+// For symmetry with `manual_unwrap_or` test
 fn allowed_manual_unwrap_or_zero() -> u32 {
     if let Some(x) = Some(42) {
         //~^ manual_unwrap_or_default
diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed
index b82d3e6d956..6c971ba6338 100644
--- a/src/tools/clippy/tests/ui/map_identity.fixed
+++ b/src/tools/clippy/tests/ui/map_identity.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::map_identity)]
-#![allow(clippy::needless_return)]
+#![allow(clippy::needless_return, clippy::disallowed_names)]
 
 fn main() {
     let x: [u16; 3] = [1, 2, 3];
@@ -99,3 +99,65 @@ fn issue15198() {
     let _ = x.iter().copied();
     //~^ map_identity
 }
+
+mod foo {
+    #[derive(Clone, Copy)]
+    pub struct Foo {
+        pub foo: u8,
+        pub bar: u8,
+    }
+
+    #[derive(Clone, Copy)]
+    pub struct Foo2(pub u8, pub u8);
+}
+use foo::{Foo, Foo2};
+
+struct Bar {
+    foo: u8,
+    bar: u8,
+}
+
+struct Bar2(u8, u8);
+
+fn structs() {
+    let x = [Foo { foo: 0, bar: 0 }];
+
+    let _ = x.into_iter();
+    //~^ map_identity
+
+    // still lint when different paths are used for the same struct
+    let _ = x.into_iter();
+    //~^ map_identity
+
+    // don't lint: same fields but different structs
+    let _ = x.into_iter().map(|Foo { foo, bar }| Bar { foo, bar });
+
+    // still lint with redundant field names
+    #[allow(clippy::redundant_field_names)]
+    let _ = x.into_iter();
+    //~^ map_identity
+
+    // still lint with field order change
+    let _ = x.into_iter();
+    //~^ map_identity
+
+    // don't lint: switched field assignment
+    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: bar, bar: foo });
+}
+
+fn tuple_structs() {
+    let x = [Foo2(0, 0)];
+
+    let _ = x.into_iter();
+    //~^ map_identity
+
+    // still lint when different paths are used for the same struct
+    let _ = x.into_iter();
+    //~^ map_identity
+
+    // don't lint: same fields but different structs
+    let _ = x.into_iter().map(|Foo2(foo, bar)| Bar2(foo, bar));
+
+    // don't lint: switched field assignment
+    let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(bar, foo));
+}
diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs
index c295bf87270..59dcfcda3b6 100644
--- a/src/tools/clippy/tests/ui/map_identity.rs
+++ b/src/tools/clippy/tests/ui/map_identity.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::map_identity)]
-#![allow(clippy::needless_return)]
+#![allow(clippy::needless_return, clippy::disallowed_names)]
 
 fn main() {
     let x: [u16; 3] = [1, 2, 3];
@@ -105,3 +105,65 @@ fn issue15198() {
     let _ = x.iter().copied().map(|[x, y]| [x, y]);
     //~^ map_identity
 }
+
+mod foo {
+    #[derive(Clone, Copy)]
+    pub struct Foo {
+        pub foo: u8,
+        pub bar: u8,
+    }
+
+    #[derive(Clone, Copy)]
+    pub struct Foo2(pub u8, pub u8);
+}
+use foo::{Foo, Foo2};
+
+struct Bar {
+    foo: u8,
+    bar: u8,
+}
+
+struct Bar2(u8, u8);
+
+fn structs() {
+    let x = [Foo { foo: 0, bar: 0 }];
+
+    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo, bar });
+    //~^ map_identity
+
+    // still lint when different paths are used for the same struct
+    let _ = x.into_iter().map(|Foo { foo, bar }| foo::Foo { foo, bar });
+    //~^ map_identity
+
+    // don't lint: same fields but different structs
+    let _ = x.into_iter().map(|Foo { foo, bar }| Bar { foo, bar });
+
+    // still lint with redundant field names
+    #[allow(clippy::redundant_field_names)]
+    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: foo, bar: bar });
+    //~^ map_identity
+
+    // still lint with field order change
+    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { bar, foo });
+    //~^ map_identity
+
+    // don't lint: switched field assignment
+    let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: bar, bar: foo });
+}
+
+fn tuple_structs() {
+    let x = [Foo2(0, 0)];
+
+    let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(foo, bar));
+    //~^ map_identity
+
+    // still lint when different paths are used for the same struct
+    let _ = x.into_iter().map(|Foo2(foo, bar)| foo::Foo2(foo, bar));
+    //~^ map_identity
+
+    // don't lint: same fields but different structs
+    let _ = x.into_iter().map(|Foo2(foo, bar)| Bar2(foo, bar));
+
+    // don't lint: switched field assignment
+    let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(bar, foo));
+}
diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr
index 9b624a0dc75..a50c0d6b87b 100644
--- a/src/tools/clippy/tests/ui/map_identity.stderr
+++ b/src/tools/clippy/tests/ui/map_identity.stderr
@@ -93,5 +93,41 @@ error: unnecessary map of the identity function
 LL |     let _ = x.iter().copied().map(|[x, y]| [x, y]);
    |                              ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
 
-error: aborting due to 14 previous errors
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:131:26
+   |
+LL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo, bar });
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:135:26
+   |
+LL |     let _ = x.into_iter().map(|Foo { foo, bar }| foo::Foo { foo, bar });
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:143:26
+   |
+LL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { foo: foo, bar: bar });
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:147:26
+   |
+LL |     let _ = x.into_iter().map(|Foo { foo, bar }| Foo { bar, foo });
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:157:26
+   |
+LL |     let _ = x.into_iter().map(|Foo2(foo, bar)| Foo2(foo, bar));
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+
+error: unnecessary map of the identity function
+  --> tests/ui/map_identity.rs:161:26
+   |
+LL |     let _ = x.into_iter().map(|Foo2(foo, bar)| foo::Foo2(foo, bar));
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+
+error: aborting due to 20 previous errors
 
diff --git a/src/tools/clippy/tests/ui/match_single_binding.fixed b/src/tools/clippy/tests/ui/match_single_binding.fixed
index e11dea35204..e29fb87dbc3 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.fixed
+++ b/src/tools/clippy/tests/ui/match_single_binding.fixed
@@ -204,3 +204,65 @@ mod issue14991 {
         }],
     }
 }
+
+mod issue15018 {
+    fn used_later(a: i32, b: i32, c: i32) {
+        let x = 1;
+        {
+            let (x, y, z) = (a, b, c);
+            println!("{} {} {}", x, y, z);
+        }
+        println!("x = {x}");
+    }
+
+    fn not_used_later(a: i32, b: i32, c: i32) {
+        let (x, y, z) = (a, b, c);
+        println!("{} {} {}", x, y, z)
+    }
+
+    #[allow(irrefutable_let_patterns)]
+    fn not_used_later_but_shadowed(a: i32, b: i32, c: i32) {
+        let (x, y, z) = (a, b, c);
+        println!("{} {} {}", x, y, z);
+        let x = 1;
+        println!("x = {x}");
+    }
+
+    #[allow(irrefutable_let_patterns)]
+    fn not_used_later_but_shadowed_nested(a: i32, b: i32, c: i32) {
+        let (x, y, z) = (a, b, c);
+        println!("{} {} {}", x, y, z);
+        if let (x, y, z) = (a, b, c) {
+            println!("{} {} {}", x, y, z)
+        }
+
+        {
+            let x: i32 = 1;
+            {
+                let (x, y, z) = (a, b, c);
+                println!("{} {} {}", x, y, z);
+            }
+            if let (x, y, z) = (a, x, c) {
+                println!("{} {} {}", x, y, z)
+            }
+        }
+
+        {
+            let (x, y, z) = (a, b, c);
+            println!("{} {} {}", x, y, z);
+            let fn_ = |y| {
+                println!("{} {} {}", a, b, y);
+            };
+            fn_(c);
+        }
+    }
+}
+
+#[allow(clippy::short_circuit_statement)]
+fn issue15269(a: usize, b: usize, c: usize) -> bool {
+    a < b
+        && b < c;
+
+    a < b
+        && b < c
+}
diff --git a/src/tools/clippy/tests/ui/match_single_binding.rs b/src/tools/clippy/tests/ui/match_single_binding.rs
index d498da30fc8..ede1ab32beb 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.rs
+++ b/src/tools/clippy/tests/ui/match_single_binding.rs
@@ -267,3 +267,79 @@ mod issue14991 {
         }],
     }
 }
+
+mod issue15018 {
+    fn used_later(a: i32, b: i32, c: i32) {
+        let x = 1;
+        match (a, b, c) {
+            //~^ match_single_binding
+            (x, y, z) => println!("{} {} {}", x, y, z),
+        }
+        println!("x = {x}");
+    }
+
+    fn not_used_later(a: i32, b: i32, c: i32) {
+        match (a, b, c) {
+            //~^ match_single_binding
+            (x, y, z) => println!("{} {} {}", x, y, z),
+        }
+    }
+
+    #[allow(irrefutable_let_patterns)]
+    fn not_used_later_but_shadowed(a: i32, b: i32, c: i32) {
+        match (a, b, c) {
+            //~^ match_single_binding
+            (x, y, z) => println!("{} {} {}", x, y, z),
+        }
+        let x = 1;
+        println!("x = {x}");
+    }
+
+    #[allow(irrefutable_let_patterns)]
+    fn not_used_later_but_shadowed_nested(a: i32, b: i32, c: i32) {
+        match (a, b, c) {
+            //~^ match_single_binding
+            (x, y, z) => println!("{} {} {}", x, y, z),
+        }
+        if let (x, y, z) = (a, b, c) {
+            println!("{} {} {}", x, y, z)
+        }
+
+        {
+            let x: i32 = 1;
+            match (a, b, c) {
+                //~^ match_single_binding
+                (x, y, z) => println!("{} {} {}", x, y, z),
+            }
+            if let (x, y, z) = (a, x, c) {
+                println!("{} {} {}", x, y, z)
+            }
+        }
+
+        {
+            match (a, b, c) {
+                //~^ match_single_binding
+                (x, y, z) => println!("{} {} {}", x, y, z),
+            }
+            let fn_ = |y| {
+                println!("{} {} {}", a, b, y);
+            };
+            fn_(c);
+        }
+    }
+}
+
+#[allow(clippy::short_circuit_statement)]
+fn issue15269(a: usize, b: usize, c: usize) -> bool {
+    a < b
+        && match b {
+            //~^ match_single_binding
+            b => b < c,
+        };
+
+    a < b
+        && match (a, b) {
+            //~^ match_single_binding
+            (a, b) => b < c,
+        }
+}
diff --git a/src/tools/clippy/tests/ui/match_single_binding.stderr b/src/tools/clippy/tests/ui/match_single_binding.stderr
index f274f80c81d..eea71777890 100644
--- a/src/tools/clippy/tests/ui/match_single_binding.stderr
+++ b/src/tools/clippy/tests/ui/match_single_binding.stderr
@@ -411,5 +411,119 @@ LL ~             let _n = 1;
 LL +             42
    |
 
-error: aborting due to 29 previous errors
+error: this match could be written as a `let` statement
+  --> tests/ui/match_single_binding.rs:274:9
+   |
+LL | /         match (a, b, c) {
+LL | |
+LL | |             (x, y, z) => println!("{} {} {}", x, y, z),
+LL | |         }
+   | |_________^
+   |
+help: consider using a `let` statement
+   |
+LL ~         {
+LL +             let (x, y, z) = (a, b, c);
+LL +             println!("{} {} {}", x, y, z);
+LL +         }
+   |
+
+error: this match could be written as a `let` statement
+  --> tests/ui/match_single_binding.rs:282:9
+   |
+LL | /         match (a, b, c) {
+LL | |
+LL | |             (x, y, z) => println!("{} {} {}", x, y, z),
+LL | |         }
+   | |_________^
+   |
+help: consider using a `let` statement
+   |
+LL ~         let (x, y, z) = (a, b, c);
+LL +         println!("{} {} {}", x, y, z)
+   |
+
+error: this match could be written as a `let` statement
+  --> tests/ui/match_single_binding.rs:290:9
+   |
+LL | /         match (a, b, c) {
+LL | |
+LL | |             (x, y, z) => println!("{} {} {}", x, y, z),
+LL | |         }
+   | |_________^
+   |
+help: consider using a `let` statement
+   |
+LL ~         let (x, y, z) = (a, b, c);
+LL +         println!("{} {} {}", x, y, z);
+   |
+
+error: this match could be written as a `let` statement
+  --> tests/ui/match_single_binding.rs:300:9
+   |
+LL | /         match (a, b, c) {
+LL | |
+LL | |             (x, y, z) => println!("{} {} {}", x, y, z),
+LL | |         }
+   | |_________^
+   |
+help: consider using a `let` statement
+   |
+LL ~         let (x, y, z) = (a, b, c);
+LL +         println!("{} {} {}", x, y, z);
+   |
+
+error: this match could be written as a `let` statement
+  --> tests/ui/match_single_binding.rs:310:13
+   |
+LL | /             match (a, b, c) {
+LL | |
+LL | |                 (x, y, z) => println!("{} {} {}", x, y, z),
+LL | |             }
+   | |_____________^
+   |
+help: consider using a `let` statement
+   |
+LL ~             {
+LL +                 let (x, y, z) = (a, b, c);
+LL +                 println!("{} {} {}", x, y, z);
+LL +             }
+   |
+
+error: this match could be written as a `let` statement
+  --> tests/ui/match_single_binding.rs:320:13
+   |
+LL | /             match (a, b, c) {
+LL | |
+LL | |                 (x, y, z) => println!("{} {} {}", x, y, z),
+LL | |             }
+   | |_____________^
+   |
+help: consider using a `let` statement
+   |
+LL ~             let (x, y, z) = (a, b, c);
+LL +             println!("{} {} {}", x, y, z);
+   |
+
+error: this match could be replaced by its body itself
+  --> tests/ui/match_single_binding.rs:335:12
+   |
+LL |           && match b {
+   |  ____________^
+LL | |
+LL | |             b => b < c,
+LL | |         };
+   | |_________^ help: consider using the match body instead: `b < c`
+
+error: this match could be replaced by its body itself
+  --> tests/ui/match_single_binding.rs:341:12
+   |
+LL |           && match (a, b) {
+   |  ____________^
+LL | |
+LL | |             (a, b) => b < c,
+LL | |         }
+   | |_________^ help: consider using the match body instead: `b < c`
+
+error: aborting due to 37 previous errors
 
diff --git a/src/tools/clippy/tests/ui/min_ident_chars.rs b/src/tools/clippy/tests/ui/min_ident_chars.rs
index f473ac848a8..e2f82e2a182 100644
--- a/src/tools/clippy/tests/ui/min_ident_chars.rs
+++ b/src/tools/clippy/tests/ui/min_ident_chars.rs
@@ -124,3 +124,52 @@ fn wrong_pythagoras(a: f32, b: f32) -> f32 {
 mod issue_11163 {
     struct Array<T, const N: usize>([T; N]);
 }
+
+struct Issue13396;
+
+impl core::fmt::Display for Issue13396 {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        write!(f, "Issue13396")
+    }
+}
+
+impl core::fmt::Debug for Issue13396 {
+    fn fmt(&self, g: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        //~^ min_ident_chars
+        write!(g, "Issue13396")
+    }
+}
+
+fn issue13396() {
+    let a = |f: i8| f;
+    //~^ min_ident_chars
+    //~| min_ident_chars
+}
+
+trait D {
+    //~^ min_ident_chars
+    fn f(g: i32);
+    //~^ min_ident_chars
+    //~| min_ident_chars
+    fn long(long: i32);
+
+    fn g(arg: i8) {
+        //~^ min_ident_chars
+        fn c(d: u8) {}
+        //~^ min_ident_chars
+        //~| min_ident_chars
+    }
+}
+
+impl D for Issue13396 {
+    fn f(g: i32) {
+        fn h() {}
+        //~^ min_ident_chars
+        fn inner(a: i32) {}
+        //~^ min_ident_chars
+        let a = |f: String| f;
+        //~^ min_ident_chars
+        //~| min_ident_chars
+    }
+    fn long(long: i32) {}
+}
diff --git a/src/tools/clippy/tests/ui/min_ident_chars.stderr b/src/tools/clippy/tests/ui/min_ident_chars.stderr
index bd6c45cf648..36bf89e79f0 100644
--- a/src/tools/clippy/tests/ui/min_ident_chars.stderr
+++ b/src/tools/clippy/tests/ui/min_ident_chars.stderr
@@ -193,5 +193,83 @@ error: this ident consists of a single char
 LL | fn wrong_pythagoras(a: f32, b: f32) -> f32 {
    |                             ^
 
-error: aborting due to 32 previous errors
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:137:19
+   |
+LL |     fn fmt(&self, g: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+   |                   ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:144:14
+   |
+LL |     let a = |f: i8| f;
+   |              ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:144:9
+   |
+LL |     let a = |f: i8| f;
+   |         ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:149:7
+   |
+LL | trait D {
+   |       ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:151:10
+   |
+LL |     fn f(g: i32);
+   |          ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:151:8
+   |
+LL |     fn f(g: i32);
+   |        ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:156:8
+   |
+LL |     fn g(arg: i8) {
+   |        ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:158:12
+   |
+LL |         fn c(d: u8) {}
+   |            ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:158:14
+   |
+LL |         fn c(d: u8) {}
+   |              ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:166:12
+   |
+LL |         fn h() {}
+   |            ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:168:18
+   |
+LL |         fn inner(a: i32) {}
+   |                  ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:170:18
+   |
+LL |         let a = |f: String| f;
+   |                  ^
+
+error: this ident consists of a single char
+  --> tests/ui/min_ident_chars.rs:170:13
+   |
+LL |         let a = |f: String| f;
+   |             ^
+
+error: aborting due to 45 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.rs b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
index 57d0f2b9948..fff6d2f34b8 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.rs
@@ -1,5 +1,4 @@
-#![allow(clippy::uninlined_format_args, clippy::useless_vec)]
-#![allow(clippy::needless_if, clippy::uninlined_format_args)]
+#![allow(clippy::uninlined_format_args, clippy::useless_vec, clippy::needless_if)]
 #![warn(clippy::needless_collect)]
 //@no-rustfix
 use std::collections::{BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
diff --git a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
index c7bf1b14df8..24523c9f97b 100644
--- a/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
+++ b/src/tools/clippy/tests/ui/needless_collect_indirect.stderr
@@ -1,5 +1,5 @@
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:9:39
+  --> tests/ui/needless_collect_indirect.rs:8:39
    |
 LL |     let indirect_iter = sample.iter().collect::<Vec<_>>();
    |                                       ^^^^^^^
@@ -18,7 +18,7 @@ LL ~     sample.iter().map(|x| (x, x + 1)).collect::<HashMap<_, _>>();
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:13:38
+  --> tests/ui/needless_collect_indirect.rs:12:38
    |
 LL |     let indirect_len = sample.iter().collect::<VecDeque<_>>();
    |                                      ^^^^^^^
@@ -35,7 +35,7 @@ LL ~     sample.iter().count();
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:17:40
+  --> tests/ui/needless_collect_indirect.rs:16:40
    |
 LL |     let indirect_empty = sample.iter().collect::<VecDeque<_>>();
    |                                        ^^^^^^^
@@ -52,7 +52,7 @@ LL ~     sample.iter().next().is_none();
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:21:43
+  --> tests/ui/needless_collect_indirect.rs:20:43
    |
 LL |     let indirect_contains = sample.iter().collect::<VecDeque<_>>();
    |                                           ^^^^^^^
@@ -69,7 +69,7 @@ LL ~     sample.iter().any(|x| x == &5);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:35:48
+  --> tests/ui/needless_collect_indirect.rs:34:48
    |
 LL |     let non_copy_contains = sample.into_iter().collect::<Vec<_>>();
    |                                                ^^^^^^^
@@ -86,7 +86,7 @@ LL ~     sample.into_iter().any(|x| x == a);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:66:51
+  --> tests/ui/needless_collect_indirect.rs:65:51
    |
 LL |         let buffer: Vec<&str> = string.split('/').collect();
    |                                                   ^^^^^^^
@@ -103,7 +103,7 @@ LL ~         string.split('/').count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:73:55
+  --> tests/ui/needless_collect_indirect.rs:72:55
    |
 LL |         let indirect_len: VecDeque<_> = sample.iter().collect();
    |                                                       ^^^^^^^
@@ -120,7 +120,7 @@ LL ~         sample.iter().count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:80:57
+  --> tests/ui/needless_collect_indirect.rs:79:57
    |
 LL |         let indirect_len: LinkedList<_> = sample.iter().collect();
    |                                                         ^^^^^^^
@@ -137,7 +137,7 @@ LL ~         sample.iter().count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:87:57
+  --> tests/ui/needless_collect_indirect.rs:86:57
    |
 LL |         let indirect_len: BinaryHeap<_> = sample.iter().collect();
    |                                                         ^^^^^^^
@@ -154,7 +154,7 @@ LL ~         sample.iter().count()
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:149:59
+  --> tests/ui/needless_collect_indirect.rs:148:59
    |
 LL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                           ^^^^^^^
@@ -172,7 +172,7 @@ LL ~             vec.iter().map(|k| k * k).any(|x| x == i);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:176:59
+  --> tests/ui/needless_collect_indirect.rs:175:59
    |
 LL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                           ^^^^^^^
@@ -190,7 +190,7 @@ LL ~             vec.iter().map(|k| k * k).any(|x| x == n);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:207:63
+  --> tests/ui/needless_collect_indirect.rs:206:63
    |
 LL |                 let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                               ^^^^^^^
@@ -208,7 +208,7 @@ LL ~                 vec.iter().map(|k| k * k).any(|x| x == n);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:245:59
+  --> tests/ui/needless_collect_indirect.rs:244:59
    |
 LL |             let y: Vec<usize> = vec.iter().map(|k| k * k).collect();
    |                                                           ^^^^^^^
@@ -226,7 +226,7 @@ LL ~                 vec.iter().map(|k| k * k).any(|x| x == n);
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:272:26
+  --> tests/ui/needless_collect_indirect.rs:271:26
    |
 LL |         let w = v.iter().collect::<Vec<_>>();
    |                          ^^^^^^^
@@ -244,7 +244,7 @@ LL ~         for _ in 0..v.iter().count() {
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:296:30
+  --> tests/ui/needless_collect_indirect.rs:295:30
    |
 LL |         let mut w = v.iter().collect::<Vec<_>>();
    |                              ^^^^^^^
@@ -262,7 +262,7 @@ LL ~         while 1 == v.iter().count() {
    |
 
 error: avoid using `collect()` when not needed
-  --> tests/ui/needless_collect_indirect.rs:320:30
+  --> tests/ui/needless_collect_indirect.rs:319:30
    |
 LL |         let mut w = v.iter().collect::<Vec<_>>();
    |                              ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs
index 1eecc3dee3d..cacce9a7d1c 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs
@@ -236,3 +236,21 @@ mod issue14404 {
         }
     }
 }
+
+fn dont_simplify_double_not_if_types_differ() {
+    struct S;
+
+    impl std::ops::Not for S {
+        type Output = bool;
+        fn not(self) -> bool {
+            true
+        }
+    }
+
+    // The lint must propose `if !!S`, not `if S`.
+    // FIXME: `bool_comparison` will propose to use `S == true`
+    // which is invalid.
+    if !S != true {}
+    //~^ nonminimal_bool
+    //~| bool_comparison
+}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
index ecb82a23da0..c20412974b2 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
@@ -179,7 +179,7 @@ error: inequality checks against true can be replaced by a negation
   --> tests/ui/nonminimal_bool.rs:186:8
    |
 LL |     if !b != true {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!!b`
+   |        ^^^^^^^^^^ help: try simplifying it as shown: `b`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:189:8
@@ -209,7 +209,7 @@ error: inequality checks against true can be replaced by a negation
   --> tests/ui/nonminimal_bool.rs:193:8
    |
 LL |     if true != !b {}
-   |        ^^^^^^^^^^ help: try simplifying it as shown: `!!b`
+   |        ^^^^^^^^^^ help: try simplifying it as shown: `b`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:196:8
@@ -235,5 +235,17 @@ error: this boolean expression can be simplified
 LL |         if !(matches!(ty, TyKind::Ref(_, _, _)) && !is_mutable(&expr)) {
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!matches!(ty, TyKind::Ref(_, _, _)) || is_mutable(&expr)`
 
-error: aborting due to 31 previous errors
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool.rs:253:8
+   |
+LL |     if !S != true {}
+   |        ^^^^^^^^^^ help: try: `S == true`
+
+error: inequality checks against true can be replaced by a negation
+  --> tests/ui/nonminimal_bool.rs:253:8
+   |
+LL |     if !S != true {}
+   |        ^^^^^^^^^^ help: try simplifying it as shown: `!!S`
+
+error: aborting due to 33 previous errors
 
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index fe3ac9e8f92..0f86de5646c 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -302,3 +302,15 @@ mod issue11059 {
         if let Some(o) = o { o } else { &S }
     }
 }
+
+fn issue15379() {
+    let opt = Some(0usize);
+    let opt_raw_ptr = &opt as *const Option<usize>;
+    let _ = unsafe { (*opt_raw_ptr).map_or(1, |o| o) };
+    //~^ option_if_let_else
+}
+
+fn issue15002() {
+    let res: Result<String, ()> = Ok("_".to_string());
+    let _ = res.map_or_else(|_| String::new(), |s| s.clone());
+}
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs
index 5b7498bc8e2..7aabd778f87 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -365,3 +365,19 @@ mod issue11059 {
         if let Some(o) = o { o } else { &S }
     }
 }
+
+fn issue15379() {
+    let opt = Some(0usize);
+    let opt_raw_ptr = &opt as *const Option<usize>;
+    let _ = unsafe { if let Some(o) = *opt_raw_ptr { o } else { 1 } };
+    //~^ option_if_let_else
+}
+
+fn issue15002() {
+    let res: Result<String, ()> = Ok("_".to_string());
+    let _ = match res {
+        //~^ option_if_let_else
+        Ok(s) => s.clone(),
+        Err(_) => String::new(),
+    };
+}
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr
index 9eb41f81a53..2e2fe6f2049 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.stderr
+++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr
@@ -334,5 +334,22 @@ error: use Option::map_or_else instead of an if let/else
 LL |     let mut _hm = if let Some(hm) = &opt { hm.clone() } else { new_map!() };
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.as_ref().map_or_else(|| new_map!(), |hm| hm.clone())`
 
-error: aborting due to 25 previous errors
+error: use Option::map_or instead of an if let/else
+  --> tests/ui/option_if_let_else.rs:372:22
+   |
+LL |     let _ = unsafe { if let Some(o) = *opt_raw_ptr { o } else { 1 } };
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(*opt_raw_ptr).map_or(1, |o| o)`
+
+error: use Option::map_or_else instead of an if let/else
+  --> tests/ui/option_if_let_else.rs:378:13
+   |
+LL |       let _ = match res {
+   |  _____________^
+LL | |
+LL | |         Ok(s) => s.clone(),
+LL | |         Err(_) => String::new(),
+LL | |     };
+   | |_____^ help: try: `res.map_or_else(|_| String::new(), |s| s.clone())`
+
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/search_is_some.rs b/src/tools/clippy/tests/ui/search_is_some.rs
index 4143b8bfba5..802d27449ab 100644
--- a/src/tools/clippy/tests/ui/search_is_some.rs
+++ b/src/tools/clippy/tests/ui/search_is_some.rs
@@ -87,3 +87,18 @@ fn is_none() {
     let _ = (0..1).find(some_closure).is_none();
     //~^ search_is_some
 }
+
+#[allow(clippy::match_like_matches_macro)]
+fn issue15102() {
+    let values = [None, Some(3)];
+    let has_even = values
+        //~^ search_is_some
+        .iter()
+        .find(|v| match v {
+            Some(x) if x % 2 == 0 => true,
+            _ => false,
+        })
+        .is_some();
+
+    println!("{has_even}");
+}
diff --git a/src/tools/clippy/tests/ui/search_is_some.stderr b/src/tools/clippy/tests/ui/search_is_some.stderr
index d9a43c8915e..d5412f90111 100644
--- a/src/tools/clippy/tests/ui/search_is_some.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some.stderr
@@ -90,5 +90,20 @@ error: called `is_none()` after searching an `Iterator` with `find`
 LL |     let _ = (0..1).find(some_closure).is_none();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(some_closure)`
 
-error: aborting due to 8 previous errors
+error: called `is_some()` after searching an `Iterator` with `find`
+  --> tests/ui/search_is_some.rs:94:20
+   |
+LL |       let has_even = values
+   |  ____________________^
+LL | |
+LL | |         .iter()
+LL | |         .find(|v| match v {
+...  |
+LL | |         })
+LL | |         .is_some();
+   | |__________________^
+   |
+   = help: this is more succinctly expressed by calling `any()`
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed
index 42b39b33b57..c7a4422f373 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.fixed
@@ -289,3 +289,10 @@ mod issue9120 {
         //~^ search_is_some
     }
 }
+
+fn issue15102() {
+    let values = [None, Some(3)];
+    let has_even = values.iter().any(|v| matches!(&v, Some(x) if x % 2 == 0));
+    //~^ search_is_some
+    println!("{has_even}");
+}
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs
index ca4f4d941cb..d6b1c67c971 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.rs
@@ -297,3 +297,10 @@ mod issue9120 {
         //~^ search_is_some
     }
 }
+
+fn issue15102() {
+    let values = [None, Some(3)];
+    let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some();
+    //~^ search_is_some
+    println!("{has_even}");
+}
diff --git a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
index 8291f48d43c..551a670d937 100644
--- a/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
+++ b/src/tools/clippy/tests/ui/search_is_some_fixable_some.stderr
@@ -289,5 +289,11 @@ error: called `is_some()` after searching an `Iterator` with `find`
 LL |         let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))`
 
-error: aborting due to 46 previous errors
+error: called `is_some()` after searching an `Iterator` with `find`
+  --> tests/ui/search_is_some_fixable_some.rs:303:34
+   |
+LL |     let has_even = values.iter().find(|v| matches!(v, Some(x) if x % 2 == 0)).is_some();
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| matches!(&v, Some(x) if x % 2 == 0))`
+
+error: aborting due to 47 previous errors
 
diff --git a/src/tools/clippy/tests/ui/string_to_string.rs b/src/tools/clippy/tests/ui/string_to_string.rs
deleted file mode 100644
index 7c5bd8a897b..00000000000
--- a/src/tools/clippy/tests/ui/string_to_string.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-#![warn(clippy::string_to_string)]
-#![allow(clippy::redundant_clone, clippy::unnecessary_literal_unwrap)]
-
-fn main() {
-    let mut message = String::from("Hello");
-    let mut v = message.to_string();
-    //~^ string_to_string
-
-    let variable1 = String::new();
-    let v = &variable1;
-    let variable2 = Some(v);
-    let _ = variable2.map(|x| {
-        println!();
-        x.to_string()
-    });
-    //~^^ string_to_string
-
-    let x = Some(String::new());
-    let _ = x.unwrap_or_else(|| v.to_string());
-    //~^ string_to_string
-}
diff --git a/src/tools/clippy/tests/ui/string_to_string.stderr b/src/tools/clippy/tests/ui/string_to_string.stderr
deleted file mode 100644
index 99eea06f18e..00000000000
--- a/src/tools/clippy/tests/ui/string_to_string.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string.rs:6:17
-   |
-LL |     let mut v = message.to_string();
-   |                 ^^^^^^^^^^^^^^^^^^^
-   |
-   = help: consider using `.clone()`
-   = note: `-D clippy::string-to-string` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::string_to_string)]`
-
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string.rs:14:9
-   |
-LL |         x.to_string()
-   |         ^^^^^^^^^^^^^
-   |
-   = help: consider using `.clone()`
-
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string.rs:19:33
-   |
-LL |     let _ = x.unwrap_or_else(|| v.to_string());
-   |                                 ^^^^^^^^^^^^^
-   |
-   = help: consider using `.clone()`
-
-error: aborting due to 3 previous errors
-
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.fixed b/src/tools/clippy/tests/ui/string_to_string_in_map.fixed
deleted file mode 100644
index efc085539f1..00000000000
--- a/src/tools/clippy/tests/ui/string_to_string_in_map.fixed
+++ /dev/null
@@ -1,20 +0,0 @@
-#![deny(clippy::string_to_string)]
-#![allow(clippy::unnecessary_literal_unwrap, clippy::useless_vec, clippy::iter_cloned_collect)]
-
-fn main() {
-    let variable1 = String::new();
-    let v = &variable1;
-    let variable2 = Some(v);
-    let _ = variable2.cloned();
-    //~^ string_to_string
-    let _ = variable2.cloned();
-    //~^ string_to_string
-    #[rustfmt::skip]
-    let _ = variable2.cloned();
-    //~^ string_to_string
-
-    let _ = vec![String::new()].iter().cloned().collect::<Vec<_>>();
-    //~^ string_to_string
-    let _ = vec![String::new()].iter().cloned().collect::<Vec<_>>();
-    //~^ string_to_string
-}
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.rs b/src/tools/clippy/tests/ui/string_to_string_in_map.rs
deleted file mode 100644
index 5bf1d7ba5a2..00000000000
--- a/src/tools/clippy/tests/ui/string_to_string_in_map.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-#![deny(clippy::string_to_string)]
-#![allow(clippy::unnecessary_literal_unwrap, clippy::useless_vec, clippy::iter_cloned_collect)]
-
-fn main() {
-    let variable1 = String::new();
-    let v = &variable1;
-    let variable2 = Some(v);
-    let _ = variable2.map(String::to_string);
-    //~^ string_to_string
-    let _ = variable2.map(|x| x.to_string());
-    //~^ string_to_string
-    #[rustfmt::skip]
-    let _ = variable2.map(|x| { x.to_string() });
-    //~^ string_to_string
-
-    let _ = vec![String::new()].iter().map(String::to_string).collect::<Vec<_>>();
-    //~^ string_to_string
-    let _ = vec![String::new()].iter().map(|x| x.to_string()).collect::<Vec<_>>();
-    //~^ string_to_string
-}
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.stderr b/src/tools/clippy/tests/ui/string_to_string_in_map.stderr
deleted file mode 100644
index 35aeed656ee..00000000000
--- a/src/tools/clippy/tests/ui/string_to_string_in_map.stderr
+++ /dev/null
@@ -1,38 +0,0 @@
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string_in_map.rs:8:23
-   |
-LL |     let _ = variable2.map(String::to_string);
-   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
-   |
-note: the lint level is defined here
-  --> tests/ui/string_to_string_in_map.rs:1:9
-   |
-LL | #![deny(clippy::string_to_string)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string_in_map.rs:10:23
-   |
-LL |     let _ = variable2.map(|x| x.to_string());
-   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
-
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string_in_map.rs:13:23
-   |
-LL |     let _ = variable2.map(|x| { x.to_string() });
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
-
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string_in_map.rs:16:40
-   |
-LL |     let _ = vec![String::new()].iter().map(String::to_string).collect::<Vec<_>>();
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
-
-error: `to_string()` called on a `String`
-  --> tests/ui/string_to_string_in_map.rs:18:40
-   |
-LL |     let _ = vec![String::new()].iter().map(|x| x.to_string()).collect::<Vec<_>>();
-   |                                        ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
-
-error: aborting due to 5 previous errors
-
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
index 28a3b551116..072e7b27b0d 100644
--- a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
@@ -1,6 +1,6 @@
 //@aux-build:proc_macro_suspicious_else_formatting.rs
 
-#![warn(clippy::suspicious_else_formatting)]
+#![warn(clippy::suspicious_else_formatting, clippy::possible_missing_else)]
 #![allow(
     clippy::if_same_then_else,
     clippy::let_unit_value,
@@ -20,12 +20,12 @@ fn main() {
     // weird `else` formatting:
     if foo() {
     } {
-    //~^ suspicious_else_formatting
+    //~^ possible_missing_else
     }
 
     if foo() {
     } if foo() {
-    //~^ suspicious_else_formatting
+    //~^ possible_missing_else
     }
 
     let _ = { // if as the last expression
@@ -33,7 +33,7 @@ fn main() {
 
         if foo() {
         } if foo() {
-        //~^ suspicious_else_formatting
+        //~^ possible_missing_else
         }
         else {
         }
@@ -42,7 +42,7 @@ fn main() {
     let _ = { // if in the middle of a block
         if foo() {
         } if foo() {
-        //~^ suspicious_else_formatting
+        //~^ possible_missing_else
         }
         else {
         }
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
index affd20b22d9..04555c6edbd 100644
--- a/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.stderr
@@ -5,8 +5,8 @@ LL |     } {
    |      ^
    |
    = note: to remove this lint, add the missing `else` or add a new line before the next block
-   = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::suspicious_else_formatting)]`
+   = note: `-D clippy::possible-missing-else` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::possible_missing_else)]`
 
 error: this looks like an `else if` but the `else` is missing
   --> tests/ui/suspicious_else_formatting.rs:27:6
@@ -41,6 +41,8 @@ LL | |     {
    | |____^
    |
    = note: to remove this lint, remove the `else` or remove the new line between `else` and `{..}`
+   = note: `-D clippy::suspicious-else-formatting` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::suspicious_else_formatting)]`
 
 error: this is an `else if` but the formatting might hide it
   --> tests/ui/suspicious_else_formatting.rs:67:6
diff --git a/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.rs b/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.rs
index e7e01248dfb..65f67df7913 100644
--- a/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.rs
@@ -1,5 +1,6 @@
 //@no-rustfix
 
+#![allow(clippy::duplicated_attributes)]
 #![warn(clippy::unnecessary_clippy_cfg)]
 #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
@@ -7,7 +8,6 @@
 //~^ unnecessary_clippy_cfg
 #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
-//~| duplicated_attributes
 #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
 
@@ -17,7 +17,6 @@
 //~^ unnecessary_clippy_cfg
 #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
-//~| duplicated_attributes
 #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
 //~^ unnecessary_clippy_cfg
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.stderr b/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.stderr
index f66c6894954..4f638d5c513 100644
--- a/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_clippy_cfg.stderr
@@ -1,5 +1,5 @@
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:4:1
+  --> tests/ui/unnecessary_clippy_cfg.rs:5:1
    |
 LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#![deny(clippy::non_minimal_cfg)]`
@@ -8,7 +8,7 @@ LL | #![cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_clippy_cfg)]`
 
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:6:37
+  --> tests/ui/unnecessary_clippy_cfg.rs:7:37
    |
 LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    = note: write instead: `#![deny(clippy::non_minimal_cfg)]`
 
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:8:37
+  --> tests/ui/unnecessary_clippy_cfg.rs:9:37
    |
 LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -52,46 +52,10 @@ LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
    = note: write instead: `#[deny(clippy::non_minimal_cfg)]`
 
 error: no need to put clippy lints behind a `clippy` cfg
-  --> tests/ui/unnecessary_clippy_cfg.rs:21:1
+  --> tests/ui/unnecessary_clippy_cfg.rs:20:1
    |
 LL | #[cfg_attr(clippy, deny(clippy::non_minimal_cfg))]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `#[deny(clippy::non_minimal_cfg)]`
 
-error: duplicated attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:8:26
-   |
-LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                          ^^^^^^^^^
-   |
-note: first defined here
-  --> tests/ui/unnecessary_clippy_cfg.rs:6:26
-   |
-LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                          ^^^^^^^^^
-help: remove this attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:8:26
-   |
-LL | #![cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                          ^^^^^^^^^
-   = note: `-D clippy::duplicated-attributes` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
-
-error: duplicated attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:18:25
-   |
-LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                         ^^^^^^^^^
-   |
-note: first defined here
-  --> tests/ui/unnecessary_clippy_cfg.rs:16:25
-   |
-LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                         ^^^^^^^^^
-help: remove this attribute
-  --> tests/ui/unnecessary_clippy_cfg.rs:18:25
-   |
-LL | #[cfg_attr(clippy, deny(dead_code, clippy::non_minimal_cfg))]
-   |                         ^^^^^^^^^
-
-error: aborting due to 10 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
index 3109c4af8e2..10552431d65 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
@@ -131,6 +131,26 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
     x && y
 }
 
+fn issue14714() {
+    assert!(Some("test") == Some("test"));
+    //~^ unnecessary_map_or
+
+    // even though we're in a macro context, we still need to parenthesise because of the `then`
+    assert!((Some("test") == Some("test")).then(|| 1).is_some());
+    //~^ unnecessary_map_or
+
+    // method lints don't fire on macros
+    macro_rules! m {
+        ($x:expr) => {
+            // should become !($x == Some(1))
+            let _ = !$x.map_or(false, |v| v == 1);
+            // should become $x == Some(1)
+            let _ = $x.map_or(false, |v| v == 1);
+        };
+    }
+    m!(Some(5));
+}
+
 fn issue15180() {
     let s = std::sync::Mutex::new(Some("foo"));
     _ = s.lock().unwrap().is_some_and(|s| s == "foo");
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.rs b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
index 52a55f9fc9e..4b406ec2998 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
@@ -135,6 +135,26 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
     x && y
 }
 
+fn issue14714() {
+    assert!(Some("test").map_or(false, |x| x == "test"));
+    //~^ unnecessary_map_or
+
+    // even though we're in a macro context, we still need to parenthesise because of the `then`
+    assert!(Some("test").map_or(false, |x| x == "test").then(|| 1).is_some());
+    //~^ unnecessary_map_or
+
+    // method lints don't fire on macros
+    macro_rules! m {
+        ($x:expr) => {
+            // should become !($x == Some(1))
+            let _ = !$x.map_or(false, |v| v == 1);
+            // should become $x == Some(1)
+            let _ = $x.map_or(false, |v| v == 1);
+        };
+    }
+    m!(Some(5));
+}
+
 fn issue15180() {
     let s = std::sync::Mutex::new(Some("foo"));
     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
index 99e17e8b34b..b8a22346c37 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
@@ -327,7 +327,31 @@ LL +     let y = b.is_none_or(|b| b == *s);
    |
 
 error: this `map_or` can be simplified
-  --> tests/ui/unnecessary_map_or.rs:140:9
+  --> tests/ui/unnecessary_map_or.rs:139:13
+   |
+LL |     assert!(Some("test").map_or(false, |x| x == "test"));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     assert!(Some("test").map_or(false, |x| x == "test"));
+LL +     assert!(Some("test") == Some("test"));
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:143:13
+   |
+LL |     assert!(Some("test").map_or(false, |x| x == "test").then(|| 1).is_some());
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use a standard comparison instead
+   |
+LL -     assert!(Some("test").map_or(false, |x| x == "test").then(|| 1).is_some());
+LL +     assert!((Some("test") == Some("test")).then(|| 1).is_some());
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:160:9
    |
 LL |     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -339,7 +363,7 @@ LL +     _ = s.lock().unwrap().is_some_and(|s| s == "foo");
    |
 
 error: this `map_or` can be simplified
-  --> tests/ui/unnecessary_map_or.rs:144:9
+  --> tests/ui/unnecessary_map_or.rs:164:9
    |
 LL |     _ = s.map_or(false, |s| s == "foo");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -350,5 +374,5 @@ LL -     _ = s.map_or(false, |s| s == "foo");
 LL +     _ = s.is_some_and(|s| s == "foo");
    |
 
-error: aborting due to 28 previous errors
+error: aborting due to 30 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr b/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
index 9a38d3746da..a066554037f 100644
--- a/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_sort_by.stderr
@@ -7,7 +7,7 @@ LL |     vec.sort_by(|a, b| a.cmp(b));
    = 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`
+error: consider using `sort_unstable`
   --> tests/ui/unnecessary_sort_by.rs:14:5
    |
 LL |     vec.sort_unstable_by(|a, b| a.cmp(b));
@@ -19,7 +19,7 @@ error: consider using `sort_by_key`
 LL |     vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (a + 5).abs())`
 
-error: consider using `sort_by_key`
+error: consider using `sort_unstable_by_key`
   --> tests/ui/unnecessary_sort_by.rs:18:5
    |
 LL |     vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b)));
@@ -31,7 +31,7 @@ error: consider using `sort_by_key`
 LL |     vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()))`
 
-error: consider using `sort_by_key`
+error: consider using `sort_unstable_by_key`
   --> tests/ui/unnecessary_sort_by.rs:24:5
    |
 LL |     vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a)));
@@ -43,7 +43,7 @@ error: consider using `sort_by_key`
 LL |     vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (***a).abs())`
 
-error: consider using `sort_by_key`
+error: consider using `sort_unstable_by_key`
   --> tests/ui/unnecessary_sort_by.rs:37:5
    |
 LL |     vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));
@@ -55,7 +55,7 @@ error: consider using `sort_by_key`
 LL |         args.sort_by(|a, b| a.name().cmp(&b.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|a| a.name())`
 
-error: consider using `sort_by_key`
+error: consider using `sort_unstable_by_key`
   --> tests/ui/unnecessary_sort_by.rs:99:9
    |
 LL |         args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));
@@ -67,7 +67,7 @@ error: consider using `sort_by_key`
 LL |         args.sort_by(|a, b| b.name().cmp(&a.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|b| std::cmp::Reverse(b.name()))`
 
-error: consider using `sort_by_key`
+error: consider using `sort_unstable_by_key`
   --> tests/ui/unnecessary_sort_by.rs:104:9
    |
 LL |         args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index a62b6269a3b..805baf2af6d 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -54,7 +54,6 @@ contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIB
 users_on_vacation = [
     "matthiaskrgr",
     "Manishearth",
-    "samueltardieu",
 ]
 
 [assign.owners]
diff --git a/src/tools/clippy/util/gh-pages/index_template.html b/src/tools/clippy/util/gh-pages/index_template.html
index 5d65ea585df..d34ff0a5973 100644
--- a/src/tools/clippy/util/gh-pages/index_template.html
+++ b/src/tools/clippy/util/gh-pages/index_template.html
@@ -14,7 +14,6 @@ Otherwise, have a great day =^.^=
 
     <title>Clippy Lints</title> {# #}
 
-    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css"/> {# #}
     <link id="githubLightHighlight" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github.min.css" disabled="true" /> {# #}
     <link id="githubDarkHighlight" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.6.0/styles/github-dark.min.css" disabled="true" /> {# #}
 
@@ -49,7 +48,7 @@ Otherwise, have a great day =^.^=
     <script src="theme.js"></script> {# #}
 
     <div class="container"> {# #}
-        <h1 class="page-header">Clippy Lints <span id="lint-count" class="badge"></span></h1> {# #}
+        <h1 class="page-header">Clippy Lints <span class="badge">Total number: {{+ count }}</span></h1> {# #}
 
         <noscript> {# #}
             <div class="alert alert-danger" role="alert"> {# #}
@@ -59,9 +58,9 @@ Otherwise, have a great day =^.^=
 
         <div id="menu-filters"> {# #}
             <div class="panel-body row"> {# #}
-                <div id="upper-filters" class="col-12 col-md-5"> {# #}
-                    <div class="btn-group" id="lint-levels" tabindex="-1"> {# #}
-                        <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+                <div id="upper-filters"> {# #}
+                    <div id="lint-levels" tabindex="-1"> {# #}
+                        <button type="button" class="btn-default dropdown-toggle"> {# #}
                             Lint levels <span class="badge">4</span> <span class="caret"></span> {# #}
                         </button> {# #}
                         <ul class="dropdown-menu" id="lint-levels-selector"> {# #}
@@ -74,8 +73,8 @@ Otherwise, have a great day =^.^=
                             <li role="separator" class="divider"></li> {# #}
                         </ul> {# #}
                     </div> {# #}
-                    <div class="btn-group" id="lint-groups" tabindex="-1"> {# #}
-                        <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+                    <div id="lint-groups" tabindex="-1"> {# #}
+                        <button type="button" class="btn-default dropdown-toggle"> {# #}
                             Lint groups <span class="badge">9</span> <span class="caret"></span> {# #}
                         </button> {# #}
                         <ul class="dropdown-menu" id="lint-groups-selector"> {# #}
@@ -91,8 +90,8 @@ Otherwise, have a great day =^.^=
                             <li role="separator" class="divider"></li> {# #}
                         </ul> {# #}
                     </div> {# #}
-                    <div class="btn-group" id="version-filter" tabindex="-1"> {# #}
-                        <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+                    <div id="version-filter" tabindex="-1"> {# #}
+                        <button type="button" class="btn-default dropdown-toggle"> {# #}
                             Version {#+ #}
                             <span id="version-filter-count" class="badge">0</span> {#+ #}
                             <span class="caret"></span> {# #}
@@ -104,8 +103,8 @@ Otherwise, have a great day =^.^=
                             <li role="separator" class="divider"></li> {# #}
                         </ul> {# #}
                     </div> {# #}
-                    <div class="btn-group" id="lint-applicabilities" tabindex="-1"> {# #}
-                        <button type="button" class="btn btn-default dropdown-toggle"> {# #}
+                    <div id="lint-applicabilities" tabindex="-1"> {# #}
+                        <button type="button" class="btn-default dropdown-toggle"> {# #}
                             Applicability {#+ #}
                             <span class="badge">4</span> {#+ #}
                             <span class="caret"></span> {# #}
@@ -121,22 +120,20 @@ Otherwise, have a great day =^.^=
                         </ul> {# #}
                     </div> {# #}
                 </div> {# #}
-                <div class="col-12 col-md-5 search-control"> {# #}
+                <div class="search-control"> {# #}
                     <div class="input-group"> {# #}
                         <label class="input-group-addon" id="filter-label" for="search-input">Filter:</label> {# #}
                         <input type="text" class="form-control filter-input" placeholder="Keywords or search string (`S` or `/` to focus)" id="search-input" /> {# #}
-                        <span class="input-group-btn"> {# #}
-                            <button class="filter-clear btn" type="button" onclick="searchState.clearInput(event)"> {# #}
-                                Clear {# #}
-                            </button> {# #}
-                        </span> {# #}
+                        <button class="filter-clear" type="button" onclick="searchState.clearInput(event)"> {# #}
+                            Clear {# #}
+                        </button> {# #}
                     </div> {# #}
                 </div> {# #}
-                <div class="col-12 col-md-2 btn-group expansion-group"> {# #}
-                    <button title="Collapse All" class="btn btn-default expansion-control" type="button" id="collapse-all"> {# #}
+                <div class="btn-group expansion-group"> {# #}
+                    <button title="Collapse All" class="btn-default expansion-control" type="button" id="collapse-all"> {# #}
                         <span class="glyphicon glyphicon-collapse-up"></span> {# #}
                     </button> {# #}
-                    <button title="Expand All" class="btn btn-default expansion-control" type="button" id="expand-all"> {# #}
+                    <button title="Expand All" class="btn-default expansion-control" type="button" id="expand-all"> {# #}
                         <span class="glyphicon glyphicon-collapse-down"></span> {# #}
                     </button> {# #}
                 </div> {# #}
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index d3204967531..2b6ee67c37d 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -208,6 +208,7 @@ const LEVEL_FILTERS_DEFAULT = {
     allow: true,
     warn: true,
     deny: true,
+    none: true,
 };
 const APPLICABILITIES_FILTER_DEFAULT = {
     Unspecified: true,
@@ -592,20 +593,8 @@ disableShortcutsButton.checked = disableShortcuts;
 
 addListeners();
 highlightLazily();
-
-function updateLintCount() {
-    const allLints = filters.getAllLints().filter(lint => lint.group != "deprecated");
-    const totalLints = allLints.length;
-
-    const countElement = document.getElementById("lint-count");
-    if (countElement) {
-        countElement.innerText = `Total number: ${totalLints}`;
-    }
-}
-
 generateSettings();
 generateSearch();
 parseURLFilters();
 scrollToLintByURL();
 filters.filterLints();
-updateLintCount();
diff --git a/src/tools/clippy/util/gh-pages/style.css b/src/tools/clippy/util/gh-pages/style.css
index 66abf4598b0..2cf93b2a71d 100644
--- a/src/tools/clippy/util/gh-pages/style.css
+++ b/src/tools/clippy/util/gh-pages/style.css
@@ -1,13 +1,73 @@
+body {
+    --icon-filter: initial;
+}
+
+body.ayu {
+    --icon-filter: invert(100%);
+}
+
+* {
+    box-sizing: border-box;
+}
+
 blockquote { font-size: 1em; }
 
+h1, h2, h3, h4, h5, h6 {
+    font-family: inherit;
+    font-weight: 500;
+    line-height: 1.1;
+    color: inherit;
+}
+h1 {
+    font-size: 36px;
+}
+
+a {
+    color: #337ab7;
+    text-decoration: none;
+}
+
+button {
+    cursor: pointer;
+    margin: 0;
+    font-family: inherit;
+    font-size: inherit;
+    line-height: inherit;
+}
+
+label {
+    display: inline-block;
+    max-width: 100%;
+}
+
 .dropdown-menu {
     color: var(--fg);
     background: var(--theme-popup-bg);
     border: 1px solid var(--theme-popup-border);
+    border-radius: 4px;
+    position: absolute;
+    top: 100%;
+    left: 0;
+    z-index: 1000;
+    display: none;
+    float: left;
+    min-width: 160px;
+    padding: 5px 0;
+    margin: 2px 0 0;
+    font-size: 14px;
+    text-align: left;
+    list-style: none;
+    box-shadow: 0 6px 12px rgba(0,0,0,.175);
+}
+.open > .dropdown-menu {
+  display: block;
 }
 
 .dropdown-menu .divider {
     background-color: var(--theme-popup-border);
+    height: 1px;
+    margin: 9px 0;
+    overflow: hidden;
 }
 
 .dropdown-menu .checkbox {
@@ -30,18 +90,49 @@ blockquote { font-size: 1em; }
     background-color: var(--theme-hover);
 }
 
+.checkbox label {
+    min-height: 20px;
+    margin-bottom: 0;
+    font-weight: 400;
+    cursor: pointer;
+}
+
+.text-capitalize {
+    text-transform: capitalize;
+}
+
+.container {
+    padding-right: 15px;
+    padding-left: 15px;
+    margin-right: auto;
+    margin-left: auto;
+}
+.container::before {
+    display: table;
+    content: " ";
+}
 .container > * {
-  margin-bottom: 20px;
-  border-radius: 4px;
-  background: var(--bg);
-  border: 1px solid var(--theme-popup-border);
-  box-shadow: 0 1px 1px rgba(0,0,0,.05);
+    margin-bottom: 20px;
+    border-radius: 4px;
+    background: var(--bg);
+    border: 1px solid var(--theme-popup-border);
+    box-shadow: 0 1px 1px rgba(0,0,0,.05);
 }
 
+div.panel-body {
+    padding: 15px;
+}
+div.panel-body::before, div.panel-body::after {
+    display: table;
+    content: " ";
+}
+div.panel-body::after {
+    clear: both;
+}
 div.panel-body button {
     background: var(--searchbar-bg);
-    color: var(--searchbar-fg);
     border-color: var(--theme-popup-border);
+    color: var(--searchbar-fg);
 }
 
 div.panel-body button:hover {
@@ -52,9 +143,79 @@ div.panel-body  button.open {
     filter: brightness(90%);
 }
 
-.dropdown-toggle .badge {
+.row {
+    margin-right: -15px;
+    margin-left: -15px;
+}
+
+#upper-filters {
+    position: relative;
+    min-height: 1px;
+    padding-right: 15px;
+    padding-left: 15px;
+}
+
+#upper-filters > * {
+    position: relative;
+}
+
+.btn-group {
+    position: relative;
+    display: inline-block;
+}
+button {
+    display: inline-block;
+    padding: 6px 12px;
+    margin-bottom: 0;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 1.42857143;
+    text-align: center;
+    white-space: nowrap;
+    vertical-align: middle;
+    touch-action: manipulation;
+    cursor: pointer;
+    user-select: none;
+    border: 1px solid transparent;
+    border-radius: 4px;
+}
+button:hover {
+    text-decoration: none;
+}
+.badge {
+    color: #fff;
+    position: relative;
+    top: -1px;
+    display: inline-block;
+    min-width: 10px;
+    padding: 3px 7px;
+    font-size: 12px;
+    font-weight: 700;
+    line-height: 1;
+    text-align: center;
+    white-space: nowrap;
+    vertical-align: middle;
+    border-radius: 10px;
     background-color: #777;
 }
+.btn-default:hover {
+    color: #333;
+    background-color: #e6e6e6;
+    border-color: #adadad;
+}
+.btn-default .badge {
+    color: #fff;
+}
+button .caret {
+    display: inline-block;
+    width: 0;
+    height: 0;
+    margin-left: 0;
+    vertical-align: middle;
+    border-top: 4px dashed;
+    border-right: 4px solid transparent;
+    border-left: 4px solid transparent;
+}
 
 .lint-title {
     cursor: pointer;
@@ -81,12 +242,93 @@ article:hover .panel-title-name .anchor { display: inline;}
 
 .search-control {
     margin-top: 15px;
+    position: relative;
+    min-height: 1px;
+    padding-right: 15px;
+    padding-left: 15px;
 }
 
-@media (min-width: 992px) {
-    .search-control {
-        margin-top: 0;
-    }
+.input-group {
+    position: relative;
+    display: flex;
+}
+.input-group > :last-child {
+    border-left: 0;
+}
+.input-group > :first-child, .btn-group > :first-child {
+    border-right: 0;
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+}
+.input-group > :last-child, .btn-group > :last-child {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+}
+.input-group .form-control:not(:first-child):not(:last-child) {
+    border-radius: 0;
+}
+.form-control:focus {
+    border-color: #66afe9;
+    outline: 0;
+    box-shadow: inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);
+}
+.input-group-addon {
+    padding: 6px 12px;
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 1;
+    text-align: center;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+    white-space: nowrap;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.glyphicon.glyphicon-collapse-up::before, .glyphicon.glyphicon-collapse-down::before {
+    --background-img-size: 14px;
+    background-repeat: no-repeat;
+    background-size: var(--background-img-size);
+    height: calc(var(--background-img-size) + 6px);
+    display: block;
+    background-position: 50%;
+    content: "";
+    filter: var(--icon-filter);
+}
+.glyphicon.glyphicon-collapse-up:hover::before, .glyphicon.glyphicon-collapse-down:hover::before {
+    filter: initial;
+}
+.glyphicon.glyphicon-collapse-up::before {
+    /* Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -
+       https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc. */
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 \
+        448 512"><path d="M64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l320 0c8.8 0 16-7.2 \
+        16-16l0-320c0-8.8-7.2-16-16-16L64 80zM0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 \
+        64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zm224 64c6.7 0 13 2.8 17.6 \
+        7.7l104 112c6.5 7 8.2 17.2 4.4 25.9s-12.5 14.4-22 14.4l-208 0c-9.5 0-18.2-5.7-22-14.4s-2.\
+        1-18.9 4.4-25.9l104-112c4.5-4.9 10.9-7.7 17.6-7.7z"/></svg>');
+}
+.glyphicon.glyphicon-collapse-down::before {
+    /* Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License -
+       https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc. */
+    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
+        viewBox="0 0 448 512"><path d="M384 432c8.8 0 16-7.2 16-16l0-320c0-8.8-7.2-16-16-16L64 \
+        80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l320 0zm64-16c0 35.3-28.7 64-64 64L64 \
+        480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 320zM224 \
+        352c-6.7 0-13-2.8-17.6-7.7l-104-112c-6.5-7-8.2-17.2-4.4-25.9s12.5-14.4 22-14.4l208 0c9.5 0 \
+        18.2 5.7 22 14.4s2.1 18.9-4.4 25.9l-104 112c-4.5 4.9-10.9 7.7-17.6 7.7z"/></svg>');
+}
+
+.expansion-group {
+    margin-top: 15px;
+    padding: 0px 8px;
+    display: flex;
+    flex-wrap: nowrap;
+}
+
+.expansion-control {
+    width: 50%;
 }
 
 @media (min-width: 405px) {
@@ -96,6 +338,38 @@ article:hover .panel-title-name .anchor { display: inline;}
     }
 }
 
+@media (min-width: 768px) {
+    .container {
+        width: 750px;
+    }
+}
+
+@media (min-width: 992px) {
+    .search-control {
+        margin-top: 0;
+    }
+    .container {
+        width: 970px;
+    }
+    #upper-filters, .search-control, .expansion-group {
+        float: left;
+    }
+    #upper-filters, .search-control {
+        width: 41.66666667%;
+    }
+    .expansion-group {
+        margin-top: 0;
+        padding: 0px 15px;
+        width: 16.66666667%;
+    }
+}
+
+@media (min-width: 1200px) {
+    .container {
+        width: 1170px;
+    }
+}
+
 @media (max-width: 430px) {
     /* Turn the version filter list to the left */
     #version-filter-selector {
@@ -113,8 +387,20 @@ article:hover .panel-title-name .anchor { display: inline;}
 }
 
 .label {
-    padding-top: 0.3em;
-    padding-bottom: 0.3em;
+    padding: 0.3em 0.6em;
+    font-size: 75%;
+    font-weight: 700;
+    line-height: 1;
+    color: #fff;
+    text-align: center;
+    white-space: nowrap;
+    vertical-align: baseline;
+    border-radius: .25em;
+    text-decoration: none;
+}
+
+.label-default {
+    background-color: #777;
 }
 
 .lint-level {
@@ -207,11 +493,6 @@ article:hover .panel-title-name .anchor { display: inline;}
     font-family: monospace;
 }
 
-details {
-    border-radius: 4px;
-    padding: .5em .5em 0;
-}
-
 pre {
     padding: 0;
 }
@@ -223,10 +504,6 @@ summary {
     display: revert;
 }
 
-details[open] {
-    padding: .5em;
-}
-
 /* Expanding the mdBook theme*/
 .light, body:not([class]) {
     --inline-code-bg: #f6f7f6;
@@ -307,13 +584,13 @@ L4.75,12h2.5l0.5393066-2.1572876  c0.2276001-0.1062012,0.4459839-0.2269287,0.649
 -0.3701782l2.1323853,0.6099854l1.25-2.1650391L10.2133789,6.362915  C10.2238159,6.241333,\
 10.25,6.1243286,10.25,6z M6,7.5C5.1715698,7.5,4.5,6.8284302,4.5,6S5.1715698,4.5,6,4.5S7.5\
 ,5.1715698,7.5,6  S6.8284302,7.5,6,7.5z" fill="black"/></svg>');
-  width: 18px;
-  height: 18px;
-  display: block;
-  filter: invert(0.7);
-  position: absolute;
-  top: 4px;
-  left: 5px;
+    width: 18px;
+    height: 18px;
+    display: block;
+    filter: invert(0.7);
+    position: absolute;
+    top: 4px;
+    left: 5px;
 }
 
 .settings-menu * {
@@ -350,6 +627,7 @@ L4.75,12h2.5l0.5393066-2.1572876  c0.2276001-0.1062012,0.4459839-0.2269287,0.649
     border-bottom: 1px solid var(--theme-popup-border);
     padding-bottom: 19px;
     border-radius: 0;
+    margin: 40px 0 20px;
 }
 pre, hr {
     background: var(--bg);
@@ -401,7 +679,16 @@ ul.dropdown-menu li.checkbox > button:hover {
 .filter-input {
     background: var(--searchbar-bg);
     color: var(--searchbar-fg);
-    border-color: var(--theme-popup-border);
+    position: relative;
+    width: 100%;
+    margin-bottom: 0;
+    height: 34px;
+    padding: 6px 12px;
+    font-size: 14px;
+    line-height: 1.42857143;
+    border: 1px solid var(--theme-popup-border);
+    box-shadow: inset 0 1px 1px rgba(0,0,0,.075);
+    transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
 }
 
 .filter-input::-webkit-input-placeholder,
@@ -410,24 +697,6 @@ ul.dropdown-menu li.checkbox > button:hover {
     opacity: 30%;
 }
 
-.expansion-group {
-    margin-top: 15px;
-    padding: 0px 8px;
-    display: flex;
-    flex-wrap: nowrap;
-}
-
-@media (min-width: 992px) {
-    .expansion-group {
-        margin-top: 0;
-        padding: 0px 15px;
-    }
-}
-
-.expansion-control {
-    width: 50%;
-}
-
 :not(pre) > code {
     color: var(--inline-code-color);
     background-color: var(--inline-code-bg);
@@ -438,6 +707,10 @@ html {
 body {
     background: var(--bg);
     color: var(--fg);
+    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
+    font-size: 14px;
+    line-height: 1.42857143;
+    margin: 0;
 }
 
 article > label {