about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2024-03-07 17:19:29 +0100
committerPhilipp Krones <hello@philkrones.com>2024-03-07 17:19:29 +0100
commit73f7e79a3ba557b8f921cf29d651ec272eb4de48 (patch)
treeb3e8f32aac078881815dc734ceaa4f87f276b153
parent52f8aec14c616387c5f793687f2d9026de6c78ca (diff)
parent93f0a9a91f58c9b2153868f458402155fb6265bb (diff)
downloadrust-73f7e79a3ba557b8f921cf29d651ec272eb4de48.tar.gz
rust-73f7e79a3ba557b8f921cf29d651ec272eb4de48.zip
Merge commit '93f0a9a91f58c9b2153868f458402155fb6265bb' into clippy-subtree-update
-rwxr-xr-xsrc/tools/clippy/.github/driver.sh4
-rw-r--r--src/tools/clippy/.github/workflows/clippy.yml11
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml32
-rw-r--r--src/tools/clippy/CHANGELOG.md112
-rw-r--r--src/tools/clippy/book/src/development/trait_checking.md50
-rw-r--r--src/tools/clippy/book/src/development/type_checking.md16
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md826
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs6
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_config/src/metadata.rs4
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs322
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs1210
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs87
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs52
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/inline_always.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs51
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs588
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs49
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs54
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs70
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs73
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/utils.rs87
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/markdown.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/let_underscore.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/identity_op.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs205
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_field_names.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs67
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/vec_box.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs1
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/main.rs9
-rw-r--r--src/tools/clippy/tests/compile-test.rs1
-rw-r--r--src/tools/clippy/tests/missing-test-files.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.rs1
-rw-r--r--src/tools/clippy/tests/ui-internal/custom_ice_message.stderr7
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.rs15
-rw-r--r--src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr74
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr94
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs7
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.fixed222
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.rs222
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.stderr107
-rw-r--r--src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs2
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed26
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs26
-rw-r--r--src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr14
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed5
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.stderr13
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_9473.fixed9
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_9473.rs9
-rw-r--r--src/tools/clippy/tests/ui/doc/issue_9473.stderr15
-rw-r--r--src/tools/clippy/tests/ui/else_if_without_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/else_if_without_else.stderr4
-rw-r--r--src/tools/clippy/tests/ui/empty_docs.rs2
-rw-r--r--src/tools/clippy/tests/ui/empty_docs.stderr18
-rw-r--r--src/tools/clippy/tests/ui/entry.fixed11
-rw-r--r--src/tools/clippy/tests/ui/entry.rs11
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.fixed2
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.rs2
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.rs1
-rw-r--r--src/tools/clippy/tests/ui/field_reassign_with_default.stderr44
-rw-r--r--src/tools/clippy/tests/ui/identity_op.fixed2
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs2
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.rs2
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr32
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_untyped.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.rs10
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.stderr68
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs58
-rw-r--r--src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr52
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.stderr76
-rw-r--r--src/tools/clippy/tests/ui/many_single_char_names.rs2
-rw-r--r--src/tools/clippy/tests/ui/many_single_char_names.stderr10
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs2
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr12
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.rs39
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.stderr30
-rw-r--r--src/tools/clippy/tests/ui/mut_mut.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_mut.stderr18
-rw-r--r--src/tools/clippy/tests/ui/no_effect_replace.rs2
-rw-r--r--src/tools/clippy/tests/ui/no_effect_replace.stderr16
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.rs1
-rw-r--r--src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr8
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.rs6
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.stderr58
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed2
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.rs2
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr26
-rw-r--r--src/tools/clippy/tests/ui/option_option.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_option.stderr26
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.fixed1
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.rs1
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.stderr66
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed10
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs10
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed17
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs17
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.fixed15
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.rs15
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.stderr15
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.fixed2
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.rs2
-rw-r--r--src/tools/clippy/tests/ui/renamed_builtin_attr.stderr2
-rw-r--r--src/tools/clippy/tests/ui/single_match.fixed2
-rw-r--r--src/tools/clippy/tests/ui/single_match.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_match.stderr36
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.fixed2
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr18
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.fixed11
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.rs9
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.stderr36
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.rs2
-rw-r--r--src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr52
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed14
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs14
-rw-r--r--src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr14
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed7
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs7
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.rs2
-rw-r--r--src/tools/clippy/tests/ui/type_complexity.stderr30
-rw-r--r--src/tools/clippy/tests/ui/unknown_attribute.rs2
-rw-r--r--src/tools/clippy/tests/ui/unknown_attribute.stderr2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.fixed6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.stderr8
155 files changed, 4114 insertions, 2401 deletions
diff --git a/src/tools/clippy/.github/driver.sh b/src/tools/clippy/.github/driver.sh
index 11fd6b5c79e..2eafdd0fbc8 100755
--- a/src/tools/clippy/.github/driver.sh
+++ b/src/tools/clippy/.github/driver.sh
@@ -50,11 +50,11 @@ diff -u normalized.stderr tests/ui/double_neg.stderr
 
 # make sure "clippy-driver --rustc --arg" and "rustc --arg" behave the same
 SYSROOT=$(rustc --print sysroot)
-diff -u <(LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver --rustc --version --verbose) <(rustc --version --verbose)
+diff -u <(./target/debug/clippy-driver --rustc --version --verbose) <(rustc --version --verbose)
 
 echo "fn main() {}" >target/driver_test.rs
 # we can't run 2 rustcs on the same file at the same time
-CLIPPY=$(LD_LIBRARY_PATH=${SYSROOT}/lib ./target/debug/clippy-driver ./target/driver_test.rs --rustc)
+CLIPPY=$(./target/debug/clippy-driver ./target/driver_test.rs --rustc)
 RUSTC=$(rustc ./target/driver_test.rs)
 diff -u <($CLIPPY) <($RUSTC)
 
diff --git a/src/tools/clippy/.github/workflows/clippy.yml b/src/tools/clippy/.github/workflows/clippy.yml
index 5ba960db66d..603f91a910b 100644
--- a/src/tools/clippy/.github/workflows/clippy.yml
+++ b/src/tools/clippy/.github/workflows/clippy.yml
@@ -44,11 +44,6 @@ jobs:
       run: rustup show active-toolchain
 
     # Run
-    - name: Set LD_LIBRARY_PATH (Linux)
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
-
     - name: Build
       run: cargo build --tests --features deny-warnings,internal
 
@@ -72,6 +67,6 @@ jobs:
       working-directory: clippy_dev
 
     - name: Test clippy-driver
-      run: bash .github/driver.sh
-      env:
-        OS: ${{ runner.os }}
+      run: |
+        TOOLCHAIN=$(rustup show active-toolchain | cut -f1 -d' ')
+        rustup run $TOOLCHAIN bash .github/driver.sh
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index 012797e5ca7..0bc28c1f9d9 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -59,7 +59,7 @@ jobs:
           host: i686-unknown-linux-gnu
         - os: windows-latest
           host: x86_64-pc-windows-msvc
-        - os: macos-latest
+        - os: macos-13
           host: x86_64-apple-darwin
 
     runs-on: ${{ matrix.os }}
@@ -87,23 +87,6 @@ jobs:
         rustup show active-toolchain
 
     # Run
-    - name: Set LD_LIBRARY_PATH (Linux)
-      if: runner.os == 'Linux'
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
-    - name: Link rustc dylib (MacOS)
-      if: runner.os == 'macOS'
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        sudo mkdir -p /usr/local/lib
-        sudo find "${SYSROOT}/lib" -maxdepth 1 -name '*dylib' -exec ln -s {} /usr/local/lib \;
-    - name: Set PATH (Windows)
-      if: runner.os == 'Windows'
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "$SYSROOT/bin" >> $GITHUB_PATH
-
     - name: Build
       run: cargo build --tests --features deny-warnings,internal
 
@@ -136,7 +119,9 @@ jobs:
       working-directory: clippy_dev
 
     - name: Test clippy-driver
-      run: bash .github/driver.sh
+      run: |
+        TOOLCHAIN=$(rustup show active-toolchain | cut -f1 -d' ')
+        rustup run $TOOLCHAIN bash .github/driver.sh
       env:
         OS: ${{ runner.os }}
 
@@ -236,11 +221,6 @@ jobs:
     - name: Install toolchain
       run: rustup show active-toolchain
 
-    - name: Set LD_LIBRARY_PATH
-      run: |
-        SYSROOT=$(rustc --print sysroot)
-        echo "LD_LIBRARY_PATH=${SYSROOT}/lib${LD_LIBRARY_PATH+:${LD_LIBRARY_PATH}}" >> $GITHUB_ENV
-
     # Download
     - name: Download target dir
       uses: actions/download-artifact@v3
@@ -254,8 +234,8 @@ jobs:
     # Run
     - name: Test ${{ matrix.integration }}
       run: |
-        RUSTUP_TOOLCHAIN="$(rustup show active-toolchain | grep -o -E "nightly-[0-9]{4}-[0-9]{2}-[0-9]{2}")" \
-          $CARGO_TARGET_DIR/debug/integration --show-output
+          TOOLCHAIN=$(rustup show active-toolchain | cut -f1 -d' ')
+          rustup run $TOOLCHAIN $CARGO_TARGET_DIR/debug/integration --show-output
       env:
         INTEGRATION: ${{ matrix.integration }}
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index f0b01742deb..d3b2c0a7bf6 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5046,6 +5046,7 @@ Released 2018-09-13
 [`assertions_on_result_states`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_result_states
 [`assign_op_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_op_pattern
 [`assign_ops`]: https://rust-lang.github.io/rust-clippy/master/index.html#assign_ops
+[`assigning_clones`]: https://rust-lang.github.io/rust-clippy/master/index.html#assigning_clones
 [`async_yields_async`]: https://rust-lang.github.io/rust-clippy/master/index.html#async_yields_async
 [`await_holding_invalid_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type
 [`await_holding_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_lock
@@ -5423,6 +5424,7 @@ Released 2018-09-13
 [`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop
 [`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_trait_methods
 [`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
+[`mixed_attributes_style`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_attributes_style
 [`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
 [`mixed_read_write_in_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_read_write_in_expression
 [`mod_module_files`]: https://rust-lang.github.io/rust-clippy/master/index.html#mod_module_files
@@ -5816,74 +5818,74 @@ Released 2018-09-13
 [`zst_offset`]: https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset
 <!-- end autogenerated links to lint list -->
 <!-- begin autogenerated links to configuration documentation -->
+[`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
+[`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
+[`accept-comment-above-attributes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-attributes
+[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement
+[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
+[`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests
+[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests
+[`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args
+[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
+[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
+[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
+[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
+[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
+[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
+[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars
+[`allowed-scripts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-scripts
+[`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports
 [`arithmetic-side-effects-allowed`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed
 [`arithmetic-side-effects-allowed-binary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-binary
 [`arithmetic-side-effects-allowed-unary`]: https://doc.rust-lang.org/clippy/lint_configuration.html#arithmetic-side-effects-allowed-unary
+[`array-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#array-size-threshold
 [`avoid-breaking-exported-api`]: https://doc.rust-lang.org/clippy/lint_configuration.html#avoid-breaking-exported-api
-[`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv
+[`await-holding-invalid-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#await-holding-invalid-types
+[`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish
+[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
 [`cognitive-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cognitive-complexity-threshold
-[`excessive-nesting-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#excessive-nesting-threshold
+[`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros
+[`disallowed-methods`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-methods
 [`disallowed-names`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-names
-[`semicolon-inside-block-ignore-singleline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-inside-block-ignore-singleline
-[`semicolon-outside-block-ignore-multiline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-outside-block-ignore-multiline
+[`disallowed-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-types
 [`doc-valid-idents`]: https://doc.rust-lang.org/clippy/lint_configuration.html#doc-valid-idents
-[`too-many-arguments-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-arguments-threshold
-[`type-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#type-complexity-threshold
-[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold
-[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack
+[`enable-raw-pointer-heuristic-for-send`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enable-raw-pointer-heuristic-for-send
+[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
+[`enforced-import-renames`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforced-import-renames
 [`enum-variant-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-name-threshold
-[`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold
 [`enum-variant-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enum-variant-size-threshold
-[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold
+[`excessive-nesting-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#excessive-nesting-threshold
+[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold
+[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability
+[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold
 [`literal-representation-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#literal-representation-threshold
-[`trivial-copy-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trivial-copy-size-limit
+[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else
+[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools
+[`max-include-file-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-include-file-size
+[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools
+[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length
+[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds
+[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
+[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
+[`msrv`]: https://doc.rust-lang.org/clippy/lint_configuration.html#msrv
 [`pass-by-value-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pass-by-value-size-limit
-[`too-many-lines-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-lines-threshold
-[`array-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#array-size-threshold
+[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
+[`semicolon-inside-block-ignore-singleline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-inside-block-ignore-singleline
+[`semicolon-outside-block-ignore-multiline`]: https://doc.rust-lang.org/clippy/lint_configuration.html#semicolon-outside-block-ignore-multiline
+[`single-char-binding-names-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#single-char-binding-names-threshold
 [`stack-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#stack-size-threshold
-[`vec-box-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#vec-box-size-threshold
-[`max-trait-bounds`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-trait-bounds
-[`max-struct-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-struct-bools
-[`max-fn-params-bools`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-fn-params-bools
-[`warn-on-all-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#warn-on-all-wildcard-imports
-[`disallowed-macros`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-macros
-[`disallowed-methods`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-methods
-[`disallowed-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#disallowed-types
-[`unreadable-literal-lint-fractions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unreadable-literal-lint-fractions
-[`upper-case-acronyms-aggressive`]: https://doc.rust-lang.org/clippy/lint_configuration.html#upper-case-acronyms-aggressive
-[`matches-for-let-else`]: https://doc.rust-lang.org/clippy/lint_configuration.html#matches-for-let-else
-[`cargo-ignore-publish`]: https://doc.rust-lang.org/clippy/lint_configuration.html#cargo-ignore-publish
 [`standard-macro-braces`]: https://doc.rust-lang.org/clippy/lint_configuration.html#standard-macro-braces
-[`enforced-import-renames`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforced-import-renames
-[`allowed-scripts`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-scripts
-[`enable-raw-pointer-heuristic-for-send`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enable-raw-pointer-heuristic-for-send
-[`max-suggested-slice-pattern-length`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-suggested-slice-pattern-length
-[`await-holding-invalid-types`]: https://doc.rust-lang.org/clippy/lint_configuration.html#await-holding-invalid-types
-[`max-include-file-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#max-include-file-size
-[`allow-expect-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-expect-in-tests
-[`allow-unwrap-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-unwrap-in-tests
-[`allow-dbg-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-dbg-in-tests
-[`allow-print-in-tests`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-print-in-tests
-[`large-error-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#large-error-threshold
-[`ignore-interior-mutability`]: https://doc.rust-lang.org/clippy/lint_configuration.html#ignore-interior-mutability
-[`allow-mixed-uninlined-format-args`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-mixed-uninlined-format-args
+[`struct-field-name-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#struct-field-name-threshold
 [`suppress-restriction-lint-in-const`]: https://doc.rust-lang.org/clippy/lint_configuration.html#suppress-restriction-lint-in-const
-[`missing-docs-in-crate-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#missing-docs-in-crate-items
-[`future-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#future-size-threshold
+[`too-large-for-stack`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-large-for-stack
+[`too-many-arguments-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-arguments-threshold
+[`too-many-lines-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#too-many-lines-threshold
+[`trivial-copy-size-limit`]: https://doc.rust-lang.org/clippy/lint_configuration.html#trivial-copy-size-limit
+[`type-complexity-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#type-complexity-threshold
 [`unnecessary-box-size`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unnecessary-box-size
-[`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception
-[`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars
-[`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold
-[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement
-[`accept-comment-above-attributes`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-attributes
-[`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
-[`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
-[`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
-[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
-[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
-[`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
-[`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
-[`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
-[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
-[`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports
+[`unreadable-literal-lint-fractions`]: https://doc.rust-lang.org/clippy/lint_configuration.html#unreadable-literal-lint-fractions
+[`upper-case-acronyms-aggressive`]: https://doc.rust-lang.org/clippy/lint_configuration.html#upper-case-acronyms-aggressive
+[`vec-box-size-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#vec-box-size-threshold
+[`verbose-bit-mask-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#verbose-bit-mask-threshold
+[`warn-on-all-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#warn-on-all-wildcard-imports
 <!-- end autogenerated links to configuration documentation -->
diff --git a/src/tools/clippy/book/src/development/trait_checking.md b/src/tools/clippy/book/src/development/trait_checking.md
index fb263922cf8..b7d229ccc19 100644
--- a/src/tools/clippy/book/src/development/trait_checking.md
+++ b/src/tools/clippy/book/src/development/trait_checking.md
@@ -94,6 +94,53 @@ impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
 }
 ```
 
+## Creating Types Programmatically
+
+Traits are often generic over a type parameter, e.g. `Borrow<T>` is generic
+over `T`. Rust allows us to implement a trait for a specific type. For example,
+we can implement `Borrow<[u8]>` for a hypothetical type `Foo`. Let's suppose
+that we would like to find whether our type actually implements `Borrow<[u8]>`.
+
+To do so, we can use the same `implements_trait` function as above, and supply
+a type parameter that represents `[u8]`. Since `[u8]` is a specialization of
+`[T]`, we can use the  [`Ty::new_slice`][new_slice] method to create a type
+that represents `[T]` and supply `u8` as a type parameter.
+To create a `ty::Ty` programmatically, we rely on `Ty::new_*` methods. These
+methods create a `TyKind` and then wrap it in a `Ty` struct. This means we
+have access to all the primitive types, such as `Ty::new_char`,
+`Ty::new_bool`, `Ty::new_int`, etc. We can also create more complex types,
+such as slices, tuples, and references out of these basic building blocks.
+
+For trait checking, it is not enough to create the types, we need to convert
+them into [GenericArg]. In rustc, a generic is an entity that the compiler
+understands and has three kinds, type, const and lifetime. By calling
+`.into()` on a constructed [Ty], we wrap the type into a generic which can
+then be used by the query system to decide whether the specialized trait
+is implemented.
+
+The following code demonstrates how to do this:
+
+```rust
+
+use rustc_middle::ty::Ty;
+use clippy_utils::ty::implements_trait;
+use rustc_span::symbol::sym;
+
+let ty = todo!("Get the `Foo` type to check for a trait implementation");
+let borrow_id = cx.tcx.get_diagnostic_item(sym::Borrow).unwrap(); // avoid unwrap in real code
+let slice_of_bytes_t = Ty::new_slice(cx.tcx, cx.tcx.types.u8);
+let generic_param = slice_of_bytes_t.into();
+if implements_trait(cx, ty, borrow_id, &[generic_param]) {
+    todo!("Rest of lint implementation")
+}
+```
+
+In essence, the [Ty] struct allows us to create types programmatically in a
+representation that can be used by the compiler and the query engine. We then
+use the `rustc_middle::Ty` of the type we are interested in, and query the
+compiler to see if it indeed implements the trait we are interested in.
+
+
 [DefId]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def_id/struct.DefId.html
 [diagnostic_items]: https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-items.html
 [lang_items]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/lang_items/struct.LanguageItems.html
@@ -102,4 +149,7 @@ impl LateLintPass<'_> for CheckTokioAsyncReadExtTrait {
 [symbol]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/symbol/struct.Symbol.html
 [symbol_index]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_span/symbol/sym/index.html
 [TyCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html
+[Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
 [rust]: https://github.com/rust-lang/rust
+[new_slice]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.new_slice
+[GenericArg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.GenericArg.html
diff --git a/src/tools/clippy/book/src/development/type_checking.md b/src/tools/clippy/book/src/development/type_checking.md
index dc29ab5d08d..136b3fd0270 100644
--- a/src/tools/clippy/book/src/development/type_checking.md
+++ b/src/tools/clippy/book/src/development/type_checking.md
@@ -123,6 +123,22 @@ the [`TypeckResults::node_type()`][node_type] method inside of bodies.
 
 > **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
 
+## Creating Types programmatically
+
+A common usecase for creating types programmatically is when we want to check if a type implements a trait (see
+[Trait Checking](trait_checking.md)).
+
+Here's an example of how to create a `Ty` for a slice of `u8`, i.e. `[u8]`
+
+```rust
+use rustc_middle::ty::Ty;
+// assume we have access to a LateContext
+let ty = Ty::new_slice(cx.tcx, Ty::new_u8());
+```
+
+In general, we rely on `Ty::new_*` methods. These methods define the basic building-blocks that the
+type-system and trait-system use to define and understand the written code.
+
 ## Useful Links
 
 Below are some useful links to further explore the concepts covered
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 214a60d3bfd..a985346b3c0 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -10,334 +10,252 @@ and lints affected.
 
 ---
 
-## `arithmetic-side-effects-allowed`
-Suppress checking of the passed type names in all types of operations.
-
-If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.
-
-#### Example
-
-```toml
-arithmetic-side-effects-allowed = ["SomeType", "AnotherType"]
-```
-
-#### Noteworthy
-
-A type, say `SomeType`, listed in this configuration has the same behavior of
-`["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
+## `absolute-paths-allowed-crates`
+Which crates to allow absolute paths from
 
 **Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
-
-
-## `arithmetic-side-effects-allowed-binary`
-Suppress checking of the passed type pair names in binary operations like addition or
-multiplication.
-
-Supports the "*" wildcard to indicate that a certain type won't trigger the lint regardless
-of the involved counterpart. For example, `["SomeType", "*"]` or `["*", "AnotherType"]`.
+* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
 
-Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the same as
-`["AnotherType", "SomeType"]`.
 
-#### Example
-
-```toml
-arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
-```
+## `absolute-paths-max-segments`
+The maximum number of segments a path can have before being linted, anything above this will
+be linted.
 
-**Default Value:** `[]`
+**Default Value:** `2`
 
 ---
 **Affected lints:**
-* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
-
-
-## `arithmetic-side-effects-allowed-unary`
-Suppress checking of the passed type names in unary operations like "negation" (`-`).
+* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
 
-#### Example
 
-```toml
-arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
-```
+## `accept-comment-above-attributes`
+Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
 
-**Default Value:** `[]`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
+* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
 
 
-## `avoid-breaking-exported-api`
-Suppress lints whenever the suggested change would cause breakage for other crates.
+## `accept-comment-above-statement`
+Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
 
 **Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
-* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
-* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
-* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps)
-* [`unused_self`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self)
-* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
-* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention)
-* [`box_collection`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection)
-* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)
-* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)
-* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
-* [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option)
-* [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist)
-* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)
-* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
-* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn)
+* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
 
 
-## `msrv`
-The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
+## `allow-comparison-to-zero`
+Don't lint when comparing the result of a modulo operation to zero.
+
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)
-* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)
-* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied)
-* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
-* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
-* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
-* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next)
-* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions)
-* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains)
-* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
-* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)
-* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive)
-* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
-* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or)
-* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro)
-* [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)
-* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)
-* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
-* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)
-* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
-* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
-* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant)
-* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr)
-* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
-* [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone)
-* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr)
-* [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits)
-* [`err_expect`](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect)
-* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned)
-* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
-* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp)
-* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
-* [`unchecked_duration_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction)
-* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace)
-* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
-* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
-* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations)
-* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
-* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range)
-* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
-* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls)
-* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check)
-* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid)
-* [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain)
-* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
-* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
-* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
-* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)
-* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
-* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)
+* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic)
 
 
-## `cognitive-complexity-threshold`
-The maximum cognitive complexity a function can have
+## `allow-dbg-in-tests`
+Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
 
-**Default Value:** `25`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity)
+* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro)
 
 
-## `excessive-nesting-threshold`
-The maximum amount of nesting a block can reside in
+## `allow-expect-in-tests`
+Whether `expect` should be allowed in test functions or `#[cfg(test)]`
 
-**Default Value:** `0`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)
+* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)
 
 
-## `disallowed-names`
-The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
-`".."` can be used as part of the list to indicate that the configured values should be appended to the
-default configuration of Clippy. By default, any configuration will replace the default value.
+## `allow-mixed-uninlined-format-args`
+Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
 
-**Default Value:** `["foo", "baz", "quux"]`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names)
+* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
 
 
-## `semicolon-inside-block-ignore-singleline`
-Whether to lint only if it's multiline.
+## `allow-one-hash-in-raw-strings`
+Whether to allow `r#""#` when `r""` can be used
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block)
+* [`unnecessary_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_raw_string_hashes)
 
 
-## `semicolon-outside-block-ignore-multiline`
-Whether to lint only if it's singleline.
+## `allow-print-in-tests`
+Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block)
+* [`print_stderr`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr)
+* [`print_stdout`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout)
 
 
-## `doc-valid-idents`
-The list of words this lint should not consider as identifiers needing ticks. The value
-`".."` can be used as part of the list to indicate, that the configured values should be appended to the
-default configuration of Clippy. By default, any configuration will replace the default value. For example:
-* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
-* `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
+## `allow-private-module-inception`
+Whether to allow module inception if it's not public.
 
-**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown)
+* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception)
 
 
-## `too-many-arguments-threshold`
-The maximum number of argument a function or method can have
+## `allow-unwrap-in-tests`
+Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
 
-**Default Value:** `7`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments)
+* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
 
 
-## `type-complexity-threshold`
-The maximum complexity a type can have
+## `allowed-dotfiles`
+Additional dotfiles (files or directories starting with a dot) to allow
 
-**Default Value:** `250`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`type_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity)
+* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
 
 
-## `single-char-binding-names-threshold`
-The maximum number of single char bindings a scope may have
+## `allowed-duplicate-crates`
+A list of crate names to allow duplicates of
 
-**Default Value:** `4`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names)
+* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
 
 
-## `too-large-for-stack`
-The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
+## `allowed-idents-below-min-chars`
+Allowed names below the minimum allowed characters. The value `".."` can be used as part of
+the list to indicate, that the configured values should be appended to the default
+configuration of Clippy. By default, any configuration will replace the default value.
 
-**Default Value:** `200`
+**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]`
 
 ---
 **Affected lints:**
-* [`boxed_local`](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local)
-* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
+* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
 
 
-## `enum-variant-name-threshold`
-The minimum number of enum variants for the lints about variant names to trigger
+## `allowed-scripts`
+The list of unicode scripts allowed to be used in the scope.
 
-**Default Value:** `3`
+**Default Value:** `["Latin"]`
 
 ---
 **Affected lints:**
-* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
+* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents)
 
 
-## `struct-field-name-threshold`
-The minimum number of struct fields for the lints about field names to trigger
+## `allowed-wildcard-imports`
+List of path segments allowed to have wildcard imports.
 
-**Default Value:** `3`
+#### Example
 
----
-**Affected lints:**
-* [`struct_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names)
+```toml
+allowed-wildcard-imports = [ "utils", "common" ]
+```
 
+#### Noteworthy
 
-## `enum-variant-size-threshold`
-The maximum size of an enum's variant to avoid box suggestion
+1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
+2. Paths with any segment that containing the word 'prelude'
+are already allowed by default.
 
-**Default Value:** `200`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant)
+* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)
 
 
-## `verbose-bit-mask-threshold`
-The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
+## `arithmetic-side-effects-allowed`
+Suppress checking of the passed type names in all types of operations.
 
-**Default Value:** `1`
+If a specific operation is desired, consider using `arithmetic_side_effects_allowed_binary` or `arithmetic_side_effects_allowed_unary` instead.
 
----
-**Affected lints:**
-* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask)
+#### Example
 
+```toml
+arithmetic-side-effects-allowed = ["SomeType", "AnotherType"]
+```
 
-## `literal-representation-threshold`
-The lower bound for linting decimal literals
+#### Noteworthy
 
-**Default Value:** `16384`
+A type, say `SomeType`, listed in this configuration has the same behavior of
+`["SomeType" , "*"], ["*", "SomeType"]` in `arithmetic_side_effects_allowed_binary`.
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation)
+* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
 
 
-## `trivial-copy-size-limit`
-The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
-reference. By default there is no limit
+## `arithmetic-side-effects-allowed-binary`
+Suppress checking of the passed type pair names in binary operations like addition or
+multiplication.
 
----
-**Affected lints:**
-* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
+Supports the "*" wildcard to indicate that a certain type won't trigger the lint regardless
+of the involved counterpart. For example, `["SomeType", "*"]` or `["*", "AnotherType"]`.
 
+Pairs are asymmetric, which means that `["SomeType", "AnotherType"]` is not the same as
+`["AnotherType", "SomeType"]`.
 
-## `pass-by-value-size-limit`
-The minimum size (in bytes) to consider a type for passing by reference instead of by value.
+#### Example
 
-**Default Value:** `256`
+```toml
+arithmetic-side-effects-allowed-binary = [["SomeType" , "f32"], ["AnotherType", "*"]]
+```
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
+* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
 
 
-## `too-many-lines-threshold`
-The maximum number of lines a function or method can have
+## `arithmetic-side-effects-allowed-unary`
+Suppress checking of the passed type names in unary operations like "negation" (`-`).
 
-**Default Value:** `100`
+#### Example
+
+```toml
+arithmetic-side-effects-allowed-unary = ["SomeType", "AnotherType"]
+```
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
+* [`arithmetic_side_effects`](https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects)
 
 
 ## `array-size-threshold`
@@ -347,68 +265,76 @@ The maximum allowed size for arrays on the stack
 
 ---
 **Affected lints:**
-* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays)
 * [`large_const_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays)
+* [`large_stack_arrays`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays)
 
 
-## `stack-size-threshold`
-The maximum allowed stack size for functions in bytes
-
-**Default Value:** `512000`
-
----
-**Affected lints:**
-* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames)
-
-
-## `vec-box-size-threshold`
-The size of the boxed type in bytes, where boxing in a `Vec` is allowed
+## `avoid-breaking-exported-api`
+Suppress lints whenever the suggested change would cause breakage for other crates.
 
-**Default Value:** `4096`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
+* [`box_collection`](https://rust-lang.github.io/rust-clippy/master/index.html#box_collection)
+* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
+* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
+* [`linkedlist`](https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist)
+* [`option_option`](https://rust-lang.github.io/rust-clippy/master/index.html#option_option)
+* [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)
+* [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)
+* [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)
+* [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn)
+* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
+* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
+* [`unnecessary_wraps`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps)
+* [`unused_self`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_self)
+* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
 * [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
+* [`wrong_self_convention`](https://rust-lang.github.io/rust-clippy/master/index.html#wrong_self_convention)
 
 
-## `max-trait-bounds`
-The maximum number of bounds a trait can have to be linted
+## `await-holding-invalid-types`
 
-**Default Value:** `3`
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
+* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type)
 
 
-## `max-struct-bools`
-The maximum number of bool fields a struct can have
+## `cargo-ignore-publish`
+For internal testing only, ignores the current `publish` settings in the Cargo manifest.
 
-**Default Value:** `3`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools)
+* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata)
 
 
-## `max-fn-params-bools`
-The maximum number of bool parameters a function can have
+## `check-private-items`
+Whether to also run the listed lints on private items.
 
-**Default Value:** `3`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools)
+* [`missing_errors_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc)
+* [`missing_panics_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc)
+* [`missing_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc)
+* [`unnecessary_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc)
 
 
-## `warn-on-all-wildcard-imports`
-Whether to allow certain wildcard imports (prelude, super in tests).
+## `cognitive-complexity-threshold`
+The maximum cognitive complexity a function can have
 
-**Default Value:** `false`
+**Default Value:** `25`
 
 ---
 **Affected lints:**
-* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)
+* [`cognitive_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#cognitive_complexity)
 
 
 ## `disallowed-macros`
@@ -431,218 +357,231 @@ The list of disallowed methods, written as fully qualified paths.
 * [`disallowed_methods`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_methods)
 
 
-## `disallowed-types`
-The list of disallowed types, written as fully qualified paths.
+## `disallowed-names`
+The list of disallowed names to lint about. NB: `bar` is not here since it has legitimate uses. The value
+`".."` can be used as part of the list to indicate that the configured values should be appended to the
+default configuration of Clippy. By default, any configuration will replace the default value.
 
-**Default Value:** `[]`
+**Default Value:** `["foo", "baz", "quux"]`
 
 ---
 **Affected lints:**
-* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types)
+* [`disallowed_names`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names)
 
 
-## `unreadable-literal-lint-fractions`
-Should the fraction of a decimal be linted to include separators.
+## `disallowed-types`
+The list of disallowed types, written as fully qualified paths.
 
-**Default Value:** `true`
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal)
+* [`disallowed_types`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types)
 
 
-## `upper-case-acronyms-aggressive`
-Enables verbose mode. Triggers if there is more than one uppercase char next to each other
+## `doc-valid-idents`
+The list of words this lint should not consider as identifiers needing ticks. The value
+`".."` can be used as part of the list to indicate, that the configured values should be appended to the
+default configuration of Clippy. By default, any configuration will replace the default value. For example:
+* `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
+* `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `false`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
-* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
+* [`doc_markdown`](https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown)
 
 
-## `matches-for-let-else`
-Whether the matches should be considered by the lint, and whether there should
-be filtering for common types.
+## `enable-raw-pointer-heuristic-for-send`
+Whether to apply the raw pointer heuristic to determine if a type is `Send`.
 
-**Default Value:** `"WellKnownTypes"`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
+* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty)
 
 
-## `cargo-ignore-publish`
-For internal testing only, ignores the current `publish` settings in the Cargo manifest.
+## `enforce-iter-loop-reborrow`
+Whether to recommend using implicit into iter for reborrowed values.
+
+#### Example
+```no_run
+let mut vec = vec![1, 2, 3];
+let rmvec = &mut vec;
+for _ in rmvec.iter() {}
+for _ in rmvec.iter_mut() {}
+```
+
+Use instead:
+```no_run
+let mut vec = vec![1, 2, 3];
+let rmvec = &mut vec;
+for _ in &*rmvec {}
+for _ in &mut *rmvec {}
+```
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`cargo_common_metadata`](https://rust-lang.github.io/rust-clippy/master/index.html#cargo_common_metadata)
-
+* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop)
 
-## `standard-macro-braces`
-Enforce the named macros always use the braces specified.
 
-A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
-could be used with a full path two `MacroMatcher`s have to be added one with the full path
-`crate_name::macro_name` and one with just the macro name.
+## `enforced-import-renames`
+The list of imports to always rename, a fully qualified path followed by the rename.
 
 **Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces)
+* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames)
 
 
-## `enforced-import-renames`
-The list of imports to always rename, a fully qualified path followed by the rename.
+## `enum-variant-name-threshold`
+The minimum number of enum variants for the lints about variant names to trigger
 
-**Default Value:** `[]`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`missing_enforced_import_renames`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames)
+* [`enum_variant_names`](https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names)
 
 
-## `allowed-scripts`
-The list of unicode scripts allowed to be used in the scope.
+## `enum-variant-size-threshold`
+The maximum size of an enum's variant to avoid box suggestion
 
-**Default Value:** `["Latin"]`
+**Default Value:** `200`
 
 ---
 **Affected lints:**
-* [`disallowed_script_idents`](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_script_idents)
+* [`large_enum_variant`](https://rust-lang.github.io/rust-clippy/master/index.html#large_enum_variant)
 
 
-## `enable-raw-pointer-heuristic-for-send`
-Whether to apply the raw pointer heuristic to determine if a type is `Send`.
+## `excessive-nesting-threshold`
+The maximum amount of nesting a block can reside in
 
-**Default Value:** `true`
+**Default Value:** `0`
 
 ---
 **Affected lints:**
-* [`non_send_fields_in_send_ty`](https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty)
+* [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)
 
 
-## `max-suggested-slice-pattern-length`
-When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in
-the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.
-For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
+## `future-size-threshold`
+The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
 
-**Default Value:** `3`
+**Default Value:** `16384`
 
 ---
 **Affected lints:**
-* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
-
+* [`large_futures`](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures)
 
-## `await-holding-invalid-types`
 
+## `ignore-interior-mutability`
+A list of paths to types that should be treated like `Arc`, i.e. ignored but
+for the generic parameters for determining interior mutability
 
-**Default Value:** `[]`
+**Default Value:** `["bytes::Bytes"]`
 
 ---
 **Affected lints:**
-* [`await_holding_invalid_type`](https://rust-lang.github.io/rust-clippy/master/index.html#await_holding_invalid_type)
+* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond)
+* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)
 
 
-## `max-include-file-size`
-The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
+## `large-error-threshold`
+The maximum size of the `Err`-variant in a `Result` returned from a function
 
-**Default Value:** `1000000`
+**Default Value:** `128`
 
 ---
 **Affected lints:**
-* [`large_include_file`](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file)
+* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)
 
 
-## `allow-expect-in-tests`
-Whether `expect` should be allowed in test functions or `#[cfg(test)]`
+## `literal-representation-threshold`
+The lower bound for linting decimal literals
 
-**Default Value:** `false`
+**Default Value:** `16384`
 
 ---
 **Affected lints:**
-* [`expect_used`](https://rust-lang.github.io/rust-clippy/master/index.html#expect_used)
+* [`decimal_literal_representation`](https://rust-lang.github.io/rust-clippy/master/index.html#decimal_literal_representation)
 
 
-## `allow-unwrap-in-tests`
-Whether `unwrap` should be allowed in test functions or `#[cfg(test)]`
+## `matches-for-let-else`
+Whether the matches should be considered by the lint, and whether there should
+be filtering for common types.
 
-**Default Value:** `false`
+**Default Value:** `"WellKnownTypes"`
 
 ---
 **Affected lints:**
-* [`unwrap_used`](https://rust-lang.github.io/rust-clippy/master/index.html#unwrap_used)
+* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
 
 
-## `allow-dbg-in-tests`
-Whether `dbg!` should be allowed in test functions or `#[cfg(test)]`
+## `max-fn-params-bools`
+The maximum number of bool parameters a function can have
 
-**Default Value:** `false`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`dbg_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#dbg_macro)
+* [`fn_params_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#fn_params_excessive_bools)
 
 
-## `allow-print-in-tests`
-Whether print macros (ex. `println!`) should be allowed in test functions or `#[cfg(test)]`
+## `max-include-file-size`
+The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
 
-**Default Value:** `false`
+**Default Value:** `1000000`
 
 ---
 **Affected lints:**
-* [`print_stdout`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stdout)
-* [`print_stderr`](https://rust-lang.github.io/rust-clippy/master/index.html#print_stderr)
+* [`large_include_file`](https://rust-lang.github.io/rust-clippy/master/index.html#large_include_file)
 
 
-## `large-error-threshold`
-The maximum size of the `Err`-variant in a `Result` returned from a function
+## `max-struct-bools`
+The maximum number of bool fields a struct can have
 
-**Default Value:** `128`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`result_large_err`](https://rust-lang.github.io/rust-clippy/master/index.html#result_large_err)
+* [`struct_excessive_bools`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_excessive_bools)
 
 
-## `ignore-interior-mutability`
-A list of paths to types that should be treated like `Arc`, i.e. ignored but
-for the generic parameters for determining interior mutability
+## `max-suggested-slice-pattern-length`
+When Clippy suggests using a slice pattern, this is the maximum number of elements allowed in
+the slice pattern that is suggested. If more elements are necessary, the lint is suppressed.
+For example, `[_, _, _, e, ..]` is a slice pattern with 4 elements.
 
-**Default Value:** `["bytes::Bytes"]`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`mutable_key_type`](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type)
-* [`ifs_same_cond`](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond)
+* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
 
 
-## `allow-mixed-uninlined-format-args`
-Whether to allow mixed uninlined format args, e.g. `format!("{} {}", a, foo.bar)`
+## `max-trait-bounds`
+The maximum number of bounds a trait can have to be linted
 
-**Default Value:** `true`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
+* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
 
 
-## `suppress-restriction-lint-in-const`
-Whether to suppress a restriction lint in constant code. In same
-cases the restructured operation might not be unavoidable, as the
-suggested counterparts are unavailable in constant code. This
-configuration will cause restriction lints to trigger even
-if no suggestion can be made.
+## `min-ident-chars-threshold`
+Minimum chars an ident can have, anything below or equal to this will be linted.
 
-**Default Value:** `false`
+**Default Value:** `1`
 
 ---
 **Affected lints:**
-* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)
+* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
 
 
 ## `missing-docs-in-crate-items`
@@ -656,205 +595,266 @@ crate. For example, `pub(crate)` items.
 * [`missing_docs_in_private_items`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items)
 
 
-## `future-size-threshold`
-The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
+## `msrv`
+The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
+
+---
+**Affected lints:**
+* [`almost_complete_range`](https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range)
+* [`approx_constant`](https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant)
+* [`borrow_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#borrow_as_ptr)
+* [`cast_abs_to_unsigned`](https://rust-lang.github.io/rust-clippy/master/index.html#cast_abs_to_unsigned)
+* [`checked_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#checked_conversions)
+* [`cloned_instead_of_copied`](https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied)
+* [`collapsible_str_replace`](https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace)
+* [`deprecated_cfg_attr`](https://rust-lang.github.io/rust-clippy/master/index.html#deprecated_cfg_attr)
+* [`derivable_impls`](https://rust-lang.github.io/rust-clippy/master/index.html#derivable_impls)
+* [`err_expect`](https://rust-lang.github.io/rust-clippy/master/index.html#err_expect)
+* [`filter_map_next`](https://rust-lang.github.io/rust-clippy/master/index.html#filter_map_next)
+* [`from_over_into`](https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into)
+* [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
+* [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
+* [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
+* [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits)
+* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)
+* [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp)
+* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)
+* [`manual_is_ascii_check`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check)
+* [`manual_let_else`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else)
+* [`manual_non_exhaustive`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive)
+* [`manual_range_contains`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_range_contains)
+* [`manual_rem_euclid`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_rem_euclid)
+* [`manual_retain`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_retain)
+* [`manual_split_once`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_split_once)
+* [`manual_str_repeat`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_str_repeat)
+* [`manual_strip`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_strip)
+* [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
+* [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone)
+* [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or)
+* [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro)
+* [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)
+* [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)
+* [`needless_borrow`](https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow)
+* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
+* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
+* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
+* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
+* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
+* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
+* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
+* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
+* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
+* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
+* [`unchecked_duration_subtraction`](https://rust-lang.github.io/rust-clippy/master/index.html#unchecked_duration_subtraction)
+* [`uninlined_format_args`](https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args)
+* [`unnecessary_lazy_evaluations`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations)
+* [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
+* [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
 
-**Default Value:** `16384`
+
+## `pass-by-value-size-limit`
+The minimum size (in bytes) to consider a type for passing by reference instead of by value.
+
+**Default Value:** `256`
 
 ---
 **Affected lints:**
-* [`large_futures`](https://rust-lang.github.io/rust-clippy/master/index.html#large_futures)
+* [`large_types_passed_by_value`](https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value)
 
 
-## `unnecessary-box-size`
-The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
+## `pub-underscore-fields-behavior`
+Lint "public" fields in a struct that are prefixed with an underscore based on their
+exported visibility, or whether they are marked as "pub".
 
-**Default Value:** `128`
+**Default Value:** `"PubliclyExported"`
 
 ---
 **Affected lints:**
-* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
+* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
 
 
-## `allow-private-module-inception`
-Whether to allow module inception if it's not public.
+## `semicolon-inside-block-ignore-singleline`
+Whether to lint only if it's multiline.
 
 **Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`module_inception`](https://rust-lang.github.io/rust-clippy/master/index.html#module_inception)
+* [`semicolon_inside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block)
 
 
-## `allowed-idents-below-min-chars`
-Allowed names below the minimum allowed characters. The value `".."` can be used as part of
-the list to indicate, that the configured values should be appended to the default
-configuration of Clippy. By default, any configuration will replace the default value.
+## `semicolon-outside-block-ignore-multiline`
+Whether to lint only if it's singleline.
 
-**Default Value:** `["j", "z", "i", "y", "n", "x", "w"]`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
+* [`semicolon_outside_block`](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block)
 
 
-## `min-ident-chars-threshold`
-Minimum chars an ident can have, anything below or equal to this will be linted.
+## `single-char-binding-names-threshold`
+The maximum number of single char bindings a scope may have
 
-**Default Value:** `1`
+**Default Value:** `4`
 
 ---
 **Affected lints:**
-* [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars)
+* [`many_single_char_names`](https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names)
 
 
-## `accept-comment-above-statement`
-Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
+## `stack-size-threshold`
+The maximum allowed stack size for functions in bytes
 
-**Default Value:** `true`
+**Default Value:** `512000`
 
 ---
 **Affected lints:**
-* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
+* [`large_stack_frames`](https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames)
 
 
-## `accept-comment-above-attributes`
-Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
+## `standard-macro-braces`
+Enforce the named macros always use the braces specified.
 
-**Default Value:** `true`
+A `MacroMatcher` can be added like so `{ name = "macro_name", brace = "(" }`. If the macro
+could be used with a full path two `MacroMatcher`s have to be added one with the full path
+`crate_name::macro_name` and one with just the macro name.
+
+**Default Value:** `[]`
 
 ---
 **Affected lints:**
-* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
+* [`nonstandard_macro_braces`](https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces)
 
 
-## `allow-one-hash-in-raw-strings`
-Whether to allow `r#""#` when `r""` can be used
+## `struct-field-name-threshold`
+The minimum number of struct fields for the lints about field names to trigger
 
-**Default Value:** `false`
+**Default Value:** `3`
 
 ---
 **Affected lints:**
-* [`unnecessary_raw_string_hashes`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_raw_string_hashes)
+* [`struct_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#struct_field_names)
 
 
-## `absolute-paths-max-segments`
-The maximum number of segments a path can have before being linted, anything above this will
-be linted.
+## `suppress-restriction-lint-in-const`
+Whether to suppress a restriction lint in constant code. In same
+cases the restructured operation might not be unavoidable, as the
+suggested counterparts are unavailable in constant code. This
+configuration will cause restriction lints to trigger even
+if no suggestion can be made.
 
-**Default Value:** `2`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
+* [`indexing_slicing`](https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing)
 
 
-## `absolute-paths-allowed-crates`
-Which crates to allow absolute paths from
+## `too-large-for-stack`
+The maximum size of objects (in bytes) that will be linted. Larger objects are ok on the heap
 
-**Default Value:** `[]`
+**Default Value:** `200`
 
 ---
 **Affected lints:**
-* [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
+* [`boxed_local`](https://rust-lang.github.io/rust-clippy/master/index.html#boxed_local)
+* [`useless_vec`](https://rust-lang.github.io/rust-clippy/master/index.html#useless_vec)
 
 
-## `allowed-dotfiles`
-Additional dotfiles (files or directories starting with a dot) to allow
+## `too-many-arguments-threshold`
+The maximum number of argument a function or method can have
 
-**Default Value:** `[]`
+**Default Value:** `7`
 
 ---
 **Affected lints:**
-* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
+* [`too_many_arguments`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments)
 
 
-## `allowed-duplicate-crates`
-A list of crate names to allow duplicates of
+## `too-many-lines-threshold`
+The maximum number of lines a function or method can have
 
-**Default Value:** `[]`
+**Default Value:** `100`
 
 ---
 **Affected lints:**
-* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
+* [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
 
 
-## `enforce-iter-loop-reborrow`
-Whether to recommend using implicit into iter for reborrowed values.
+## `trivial-copy-size-limit`
+The maximum size (in bytes) to consider a `Copy` type for passing by value instead of by
+reference. By default there is no limit
 
-#### Example
-```no_run
-let mut vec = vec![1, 2, 3];
-let rmvec = &mut vec;
-for _ in rmvec.iter() {}
-for _ in rmvec.iter_mut() {}
-```
+---
+**Affected lints:**
+* [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
 
-Use instead:
-```no_run
-let mut vec = vec![1, 2, 3];
-let rmvec = &mut vec;
-for _ in &*rmvec {}
-for _ in &mut *rmvec {}
-```
 
-**Default Value:** `false`
+## `type-complexity-threshold`
+The maximum complexity a type can have
+
+**Default Value:** `250`
 
 ---
 **Affected lints:**
-* [`explicit_iter_loop`](https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop)
+* [`type_complexity`](https://rust-lang.github.io/rust-clippy/master/index.html#type_complexity)
 
 
-## `check-private-items`
-Whether to also run the listed lints on private items.
+## `unnecessary-box-size`
+The byte size a `T` in `Box<T>` can have, below which it triggers the `clippy::unnecessary_box` lint
 
-**Default Value:** `false`
+**Default Value:** `128`
 
 ---
 **Affected lints:**
-* [`missing_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc)
-* [`unnecessary_safety_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc)
-* [`missing_panics_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_panics_doc)
-* [`missing_errors_doc`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_errors_doc)
+* [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
 
 
-## `pub-underscore-fields-behavior`
-Lint "public" fields in a struct that are prefixed with an underscore based on their
-exported visibility, or whether they are marked as "pub".
+## `unreadable-literal-lint-fractions`
+Should the fraction of a decimal be linted to include separators.
 
-**Default Value:** `"PubliclyExported"`
+**Default Value:** `true`
 
 ---
 **Affected lints:**
-* [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
+* [`unreadable_literal`](https://rust-lang.github.io/rust-clippy/master/index.html#unreadable_literal)
 
 
-## `allow-comparison-to-zero`
-Don't lint when comparing the result of a modulo operation to zero.
+## `upper-case-acronyms-aggressive`
+Enables verbose mode. Triggers if there is more than one uppercase char next to each other
 
-**Default Value:** `true`
+**Default Value:** `false`
 
 ---
 **Affected lints:**
-* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic)
+* [`upper_case_acronyms`](https://rust-lang.github.io/rust-clippy/master/index.html#upper_case_acronyms)
 
 
-## `allowed-wildcard-imports`
-List of path segments allowed to have wildcard imports.
+## `vec-box-size-threshold`
+The size of the boxed type in bytes, where boxing in a `Vec` is allowed
 
-#### Example
+**Default Value:** `4096`
 
-```toml
-allowed-wildcard-imports = [ "utils", "common" ]
-```
+---
+**Affected lints:**
+* [`vec_box`](https://rust-lang.github.io/rust-clippy/master/index.html#vec_box)
 
-#### Noteworthy
 
-1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
-2. Paths with any segment that containing the word 'prelude'
-are already allowed by default.
+## `verbose-bit-mask-threshold`
+The maximum allowed size of a bit mask before suggesting to use 'trailing_zeros'
 
-**Default Value:** `[]`
+**Default Value:** `1`
+
+---
+**Affected lints:**
+* [`verbose_bit_mask`](https://rust-lang.github.io/rust-clippy/master/index.html#verbose_bit_mask)
+
+
+## `warn-on-all-wildcard-imports`
+Whether to allow certain wildcard imports (prelude, super in tests).
+
+**Default Value:** `false`
 
 ---
 **Affected lints:**
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index b781259ad96..673b6328b39 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -193,7 +193,7 @@ macro_rules! define_Conf {
         }
 
         pub fn get_configuration_metadata() -> Vec<ClippyConfiguration> {
-            vec![
+            let mut sorted = vec![
                 $(
                     {
                         let deprecation_reason = wrap_option!($($dep)?);
@@ -206,7 +206,9 @@ macro_rules! define_Conf {
                         )
                     },
                 )+
-            ]
+            ];
+            sorted.sort_by(|a, b| a.name.cmp(&b.name));
+            sorted
         }
     };
 }
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index 3d5002f1780..01e2aa6e0a6 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -5,7 +5,7 @@
     clippy::must_use_candidate,
     clippy::missing_panics_doc,
     rustc::diagnostic_outside_of_impl,
-    rustc::untranslatable_diagnostic,
+    rustc::untranslatable_diagnostic
 )]
 
 extern crate rustc_ast;
diff --git a/src/tools/clippy/clippy_config/src/metadata.rs b/src/tools/clippy/clippy_config/src/metadata.rs
index 3ba2796e18d..400887185e8 100644
--- a/src/tools/clippy/clippy_config/src/metadata.rs
+++ b/src/tools/clippy/clippy_config/src/metadata.rs
@@ -26,9 +26,11 @@ impl ClippyConfiguration {
         doc_comment: &'static str,
         deprecation_reason: Option<&'static str>,
     ) -> Self {
-        let (lints, doc) = parse_config_field_doc(doc_comment)
+        let (mut lints, doc) = parse_config_field_doc(doc_comment)
             .unwrap_or_else(|| (vec![], "[ERROR] MALFORMED DOC COMMENT".to_string()));
 
+        lints.sort();
+
         Self {
             name: to_kebab(name),
             lints,
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index f4389db627d..a8a32f7ed20 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -24,6 +24,7 @@ msrv_aliases! {
     1,68,0 { PATH_MAIN_SEPARATOR_STR }
     1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
     1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE }
+    1,59,0 { THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST }
     1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY }
     1,55,0 { SEEK_REWIND }
     1,54,0 { INTO_KEYS }
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
new file mode 100644
index 00000000000..b1c552c7a8d
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -0,0 +1,322 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::macros::HirNode;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{is_trait_method, path_to_local};
+use rustc_errors::Applicability;
+use rustc_hir::{self as hir, Expr, ExprKind, Node};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{self, Instance, Mutability};
+use rustc_session::declare_lint_pass;
+use rustc_span::def_id::DefId;
+use rustc_span::symbol::sym;
+use rustc_span::ExpnKind;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for code like `foo = bar.clone();`
+    ///
+    /// ### Why is this bad?
+    /// Custom `Clone::clone_from()` or `ToOwned::clone_into` implementations allow the objects
+    /// to share resources and therefore avoid allocations.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct Thing;
+    ///
+    /// impl Clone for Thing {
+    ///     fn clone(&self) -> Self { todo!() }
+    ///     fn clone_from(&mut self, other: &Self) { todo!() }
+    /// }
+    ///
+    /// pub fn assign_to_ref(a: &mut Thing, b: Thing) {
+    ///     *a = b.clone();
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// struct Thing;
+    /// impl Clone for Thing {
+    ///     fn clone(&self) -> Self { todo!() }
+    ///     fn clone_from(&mut self, other: &Self) { todo!() }
+    /// }
+    ///
+    /// pub fn assign_to_ref(a: &mut Thing, b: Thing) {
+    ///     a.clone_from(&b);
+    /// }
+    /// ```
+    #[clippy::version = "1.77.0"]
+    pub ASSIGNING_CLONES,
+    perf,
+    "assigning the result of cloning may be inefficient"
+}
+declare_lint_pass!(AssigningClones => [ASSIGNING_CLONES]);
+
+impl<'tcx> LateLintPass<'tcx> for AssigningClones {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, assign_expr: &'tcx hir::Expr<'_>) {
+        // Do not fire the lint in macros
+        let expn_data = assign_expr.span().ctxt().outer_expn_data();
+        match expn_data.kind {
+            ExpnKind::AstPass(_) | ExpnKind::Desugaring(_) | ExpnKind::Macro(..) => return,
+            ExpnKind::Root => {},
+        }
+
+        let ExprKind::Assign(lhs, rhs, _span) = assign_expr.kind else {
+            return;
+        };
+
+        let Some(call) = extract_call(cx, rhs) else {
+            return;
+        };
+
+        if is_ok_to_suggest(cx, lhs, &call) {
+            suggest(cx, assign_expr, lhs, &call);
+        }
+    }
+}
+
+// Try to resolve the call to `Clone::clone` or `ToOwned::to_owned`.
+fn extract_call<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Option<CallCandidate<'tcx>> {
+    let fn_def_id = clippy_utils::fn_def_id(cx, expr)?;
+
+    // Fast paths to only check method calls without arguments or function calls with a single argument
+    let (target, kind, resolved_method) = match expr.kind {
+        ExprKind::MethodCall(path, receiver, [], _span) => {
+            let args = cx.typeck_results().node_args(expr.hir_id);
+
+            // If we could not resolve the method, don't apply the lint
+            let Ok(Some(resolved_method)) = Instance::resolve(cx.tcx, cx.param_env, fn_def_id, args) else {
+                return None;
+            };
+            if is_trait_method(cx, expr, sym::Clone) && path.ident.name == sym::clone {
+                (TargetTrait::Clone, CallKind::MethodCall { receiver }, resolved_method)
+            } else if is_trait_method(cx, expr, sym::ToOwned) && path.ident.name.as_str() == "to_owned" {
+                (TargetTrait::ToOwned, CallKind::MethodCall { receiver }, resolved_method)
+            } else {
+                return None;
+            }
+        },
+        ExprKind::Call(function, [arg]) => {
+            let kind = cx.typeck_results().node_type(function.hir_id).kind();
+
+            // If we could not resolve the method, don't apply the lint
+            let Ok(Some(resolved_method)) = (match kind {
+                ty::FnDef(_, args) => Instance::resolve(cx.tcx, cx.param_env, fn_def_id, args),
+                _ => Ok(None),
+            }) else {
+                return None;
+            };
+            if cx.tcx.is_diagnostic_item(sym::to_owned_method, fn_def_id) {
+                (
+                    TargetTrait::ToOwned,
+                    CallKind::FunctionCall { self_arg: arg },
+                    resolved_method,
+                )
+            } else if let Some(trait_did) = cx.tcx.trait_of_item(fn_def_id)
+                && cx.tcx.is_diagnostic_item(sym::Clone, trait_did)
+            {
+                (
+                    TargetTrait::Clone,
+                    CallKind::FunctionCall { self_arg: arg },
+                    resolved_method,
+                )
+            } else {
+                return None;
+            }
+        },
+        _ => return None,
+    };
+
+    Some(CallCandidate {
+        target,
+        kind,
+        method_def_id: resolved_method.def_id(),
+    })
+}
+
+// Return true if we find that the called method has a custom implementation and isn't derived or
+// provided by default by the corresponding trait.
+fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>) -> bool {
+    // If the left-hand side is a local variable, it might be uninitialized at this point.
+    // In that case we do not want to suggest the lint.
+    if let Some(local) = path_to_local(lhs) {
+        // TODO: This check currently bails if the local variable has no initializer.
+        // That is overly conservative - the lint should fire even if there was no initializer,
+        // but the variable has been initialized before `lhs` was evaluated.
+        if let Some(Node::Local(local)) = cx.tcx.hir().parent_id_iter(local).next().map(|p| cx.tcx.hir_node(p))
+            && local.init.is_none()
+        {
+            return false;
+        }
+    }
+
+    let Some(impl_block) = cx.tcx.impl_of_method(call.method_def_id) else {
+        return false;
+    };
+
+    // If the method implementation comes from #[derive(Clone)], then don't suggest the lint.
+    // Automatically generated Clone impls do not currently override `clone_from`.
+    // See e.g. https://github.com/rust-lang/rust/pull/98445#issuecomment-1190681305 for more details.
+    if cx.tcx.is_builtin_derived(impl_block) {
+        return false;
+    }
+
+    // Find the function for which we want to check that it is implemented.
+    let provided_fn = match call.target {
+        TargetTrait::Clone => cx.tcx.get_diagnostic_item(sym::Clone).and_then(|clone| {
+            cx.tcx
+                .provided_trait_methods(clone)
+                .find(|item| item.name == sym::clone_from)
+        }),
+        TargetTrait::ToOwned => cx.tcx.get_diagnostic_item(sym::ToOwned).and_then(|to_owned| {
+            cx.tcx
+                .provided_trait_methods(to_owned)
+                .find(|item| item.name.as_str() == "clone_into")
+        }),
+    };
+    let Some(provided_fn) = provided_fn else {
+        return false;
+    };
+
+    // Now take a look if the impl block defines an implementation for the method that we're interested
+    // in. If not, then we're using a default implementation, which is not interesting, so we will
+    // not suggest the lint.
+    let implemented_fns = cx.tcx.impl_item_implementor_ids(impl_block);
+    implemented_fns.contains_key(&provided_fn.def_id)
+}
+
+fn suggest<'tcx>(
+    cx: &LateContext<'tcx>,
+    assign_expr: &hir::Expr<'tcx>,
+    lhs: &hir::Expr<'tcx>,
+    call: &CallCandidate<'tcx>,
+) {
+    span_lint_and_then(cx, ASSIGNING_CLONES, assign_expr.span, call.message(), |diag| {
+        let mut applicability = Applicability::MachineApplicable;
+
+        diag.span_suggestion(
+            assign_expr.span,
+            call.suggestion_msg(),
+            call.suggested_replacement(cx, lhs, &mut applicability),
+            applicability,
+        );
+    });
+}
+
+#[derive(Copy, Clone, Debug)]
+enum CallKind<'tcx> {
+    MethodCall { receiver: &'tcx Expr<'tcx> },
+    FunctionCall { self_arg: &'tcx Expr<'tcx> },
+}
+
+#[derive(Copy, Clone, Debug)]
+enum TargetTrait {
+    Clone,
+    ToOwned,
+}
+
+#[derive(Debug)]
+struct CallCandidate<'tcx> {
+    target: TargetTrait,
+    kind: CallKind<'tcx>,
+    // DefId of the called method from an impl block that implements the target trait
+    method_def_id: DefId,
+}
+
+impl<'tcx> CallCandidate<'tcx> {
+    #[inline]
+    fn message(&self) -> &'static str {
+        match self.target {
+            TargetTrait::Clone => "assigning the result of `Clone::clone()` may be inefficient",
+            TargetTrait::ToOwned => "assigning the result of `ToOwned::to_owned()` may be inefficient",
+        }
+    }
+
+    #[inline]
+    fn suggestion_msg(&self) -> &'static str {
+        match self.target {
+            TargetTrait::Clone => "use `clone_from()`",
+            TargetTrait::ToOwned => "use `clone_into()`",
+        }
+    }
+
+    fn suggested_replacement(
+        &self,
+        cx: &LateContext<'tcx>,
+        lhs: &hir::Expr<'tcx>,
+        applicability: &mut Applicability,
+    ) -> String {
+        match self.target {
+            TargetTrait::Clone => {
+                match self.kind {
+                    CallKind::MethodCall { receiver } => {
+                        let receiver_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
+                            // `*lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`
+                            Sugg::hir_with_applicability(cx, ref_expr, "_", applicability)
+                        } else {
+                            // `lhs = self_expr.clone();` -> `lhs.clone_from(self_expr)`
+                            Sugg::hir_with_applicability(cx, lhs, "_", applicability)
+                        }
+                        .maybe_par();
+
+                        // Determine whether we need to reference the argument to clone_from().
+                        let clone_receiver_type = cx.typeck_results().expr_ty(receiver);
+                        let clone_receiver_adj_type = cx.typeck_results().expr_ty_adjusted(receiver);
+                        let mut arg_sugg = Sugg::hir_with_applicability(cx, receiver, "_", applicability);
+                        if clone_receiver_type != clone_receiver_adj_type {
+                            // The receiver may have been a value type, so we need to add an `&` to
+                            // be sure the argument to clone_from will be a reference.
+                            arg_sugg = arg_sugg.addr();
+                        };
+
+                        format!("{receiver_sugg}.clone_from({arg_sugg})")
+                    },
+                    CallKind::FunctionCall { self_arg, .. } => {
+                        let self_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
+                            // `*lhs = Clone::clone(self_expr);` -> `Clone::clone_from(lhs, self_expr)`
+                            Sugg::hir_with_applicability(cx, ref_expr, "_", applicability)
+                        } else {
+                            // `lhs = Clone::clone(self_expr);` -> `Clone::clone_from(&mut lhs, self_expr)`
+                            Sugg::hir_with_applicability(cx, lhs, "_", applicability).mut_addr()
+                        };
+                        // The RHS had to be exactly correct before the call, there is no auto-deref for function calls.
+                        let rhs_sugg = Sugg::hir_with_applicability(cx, self_arg, "_", applicability);
+
+                        format!("Clone::clone_from({self_sugg}, {rhs_sugg})")
+                    },
+                }
+            },
+            TargetTrait::ToOwned => {
+                let rhs_sugg = if let ExprKind::Unary(hir::UnOp::Deref, ref_expr) = lhs.kind {
+                    // `*lhs = rhs.to_owned()` -> `rhs.clone_into(lhs)`
+                    // `*lhs = ToOwned::to_owned(rhs)` -> `ToOwned::clone_into(rhs, lhs)`
+                    let sugg = Sugg::hir_with_applicability(cx, ref_expr, "_", applicability).maybe_par();
+                    let inner_type = cx.typeck_results().expr_ty(ref_expr);
+                    // If after unwrapping the dereference, the type is not a mutable reference, we add &mut to make it
+                    // deref to a mutable reference.
+                    if matches!(inner_type.kind(), ty::Ref(_, _, Mutability::Mut)) {
+                        sugg
+                    } else {
+                        sugg.mut_addr()
+                    }
+                } else {
+                    // `lhs = rhs.to_owned()` -> `rhs.clone_into(&mut lhs)`
+                    // `lhs = ToOwned::to_owned(rhs)` -> `ToOwned::clone_into(rhs, &mut lhs)`
+                    Sugg::hir_with_applicability(cx, lhs, "_", applicability)
+                        .maybe_par()
+                        .mut_addr()
+                };
+
+                match self.kind {
+                    CallKind::MethodCall { receiver } => {
+                        let receiver_sugg = Sugg::hir_with_applicability(cx, receiver, "_", applicability);
+                        format!("{receiver_sugg}.clone_into({rhs_sugg})")
+                    },
+                    CallKind::FunctionCall { self_arg, .. } => {
+                        let self_sugg = Sugg::hir_with_applicability(cx, self_arg, "_", applicability);
+                        format!("ToOwned::clone_into({self_sugg}, {rhs_sugg})")
+                    },
+                }
+            },
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
deleted file mode 100644
index f2937d51340..00000000000
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ /dev/null
@@ -1,1210 +0,0 @@
-//! checks for attributes
-
-use clippy_config::msrvs::{self, Msrv};
-use clippy_utils::diagnostics::{
-    span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then,
-};
-use clippy_utils::is_from_proc_macro;
-use clippy_utils::macros::{is_panic, macro_backtrace};
-use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
-use rustc_ast::token::{Token, TokenKind};
-use rustc_ast::tokenstream::TokenTree;
-use rustc_ast::{
-    AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem,
-};
-use rustc_errors::Applicability;
-use rustc_hir::{
-    Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
-};
-use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext};
-use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, impl_lint_pass};
-use rustc_span::symbol::Symbol;
-use rustc_span::{sym, Span, DUMMY_SP};
-use semver::Version;
-
-static UNIX_SYSTEMS: &[&str] = &[
-    "android",
-    "dragonfly",
-    "emscripten",
-    "freebsd",
-    "fuchsia",
-    "haiku",
-    "illumos",
-    "ios",
-    "l4re",
-    "linux",
-    "macos",
-    "netbsd",
-    "openbsd",
-    "redox",
-    "solaris",
-    "vxworks",
-];
-
-// NOTE: windows is excluded from the list because it's also a valid target family.
-static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"];
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for items annotated with `#[inline(always)]`,
-    /// unless the annotated function is empty or simply panics.
-    ///
-    /// ### Why is this bad?
-    /// While there are valid uses of this annotation (and once
-    /// you know when to use it, by all means `allow` this lint), it's a common
-    /// newbie-mistake to pepper one's code with it.
-    ///
-    /// As a rule of thumb, before slapping `#[inline(always)]` on a function,
-    /// measure if that additional function call really affects your runtime profile
-    /// sufficiently to make up for the increase in compile time.
-    ///
-    /// ### Known problems
-    /// False positives, big time. This lint is meant to be
-    /// deactivated by everyone doing serious performance work. This means having
-    /// done the measurement.
-    ///
-    /// ### Example
-    /// ```ignore
-    /// #[inline(always)]
-    /// fn not_quite_hot_code(..) { ... }
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub INLINE_ALWAYS,
-    pedantic,
-    "use of `#[inline(always)]`"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `extern crate` and `use` items annotated with
-    /// lint attributes.
-    ///
-    /// This lint permits lint attributes for lints emitted on the items themself.
-    /// For `use` items these lints are:
-    /// * deprecated
-    /// * unreachable_pub
-    /// * unused_imports
-    /// * clippy::enum_glob_use
-    /// * clippy::macro_use_imports
-    /// * clippy::wildcard_imports
-    ///
-    /// For `extern crate` items these lints are:
-    /// * `unused_imports` on items with `#[macro_use]`
-    ///
-    /// ### Why is this bad?
-    /// Lint attributes have no effect on crate imports. Most
-    /// likely a `!` was forgotten.
-    ///
-    /// ### Example
-    /// ```ignore
-    /// #[deny(dead_code)]
-    /// extern crate foo;
-    /// #[forbid(dead_code)]
-    /// use foo::bar;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```rust,ignore
-    /// #[allow(unused_imports)]
-    /// use foo::baz;
-    /// #[allow(unused_imports)]
-    /// #[macro_use]
-    /// extern crate baz;
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub USELESS_ATTRIBUTE,
-    correctness,
-    "use of lint attributes on `extern crate` items"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[deprecated]` annotations with a `since`
-    /// field that is not a valid semantic version. Also allows "TBD" to signal
-    /// future deprecation.
-    ///
-    /// ### Why is this bad?
-    /// For checking the version of the deprecation, it must be
-    /// a valid semver. Failing that, the contained information is useless.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[deprecated(since = "forever")]
-    /// fn something_else() { /* ... */ }
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub DEPRECATED_SEMVER,
-    correctness,
-    "use of `#[deprecated(since = \"x\")]` where x is not semver"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for empty lines after outer attributes
-    ///
-    /// ### Why is this bad?
-    /// Most likely the attribute was meant to be an inner attribute using a '!'.
-    /// If it was meant to be an outer attribute, then the following item
-    /// should not be separated by empty lines.
-    ///
-    /// ### Known problems
-    /// Can cause false positives.
-    ///
-    /// From the clippy side it's difficult to detect empty lines between an attributes and the
-    /// following item because empty lines and comments are not part of the AST. The parsing
-    /// currently works for basic cases but is not perfect.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[allow(dead_code)]
-    ///
-    /// fn not_quite_good_code() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// // Good (as inner attribute)
-    /// #![allow(dead_code)]
-    ///
-    /// fn this_is_fine() { }
-    ///
-    /// // or
-    ///
-    /// // Good (as outer attribute)
-    /// #[allow(dead_code)]
-    /// fn this_is_fine_too() { }
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub EMPTY_LINE_AFTER_OUTER_ATTR,
-    nursery,
-    "empty line after outer attribute"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for empty lines after documentation comments.
-    ///
-    /// ### Why is this bad?
-    /// The documentation comment was most likely meant to be an inner attribute or regular comment.
-    /// If it was intended to be a documentation comment, then the empty line should be removed to
-    /// be more idiomatic.
-    ///
-    /// ### Known problems
-    /// Only detects empty lines immediately following the documentation. If the doc comment is followed
-    /// by an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr`
-    /// in combination with this lint to detect both cases.
-    ///
-    /// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
-    ///
-    /// ### Example
-    /// ```no_run
-    /// /// Some doc comment with a blank line after it.
-    ///
-    /// fn not_quite_good_code() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// /// Good (no blank line)
-    /// fn this_is_fine() { }
-    /// ```
-    ///
-    /// ```no_run
-    /// // Good (convert to a regular comment)
-    ///
-    /// fn this_is_fine_too() { }
-    /// ```
-    ///
-    /// ```no_run
-    /// //! Good (convert to a comment on an inner attribute)
-    ///
-    /// fn this_is_fine_as_well() { }
-    /// ```
-    #[clippy::version = "1.70.0"]
-    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
-    nursery,
-    "empty line after documentation comments"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
-    ///
-    /// ### Why is this bad?
-    /// Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
-    /// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #![deny(clippy::restriction)]
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #![deny(clippy::as_conversions)]
-    /// ```
-    #[clippy::version = "1.47.0"]
-    pub BLANKET_CLIPPY_RESTRICTION_LINTS,
-    suspicious,
-    "enabling the complete restriction group"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
-    /// with `#[rustfmt::skip]`.
-    ///
-    /// ### Why is this bad?
-    /// Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
-    /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
-    ///
-    /// ### Known problems
-    /// This lint doesn't detect crate level inner attributes, because they get
-    /// processed before the PreExpansionPass lints get executed. See
-    /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg_attr(rustfmt, rustfmt_skip)]
-    /// fn main() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[rustfmt::skip]
-    /// fn main() { }
-    /// ```
-    #[clippy::version = "1.32.0"]
-    pub DEPRECATED_CFG_ATTR,
-    complexity,
-    "usage of `cfg_attr(rustfmt)` instead of tool attributes"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for cfg attributes having operating systems used in target family position.
-    ///
-    /// ### Why is this bad?
-    /// The configuration option will not be recognised and the related item will not be included
-    /// by the conditional compilation engine.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(linux)]
-    /// fn conditional() { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// # mod hidden {
-    /// #[cfg(target_os = "linux")]
-    /// fn conditional() { }
-    /// # }
-    ///
-    /// // or
-    ///
-    /// #[cfg(unix)]
-    /// fn conditional() { }
-    /// ```
-    /// Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details.
-    #[clippy::version = "1.45.0"]
-    pub MISMATCHED_TARGET_OS,
-    correctness,
-    "usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for attributes that allow lints without a reason.
-    ///
-    /// (This requires the `lint_reasons` feature)
-    ///
-    /// ### Why is this bad?
-    /// Allowing a lint should always have a reason. This reason should be documented to
-    /// ensure that others understand the reasoning
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #![feature(lint_reasons)]
-    ///
-    /// #![allow(clippy::some_lint)]
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #![feature(lint_reasons)]
-    ///
-    /// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
-    /// ```
-    #[clippy::version = "1.61.0"]
-    pub ALLOW_ATTRIBUTES_WITHOUT_REASON,
-    restriction,
-    "ensures that all `allow` and `expect` attributes have a reason"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[should_panic]` attributes without specifying the expected panic message.
-    ///
-    /// ### Why is this bad?
-    /// The expected panic message should be specified to ensure that the test is actually
-    /// panicking with the expected message, and not another unrelated panic.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// fn random() -> i32 { 0 }
-    ///
-    /// #[should_panic]
-    /// #[test]
-    /// fn my_test() {
-    ///     let _ = 1 / random();
-    /// }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// fn random() -> i32 { 0 }
-    ///
-    /// #[should_panic = "attempt to divide by zero"]
-    /// #[test]
-    /// fn my_test() {
-    ///     let _ = 1 / random();
-    /// }
-    /// ```
-    #[clippy::version = "1.74.0"]
-    pub SHOULD_PANIC_WITHOUT_EXPECT,
-    pedantic,
-    "ensures that all `should_panic` attributes specify its expected panic message"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `any` and `all` combinators in `cfg` with only one condition.
-    ///
-    /// ### Why is this bad?
-    /// If there is only one condition, no need to wrap it into `any` or `all` combinators.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(any(unix))]
-    /// pub struct Bar;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[cfg(unix)]
-    /// pub struct Bar;
-    /// ```
-    #[clippy::version = "1.71.0"]
-    pub NON_MINIMAL_CFG,
-    style,
-    "ensure that all `cfg(any())` and `cfg(all())` have more than one condition"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg(features = "...")]` and suggests to replace it with
-    /// `#[cfg(feature = "...")]`.
-    ///
-    /// It also checks if `cfg(test)` was misspelled.
-    ///
-    /// ### Why is this bad?
-    /// Misspelling `feature` as `features` or `test` as `tests` can be sometimes hard to spot. It
-    /// may cause conditional compilation not work quietly.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(features = "some-feature")]
-    /// fn conditional() { }
-    /// #[cfg(tests)]
-    /// mod tests { }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[cfg(feature = "some-feature")]
-    /// fn conditional() { }
-    /// #[cfg(test)]
-    /// mod tests { }
-    /// ```
-    #[clippy::version = "1.69.0"]
-    pub MAYBE_MISUSED_CFG,
-    suspicious,
-    "prevent from misusing the wrong attr name"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg_attr(feature = "cargo-clippy", ...)]` and for
-    /// `#[cfg(feature = "cargo-clippy")]` and suggests to replace it with
-    /// `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`.
-    ///
-    /// ### Why is this bad?
-    /// This feature has been deprecated for years and shouldn't be used anymore.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #[cfg(feature = "cargo-clippy")]
-    /// struct Bar;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #[cfg(clippy)]
-    /// struct Bar;
-    /// ```
-    #[clippy::version = "1.78.0"]
-    pub DEPRECATED_CLIPPY_CFG_ATTR,
-    suspicious,
-    "usage of `cfg(feature = \"cargo-clippy\")` instead of `cfg(clippy)`"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `#[cfg_attr(clippy, allow(clippy::lint))]`
-    /// and suggests to replace it with `#[allow(clippy::lint)]`.
-    ///
-    /// ### Why is this bad?
-    /// There is no reason to put clippy attributes behind a clippy `cfg` as they are not
-    /// run by anything else than clippy.
-    ///
-    /// ### Example
-    /// ```no_run
-    /// #![cfg_attr(clippy, allow(clippy::deprecated_cfg_attr))]
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// #![allow(clippy::deprecated_cfg_attr)]
-    /// ```
-    #[clippy::version = "1.78.0"]
-    pub UNNECESSARY_CLIPPY_CFG,
-    suspicious,
-    "usage of `cfg_attr(clippy, allow(clippy::lint))` instead of `allow(clippy::lint)`"
-}
-
-declare_lint_pass!(Attributes => [
-    ALLOW_ATTRIBUTES_WITHOUT_REASON,
-    INLINE_ALWAYS,
-    DEPRECATED_SEMVER,
-    USELESS_ATTRIBUTE,
-    BLANKET_CLIPPY_RESTRICTION_LINTS,
-    SHOULD_PANIC_WITHOUT_EXPECT,
-]);
-
-impl<'tcx> LateLintPass<'tcx> for Attributes {
-    fn check_crate(&mut self, cx: &LateContext<'tcx>) {
-        for (name, level) in &cx.sess().opts.lint_opts {
-            if name == "clippy::restriction" && *level > Level::Allow {
-                span_lint_and_then(
-                    cx,
-                    BLANKET_CLIPPY_RESTRICTION_LINTS,
-                    DUMMY_SP,
-                    "`clippy::restriction` is not meant to be enabled as a group",
-                    |diag| {
-                        diag.note(format!(
-                            "because of the command line `--{} clippy::restriction`",
-                            level.as_str()
-                        ));
-                        diag.help("enable the restriction lints you need individually");
-                    },
-                );
-            }
-        }
-    }
-
-    fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
-        if let Some(items) = &attr.meta_item_list() {
-            if let Some(ident) = attr.ident() {
-                if is_lint_level(ident.name) {
-                    check_clippy_lint_names(cx, ident.name, items);
-                }
-                if matches!(ident.name, sym::allow | sym::expect) {
-                    check_lint_reason(cx, ident.name, items, attr);
-                }
-                if items.is_empty() || !attr.has_name(sym::deprecated) {
-                    return;
-                }
-                for item in items {
-                    if let NestedMetaItem::MetaItem(mi) = &item
-                        && let MetaItemKind::NameValue(lit) = &mi.kind
-                        && mi.has_name(sym::since)
-                    {
-                        check_deprecated_since(cx, item.span(), lit);
-                    }
-                }
-            }
-        }
-        if attr.has_name(sym::should_panic) {
-            check_should_panic_reason(cx, attr);
-        }
-    }
-
-    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
-        let attrs = cx.tcx.hir().attrs(item.hir_id());
-        if is_relevant_item(cx, item) {
-            check_attrs(cx, item.span, item.ident.name, attrs);
-        }
-        match item.kind {
-            ItemKind::ExternCrate(..) | ItemKind::Use(..) => {
-                let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
-
-                for attr in attrs {
-                    if in_external_macro(cx.sess(), attr.span) {
-                        return;
-                    }
-                    if let Some(lint_list) = &attr.meta_item_list() {
-                        if attr.ident().map_or(false, |ident| is_lint_level(ident.name)) {
-                            for lint in lint_list {
-                                match item.kind {
-                                    ItemKind::Use(..) => {
-                                        if is_word(lint, sym::unused_imports)
-                                            || is_word(lint, sym::deprecated)
-                                            || is_word(lint, sym!(unreachable_pub))
-                                            || is_word(lint, sym!(unused))
-                                            || is_word(lint, sym!(unused_import_braces))
-                                            || extract_clippy_lint(lint).map_or(false, |s| {
-                                                matches!(
-                                                    s.as_str(),
-                                                    "wildcard_imports"
-                                                        | "enum_glob_use"
-                                                        | "redundant_pub_crate"
-                                                        | "macro_use_imports"
-                                                        | "unsafe_removed_from_name"
-                                                        | "module_name_repetitions"
-                                                        | "single_component_path_imports"
-                                                )
-                                            })
-                                        {
-                                            return;
-                                        }
-                                    },
-                                    ItemKind::ExternCrate(..) => {
-                                        if is_word(lint, sym::unused_imports) && skip_unused_imports {
-                                            return;
-                                        }
-                                        if is_word(lint, sym!(unused_extern_crates)) {
-                                            return;
-                                        }
-                                    },
-                                    _ => {},
-                                }
-                            }
-                            let line_span = first_line_of_span(cx, attr.span);
-
-                            if let Some(mut sugg) = snippet_opt(cx, line_span) {
-                                if sugg.contains("#[") {
-                                    span_lint_and_then(
-                                        cx,
-                                        USELESS_ATTRIBUTE,
-                                        line_span,
-                                        "useless lint attribute",
-                                        |diag| {
-                                            sugg = sugg.replacen("#[", "#![", 1);
-                                            diag.span_suggestion(
-                                                line_span,
-                                                "if you just forgot a `!`, use",
-                                                sugg,
-                                                Applicability::MaybeIncorrect,
-                                            );
-                                        },
-                                    );
-                                }
-                            }
-                        }
-                    }
-                }
-            },
-            _ => {},
-        }
-    }
-
-    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
-        if is_relevant_impl(cx, item) {
-            check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
-        }
-    }
-
-    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
-        if is_relevant_trait(cx, item) {
-            check_attrs(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
-        }
-    }
-}
-
-/// Returns the lint name if it is clippy lint.
-fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
-    if let Some(meta_item) = lint.meta_item()
-        && meta_item.path.segments.len() > 1
-        && let tool_name = meta_item.path.segments[0].ident
-        && tool_name.name == sym::clippy
-    {
-        let lint_name = meta_item.path.segments.last().unwrap().ident.name;
-        return Some(lint_name);
-    }
-    None
-}
-
-fn check_should_panic_reason(cx: &LateContext<'_>, attr: &Attribute) {
-    if let AttrKind::Normal(normal_attr) = &attr.kind {
-        if let AttrArgs::Eq(_, AttrArgsEq::Hir(_)) = &normal_attr.item.args {
-            // `#[should_panic = ".."]` found, good
-            return;
-        }
-
-        if let AttrArgs::Delimited(args) = &normal_attr.item.args
-            && let mut tt_iter = args.tokens.trees()
-            && let Some(TokenTree::Token(
-                Token {
-                    kind: TokenKind::Ident(sym::expected, _),
-                    ..
-                },
-                _,
-            )) = tt_iter.next()
-            && let Some(TokenTree::Token(
-                Token {
-                    kind: TokenKind::Eq, ..
-                },
-                _,
-            )) = tt_iter.next()
-            && let Some(TokenTree::Token(
-                Token {
-                    kind: TokenKind::Literal(_),
-                    ..
-                },
-                _,
-            )) = tt_iter.next()
-        {
-            // `#[should_panic(expected = "..")]` found, good
-            return;
-        }
-
-        span_lint_and_sugg(
-            cx,
-            SHOULD_PANIC_WITHOUT_EXPECT,
-            attr.span,
-            "#[should_panic] attribute without a reason",
-            "consider specifying the expected panic",
-            "#[should_panic(expected = /* panic message */)]".into(),
-            Applicability::HasPlaceholders,
-        );
-    }
-}
-
-fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
-    for lint in items {
-        if let Some(lint_name) = extract_clippy_lint(lint) {
-            if lint_name.as_str() == "restriction" && name != sym::allow {
-                span_lint_and_help(
-                    cx,
-                    BLANKET_CLIPPY_RESTRICTION_LINTS,
-                    lint.span(),
-                    "`clippy::restriction` is not meant to be enabled as a group",
-                    None,
-                    "enable the restriction lints you need individually",
-                );
-            }
-        }
-    }
-}
-
-fn check_lint_reason<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) {
-    // Check for the feature
-    if !cx.tcx.features().lint_reasons {
-        return;
-    }
-
-    // Check if the reason is present
-    if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
-        && let MetaItemKind::NameValue(_) = &item.kind
-        && item.path == sym::reason
-    {
-        return;
-    }
-
-    // Check if the attribute is in an external macro and therefore out of the developer's control
-    if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &attr) {
-        return;
-    }
-
-    span_lint_and_help(
-        cx,
-        ALLOW_ATTRIBUTES_WITHOUT_REASON,
-        attr.span,
-        &format!("`{}` attribute without specifying a reason", name.as_str()),
-        None,
-        "try adding a reason at the end with `, reason = \"..\"`",
-    );
-}
-
-fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
-    if let ItemKind::Fn(_, _, eid) = item.kind {
-        is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
-    } else {
-        true
-    }
-}
-
-fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool {
-    match item.kind {
-        ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value),
-        _ => false,
-    }
-}
-
-fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool {
-    match item.kind {
-        TraitItemKind::Fn(_, TraitFn::Required(_)) => true,
-        TraitItemKind::Fn(_, TraitFn::Provided(eid)) => {
-            is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
-        },
-        _ => false,
-    }
-}
-
-fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, block: &Block<'_>) -> bool {
-    block.stmts.first().map_or(
-        block
-            .expr
-            .as_ref()
-            .map_or(false, |e| is_relevant_expr(cx, typeck_results, e)),
-        |stmt| match &stmt.kind {
-            StmtKind::Local(_) => true,
-            StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
-            StmtKind::Item(_) => false,
-        },
-    )
-}
-
-fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, expr: &Expr<'_>) -> bool {
-    if macro_backtrace(expr.span).last().map_or(false, |macro_call| {
-        is_panic(cx, macro_call.def_id) || cx.tcx.item_name(macro_call.def_id) == sym::unreachable
-    }) {
-        return false;
-    }
-    match &expr.kind {
-        ExprKind::Block(block, _) => is_relevant_block(cx, typeck_results, block),
-        ExprKind::Ret(Some(e)) => is_relevant_expr(cx, typeck_results, e),
-        ExprKind::Ret(None) | ExprKind::Break(_, None) => false,
-        _ => true,
-    }
-}
-
-fn check_attrs(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
-    if span.from_expansion() {
-        return;
-    }
-
-    for attr in attrs {
-        if let Some(values) = attr.meta_item_list() {
-            if values.len() != 1 || !attr.has_name(sym::inline) {
-                continue;
-            }
-            if is_word(&values[0], sym::always) {
-                span_lint(
-                    cx,
-                    INLINE_ALWAYS,
-                    attr.span,
-                    &format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
-                );
-            }
-        }
-    }
-}
-
-fn check_deprecated_since(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
-    if let LitKind::Str(is, _) = lit.kind {
-        if is.as_str() == "TBD" || Version::parse(is.as_str()).is_ok() {
-            return;
-        }
-    }
-    span_lint(
-        cx,
-        DEPRECATED_SEMVER,
-        span,
-        "the since field must contain a semver-compliant version",
-    );
-}
-
-fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
-    if let NestedMetaItem::MetaItem(mi) = &nmi {
-        mi.is_word() && mi.has_name(expected)
-    } else {
-        false
-    }
-}
-
-pub struct EarlyAttributes {
-    pub msrv: Msrv,
-}
-
-impl_lint_pass!(EarlyAttributes => [
-    DEPRECATED_CFG_ATTR,
-    MISMATCHED_TARGET_OS,
-    EMPTY_LINE_AFTER_OUTER_ATTR,
-    EMPTY_LINE_AFTER_DOC_COMMENTS,
-    NON_MINIMAL_CFG,
-    MAYBE_MISUSED_CFG,
-    DEPRECATED_CLIPPY_CFG_ATTR,
-    UNNECESSARY_CLIPPY_CFG,
-]);
-
-impl EarlyLintPass for EarlyAttributes {
-    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
-        check_empty_line_after_outer_attr(cx, item);
-    }
-
-    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
-        check_deprecated_cfg_attr(cx, attr, &self.msrv);
-        check_deprecated_cfg(cx, attr);
-        check_mismatched_target_os(cx, attr);
-        check_minimal_cfg_condition(cx, attr);
-        check_misused_cfg(cx, attr);
-    }
-
-    extract_msrv_attr!(EarlyContext);
-}
-
-/// Check for empty lines after outer attributes.
-///
-/// Attributes and documentation comments are both considered outer attributes
-/// by the AST. However, the average user likely considers them to be different.
-/// Checking for empty lines after each of these attributes is split into two different
-/// lints but can share the same logic.
-fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
-    let mut iter = item.attrs.iter().peekable();
-    while let Some(attr) = iter.next() {
-        if (matches!(attr.kind, AttrKind::Normal(..)) || matches!(attr.kind, AttrKind::DocComment(..)))
-            && attr.style == AttrStyle::Outer
-            && is_present_in_source(cx, attr.span)
-        {
-            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
-            let end_of_attr_to_next_attr_or_item = Span::new(
-                attr.span.hi(),
-                iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
-                item.span.ctxt(),
-                item.span.parent(),
-            );
-
-            if let Some(snippet) = snippet_opt(cx, end_of_attr_to_next_attr_or_item) {
-                let lines = snippet.split('\n').collect::<Vec<_>>();
-                let lines = without_block_comments(lines);
-
-                if lines.iter().filter(|l| l.trim().is_empty()).count() > 2 {
-                    let (lint_msg, lint_type) = match attr.kind {
-                        AttrKind::DocComment(..) => (
-                            "found an empty line after a doc comment. \
-                            Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?",
-                            EMPTY_LINE_AFTER_DOC_COMMENTS,
-                        ),
-                        AttrKind::Normal(..) => (
-                            "found an empty line after an outer attribute. \
-                            Perhaps you forgot to add a `!` to make it an inner attribute?",
-                            EMPTY_LINE_AFTER_OUTER_ATTR,
-                        ),
-                    };
-
-                    span_lint(cx, lint_type, begin_of_attr_to_item, lint_msg);
-                }
-            }
-        }
-    }
-}
-
-fn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {
-    if item.has_name(sym::feature) && item.value_str().is_some_and(|v| v.as_str() == "cargo-clippy") {
-        span_lint_and_sugg(
-            cx,
-            DEPRECATED_CLIPPY_CFG_ATTR,
-            item.span,
-            "`feature = \"cargo-clippy\"` was replaced by `clippy`",
-            "replace with",
-            "clippy".to_string(),
-            Applicability::MachineApplicable,
-        );
-    }
-}
-
-fn check_deprecated_cfg_recursively(cx: &EarlyContext<'_>, attr: &rustc_ast::MetaItem) {
-    if let Some(ident) = attr.ident() {
-        if ["any", "all", "not"].contains(&ident.name.as_str()) {
-            let Some(list) = attr.meta_item_list() else { return };
-            for item in list.iter().filter_map(|item| item.meta_item()) {
-                check_deprecated_cfg_recursively(cx, item);
-            }
-        } else {
-            check_cargo_clippy_attr(cx, attr);
-        }
-    }
-}
-
-fn check_deprecated_cfg(cx: &EarlyContext<'_>, attr: &Attribute) {
-    if attr.has_name(sym::cfg)
-        && let Some(list) = attr.meta_item_list()
-    {
-        for item in list.iter().filter_map(|item| item.meta_item()) {
-            check_deprecated_cfg_recursively(cx, item);
-        }
-    }
-}
-
-fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) {
-    // check cfg_attr
-    if attr.has_name(sym::cfg_attr)
-        && let Some(items) = attr.meta_item_list()
-        && items.len() == 2
-        && let Some(feature_item) = items[0].meta_item()
-    {
-        // check for `rustfmt`
-        if feature_item.has_name(sym::rustfmt)
-            && msrv.meets(msrvs::TOOL_ATTRIBUTES)
-            // check for `rustfmt_skip` and `rustfmt::skip`
-            && let Some(skip_item) = &items[1].meta_item()
-            && (skip_item.has_name(sym!(rustfmt_skip))
-                || skip_item
-                    .path
-                    .segments
-                    .last()
-                    .expect("empty path in attribute")
-                    .ident
-                    .name
-                    == sym::skip)
-            // Only lint outer attributes, because custom inner attributes are unstable
-            // Tracking issue: https://github.com/rust-lang/rust/issues/54726
-            && attr.style == AttrStyle::Outer
-        {
-            span_lint_and_sugg(
-                cx,
-                DEPRECATED_CFG_ATTR,
-                attr.span,
-                "`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes",
-                "use",
-                "#[rustfmt::skip]".to_string(),
-                Applicability::MachineApplicable,
-            );
-        } else {
-            check_deprecated_cfg_recursively(cx, feature_item);
-            if let Some(behind_cfg_attr) = items[1].meta_item() {
-                check_clippy_cfg_attr(cx, feature_item, behind_cfg_attr, attr);
-            }
-        }
-    }
-}
-
-fn check_clippy_cfg_attr(
-    cx: &EarlyContext<'_>,
-    cfg_attr: &rustc_ast::MetaItem,
-    behind_cfg_attr: &rustc_ast::MetaItem,
-    attr: &Attribute,
-) {
-    if cfg_attr.has_name(sym::clippy)
-        && let Some(ident) = behind_cfg_attr.ident()
-        && Level::from_symbol(ident.name, Some(attr.id)).is_some()
-        && let Some(items) = behind_cfg_attr.meta_item_list()
-    {
-        let nb_items = items.len();
-        let mut clippy_lints = Vec::with_capacity(items.len());
-        for item in items {
-            if let Some(meta_item) = item.meta_item()
-                && let [part1, _] = meta_item.path.segments.as_slice()
-                && part1.ident.name == sym::clippy
-            {
-                clippy_lints.push(item.span());
-            }
-        }
-        if clippy_lints.is_empty() {
-            return;
-        }
-        if nb_items == clippy_lints.len() {
-            if let Some(snippet) = snippet_opt(cx, behind_cfg_attr.span) {
-                span_lint_and_sugg(
-                    cx,
-                    UNNECESSARY_CLIPPY_CFG,
-                    attr.span,
-                    "no need to put clippy lints behind a `clippy` cfg",
-                    "replace with",
-                    format!(
-                        "#{}[{}]",
-                        if attr.style == AttrStyle::Inner { "!" } else { "" },
-                        snippet
-                    ),
-                    Applicability::MachineApplicable,
-                );
-            }
-        } else {
-            let snippet = clippy_lints
-                .iter()
-                .filter_map(|sp| snippet_opt(cx, *sp))
-                .collect::<Vec<_>>()
-                .join(",");
-            span_lint_and_note(
-                cx,
-                UNNECESSARY_CLIPPY_CFG,
-                clippy_lints,
-                "no need to put clippy lints behind a `clippy` cfg",
-                None,
-                &format!(
-                    "write instead: `#{}[{}({})]`",
-                    if attr.style == AttrStyle::Inner { "!" } else { "" },
-                    ident.name,
-                    snippet
-                ),
-            );
-        }
-    }
-}
-
-fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
-    for item in items {
-        if let NestedMetaItem::MetaItem(meta) = item {
-            if !meta.has_name(sym::any) && !meta.has_name(sym::all) {
-                continue;
-            }
-            if let MetaItemKind::List(list) = &meta.kind {
-                check_nested_cfg(cx, list);
-                if list.len() == 1 {
-                    span_lint_and_then(
-                        cx,
-                        NON_MINIMAL_CFG,
-                        meta.span,
-                        "unneeded sub `cfg` when there is only one condition",
-                        |diag| {
-                            if let Some(snippet) = snippet_opt(cx, list[0].span()) {
-                                diag.span_suggestion(meta.span, "try", snippet, Applicability::MaybeIncorrect);
-                            }
-                        },
-                    );
-                } else if list.is_empty() && meta.has_name(sym::all) {
-                    span_lint_and_then(
-                        cx,
-                        NON_MINIMAL_CFG,
-                        meta.span,
-                        "unneeded sub `cfg` when there is no condition",
-                        |_| {},
-                    );
-                }
-            }
-        }
-    }
-}
-
-fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
-    for item in items {
-        if let NestedMetaItem::MetaItem(meta) = item {
-            if let Some(ident) = meta.ident()
-                && ident.name.as_str() == "features"
-                && let Some(val) = meta.value_str()
-            {
-                span_lint_and_sugg(
-                    cx,
-                    MAYBE_MISUSED_CFG,
-                    meta.span,
-                    "'feature' may be misspelled as 'features'",
-                    "did you mean",
-                    format!("feature = \"{val}\""),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            if let MetaItemKind::List(list) = &meta.kind {
-                check_nested_misused_cfg(cx, list);
-            // If this is not a list, then we check for `cfg(test)`.
-            } else if let Some(ident) = meta.ident()
-                && matches!(ident.name.as_str(), "tests" | "Test")
-            {
-                span_lint_and_sugg(
-                    cx,
-                    MAYBE_MISUSED_CFG,
-                    meta.span,
-                    &format!("'test' may be misspelled as '{}'", ident.name.as_str()),
-                    "did you mean",
-                    "test".to_string(),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-        }
-    }
-}
-
-fn check_minimal_cfg_condition(cx: &EarlyContext<'_>, attr: &Attribute) {
-    if attr.has_name(sym::cfg)
-        && let Some(items) = attr.meta_item_list()
-    {
-        check_nested_cfg(cx, &items);
-    }
-}
-
-fn check_misused_cfg(cx: &EarlyContext<'_>, attr: &Attribute) {
-    if attr.has_name(sym::cfg)
-        && let Some(items) = attr.meta_item_list()
-    {
-        check_nested_misused_cfg(cx, &items);
-    }
-}
-
-fn check_mismatched_target_os(cx: &EarlyContext<'_>, attr: &Attribute) {
-    fn find_os(name: &str) -> Option<&'static str> {
-        UNIX_SYSTEMS
-            .iter()
-            .chain(NON_UNIX_SYSTEMS.iter())
-            .find(|&&os| os == name)
-            .copied()
-    }
-
-    fn is_unix(name: &str) -> bool {
-        UNIX_SYSTEMS.iter().any(|&os| os == name)
-    }
-
-    fn find_mismatched_target_os(items: &[NestedMetaItem]) -> Vec<(&str, Span)> {
-        let mut mismatched = Vec::new();
-
-        for item in items {
-            if let NestedMetaItem::MetaItem(meta) = item {
-                match &meta.kind {
-                    MetaItemKind::List(list) => {
-                        mismatched.extend(find_mismatched_target_os(list));
-                    },
-                    MetaItemKind::Word => {
-                        if let Some(ident) = meta.ident()
-                            && let Some(os) = find_os(ident.name.as_str())
-                        {
-                            mismatched.push((os, ident.span));
-                        }
-                    },
-                    MetaItemKind::NameValue(..) => {},
-                }
-            }
-        }
-
-        mismatched
-    }
-
-    if attr.has_name(sym::cfg)
-        && let Some(list) = attr.meta_item_list()
-        && let mismatched = find_mismatched_target_os(&list)
-        && !mismatched.is_empty()
-    {
-        let mess = "operating system used in target family position";
-
-        span_lint_and_then(cx, MISMATCHED_TARGET_OS, attr.span, mess, |diag| {
-            // Avoid showing the unix suggestion multiple times in case
-            // we have more than one mismatch for unix-like systems
-            let mut unix_suggested = false;
-
-            for (os, span) in mismatched {
-                let sugg = format!("target_os = \"{os}\"");
-                diag.span_suggestion(span, "try", sugg, Applicability::MaybeIncorrect);
-
-                if !unix_suggested && is_unix(os) {
-                    diag.help("did you mean `unix`?");
-                    unix_suggested = true;
-                }
-            }
-        });
-    }
-}
-
-fn is_lint_level(symbol: Symbol) -> bool {
-    matches!(symbol, sym::allow | sym::expect | sym::warn | sym::deny | sym::forbid)
-}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
new file mode 100644
index 00000000000..df00f23e37e
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
@@ -0,0 +1,37 @@
+use super::{Attribute, ALLOW_ATTRIBUTES_WITHOUT_REASON};
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::is_from_proc_macro;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_lint::{LateContext, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_span::sym;
+use rustc_span::symbol::Symbol;
+
+pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMetaItem], attr: &'cx Attribute) {
+    // Check for the feature
+    if !cx.tcx.features().lint_reasons {
+        return;
+    }
+
+    // Check if the reason is present
+    if let Some(item) = items.last().and_then(NestedMetaItem::meta_item)
+        && let MetaItemKind::NameValue(_) = &item.kind
+        && item.path == sym::reason
+    {
+        return;
+    }
+
+    // Check if the attribute is in an external macro and therefore out of the developer's control
+    if in_external_macro(cx.sess(), attr.span) || is_from_proc_macro(cx, &attr) {
+        return;
+    }
+
+    span_lint_and_help(
+        cx,
+        ALLOW_ATTRIBUTES_WITHOUT_REASON,
+        attr.span,
+        &format!("`{}` attribute without specifying a reason", name.as_str()),
+        None,
+        "try adding a reason at the end with `, reason = \"..\"`",
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs b/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
new file mode 100644
index 00000000000..9b08fd6d654
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/blanket_clippy_restriction_lints.rs
@@ -0,0 +1,44 @@
+use super::utils::extract_clippy_lint;
+use super::BLANKET_CLIPPY_RESTRICTION_LINTS;
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
+use rustc_ast::NestedMetaItem;
+use rustc_lint::{LateContext, Level, LintContext};
+use rustc_span::symbol::Symbol;
+use rustc_span::{sym, DUMMY_SP};
+
+pub(super) fn check(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
+    for lint in items {
+        if let Some(lint_name) = extract_clippy_lint(lint) {
+            if lint_name.as_str() == "restriction" && name != sym::allow {
+                span_lint_and_help(
+                    cx,
+                    BLANKET_CLIPPY_RESTRICTION_LINTS,
+                    lint.span(),
+                    "`clippy::restriction` is not meant to be enabled as a group",
+                    None,
+                    "enable the restriction lints you need individually",
+                );
+            }
+        }
+    }
+}
+
+pub(super) fn check_command_line(cx: &LateContext<'_>) {
+    for (name, level) in &cx.sess().opts.lint_opts {
+        if name == "clippy::restriction" && *level > Level::Allow {
+            span_lint_and_then(
+                cx,
+                BLANKET_CLIPPY_RESTRICTION_LINTS,
+                DUMMY_SP,
+                "`clippy::restriction` is not meant to be enabled as a group",
+                |diag| {
+                    diag.note(format!(
+                        "because of the command line `--{} clippy::restriction`",
+                        level.as_str()
+                    ));
+                    diag.help("enable the restriction lints you need individually");
+                },
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
new file mode 100644
index 00000000000..e872ab6b4b5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_cfg_attr.rs
@@ -0,0 +1,87 @@
+use super::{unnecessary_clippy_cfg, Attribute, DEPRECATED_CFG_ATTR, DEPRECATED_CLIPPY_CFG_ATTR};
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::AttrStyle;
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute, msrv: &Msrv) {
+    // check cfg_attr
+    if attr.has_name(sym::cfg_attr)
+        && let Some(items) = attr.meta_item_list()
+        && items.len() == 2
+        && let Some(feature_item) = items[0].meta_item()
+    {
+        // check for `rustfmt`
+        if feature_item.has_name(sym::rustfmt)
+            && msrv.meets(msrvs::TOOL_ATTRIBUTES)
+            // check for `rustfmt_skip` and `rustfmt::skip`
+            && let Some(skip_item) = &items[1].meta_item()
+            && (skip_item.has_name(sym!(rustfmt_skip))
+                || skip_item
+                    .path
+                    .segments
+                    .last()
+                    .expect("empty path in attribute")
+                    .ident
+                    .name
+                    == sym::skip)
+            // Only lint outer attributes, because custom inner attributes are unstable
+            // Tracking issue: https://github.com/rust-lang/rust/issues/54726
+            && attr.style == AttrStyle::Outer
+        {
+            span_lint_and_sugg(
+                cx,
+                DEPRECATED_CFG_ATTR,
+                attr.span,
+                "`cfg_attr` is deprecated for rustfmt and got replaced by tool attributes",
+                "use",
+                "#[rustfmt::skip]".to_string(),
+                Applicability::MachineApplicable,
+            );
+        } else {
+            check_deprecated_cfg_recursively(cx, feature_item);
+            if let Some(behind_cfg_attr) = items[1].meta_item() {
+                unnecessary_clippy_cfg::check(cx, feature_item, behind_cfg_attr, attr);
+            }
+        }
+    }
+}
+
+pub(super) fn check_clippy(cx: &EarlyContext<'_>, attr: &Attribute) {
+    if attr.has_name(sym::cfg)
+        && let Some(list) = attr.meta_item_list()
+    {
+        for item in list.iter().filter_map(|item| item.meta_item()) {
+            check_deprecated_cfg_recursively(cx, item);
+        }
+    }
+}
+
+fn check_deprecated_cfg_recursively(cx: &EarlyContext<'_>, attr: &rustc_ast::MetaItem) {
+    if let Some(ident) = attr.ident() {
+        if ["any", "all", "not"].contains(&ident.name.as_str()) {
+            let Some(list) = attr.meta_item_list() else { return };
+            for item in list.iter().filter_map(|item| item.meta_item()) {
+                check_deprecated_cfg_recursively(cx, item);
+            }
+        } else {
+            check_cargo_clippy_attr(cx, attr);
+        }
+    }
+}
+
+fn check_cargo_clippy_attr(cx: &EarlyContext<'_>, item: &rustc_ast::MetaItem) {
+    if item.has_name(sym::feature) && item.value_str().is_some_and(|v| v.as_str() == "cargo-clippy") {
+        span_lint_and_sugg(
+            cx,
+            DEPRECATED_CLIPPY_CFG_ATTR,
+            item.span,
+            "`feature = \"cargo-clippy\"` was replaced by `clippy`",
+            "replace with",
+            "clippy".to_string(),
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs b/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs
new file mode 100644
index 00000000000..1898c145c76
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/deprecated_semver.rs
@@ -0,0 +1,20 @@
+use super::DEPRECATED_SEMVER;
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::{LitKind, MetaItemLit};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+use semver::Version;
+
+pub(super) fn check(cx: &LateContext<'_>, span: Span, lit: &MetaItemLit) {
+    if let LitKind::Str(is, _) = lit.kind {
+        if is.as_str() == "TBD" || Version::parse(is.as_str()).is_ok() {
+            return;
+        }
+    }
+    span_lint(
+        cx,
+        DEPRECATED_SEMVER,
+        span,
+        "the since field must contain a semver-compliant version",
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs b/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
new file mode 100644
index 00000000000..ca43e76ac57
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/empty_line_after.rs
@@ -0,0 +1,52 @@
+use super::{EMPTY_LINE_AFTER_DOC_COMMENTS, EMPTY_LINE_AFTER_OUTER_ATTR};
+use clippy_utils::diagnostics::span_lint;
+use clippy_utils::source::{is_present_in_source, snippet_opt, without_block_comments};
+use rustc_ast::{AttrKind, AttrStyle};
+use rustc_lint::EarlyContext;
+use rustc_span::Span;
+
+/// Check for empty lines after outer attributes.
+///
+/// Attributes and documentation comments are both considered outer attributes
+/// by the AST. However, the average user likely considers them to be different.
+/// Checking for empty lines after each of these attributes is split into two different
+/// lints but can share the same logic.
+pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
+    let mut iter = item.attrs.iter().peekable();
+    while let Some(attr) = iter.next() {
+        if (matches!(attr.kind, AttrKind::Normal(..)) || matches!(attr.kind, AttrKind::DocComment(..)))
+            && attr.style == AttrStyle::Outer
+            && is_present_in_source(cx, attr.span)
+        {
+            let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
+            let end_of_attr_to_next_attr_or_item = Span::new(
+                attr.span.hi(),
+                iter.peek().map_or(item.span.lo(), |next_attr| next_attr.span.lo()),
+                item.span.ctxt(),
+                item.span.parent(),
+            );
+
+            if let Some(snippet) = snippet_opt(cx, end_of_attr_to_next_attr_or_item) {
+                let lines = snippet.split('\n').collect::<Vec<_>>();
+                let lines = without_block_comments(lines);
+
+                if lines.iter().filter(|l| l.trim().is_empty()).count() > 2 {
+                    let (lint_msg, lint_type) = match attr.kind {
+                        AttrKind::DocComment(..) => (
+                            "found an empty line after a doc comment. \
+                            Perhaps you need to use `//!` to make a comment on a module, remove the empty line, or make a regular comment with `//`?",
+                            EMPTY_LINE_AFTER_DOC_COMMENTS,
+                        ),
+                        AttrKind::Normal(..) => (
+                            "found an empty line after an outer attribute. \
+                            Perhaps you forgot to add a `!` to make it an inner attribute?",
+                            EMPTY_LINE_AFTER_OUTER_ATTR,
+                        ),
+                    };
+
+                    span_lint(cx, lint_type, begin_of_attr_to_item, lint_msg);
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
new file mode 100644
index 00000000000..cfcd2cc6a00
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
@@ -0,0 +1,29 @@
+use super::utils::is_word;
+use super::INLINE_ALWAYS;
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::Attribute;
+use rustc_lint::LateContext;
+use rustc_span::symbol::Symbol;
+use rustc_span::{sym, Span};
+
+pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Attribute]) {
+    if span.from_expansion() {
+        return;
+    }
+
+    for attr in attrs {
+        if let Some(values) = attr.meta_item_list() {
+            if values.len() != 1 || !attr.has_name(sym::inline) {
+                continue;
+            }
+            if is_word(&values[0], sym::always) {
+                span_lint(
+                    cx,
+                    INLINE_ALWAYS,
+                    attr.span,
+                    &format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs
new file mode 100644
index 00000000000..5a70866eda5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs
@@ -0,0 +1,51 @@
+use super::{Attribute, MAYBE_MISUSED_CFG};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
+    if attr.has_name(sym::cfg)
+        && let Some(items) = attr.meta_item_list()
+    {
+        check_nested_misused_cfg(cx, &items);
+    }
+}
+
+fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
+    for item in items {
+        if let NestedMetaItem::MetaItem(meta) = item {
+            if let Some(ident) = meta.ident()
+                && ident.name.as_str() == "features"
+                && let Some(val) = meta.value_str()
+            {
+                span_lint_and_sugg(
+                    cx,
+                    MAYBE_MISUSED_CFG,
+                    meta.span,
+                    "'feature' may be misspelled as 'features'",
+                    "did you mean",
+                    format!("feature = \"{val}\""),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            if let MetaItemKind::List(list) = &meta.kind {
+                check_nested_misused_cfg(cx, list);
+            // If this is not a list, then we check for `cfg(test)`.
+            } else if let Some(ident) = meta.ident()
+                && matches!(ident.name.as_str(), "tests" | "Test")
+            {
+                span_lint_and_sugg(
+                    cx,
+                    MAYBE_MISUSED_CFG,
+                    meta.span,
+                    &format!("'test' may be misspelled as '{}'", ident.name.as_str()),
+                    "did you mean",
+                    "test".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs b/src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs
new file mode 100644
index 00000000000..b1cc0a763c5
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/mismatched_target_os.rs
@@ -0,0 +1,90 @@
+use super::{Attribute, MISMATCHED_TARGET_OS};
+use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::{sym, Span};
+
+static UNIX_SYSTEMS: &[&str] = &[
+    "android",
+    "dragonfly",
+    "emscripten",
+    "freebsd",
+    "fuchsia",
+    "haiku",
+    "illumos",
+    "ios",
+    "l4re",
+    "linux",
+    "macos",
+    "netbsd",
+    "openbsd",
+    "redox",
+    "solaris",
+    "vxworks",
+];
+
+// NOTE: windows is excluded from the list because it's also a valid target family.
+static NON_UNIX_SYSTEMS: &[&str] = &["hermit", "none", "wasi"];
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
+    fn find_os(name: &str) -> Option<&'static str> {
+        UNIX_SYSTEMS
+            .iter()
+            .chain(NON_UNIX_SYSTEMS.iter())
+            .find(|&&os| os == name)
+            .copied()
+    }
+
+    fn is_unix(name: &str) -> bool {
+        UNIX_SYSTEMS.iter().any(|&os| os == name)
+    }
+
+    fn find_mismatched_target_os(items: &[NestedMetaItem]) -> Vec<(&str, Span)> {
+        let mut mismatched = Vec::new();
+
+        for item in items {
+            if let NestedMetaItem::MetaItem(meta) = item {
+                match &meta.kind {
+                    MetaItemKind::List(list) => {
+                        mismatched.extend(find_mismatched_target_os(list));
+                    },
+                    MetaItemKind::Word => {
+                        if let Some(ident) = meta.ident()
+                            && let Some(os) = find_os(ident.name.as_str())
+                        {
+                            mismatched.push((os, ident.span));
+                        }
+                    },
+                    MetaItemKind::NameValue(..) => {},
+                }
+            }
+        }
+
+        mismatched
+    }
+
+    if attr.has_name(sym::cfg)
+        && let Some(list) = attr.meta_item_list()
+        && let mismatched = find_mismatched_target_os(&list)
+        && !mismatched.is_empty()
+    {
+        let mess = "operating system used in target family position";
+
+        span_lint_and_then(cx, MISMATCHED_TARGET_OS, attr.span, mess, |diag| {
+            // Avoid showing the unix suggestion multiple times in case
+            // we have more than one mismatch for unix-like systems
+            let mut unix_suggested = false;
+
+            for (os, span) in mismatched {
+                let sugg = format!("target_os = \"{os}\"");
+                diag.span_suggestion(span, "try", sugg, Applicability::MaybeIncorrect);
+
+                if !unix_suggested && is_unix(os) {
+                    diag.help("did you mean `unix`?");
+                    unix_suggested = true;
+                }
+            }
+        });
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
new file mode 100644
index 00000000000..c2e21cfd330
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
@@ -0,0 +1,30 @@
+use super::MIXED_ATTRIBUTES_STYLE;
+use clippy_utils::diagnostics::span_lint;
+use rustc_ast::AttrStyle;
+use rustc_lint::EarlyContext;
+
+pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
+    let mut has_outer = false;
+    let mut has_inner = false;
+
+    for attr in &item.attrs {
+        if attr.span.from_expansion() {
+            continue;
+        }
+        match attr.style {
+            AttrStyle::Inner => has_inner = true,
+            AttrStyle::Outer => has_outer = true,
+        }
+    }
+    if !has_outer || !has_inner {
+        return;
+    }
+    let mut attrs_iter = item.attrs.iter().filter(|attr| !attr.span.from_expansion());
+    let span = attrs_iter.next().unwrap().span;
+    span_lint(
+        cx,
+        MIXED_ATTRIBUTES_STYLE,
+        span.with_hi(attrs_iter.last().unwrap().span.hi()),
+        "item has both inner and outer attributes",
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
new file mode 100644
index 00000000000..c4c65d3248a
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -0,0 +1,588 @@
+//! checks for attributes
+
+mod allow_attributes_without_reason;
+mod blanket_clippy_restriction_lints;
+mod deprecated_cfg_attr;
+mod deprecated_semver;
+mod empty_line_after;
+mod inline_always;
+mod maybe_misused_cfg;
+mod mismatched_target_os;
+mod mixed_attributes_style;
+mod non_minimal_cfg;
+mod should_panic_without_expect;
+mod unnecessary_clippy_cfg;
+mod useless_attribute;
+mod utils;
+
+use clippy_config::msrvs::Msrv;
+use rustc_ast::{Attribute, MetaItemKind, NestedMetaItem};
+use rustc_hir::{ImplItem, Item, ItemKind, TraitItem};
+use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, impl_lint_pass};
+use rustc_span::sym;
+use utils::{is_lint_level, is_relevant_impl, is_relevant_item, is_relevant_trait};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for items annotated with `#[inline(always)]`,
+    /// unless the annotated function is empty or simply panics.
+    ///
+    /// ### Why is this bad?
+    /// While there are valid uses of this annotation (and once
+    /// you know when to use it, by all means `allow` this lint), it's a common
+    /// newbie-mistake to pepper one's code with it.
+    ///
+    /// As a rule of thumb, before slapping `#[inline(always)]` on a function,
+    /// measure if that additional function call really affects your runtime profile
+    /// sufficiently to make up for the increase in compile time.
+    ///
+    /// ### Known problems
+    /// False positives, big time. This lint is meant to be
+    /// deactivated by everyone doing serious performance work. This means having
+    /// done the measurement.
+    ///
+    /// ### Example
+    /// ```ignore
+    /// #[inline(always)]
+    /// fn not_quite_hot_code(..) { ... }
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub INLINE_ALWAYS,
+    pedantic,
+    "use of `#[inline(always)]`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `extern crate` and `use` items annotated with
+    /// lint attributes.
+    ///
+    /// This lint permits lint attributes for lints emitted on the items themself.
+    /// For `use` items these lints are:
+    /// * deprecated
+    /// * unreachable_pub
+    /// * unused_imports
+    /// * clippy::enum_glob_use
+    /// * clippy::macro_use_imports
+    /// * clippy::wildcard_imports
+    ///
+    /// For `extern crate` items these lints are:
+    /// * `unused_imports` on items with `#[macro_use]`
+    ///
+    /// ### Why is this bad?
+    /// Lint attributes have no effect on crate imports. Most
+    /// likely a `!` was forgotten.
+    ///
+    /// ### Example
+    /// ```ignore
+    /// #[deny(dead_code)]
+    /// extern crate foo;
+    /// #[forbid(dead_code)]
+    /// use foo::bar;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust,ignore
+    /// #[allow(unused_imports)]
+    /// use foo::baz;
+    /// #[allow(unused_imports)]
+    /// #[macro_use]
+    /// extern crate baz;
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub USELESS_ATTRIBUTE,
+    correctness,
+    "use of lint attributes on `extern crate` items"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[deprecated]` annotations with a `since`
+    /// field that is not a valid semantic version. Also allows "TBD" to signal
+    /// future deprecation.
+    ///
+    /// ### Why is this bad?
+    /// For checking the version of the deprecation, it must be
+    /// a valid semver. Failing that, the contained information is useless.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[deprecated(since = "forever")]
+    /// fn something_else() { /* ... */ }
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub DEPRECATED_SEMVER,
+    correctness,
+    "use of `#[deprecated(since = \"x\")]` where x is not semver"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after outer attributes
+    ///
+    /// ### Why is this bad?
+    /// Most likely the attribute was meant to be an inner attribute using a '!'.
+    /// If it was meant to be an outer attribute, then the following item
+    /// should not be separated by empty lines.
+    ///
+    /// ### Known problems
+    /// Can cause false positives.
+    ///
+    /// From the clippy side it's difficult to detect empty lines between an attributes and the
+    /// following item because empty lines and comments are not part of the AST. The parsing
+    /// currently works for basic cases but is not perfect.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[allow(dead_code)]
+    ///
+    /// fn not_quite_good_code() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// // Good (as inner attribute)
+    /// #![allow(dead_code)]
+    ///
+    /// fn this_is_fine() { }
+    ///
+    /// // or
+    ///
+    /// // Good (as outer attribute)
+    /// #[allow(dead_code)]
+    /// fn this_is_fine_too() { }
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub EMPTY_LINE_AFTER_OUTER_ATTR,
+    nursery,
+    "empty line after outer attribute"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for empty lines after documentation comments.
+    ///
+    /// ### Why is this bad?
+    /// The documentation comment was most likely meant to be an inner attribute or regular comment.
+    /// If it was intended to be a documentation comment, then the empty line should be removed to
+    /// be more idiomatic.
+    ///
+    /// ### Known problems
+    /// Only detects empty lines immediately following the documentation. If the doc comment is followed
+    /// by an attribute and then an empty line, this lint will not trigger. Use `empty_line_after_outer_attr`
+    /// in combination with this lint to detect both cases.
+    ///
+    /// Does not detect empty lines after doc attributes (e.g. `#[doc = ""]`).
+    ///
+    /// ### Example
+    /// ```no_run
+    /// /// Some doc comment with a blank line after it.
+    ///
+    /// fn not_quite_good_code() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// /// Good (no blank line)
+    /// fn this_is_fine() { }
+    /// ```
+    ///
+    /// ```no_run
+    /// // Good (convert to a regular comment)
+    ///
+    /// fn this_is_fine_too() { }
+    /// ```
+    ///
+    /// ```no_run
+    /// //! Good (convert to a comment on an inner attribute)
+    ///
+    /// fn this_is_fine_as_well() { }
+    /// ```
+    #[clippy::version = "1.70.0"]
+    pub EMPTY_LINE_AFTER_DOC_COMMENTS,
+    nursery,
+    "empty line after documentation comments"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `warn`/`deny`/`forbid` attributes targeting the whole clippy::restriction category.
+    ///
+    /// ### Why is this bad?
+    /// Restriction lints sometimes are in contrast with other lints or even go against idiomatic rust.
+    /// These lints should only be enabled on a lint-by-lint basis and with careful consideration.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #![deny(clippy::restriction)]
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #![deny(clippy::as_conversions)]
+    /// ```
+    #[clippy::version = "1.47.0"]
+    pub BLANKET_CLIPPY_RESTRICTION_LINTS,
+    suspicious,
+    "enabling the complete restriction group"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg_attr(rustfmt, rustfmt_skip)]` and suggests to replace it
+    /// with `#[rustfmt::skip]`.
+    ///
+    /// ### Why is this bad?
+    /// Since tool_attributes ([rust-lang/rust#44690](https://github.com/rust-lang/rust/issues/44690))
+    /// are stable now, they should be used instead of the old `cfg_attr(rustfmt)` attributes.
+    ///
+    /// ### Known problems
+    /// This lint doesn't detect crate level inner attributes, because they get
+    /// processed before the PreExpansionPass lints get executed. See
+    /// [#3123](https://github.com/rust-lang/rust-clippy/pull/3123#issuecomment-422321765)
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg_attr(rustfmt, rustfmt_skip)]
+    /// fn main() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[rustfmt::skip]
+    /// fn main() { }
+    /// ```
+    #[clippy::version = "1.32.0"]
+    pub DEPRECATED_CFG_ATTR,
+    complexity,
+    "usage of `cfg_attr(rustfmt)` instead of tool attributes"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for cfg attributes having operating systems used in target family position.
+    ///
+    /// ### Why is this bad?
+    /// The configuration option will not be recognised and the related item will not be included
+    /// by the conditional compilation engine.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(linux)]
+    /// fn conditional() { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// # mod hidden {
+    /// #[cfg(target_os = "linux")]
+    /// fn conditional() { }
+    /// # }
+    ///
+    /// // or
+    ///
+    /// #[cfg(unix)]
+    /// fn conditional() { }
+    /// ```
+    /// Check the [Rust Reference](https://doc.rust-lang.org/reference/conditional-compilation.html#target_os) for more details.
+    #[clippy::version = "1.45.0"]
+    pub MISMATCHED_TARGET_OS,
+    correctness,
+    "usage of `cfg(operating_system)` instead of `cfg(target_os = \"operating_system\")`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for attributes that allow lints without a reason.
+    ///
+    /// (This requires the `lint_reasons` feature)
+    ///
+    /// ### Why is this bad?
+    /// Allowing a lint should always have a reason. This reason should be documented to
+    /// ensure that others understand the reasoning
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #![feature(lint_reasons)]
+    ///
+    /// #![allow(clippy::some_lint)]
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #![feature(lint_reasons)]
+    ///
+    /// #![allow(clippy::some_lint, reason = "False positive rust-lang/rust-clippy#1002020")]
+    /// ```
+    #[clippy::version = "1.61.0"]
+    pub ALLOW_ATTRIBUTES_WITHOUT_REASON,
+    restriction,
+    "ensures that all `allow` and `expect` attributes have a reason"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[should_panic]` attributes without specifying the expected panic message.
+    ///
+    /// ### Why is this bad?
+    /// The expected panic message should be specified to ensure that the test is actually
+    /// panicking with the expected message, and not another unrelated panic.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// fn random() -> i32 { 0 }
+    ///
+    /// #[should_panic]
+    /// #[test]
+    /// fn my_test() {
+    ///     let _ = 1 / random();
+    /// }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// fn random() -> i32 { 0 }
+    ///
+    /// #[should_panic = "attempt to divide by zero"]
+    /// #[test]
+    /// fn my_test() {
+    ///     let _ = 1 / random();
+    /// }
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub SHOULD_PANIC_WITHOUT_EXPECT,
+    pedantic,
+    "ensures that all `should_panic` attributes specify its expected panic message"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `any` and `all` combinators in `cfg` with only one condition.
+    ///
+    /// ### Why is this bad?
+    /// If there is only one condition, no need to wrap it into `any` or `all` combinators.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(any(unix))]
+    /// pub struct Bar;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(unix)]
+    /// pub struct Bar;
+    /// ```
+    #[clippy::version = "1.71.0"]
+    pub NON_MINIMAL_CFG,
+    style,
+    "ensure that all `cfg(any())` and `cfg(all())` have more than one condition"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg(features = "...")]` and suggests to replace it with
+    /// `#[cfg(feature = "...")]`.
+    ///
+    /// It also checks if `cfg(test)` was misspelled.
+    ///
+    /// ### Why is this bad?
+    /// Misspelling `feature` as `features` or `test` as `tests` can be sometimes hard to spot. It
+    /// may cause conditional compilation not work quietly.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(features = "some-feature")]
+    /// fn conditional() { }
+    /// #[cfg(tests)]
+    /// mod tests { }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(feature = "some-feature")]
+    /// fn conditional() { }
+    /// #[cfg(test)]
+    /// mod tests { }
+    /// ```
+    #[clippy::version = "1.69.0"]
+    pub MAYBE_MISUSED_CFG,
+    suspicious,
+    "prevent from misusing the wrong attr name"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg_attr(feature = "cargo-clippy", ...)]` and for
+    /// `#[cfg(feature = "cargo-clippy")]` and suggests to replace it with
+    /// `#[cfg_attr(clippy, ...)]` or `#[cfg(clippy)]`.
+    ///
+    /// ### Why is this bad?
+    /// This feature has been deprecated for years and shouldn't be used anymore.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(feature = "cargo-clippy")]
+    /// struct Bar;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(clippy)]
+    /// struct Bar;
+    /// ```
+    #[clippy::version = "1.78.0"]
+    pub DEPRECATED_CLIPPY_CFG_ATTR,
+    suspicious,
+    "usage of `cfg(feature = \"cargo-clippy\")` instead of `cfg(clippy)`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `#[cfg_attr(clippy, allow(clippy::lint))]`
+    /// and suggests to replace it with `#[allow(clippy::lint)]`.
+    ///
+    /// ### Why is this bad?
+    /// There is no reason to put clippy attributes behind a clippy `cfg` as they are not
+    /// run by anything else than clippy.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #![cfg_attr(clippy, allow(clippy::deprecated_cfg_attr))]
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// #![allow(clippy::deprecated_cfg_attr)]
+    /// ```
+    #[clippy::version = "1.78.0"]
+    pub UNNECESSARY_CLIPPY_CFG,
+    suspicious,
+    "usage of `cfg_attr(clippy, allow(clippy::lint))` instead of `allow(clippy::lint)`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks that an item has only one kind of attributes.
+    ///
+    /// ### Why is this bad?
+    /// Having both kinds of attributes makes it more complicated to read code.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// #[cfg(linux)]
+    /// pub fn foo() {
+    ///     #![cfg(windows)]
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// #[cfg(linux)]
+    /// #[cfg(windows)]
+    /// pub fn foo() {
+    /// }
+    /// ```
+    #[clippy::version = "1.78.0"]
+    pub MIXED_ATTRIBUTES_STYLE,
+    suspicious,
+    "item has both inner and outer attributes"
+}
+
+declare_lint_pass!(Attributes => [
+    ALLOW_ATTRIBUTES_WITHOUT_REASON,
+    INLINE_ALWAYS,
+    DEPRECATED_SEMVER,
+    USELESS_ATTRIBUTE,
+    BLANKET_CLIPPY_RESTRICTION_LINTS,
+    SHOULD_PANIC_WITHOUT_EXPECT,
+]);
+
+impl<'tcx> LateLintPass<'tcx> for Attributes {
+    fn check_crate(&mut self, cx: &LateContext<'tcx>) {
+        blanket_clippy_restriction_lints::check_command_line(cx);
+    }
+
+    fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
+        if let Some(items) = &attr.meta_item_list() {
+            if let Some(ident) = attr.ident() {
+                if is_lint_level(ident.name, attr.id) {
+                    blanket_clippy_restriction_lints::check(cx, ident.name, items);
+                }
+                if matches!(ident.name, sym::allow | sym::expect) {
+                    allow_attributes_without_reason::check(cx, ident.name, items, attr);
+                }
+                if items.is_empty() || !attr.has_name(sym::deprecated) {
+                    return;
+                }
+                for item in items {
+                    if let NestedMetaItem::MetaItem(mi) = &item
+                        && let MetaItemKind::NameValue(lit) = &mi.kind
+                        && mi.has_name(sym::since)
+                    {
+                        deprecated_semver::check(cx, item.span(), lit);
+                    }
+                }
+            }
+        }
+        if attr.has_name(sym::should_panic) {
+            should_panic_without_expect::check(cx, attr);
+        }
+    }
+
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
+        let attrs = cx.tcx.hir().attrs(item.hir_id());
+        if is_relevant_item(cx, item) {
+            inline_always::check(cx, item.span, item.ident.name, attrs);
+        }
+        match item.kind {
+            ItemKind::ExternCrate(..) | ItemKind::Use(..) => useless_attribute::check(cx, item, attrs),
+            _ => {},
+        }
+    }
+
+    fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
+        if is_relevant_impl(cx, item) {
+            inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
+        }
+    }
+
+    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_>) {
+        if is_relevant_trait(cx, item) {
+            inline_always::check(cx, item.span, item.ident.name, cx.tcx.hir().attrs(item.hir_id()));
+        }
+    }
+}
+
+pub struct EarlyAttributes {
+    pub msrv: Msrv,
+}
+
+impl_lint_pass!(EarlyAttributes => [
+    DEPRECATED_CFG_ATTR,
+    MISMATCHED_TARGET_OS,
+    EMPTY_LINE_AFTER_OUTER_ATTR,
+    EMPTY_LINE_AFTER_DOC_COMMENTS,
+    NON_MINIMAL_CFG,
+    MAYBE_MISUSED_CFG,
+    DEPRECATED_CLIPPY_CFG_ATTR,
+    UNNECESSARY_CLIPPY_CFG,
+    MIXED_ATTRIBUTES_STYLE,
+]);
+
+impl EarlyLintPass for EarlyAttributes {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
+        empty_line_after::check(cx, item);
+        mixed_attributes_style::check(cx, item);
+    }
+
+    fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
+        deprecated_cfg_attr::check(cx, attr, &self.msrv);
+        deprecated_cfg_attr::check_clippy(cx, attr);
+        mismatched_target_os::check(cx, attr);
+        non_minimal_cfg::check(cx, attr);
+        maybe_misused_cfg::check(cx, attr);
+    }
+
+    extract_msrv_attr!(EarlyContext);
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
new file mode 100644
index 00000000000..3fde7061585
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/non_minimal_cfg.rs
@@ -0,0 +1,49 @@
+use super::{Attribute, NON_MINIMAL_CFG};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet_opt;
+use rustc_ast::{MetaItemKind, NestedMetaItem};
+use rustc_errors::Applicability;
+use rustc_lint::EarlyContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &EarlyContext<'_>, attr: &Attribute) {
+    if attr.has_name(sym::cfg)
+        && let Some(items) = attr.meta_item_list()
+    {
+        check_nested_cfg(cx, &items);
+    }
+}
+
+fn check_nested_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
+    for item in items {
+        if let NestedMetaItem::MetaItem(meta) = item {
+            if !meta.has_name(sym::any) && !meta.has_name(sym::all) {
+                continue;
+            }
+            if let MetaItemKind::List(list) = &meta.kind {
+                check_nested_cfg(cx, list);
+                if list.len() == 1 {
+                    span_lint_and_then(
+                        cx,
+                        NON_MINIMAL_CFG,
+                        meta.span,
+                        "unneeded sub `cfg` when there is only one condition",
+                        |diag| {
+                            if let Some(snippet) = snippet_opt(cx, list[0].span()) {
+                                diag.span_suggestion(meta.span, "try", snippet, Applicability::MaybeIncorrect);
+                            }
+                        },
+                    );
+                } else if list.is_empty() && meta.has_name(sym::all) {
+                    span_lint_and_then(
+                        cx,
+                        NON_MINIMAL_CFG,
+                        meta.span,
+                        "unneeded sub `cfg` when there is no condition",
+                        |_| {},
+                    );
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs
new file mode 100644
index 00000000000..2d45cbbf621
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/should_panic_without_expect.rs
@@ -0,0 +1,54 @@
+use super::{Attribute, SHOULD_PANIC_WITHOUT_EXPECT};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_ast::token::{Token, TokenKind};
+use rustc_ast::tokenstream::TokenTree;
+use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind};
+use rustc_errors::Applicability;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &LateContext<'_>, attr: &Attribute) {
+    if let AttrKind::Normal(normal_attr) = &attr.kind {
+        if let AttrArgs::Eq(_, AttrArgsEq::Hir(_)) = &normal_attr.item.args {
+            // `#[should_panic = ".."]` found, good
+            return;
+        }
+
+        if let AttrArgs::Delimited(args) = &normal_attr.item.args
+            && let mut tt_iter = args.tokens.trees()
+            && let Some(TokenTree::Token(
+                Token {
+                    kind: TokenKind::Ident(sym::expected, _),
+                    ..
+                },
+                _,
+            )) = tt_iter.next()
+            && let Some(TokenTree::Token(
+                Token {
+                    kind: TokenKind::Eq, ..
+                },
+                _,
+            )) = tt_iter.next()
+            && let Some(TokenTree::Token(
+                Token {
+                    kind: TokenKind::Literal(_),
+                    ..
+                },
+                _,
+            )) = tt_iter.next()
+        {
+            // `#[should_panic(expected = "..")]` found, good
+            return;
+        }
+
+        span_lint_and_sugg(
+            cx,
+            SHOULD_PANIC_WITHOUT_EXPECT,
+            attr.span,
+            "#[should_panic] attribute without a reason",
+            "consider specifying the expected panic",
+            "#[should_panic(expected = /* panic message */)]".into(),
+            Applicability::HasPlaceholders,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
new file mode 100644
index 00000000000..05da69636c6
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
@@ -0,0 +1,70 @@
+use super::{Attribute, UNNECESSARY_CLIPPY_CFG};
+use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg};
+use clippy_utils::source::snippet_opt;
+use rustc_ast::AttrStyle;
+use rustc_errors::Applicability;
+use rustc_lint::{EarlyContext, Level};
+use rustc_span::sym;
+
+pub(super) fn check(
+    cx: &EarlyContext<'_>,
+    cfg_attr: &rustc_ast::MetaItem,
+    behind_cfg_attr: &rustc_ast::MetaItem,
+    attr: &Attribute,
+) {
+    if cfg_attr.has_name(sym::clippy)
+        && let Some(ident) = behind_cfg_attr.ident()
+        && Level::from_symbol(ident.name, Some(attr.id)).is_some()
+        && let Some(items) = behind_cfg_attr.meta_item_list()
+    {
+        let nb_items = items.len();
+        let mut clippy_lints = Vec::with_capacity(items.len());
+        for item in items {
+            if let Some(meta_item) = item.meta_item()
+                && let [part1, _] = meta_item.path.segments.as_slice()
+                && part1.ident.name == sym::clippy
+            {
+                clippy_lints.push(item.span());
+            }
+        }
+        if clippy_lints.is_empty() {
+            return;
+        }
+        if nb_items == clippy_lints.len() {
+            if let Some(snippet) = snippet_opt(cx, behind_cfg_attr.span) {
+                span_lint_and_sugg(
+                    cx,
+                    UNNECESSARY_CLIPPY_CFG,
+                    attr.span,
+                    "no need to put clippy lints behind a `clippy` cfg",
+                    "replace with",
+                    format!(
+                        "#{}[{}]",
+                        if attr.style == AttrStyle::Inner { "!" } else { "" },
+                        snippet
+                    ),
+                    Applicability::MachineApplicable,
+                );
+            }
+        } else {
+            let snippet = clippy_lints
+                .iter()
+                .filter_map(|sp| snippet_opt(cx, *sp))
+                .collect::<Vec<_>>()
+                .join(",");
+            span_lint_and_note(
+                cx,
+                UNNECESSARY_CLIPPY_CFG,
+                clippy_lints,
+                "no need to put clippy lints behind a `clippy` cfg",
+                None,
+                &format!(
+                    "write instead: `#{}[{}({})]`",
+                    if attr.style == AttrStyle::Inner { "!" } else { "" },
+                    ident.name,
+                    snippet
+                ),
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
new file mode 100644
index 00000000000..7575f502a7c
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs
@@ -0,0 +1,73 @@
+use super::utils::{extract_clippy_lint, is_lint_level, is_word};
+use super::{Attribute, USELESS_ATTRIBUTE};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::{first_line_of_span, snippet_opt};
+use rustc_errors::Applicability;
+use rustc_hir::{Item, ItemKind};
+use rustc_lint::{LateContext, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_span::sym;
+
+pub(super) fn check(cx: &LateContext<'_>, item: &Item<'_>, attrs: &[Attribute]) {
+    let skip_unused_imports = attrs.iter().any(|attr| attr.has_name(sym::macro_use));
+
+    for attr in attrs {
+        if in_external_macro(cx.sess(), attr.span) {
+            return;
+        }
+        if let Some(lint_list) = &attr.meta_item_list() {
+            if attr.ident().map_or(false, |ident| is_lint_level(ident.name, attr.id)) {
+                for lint in lint_list {
+                    match item.kind {
+                        ItemKind::Use(..) => {
+                            if is_word(lint, sym::unused_imports)
+                                || is_word(lint, sym::deprecated)
+                                || is_word(lint, sym!(unreachable_pub))
+                                || is_word(lint, sym!(unused))
+                                || is_word(lint, sym!(unused_import_braces))
+                                || extract_clippy_lint(lint).map_or(false, |s| {
+                                    matches!(
+                                        s.as_str(),
+                                        "wildcard_imports"
+                                            | "enum_glob_use"
+                                            | "redundant_pub_crate"
+                                            | "macro_use_imports"
+                                            | "unsafe_removed_from_name"
+                                            | "module_name_repetitions"
+                                            | "single_component_path_imports"
+                                    )
+                                })
+                            {
+                                return;
+                            }
+                        },
+                        ItemKind::ExternCrate(..) => {
+                            if is_word(lint, sym::unused_imports) && skip_unused_imports {
+                                return;
+                            }
+                            if is_word(lint, sym!(unused_extern_crates)) {
+                                return;
+                            }
+                        },
+                        _ => {},
+                    }
+                }
+                let line_span = first_line_of_span(cx, attr.span);
+
+                if let Some(mut sugg) = snippet_opt(cx, line_span) {
+                    if sugg.contains("#[") {
+                        span_lint_and_then(cx, USELESS_ATTRIBUTE, line_span, "useless lint attribute", |diag| {
+                            sugg = sugg.replacen("#[", "#![", 1);
+                            diag.span_suggestion(
+                                line_span,
+                                "if you just forgot a `!`, use",
+                                sugg,
+                                Applicability::MaybeIncorrect,
+                            );
+                        });
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/utils.rs b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
new file mode 100644
index 00000000000..9b36cc00444
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/attrs/utils.rs
@@ -0,0 +1,87 @@
+use clippy_utils::macros::{is_panic, macro_backtrace};
+use rustc_ast::{AttrId, NestedMetaItem};
+use rustc_hir::{
+    Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
+};
+use rustc_lint::{LateContext, Level};
+use rustc_middle::ty;
+use rustc_span::sym;
+use rustc_span::symbol::Symbol;
+
+pub(super) fn is_word(nmi: &NestedMetaItem, expected: Symbol) -> bool {
+    if let NestedMetaItem::MetaItem(mi) = &nmi {
+        mi.is_word() && mi.has_name(expected)
+    } else {
+        false
+    }
+}
+
+pub(super) fn is_lint_level(symbol: Symbol, attr_id: AttrId) -> bool {
+    Level::from_symbol(symbol, Some(attr_id)).is_some()
+}
+
+pub(super) fn is_relevant_item(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
+    if let ItemKind::Fn(_, _, eid) = item.kind {
+        is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
+    } else {
+        true
+    }
+}
+
+pub(super) fn is_relevant_impl(cx: &LateContext<'_>, item: &ImplItem<'_>) -> bool {
+    match item.kind {
+        ImplItemKind::Fn(_, eid) => is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value),
+        _ => false,
+    }
+}
+
+pub(super) fn is_relevant_trait(cx: &LateContext<'_>, item: &TraitItem<'_>) -> bool {
+    match item.kind {
+        TraitItemKind::Fn(_, TraitFn::Required(_)) => true,
+        TraitItemKind::Fn(_, TraitFn::Provided(eid)) => {
+            is_relevant_expr(cx, cx.tcx.typeck_body(eid), cx.tcx.hir().body(eid).value)
+        },
+        _ => false,
+    }
+}
+
+fn is_relevant_block(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, block: &Block<'_>) -> bool {
+    block.stmts.first().map_or(
+        block
+            .expr
+            .as_ref()
+            .map_or(false, |e| is_relevant_expr(cx, typeck_results, e)),
+        |stmt| match &stmt.kind {
+            StmtKind::Local(_) => true,
+            StmtKind::Expr(expr) | StmtKind::Semi(expr) => is_relevant_expr(cx, typeck_results, expr),
+            StmtKind::Item(_) => false,
+        },
+    )
+}
+
+fn is_relevant_expr(cx: &LateContext<'_>, typeck_results: &ty::TypeckResults<'_>, expr: &Expr<'_>) -> bool {
+    if macro_backtrace(expr.span).last().map_or(false, |macro_call| {
+        is_panic(cx, macro_call.def_id) || cx.tcx.item_name(macro_call.def_id) == sym::unreachable
+    }) {
+        return false;
+    }
+    match &expr.kind {
+        ExprKind::Block(block, _) => is_relevant_block(cx, typeck_results, block),
+        ExprKind::Ret(Some(e)) => is_relevant_expr(cx, typeck_results, e),
+        ExprKind::Ret(None) | ExprKind::Break(_, None) => false,
+        _ => true,
+    }
+}
+
+/// Returns the lint name if it is clippy lint.
+pub(super) fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
+    if let Some(meta_item) = lint.meta_item()
+        && meta_item.path.segments.len() > 1
+        && let tool_name = meta_item.path.segments[0].ident
+        && tool_name.name == sym::clippy
+    {
+        let lint_name = meta_item.path.segments.last().unwrap().ident.name;
+        return Some(lint_name);
+    }
+    None
+}
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 0d66f2d644d..a474356608f 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -88,7 +88,6 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         match expr.kind {
-            ExprKind::Unary(UnOp::Not, sub) => check_inverted_condition(cx, expr.span, sub),
             // This check the case where an element in a boolean comparison is inverted, like:
             //
             // ```
@@ -119,27 +118,6 @@ fn bin_op_eq_str(op: BinOpKind) -> Option<&'static str> {
     }
 }
 
-fn check_inverted_condition(cx: &LateContext<'_>, expr_span: Span, sub_expr: &Expr<'_>) {
-    if !expr_span.from_expansion()
-        && let ExprKind::Binary(op, left, right) = sub_expr.kind
-        && let Some(left) = snippet_opt(cx, left.span)
-        && let Some(right) = snippet_opt(cx, right.span)
-    {
-        let Some(op) = inverted_bin_op_eq_str(op.node) else {
-            return;
-        };
-        span_lint_and_sugg(
-            cx,
-            NONMINIMAL_BOOL,
-            expr_span,
-            "this boolean expression can be simplified",
-            "try",
-            format!("{left} {op} {right}",),
-            Applicability::MachineApplicable,
-        );
-    }
-}
-
 fn check_inverted_bool_in_condition(
     cx: &LateContext<'_>,
     expr_span: Span,
@@ -148,8 +126,8 @@ fn check_inverted_bool_in_condition(
     right: &Expr<'_>,
 ) {
     if expr_span.from_expansion()
-        && (!cx.typeck_results().node_types()[left.hir_id].is_bool()
-            || !cx.typeck_results().node_types()[right.hir_id].is_bool())
+        || !cx.typeck_results().node_types()[left.hir_id].is_bool()
+        || !cx.typeck_results().node_types()[right.hir_id].is_bool()
     {
         return;
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index cc513d46bf4..08341ff32f3 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -151,13 +151,24 @@ pub(super) fn check<'tcx>(
             return false;
         }
 
+        // If the whole cast expression is a unary expression (`(*x as T)`) or an addressof
+        // expression (`(&x as T)`), then not surrounding the suggestion into a block risks us
+        // changing the precedence of operators if the cast expression is followed by an operation
+        // with higher precedence than the unary operator (`(*x as T).foo()` would become
+        // `*x.foo()`, which changes what the `*` applies on).
+        // The same is true if the expression encompassing the cast expression is a unary
+        // expression or an addressof expression.
+        let needs_block = matches!(cast_expr.kind, ExprKind::Unary(..) | ExprKind::AddrOf(..))
+            || get_parent_expr(cx, expr)
+                .map_or(false, |e| matches!(e.kind, ExprKind::Unary(..) | ExprKind::AddrOf(..)));
+
         span_lint_and_sugg(
             cx,
             UNNECESSARY_CAST,
             expr.span,
             &format!("casting to the same type is unnecessary (`{cast_from}` -> `{cast_to}`)"),
             "try",
-            if get_parent_expr(cx, expr).map_or(false, |e| matches!(e.kind, ExprKind::AddrOf(..))) {
+            if needs_block {
                 format!("{{ {cast_str} }}")
             } else {
                 cast_str
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index fb3ae2457e3..2b324f5f96e 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -47,6 +47,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX_INFO,
     crate::assertions_on_constants::ASSERTIONS_ON_CONSTANTS_INFO,
     crate::assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES_INFO,
+    crate::assigning_clones::ASSIGNING_CLONES_INFO,
     crate::async_yields_async::ASYNC_YIELDS_ASYNC_INFO,
     crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO,
     crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO,
@@ -58,6 +59,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::attrs::INLINE_ALWAYS_INFO,
     crate::attrs::MAYBE_MISUSED_CFG_INFO,
     crate::attrs::MISMATCHED_TARGET_OS_INFO,
+    crate::attrs::MIXED_ATTRIBUTES_STYLE_INFO,
     crate::attrs::NON_MINIMAL_CFG_INFO,
     crate::attrs::SHOULD_PANIC_WITHOUT_EXPECT_INFO,
     crate::attrs::UNNECESSARY_CLIPPY_CFG_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 6144ec7b3ca..f0f2c7d6658 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -451,8 +451,8 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
         && let Some(def_id) = trait_ref.trait_def_id()
         && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
         && !has_non_exhaustive_attr(cx.tcx, *adt)
+        && !ty_implements_eq_trait(cx.tcx, ty, eq_trait_def_id)
         && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
-        && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
         // If all of our fields implement `Eq`, we can implement `Eq` too
         && adt
             .all_fields()
@@ -471,6 +471,10 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
     }
 }
 
+fn ty_implements_eq_trait<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, eq_trait_id: DefId) -> bool {
+    tcx.non_blanket_impls_for_ty(eq_trait_id, ty).next().is_some()
+}
+
 /// Creates the `ParamEnv` used for the give type's derived `Eq` impl.
 fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> ParamEnv<'_> {
     // Initial map from generic index to param def.
diff --git a/src/tools/clippy/clippy_lints/src/doc/markdown.rs b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
index a58219c2946..d2f14756591 100644
--- a/src/tools/clippy/clippy_lints/src/doc/markdown.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
@@ -8,7 +8,7 @@ use url::Url;
 
 use crate::doc::DOC_MARKDOWN;
 
-pub fn check(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span) {
+pub fn check(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span, code_level: isize) {
     for orig_word in text.split(|c: char| c.is_whitespace() || c == '\'') {
         // Trim punctuation as in `some comment (see foo::bar).`
         //                                                   ^^
@@ -46,11 +46,11 @@ pub fn check(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str,
             span.parent(),
         );
 
-        check_word(cx, word, span);
+        check_word(cx, word, span, code_level);
     }
 }
 
-fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
+fn check_word(cx: &LateContext<'_>, word: &str, span: Span, code_level: isize) {
     /// Checks if a string is upper-camel-case, i.e., starts with an uppercase and
     /// contains at least two uppercase letters (`Clippy` is ok) and one lower-case
     /// letter (`NASA` is ok).
@@ -60,7 +60,14 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
             return false;
         }
 
-        let s = s.strip_suffix('s').unwrap_or(s);
+        let s = if let Some(prefix) = s.strip_suffix("es")
+            && prefix.chars().all(|c| c.is_ascii_uppercase())
+            && matches!(prefix.chars().last(), Some('S' | 'X'))
+        {
+            prefix
+        } else {
+            s.strip_suffix('s').unwrap_or(s)
+        };
 
         s.chars().all(char::is_alphanumeric)
             && s.chars().filter(|&c| c.is_uppercase()).take(2).count() > 1
@@ -90,7 +97,7 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
     }
 
     // We assume that mixed-case words are not meant to be put inside backticks. (Issue #2343)
-    if has_underscore(word) && has_hyphen(word) {
+    if code_level > 0 || (has_underscore(word) && has_hyphen(word)) {
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 9af34c3a7bf..003d26b7b89 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -599,10 +599,19 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
     let mut ignore = false;
     let mut edition = None;
     let mut ticks_unbalanced = false;
-    let mut text_to_check: Vec<(CowStr<'_>, Range<usize>)> = Vec::new();
+    let mut text_to_check: Vec<(CowStr<'_>, Range<usize>, isize)> = Vec::new();
     let mut paragraph_range = 0..0;
+    let mut code_level = 0;
+
     for (event, range) in events {
         match event {
+            Html(tag) => {
+                if tag.starts_with("<code") {
+                    code_level += 1;
+                } else if tag.starts_with("</code") {
+                    code_level -= 1;
+                }
+            },
             Start(CodeBlock(ref kind)) => {
                 in_code = true;
                 if let CodeBlockKind::Fenced(lang) = kind {
@@ -652,16 +661,15 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                         "a backtick may be missing a pair",
                     );
                 } else {
-                    for (text, range) in text_to_check {
+                    for (text, range, assoc_code_level) in text_to_check {
                         if let Some(span) = fragments.span(cx, range) {
-                            markdown::check(cx, valid_idents, &text, span);
+                            markdown::check(cx, valid_idents, &text, span, assoc_code_level);
                         }
                     }
                 }
                 text_to_check = Vec::new();
             },
             Start(_tag) | End(_tag) => (), // We don't care about other tags
-            Html(_html) => (),             // HTML is weird, just ignore it
             SoftBreak | HardBreak | TaskListMarker(_) | Code(_) | Rule => (),
             FootnoteReference(text) | Text(text) => {
                 paragraph_range.end = range.end;
@@ -694,7 +702,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
                         // Don't check the text associated with external URLs
                         continue;
                     }
-                    text_to_check.push((text, range));
+                    text_to_check.push((text, range, code_level));
                 }
             },
         }
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index 0b4bc375df0..de6073c2723 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -214,12 +214,31 @@ impl MapType {
     }
 }
 
+/// Details on an expression checking whether a map contains a key.
+///
+/// For instance, with the following:
+/// ```ignore
+/// !!!self.the_map.contains_key("the_key")
+/// ```
+///
+/// - `negated` will be set to `true` (the 3 `!` negate the condition)
+/// - `map` will be the `self.the_map` expression
+/// - `key` will be the `"the_key"` expression
 struct ContainsExpr<'tcx> {
+    /// Whether the check for `contains_key` was negated.
     negated: bool,
+    /// The map on which the check is performed.
     map: &'tcx Expr<'tcx>,
+    /// The key that is checked to be contained.
     key: &'tcx Expr<'tcx>,
+    /// The context of the whole condition expression.
     call_ctxt: SyntaxContext,
 }
+
+/// Inspect the given expression and return details about the `contains_key` check.
+///
+/// If the given expression is not a `contains_key` check against a `BTreeMap` or a `HashMap`,
+/// return `None`.
 fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Option<(MapType, ContainsExpr<'tcx>)> {
     let mut negated = false;
     let expr = peel_hir_expr_while(expr, |e| match e.kind {
@@ -229,6 +248,7 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
         },
         _ => None,
     });
+
     match expr.kind {
         ExprKind::MethodCall(
             _,
@@ -261,11 +281,28 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
     }
 }
 
+/// Details on an expression inserting a key into a map.
+///
+/// For instance, on the following:
+/// ```ignore
+/// self.the_map.insert("the_key", 3 + 4);
+/// ```
+///
+/// - `map` will be the `self.the_map` expression
+/// - `key` will be the `"the_key"` expression
+/// - `value` will be the `3 + 4` expression
 struct InsertExpr<'tcx> {
+    /// The map into which the insertion is performed.
     map: &'tcx Expr<'tcx>,
+    /// The key at which to insert.
     key: &'tcx Expr<'tcx>,
+    /// The value to insert.
     value: &'tcx Expr<'tcx>,
 }
+
+/// Inspect the given expression and return details about the `insert` call.
+///
+/// If the given expression is not an `insert` call into a `BTreeMap` or a `HashMap`, return `None`.
 fn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {
     if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {
         let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
@@ -298,7 +335,7 @@ struct Insertion<'tcx> {
     value: &'tcx Expr<'tcx>,
 }
 
-/// This visitor needs to do a multiple things:
+/// This visitor needs to do multiple things:
 /// * Find all usages of the map. An insertion can only be made before any other usages of the map.
 /// * Determine if there's an insertion using the same key. There's no need for the entry api
 ///   otherwise.
@@ -346,7 +383,7 @@ impl<'tcx> InsertSearcher<'_, 'tcx> {
         res
     }
 
-    /// Visits an expression which is not itself in a tail position, but other sibling expressions
+    /// Visit an expression which is not itself in a tail position, but other sibling expressions
     /// may be. e.g. if conditions
     fn visit_non_tail_expr(&mut self, e: &'tcx Expr<'_>) {
         let in_tail_pos = self.in_tail_pos;
@@ -354,6 +391,19 @@ impl<'tcx> InsertSearcher<'_, 'tcx> {
         self.visit_expr(e);
         self.in_tail_pos = in_tail_pos;
     }
+
+    /// Visit the key and value expression of an insert expression.
+    /// There may not be uses of the map in either of those two either.
+    fn visit_insert_expr_arguments(&mut self, e: &InsertExpr<'tcx>) {
+        let in_tail_pos = self.in_tail_pos;
+        let allow_insert_closure = self.allow_insert_closure;
+        let is_single_insert = self.is_single_insert;
+        walk_expr(self, e.key);
+        walk_expr(self, e.value);
+        self.in_tail_pos = in_tail_pos;
+        self.allow_insert_closure = allow_insert_closure;
+        self.is_single_insert = is_single_insert;
+    }
 }
 impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
     fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
@@ -425,6 +475,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
 
         match try_parse_insert(self.cx, expr) {
             Some(insert_expr) if SpanlessEq::new(self.cx).eq_expr(self.map, insert_expr.map) => {
+                self.visit_insert_expr_arguments(&insert_expr);
                 // Multiple inserts, inserts with a different key, and inserts from a macro can't use the entry api.
                 if self.is_map_used
                     || !SpanlessEq::new(self.cx).eq_expr(self.key, insert_expr.key)
diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs
index 606c2ed72be..0ea53c39280 100644
--- a/src/tools/clippy/clippy_lints/src/let_underscore.rs
+++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
 use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
-use rustc_hir::{Local, PatKind};
+use rustc_hir::{Local, LocalSource, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{GenericArgKind, IsSuggestable};
@@ -139,7 +139,8 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
 
 impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) {
-        if !in_external_macro(cx.tcx.sess, local.span)
+        if matches!(local.source, LocalSource::Normal)
+            && !in_external_macro(cx.tcx.sess, local.span)
             && let PatKind::Wild = local.pat.kind
             && let Some(init) = local.init
         {
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 76e75968314..b930175c4d8 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -80,6 +80,7 @@ mod as_conversions;
 mod asm_syntax;
 mod assertions_on_constants;
 mod assertions_on_result_states;
+mod assigning_clones;
 mod async_yields_async;
 mod attrs;
 mod await_holding_invalid;
@@ -1118,6 +1119,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| Box::new(incompatible_msrv::IncompatibleMsrv::new(msrv())));
     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(|_| Box::new(assigning_clones::AssigningClones));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index 58f713d8187..18f799e875a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -3,6 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_copy;
+use clippy_utils::usage::local_used_in;
 use clippy_utils::{get_enclosing_block, higher, path_to_local, sugg};
 use rustc_ast::ast;
 use rustc_errors::Applicability;
@@ -63,8 +64,9 @@ pub(super) fn check<'tcx>(
                             && get_slice_like_element_ty(cx, cx.typeck_results().expr_ty(base_right)).is_some()
                             && let Some((start_left, offset_left)) = get_details_from_idx(cx, idx_left, &starts)
                             && let Some((start_right, offset_right)) = get_details_from_idx(cx, idx_right, &starts)
-
-                            // Source and destination must be different
+                            && !local_used_in(cx, canonical_id, base_left)
+                            && !local_used_in(cx, canonical_id, base_right)
+							// Source and destination must be different
                             && path_to_local(base_left) != path_to_local(base_right)
                         {
                             Some((
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 69f86836775..b770ad0ddb5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -37,12 +37,7 @@ pub(super) fn check<'tcx>(
     }
 }
 
-fn set_diagnostic<'tcx>(
-    diag: &mut Diag<'_, ()>,
-    cx: &LateContext<'tcx>,
-    expr: &'tcx Expr<'tcx>,
-    found: FoundSigDrop,
-) {
+fn set_diagnostic<'tcx>(diag: &mut Diag<'_, ()>, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, found: FoundSigDrop) {
     if found.lint_suggestion == LintSuggestion::MoveAndClone {
         // If our suggestion is to move and clone, then we want to leave it to the user to
         // decide how to address this lint, since it may be that cloning is inappropriate.
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index adb696ad509..8a24ccea3a1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -3875,6 +3875,7 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// ### What it does
     /// Checks for usage of `option.map(f).unwrap_or_default()` and `result.map(f).unwrap_or_default()` where f is a function or closure that returns the `bool` type.
     ///
     /// ### Why is this bad?
@@ -3981,6 +3982,7 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// ### What it does
     /// Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either
     /// through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()`
     /// on a (byte) string literal with a hardcoded `\0` byte at the end.
diff --git a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
index f671517c134..0879dcd9bcd 100644
--- a/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/identity_op.rs
@@ -42,7 +42,7 @@ pub(crate) fn check<'tcx>(
 
     match op {
         BinOpKind::Add | BinOpKind::BitOr | BinOpKind::BitXor => {
-            check_op(
+            let _ = check_op(
                 cx,
                 left,
                 0,
@@ -50,8 +50,7 @@ pub(crate) fn check<'tcx>(
                 peeled_right_span,
                 needs_parenthesis(cx, expr, right),
                 right_is_coerced_to_value,
-            );
-            check_op(
+            ) || check_op(
                 cx,
                 right,
                 0,
@@ -62,7 +61,7 @@ pub(crate) fn check<'tcx>(
             );
         },
         BinOpKind::Shl | BinOpKind::Shr | BinOpKind::Sub => {
-            check_op(
+            let _ = check_op(
                 cx,
                 right,
                 0,
@@ -73,7 +72,7 @@ pub(crate) fn check<'tcx>(
             );
         },
         BinOpKind::Mul => {
-            check_op(
+            let _ = check_op(
                 cx,
                 left,
                 1,
@@ -81,8 +80,18 @@ pub(crate) fn check<'tcx>(
                 peeled_right_span,
                 needs_parenthesis(cx, expr, right),
                 right_is_coerced_to_value,
+            ) || check_op(
+                cx,
+                right,
+                1,
+                expr.span,
+                peeled_left_span,
+                Parens::Unneeded,
+                left_is_coerced_to_value,
             );
-            check_op(
+        },
+        BinOpKind::Div => {
+            let _ = check_op(
                 cx,
                 right,
                 1,
@@ -92,17 +101,8 @@ pub(crate) fn check<'tcx>(
                 left_is_coerced_to_value,
             );
         },
-        BinOpKind::Div => check_op(
-            cx,
-            right,
-            1,
-            expr.span,
-            peeled_left_span,
-            Parens::Unneeded,
-            left_is_coerced_to_value,
-        ),
         BinOpKind::BitAnd => {
-            check_op(
+            let _ = check_op(
                 cx,
                 left,
                 -1,
@@ -110,8 +110,7 @@ pub(crate) fn check<'tcx>(
                 peeled_right_span,
                 needs_parenthesis(cx, expr, right),
                 right_is_coerced_to_value,
-            );
-            check_op(
+            ) || check_op(
                 cx,
                 right,
                 -1,
@@ -201,12 +200,12 @@ fn check_remainder(cx: &LateContext<'_>, left: &Expr<'_>, right: &Expr<'_>, span
     }
 }
 
-fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, parens: Parens, is_erased: bool) {
+fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, parens: Parens, is_erased: bool) -> bool {
     if let Some(Constant::Int(v)) = constant_simple(cx, cx.typeck_results(), e).map(Constant::peel_refs) {
         let check = match *cx.typeck_results().expr_ty(e).peel_refs().kind() {
             ty::Int(ity) => unsext(cx.tcx, -1_i128, ity),
             ty::Uint(uty) => clip(cx.tcx, !0, uty),
-            _ => return,
+            _ => return false,
         };
         if match m {
             0 => v == 0,
@@ -215,8 +214,10 @@ fn check_op(cx: &LateContext<'_>, e: &Expr<'_>, m: i8, span: Span, arg: Span, pa
             _ => unreachable!(),
         } {
             span_ineffective_operation(cx, span, arg, parens, is_erased);
+            return true;
         }
     }
+    false
 }
 
 fn span_ineffective_operation(
diff --git a/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs b/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
index fecc5a8578e..311cbd050a1 100644
--- a/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/misrefactored_assign_op.rs
@@ -21,9 +21,8 @@ pub(super) fn check<'tcx>(
         // lhs op= l op r
         if eq_expr_value(cx, lhs, l) {
             lint_misrefactored_assign_op(cx, expr, op, rhs, lhs, r);
-        }
-        // lhs op= l commutative_op r
-        if is_commutative(op) && eq_expr_value(cx, lhs, r) {
+        } else if is_commutative(op) && eq_expr_value(cx, lhs, r) {
+            // lhs op= l commutative_op r
             lint_misrefactored_assign_op(cx, expr, op, rhs, lhs, l);
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index 1df2d5e4602..cf7f730140c 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -203,108 +203,106 @@ fn expr_return_none_or_err(
     }
 }
 
-impl QuestionMark {
-    fn inside_try_block(&self) -> bool {
-        self.try_block_depth_stack.last() > Some(&0)
-    }
-
-    /// Checks if the given expression on the given context matches the following structure:
-    ///
-    /// ```ignore
-    /// if option.is_none() {
-    ///    return None;
-    /// }
-    /// ```
-    ///
-    /// ```ignore
-    /// if result.is_err() {
-    ///     return result;
-    /// }
-    /// ```
-    ///
-    /// If it matches, it will suggest to use the question mark operator instead
-    fn check_is_none_or_err_and_early_return<'tcx>(&self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
-        if !self.inside_try_block()
-            && let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr)
-            && !is_else_clause(cx.tcx, expr)
-            && let ExprKind::MethodCall(segment, caller, ..) = &cond.kind
-            && let caller_ty = cx.typeck_results().expr_ty(caller)
-            && let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then)
-            && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block))
-        {
-            let mut applicability = Applicability::MachineApplicable;
-            let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
-            let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
-                && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
-            let sugg = if let Some(else_inner) = r#else {
-                if eq_expr_value(cx, caller, peel_blocks(else_inner)) {
-                    format!("Some({receiver_str}?)")
-                } else {
-                    return;
-                }
+/// Checks if the given expression on the given context matches the following structure:
+///
+/// ```ignore
+/// if option.is_none() {
+///    return None;
+/// }
+/// ```
+///
+/// ```ignore
+/// if result.is_err() {
+///     return result;
+/// }
+/// ```
+///
+/// If it matches, it will suggest to use the question mark operator instead
+fn check_is_none_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
+    if let Some(higher::If { cond, then, r#else }) = higher::If::hir(expr)
+        && !is_else_clause(cx.tcx, expr)
+        && let ExprKind::MethodCall(segment, caller, ..) = &cond.kind
+        && let caller_ty = cx.typeck_results().expr_ty(caller)
+        && let if_block = IfBlockType::IfIs(caller, caller_ty, segment.ident.name, then)
+        && (is_early_return(sym::Option, cx, &if_block) || is_early_return(sym::Result, cx, &if_block))
+    {
+        let mut applicability = Applicability::MachineApplicable;
+        let receiver_str = snippet_with_applicability(cx, caller.span, "..", &mut applicability);
+        let by_ref = !caller_ty.is_copy_modulo_regions(cx.tcx, cx.param_env)
+            && !matches!(caller.kind, ExprKind::Call(..) | ExprKind::MethodCall(..));
+        let sugg = if let Some(else_inner) = r#else {
+            if eq_expr_value(cx, caller, peel_blocks(else_inner)) {
+                format!("Some({receiver_str}?)")
             } else {
-                format!("{receiver_str}{}?;", if by_ref { ".as_ref()" } else { "" })
-            };
+                return;
+            }
+        } else {
+            format!("{receiver_str}{}?;", if by_ref { ".as_ref()" } else { "" })
+        };
 
-            span_lint_and_sugg(
-                cx,
-                QUESTION_MARK,
-                expr.span,
-                "this block may be rewritten with the `?` operator",
-                "replace it with",
-                sugg,
-                applicability,
-            );
-        }
+        span_lint_and_sugg(
+            cx,
+            QUESTION_MARK,
+            expr.span,
+            "this block may be rewritten with the `?` operator",
+            "replace it with",
+            sugg,
+            applicability,
+        );
     }
+}
 
-    fn check_if_let_some_or_err_and_early_return<'tcx>(&self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
-        if !self.inside_try_block()
-            && let Some(higher::IfLet {
-                let_pat,
-                let_expr,
-                if_then,
-                if_else,
-                ..
-            }) = higher::IfLet::hir(cx, expr)
-            && !is_else_clause(cx.tcx, expr)
-            && let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind
-            && ddpos.as_opt_usize().is_none()
-            && let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind
-            && let caller_ty = cx.typeck_results().expr_ty(let_expr)
-            && let if_block = IfBlockType::IfLet(
-                cx.qpath_res(path1, let_pat.hir_id),
-                caller_ty,
-                ident.name,
-                let_expr,
-                if_then,
-                if_else,
-            )
-            && ((is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id))
-                || is_early_return(sym::Result, cx, &if_block))
-            && if_else
-                .map(|e| eq_expr_value(cx, let_expr, peel_blocks(e)))
-                .filter(|e| *e)
-                .is_none()
-        {
-            let mut applicability = Applicability::MachineApplicable;
-            let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
-            let requires_semi = matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(_));
-            let sugg = format!(
-                "{receiver_str}{}?{}",
-                if by_ref == ByRef::Yes { ".as_ref()" } else { "" },
-                if requires_semi { ";" } else { "" }
-            );
-            span_lint_and_sugg(
-                cx,
-                QUESTION_MARK,
-                expr.span,
-                "this block may be rewritten with the `?` operator",
-                "replace it with",
-                sugg,
-                applicability,
-            );
-        }
+fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
+    if let Some(higher::IfLet {
+        let_pat,
+        let_expr,
+        if_then,
+        if_else,
+        ..
+    }) = higher::IfLet::hir(cx, expr)
+        && !is_else_clause(cx.tcx, expr)
+        && let PatKind::TupleStruct(ref path1, [field], ddpos) = let_pat.kind
+        && ddpos.as_opt_usize().is_none()
+        && let PatKind::Binding(BindingAnnotation(by_ref, _), bind_id, ident, None) = field.kind
+        && let caller_ty = cx.typeck_results().expr_ty(let_expr)
+        && let if_block = IfBlockType::IfLet(
+            cx.qpath_res(path1, let_pat.hir_id),
+            caller_ty,
+            ident.name,
+            let_expr,
+            if_then,
+            if_else,
+        )
+        && ((is_early_return(sym::Option, cx, &if_block) && path_to_local_id(peel_blocks(if_then), bind_id))
+            || is_early_return(sym::Result, cx, &if_block))
+        && if_else
+            .map(|e| eq_expr_value(cx, let_expr, peel_blocks(e)))
+            .filter(|e| *e)
+            .is_none()
+    {
+        let mut applicability = Applicability::MachineApplicable;
+        let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
+        let requires_semi = matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(_));
+        let sugg = format!(
+            "{receiver_str}{}?{}",
+            if by_ref == ByRef::Yes { ".as_ref()" } else { "" },
+            if requires_semi { ";" } else { "" }
+        );
+        span_lint_and_sugg(
+            cx,
+            QUESTION_MARK,
+            expr.span,
+            "this block may be rewritten with the `?` operator",
+            "replace it with",
+            sugg,
+            applicability,
+        );
+    }
+}
+
+impl QuestionMark {
+    fn inside_try_block(&self) -> bool {
+        self.try_block_depth_stack.last() > Some(&0)
     }
 }
 
@@ -324,15 +322,18 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
             return;
         }
 
-        if !in_constant(cx, stmt.hir_id) {
+        if !self.inside_try_block() && !in_constant(cx, stmt.hir_id) {
             check_let_some_else_return_none(cx, stmt);
         }
         self.check_manual_let_else(cx, stmt);
     }
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if !in_constant(cx, expr.hir_id) && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id) {
-            self.check_is_none_or_err_and_early_return(cx, expr);
-            self.check_if_let_some_or_err_and_early_return(cx, expr);
+        if !self.inside_try_block()
+            && !in_constant(cx, expr.hir_id)
+            && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)
+        {
+            check_is_none_or_err_and_early_return(cx, expr);
+            check_if_let_some_or_err_and_early_return(cx, expr);
         }
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index e3f0ce2a922..f61527cc0a9 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -159,6 +159,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
             //           ^^  we only want to lint for this call (but we walk up the calls to consider both calls).
             // without this check, we'd end up linting twice.
             && !matches!(recv.kind, hir::ExprKind::Call(..))
+            // Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is
+            // the same as the one the call is in.
+            // For instance, let's assume `x!()` returns a closure:
+            //    B ---v
+            //      x!()()
+            //          ^- A
+            // The call happens in the expansion `A`, while the closure originates from the expansion `B`.
+            // We don't want to suggest replacing `x!()()` with `x!()`.
+            && recv.span.ctxt().outer_expn() == expr.span.ctxt().outer_expn()
             && let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
             && let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
             // outside macros we lint properly. Inside macros, we lint only ||() style closures.
diff --git a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
index fb000cd7184..17b031d5f01 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_field_names.rs
@@ -59,24 +59,22 @@ impl EarlyLintPass for RedundantFieldNames {
         }
         if let ExprKind::Struct(ref se) = expr.kind {
             for field in &se.fields {
-                if field.is_shorthand {
-                    continue;
-                }
-                if let ExprKind::Path(None, path) = &field.expr.kind {
-                    if path.segments.len() == 1
-                        && path.segments[0].ident == field.ident
-                        && path.segments[0].args.is_none()
-                    {
-                        span_lint_and_sugg(
-                            cx,
-                            REDUNDANT_FIELD_NAMES,
-                            field.span,
-                            "redundant field names in struct initialization",
-                            "replace it with",
-                            field.ident.to_string(),
-                            Applicability::MachineApplicable,
-                        );
-                    }
+                if !field.is_shorthand
+                    && let ExprKind::Path(None, path) = &field.expr.kind
+                    && let [segment] = path.segments.as_slice()
+                    && segment.args.is_none()
+                    && segment.ident == field.ident
+                    && field.span.eq_ctxt(field.ident.span)
+                {
+                    span_lint_and_sugg(
+                        cx,
+                        REDUNDANT_FIELD_NAMES,
+                        field.span,
+                        "redundant field names in struct initialization",
+                        "replace it with",
+                        field.ident.to_string(),
+                        Applicability::MachineApplicable,
+                    );
                 }
             }
         }
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 38fd54a0f1e..c0e4f3c368a 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
@@ -109,7 +109,6 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     sym::core => (STD_INSTEAD_OF_CORE, "std", "core"),
                     sym::alloc => (STD_INSTEAD_OF_ALLOC, "std", "alloc"),
                     _ => {
-                        self.prev_span = path.span;
                         return;
                     },
                 },
@@ -117,13 +116,12 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     if cx.tcx.crate_name(def_id.krate) == sym::core {
                         (ALLOC_INSTEAD_OF_CORE, "alloc", "core")
                     } else {
-                        self.prev_span = path.span;
                         return;
                     }
                 },
                 _ => return,
             };
-            if path.span != self.prev_span {
+            if first_segment.ident.span != self.prev_span {
                 span_lint_and_sugg(
                     cx,
                     lint,
@@ -133,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     replace_with.to_string(),
                     Applicability::MachineApplicable,
                 );
-                self.prev_span = path.span;
+                self.prev_span = first_segment.ident.span;
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
index 9fee4c06200..1af3733ebfa 100644
--- a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
+++ b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
@@ -1,12 +1,11 @@
-use clippy_config::msrvs::Msrv;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::fn_has_unsatisfiable_preds;
 use clippy_utils::qualify_min_const_fn::is_min_const_fn;
 use clippy_utils::source::snippet;
+use clippy_utils::{fn_has_unsatisfiable_preds, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::{intravisit, ExprKind};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym::thread_local_macro;
 
@@ -57,6 +56,31 @@ impl ThreadLocalInitializerCanBeMadeConst {
 
 impl_lint_pass!(ThreadLocalInitializerCanBeMadeConst => [THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST]);
 
+#[inline]
+fn is_thread_local_initializer(
+    cx: &LateContext<'_>,
+    fn_kind: rustc_hir::intravisit::FnKind<'_>,
+    span: rustc_span::Span,
+) -> Option<bool> {
+    let macro_def_id = span.source_callee()?.macro_def_id?;
+    Some(
+        cx.tcx.is_diagnostic_item(thread_local_macro, macro_def_id)
+            && matches!(fn_kind, intravisit::FnKind::ItemFn(..)),
+    )
+}
+
+#[inline]
+fn initializer_can_be_made_const(cx: &LateContext<'_>, defid: rustc_span::def_id::DefId, msrv: &Msrv) -> bool {
+    // Building MIR for `fn`s with unsatisfiable preds results in ICE.
+    if !fn_has_unsatisfiable_preds(cx, defid)
+        && let mir = cx.tcx.optimized_mir(defid)
+        && let Ok(()) = is_min_const_fn(cx.tcx, mir, msrv)
+    {
+        return true;
+    }
+    false
+}
+
 impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst {
     fn check_fn(
         &mut self,
@@ -65,31 +89,32 @@ impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst {
         _: &'tcx rustc_hir::FnDecl<'tcx>,
         body: &'tcx rustc_hir::Body<'tcx>,
         span: rustc_span::Span,
-        defid: rustc_span::def_id::LocalDefId,
+        local_defid: rustc_span::def_id::LocalDefId,
     ) {
-        if in_external_macro(cx.sess(), span)
-            && let Some(callee) = span.source_callee()
-            && let Some(macro_def_id) = callee.macro_def_id
-            && cx.tcx.is_diagnostic_item(thread_local_macro, macro_def_id)
-            && let intravisit::FnKind::ItemFn(..) = fn_kind
-            // Building MIR for `fn`s with unsatisfiable preds results in ICE.
-            && !fn_has_unsatisfiable_preds(cx, defid.to_def_id())
-            && let mir = cx.tcx.optimized_mir(defid.to_def_id())
-            && let Ok(()) = is_min_const_fn(cx.tcx, mir, &self.msrv)
-            // this is the `__init` function emitted by the `thread_local!` macro
-            // when the `const` keyword is not used. We avoid checking the `__init` directly
-            // as that is not a public API.
-            // we know that the function is const-qualifiable, so now we need only to get the
-            // initializer expression to span-lint it.
+        let defid = local_defid.to_def_id();
+        if self.msrv.meets(msrvs::THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST)
+            && is_thread_local_initializer(cx, fn_kind, span).unwrap_or(false)
+            // Some implementations of `thread_local!` include an initializer fn.
+            // In the case of a const initializer, the init fn is also const,
+            // so we can skip the lint in that case. This occurs only on some
+            // backends due to conditional compilation:
+            // https://doc.rust-lang.org/src/std/sys/common/thread_local/mod.rs.html
+            // for details on this issue, see:
+            // https://github.com/rust-lang/rust-clippy/pull/12276
+            && !cx.tcx.is_const_fn(defid)
+            && initializer_can_be_made_const(cx, defid, &self.msrv)
+            // we know that the function is const-qualifiable, so now
+            // we need only to get the initializer expression to span-lint it.
             && let ExprKind::Block(block, _) = body.value.kind
-            && let Some(ret_expr) = block.expr
+            && let Some(unpeeled) = block.expr
+            && let ret_expr = peel_blocks(unpeeled)
             && let initializer_snippet = snippet(cx, ret_expr.span, "thread_local! { ... }")
             && initializer_snippet != "thread_local! { ... }"
         {
             span_lint_and_sugg(
                 cx,
                 THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST,
-                ret_expr.span,
+                unpeeled.span,
                 "initializer for `thread_local` value can be made `const`",
                 "replace with",
                 format!("const {{ {initializer_snippet} }}"),
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 06de7a11031..e47b14bf63b 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -592,7 +592,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 | (eager_transmute::check(cx, e, arg, from_ty, to_ty));
 
             if !linted {
-                transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, from_ty_adjusted, to_ty, arg);
+                transmutes_expressible_as_ptr_casts::check(cx, e, from_ty, from_ty_adjusted, to_ty, arg, const_context);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index bbecc39a813..043c9c88601 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -18,10 +18,12 @@ pub(super) fn check<'tcx>(
     from_ty_adjusted: bool,
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
+    const_context: bool,
 ) -> bool {
     use CastKind::{AddrPtrCast, ArrayPtrCast, FnPtrAddrCast, FnPtrPtrCast, PtrAddrCast, PtrPtrCast};
     let mut app = Applicability::MachineApplicable;
     let mut sugg = match check_cast(cx, e, from_ty, to_ty) {
+        Some(FnPtrAddrCast | PtrAddrCast) if const_context => return false,
         Some(PtrPtrCast | AddrPtrCast | ArrayPtrCast | FnPtrPtrCast | FnPtrAddrCast) => {
             Sugg::hir_with_context(cx, arg, e.span.ctxt(), "..", &mut app)
                 .as_ty(to_ty.to_string())
diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
index a285f771f1b..7926738d68f 100644
--- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs
+++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs
@@ -1,10 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::paths::ALLOCATOR_GLOBAL;
+use clippy_utils::last_path_segment;
 use clippy_utils::source::snippet;
-use clippy_utils::{last_path_segment, match_def_path};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{self as hir, GenericArg, QPath, TyKind};
+use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::LateContext;
 use rustc_middle::ty::layout::LayoutOf;
@@ -50,7 +49,7 @@ pub(super) fn check<'tcx>(
                 (None, Some(GenericArg::Type(inner))) | (Some(GenericArg::Type(inner)), None) => {
                     if let TyKind::Path(path) = inner.kind
                         && let Some(did) = cx.qpath_res(&path, inner.hir_id).opt_def_id() {
-                        match_def_path(cx, did, &ALLOCATOR_GLOBAL)
+                        cx.tcx.lang_items().get(LangItem::GlobalAlloc) == Some(did)
                     } else {
                         false
                     }
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 2f728b62754..987f28192a8 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -115,4 +115,3 @@ pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"];
 pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"];
 #[expect(clippy::invalid_paths)] // not sure why it thinks this, it works so
 pub const BOOL_THEN: [&str; 4] = ["core", "bool", "<impl bool>", "then"];
-pub const ALLOCATOR_GLOBAL: [&str; 3] = ["alloc", "alloc", "Global"];
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index e74621a0fbb..5090d0bd98b 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -995,7 +995,7 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
                         // no adjustment needed here, as field projections are handled by the compiler
                         ProjectionKind::Field(..) => match cmt.place.ty_before_projection(i).kind() {
                             ty::Adt(..) | ty::Tuple(_) => {
-                                replacement_str = ident_str_with_proj.clone();
+                                replacement_str.clone_from(&ident_str_with_proj);
                                 projections_handled = true;
                             },
                             _ => (),
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index fb038b617df..070b62887d5 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-02-22"
+channel = "nightly-2024-03-07"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index dffa854177b..30beaae34d2 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -174,8 +174,13 @@ To allow or deny a lint from the command line you can use <cyan,bold>cargo clipp
 You can use tool lints to allow or deny lints from your code, e.g.:
 
     <yellow,bold>#[allow(clippy::needless_lifetimes)]</>
-"
-    )
+
+<green,bold>Manifest Options:</>
+    <cyan,bold>--manifest-path</> <cyan><<PATH>></>  Path to Cargo.toml
+    <cyan,bold>--frozen</>                Require Cargo.lock and cache are up to date
+    <cyan,bold>--locked</>                Require Cargo.lock is up to date
+    <cyan,bold>--offline</>               Run without accessing the network
+")
 }
 #[cfg(test)]
 mod tests {
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index a088896b6b0..a0c8bf9334c 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -138,6 +138,7 @@ fn base_config(test_dir: &str) -> (Config, Args) {
             "-Aunused",
             "-Ainternal_features",
             "-Zui-testing",
+            "-Zdeduplicate-diagnostics=no",
             "-Dwarnings",
             &format!("-Ldependency={}", deps_path.display()),
         ]
diff --git a/src/tools/clippy/tests/missing-test-files.rs b/src/tools/clippy/tests/missing-test-files.rs
index 0d35a22cd9a..141c11ddb47 100644
--- a/src/tools/clippy/tests/missing-test-files.rs
+++ b/src/tools/clippy/tests/missing-test-files.rs
@@ -54,7 +54,7 @@ fn explore_directory(dir: &Path) -> Vec<String> {
             let file_prefix = path.file_prefix().unwrap().to_str().unwrap().to_string();
             if let Some(ext) = path.extension() {
                 match ext.to_str().unwrap() {
-                    "rs" | "toml" => current_file = file_prefix.clone(),
+                    "rs" | "toml" => current_file.clone_from(&file_prefix),
                     "stderr" | "stdout" => {
                         if file_prefix != current_file {
                             missing_files.push(path.to_str().unwrap().to_string());
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
index 9b0db660c99..400bfd5d975 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.rs
@@ -5,6 +5,7 @@
 //@normalize-stderr-test: "'rustc'" -> "'<unnamed>'"
 //@normalize-stderr-test: "rustc 1\.\d+.* running on .*" -> "rustc <version> running on <target>"
 //@normalize-stderr-test: "(?ms)query stack during panic:\n.*end of query stack\n" -> ""
+//@normalize-stderr-test: "this compiler `.*` is outdated" -> "this compiler <version> is outdated"
 
 #![deny(clippy::internal)]
 #![allow(clippy::missing_clippy_version_attribute)]
diff --git a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
index d8b158816c9..b84f4e87e07 100644
--- a/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
+++ b/src/tools/clippy/tests/ui-internal/custom_ice_message.stderr
@@ -4,11 +4,14 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 error: the compiler unexpectedly panicked. this is a bug.
 
-note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml
+note: it seems that this compiler <version> is outdated, a newer nightly should have been released in the mean time
+  |
+  = note: please consider running `rustup update nightly` to update the nightly channel and check if this problem still persists
+  = note: if the problem still persists, we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml
 
 note: rustc <version> running on <target>
 
-note: compiler flags: -Z ui-testing
+note: compiler flags: -Z ui-testing -Z deduplicate-diagnostics=no
 
 note: Clippy version: foo
 
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
index c5029bbd9a4..5a2a868ed3e 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.rs
@@ -10,22 +10,11 @@ use rustc_hir::hir_id::HirId;
 use rustc_lint::{Lint, LintContext};
 use rustc_middle::ty::TyCtxt;
 
-pub fn a(
-    cx: impl LintContext,
-    lint: &'static Lint,
-    span: impl Into<MultiSpan>,
-    msg: impl Into<DiagMessage>)
-{
+pub fn a(cx: impl LintContext, lint: &'static Lint, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
     cx.span_lint(lint, span, msg, |_| {});
 }
 
-pub fn b(
-    tcx: TyCtxt<'_>,
-    lint: &'static Lint,
-    hir_id: HirId,
-    span: impl Into<MultiSpan>,
-    msg: impl Into<DiagMessage>,
-) {
+pub fn b(tcx: TyCtxt<'_>, lint: &'static Lint, hir_id: HirId, span: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
     tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
 }
 
diff --git a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
index 1a1ad26290c..ae5d6843406 100644
--- a/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
+++ b/src/tools/clippy/tests/ui-internal/disallow_span_lint.stderr
@@ -8,7 +8,7 @@ LL |     cx.span_lint(lint, span, msg, |_| {});
    = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
 
 error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`
-  --> tests/ui-internal/disallow_span_lint.rs:24:5
+  --> tests/ui-internal/disallow_span_lint.rs:18:5
    |
 LL |     tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index 87f84d8f7dd..37d69055737 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:266:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:271:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     /* Safety: */ unsafe {}
    = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:29
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:48
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:18
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:37
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     let _ = *unsafe { &42 };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:292:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     let _ = match unsafe {} {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:298:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     let _ = &unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:302:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |     let _ = [unsafe {}; 5];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     let _ = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:8
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:317:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:322:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     t!();
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:325:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:330:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |     unsafe {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -133,7 +133,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:339:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:344:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -141,7 +141,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:20
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:348:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:350:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:355:5
    |
 LL |     unsafe impl A for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL |     unsafe impl A for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:357:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:362:9
    |
 LL |         unsafe impl B for (u32) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         unsafe impl B for (u32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,7 +177,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:411:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5
    |
 LL |     unsafe impl T for (i32) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -197,7 +197,7 @@ LL |     unsafe impl T for (i32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     no_safety_comment!(u32);
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:417:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:422:5
    |
 LL |     unsafe impl T for (bool) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL |     unsafe impl T for (bool) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:463:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:468:5
    |
 LL |     unsafe impl NoComment for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -225,7 +225,7 @@ LL |     unsafe impl NoComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:472:19
    |
 LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5
    |
 LL |     unsafe impl TrailingComment for () {} // SAFETY:
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,13 +241,13 @@ LL |     unsafe impl TrailingComment for () {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: constant item has unnecessary safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:474:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5
    |
 LL |     // SAFETY:
    |     ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     // SAFETY:
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:481:5
    |
 LL |     unsafe impl Interference for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     unsafe impl Interference for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:483:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:488:5
    |
 LL |     unsafe impl ImplInFn for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     unsafe impl ImplInFn for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:492:1
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:497:1
    |
 LL | unsafe impl CrateRoot for () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: statement has unnecessary safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:505:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -291,13 +291,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:504:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:12
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:511:12
    |
 LL |         if unsafe { true } {
    |            ^^^^^^^^^^^^^^^
@@ -305,7 +305,7 @@ LL |         if unsafe { true } {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:23
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:514:23
    |
 LL |             let bar = unsafe {};
    |                       ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index 5ffe73f5a2f..400fde997e9 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:266:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:271:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     /* Safety: */ unsafe {}
    = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:270:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:275:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:29
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:274:48
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:279:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:18
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:278:37
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:283:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:282:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     let _ = *unsafe { &42 };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:287:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:292:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     let _ = match unsafe {} {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:293:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:298:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     let _ = &unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:297:14
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:302:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |     let _ = [unsafe {}; 5];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:301:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:306:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     let _ = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:311:8
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:316:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:317:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:322:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     t!();
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:325:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:330:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |     unsafe {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:329:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:334:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -133,7 +133,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:339:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:344:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -141,7 +141,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:343:20
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:348:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:350:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:355:5
    |
 LL |     unsafe impl A for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL |     unsafe impl A for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:357:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:362:9
    |
 LL |         unsafe impl B for (u32) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         unsafe impl B for (u32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:378:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:383:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,7 +177,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:411:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:416:5
    |
 LL |     unsafe impl T for (i32) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -197,7 +197,7 @@ LL |     unsafe impl T for (i32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:403:13
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:408:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     no_safety_comment!(u32);
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:417:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:422:5
    |
 LL |     unsafe impl T for (bool) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL |     unsafe impl T for (bool) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:463:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:468:5
    |
 LL |     unsafe impl NoComment for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -225,7 +225,7 @@ LL |     unsafe impl NoComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:467:19
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:472:19
    |
 LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:471:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5
    |
 LL |     unsafe impl TrailingComment for () {} // SAFETY:
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,13 +241,13 @@ LL |     unsafe impl TrailingComment for () {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: constant item has unnecessary safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:475:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:480:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:474:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:479:5
    |
 LL |     // SAFETY:
    |     ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     // SAFETY:
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:476:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:481:5
    |
 LL |     unsafe impl Interference for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     unsafe impl Interference for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:483:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:488:5
    |
 LL |     unsafe impl ImplInFn for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     unsafe impl ImplInFn for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:492:1
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:497:1
    |
 LL | unsafe impl CrateRoot for () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:502:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:507:9
    |
 LL |         unsafe {};
    |         ^^^^^^^^^
@@ -287,7 +287,7 @@ LL |         unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: statement has unnecessary safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:505:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:510:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -299,13 +299,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:504:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:506:12
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:511:12
    |
 LL |         if unsafe { true } {
    |            ^^^^^^^^^^^^^^^
@@ -313,7 +313,7 @@ LL |         if unsafe { true } {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:509:23
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:514:23
    |
 LL |             let bar = unsafe {};
    |                       ^^^^^^^^^
@@ -321,7 +321,7 @@ LL |             let bar = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:527:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:532:9
    |
 LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -329,7 +329,7 @@ LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:531:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:536:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -337,7 +337,7 @@ LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line()
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:535:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:540:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -345,7 +345,7 @@ LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line()
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:541:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:546:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -353,7 +353,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:545:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:550:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -361,7 +361,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:552:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:557:9
    |
 LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -369,7 +369,7 @@ LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:557:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:562:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -377,7 +377,7 @@ LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line()
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:563:9
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:568:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -385,7 +385,7 @@ LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line()
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:568:5
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:573:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index 8997073c8a5..e5ef9d35fb6 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -4,7 +4,12 @@
 //@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled
 
 #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
-#![allow(deref_nullptr, non_local_definitions, clippy::let_unit_value, clippy::missing_safety_doc)]
+#![allow(
+    deref_nullptr,
+    non_local_definitions,
+    clippy::let_unit_value,
+    clippy::missing_safety_doc
+)]
 #![feature(lint_reasons)]
 
 extern crate proc_macro_unsafe;
diff --git a/src/tools/clippy/tests/ui/assigning_clones.fixed b/src/tools/clippy/tests/ui/assigning_clones.fixed
new file mode 100644
index 00000000000..c66e0c1f602
--- /dev/null
+++ b/src/tools/clippy/tests/ui/assigning_clones.fixed
@@ -0,0 +1,222 @@
+#![allow(unused)]
+#![allow(clippy::redundant_clone)]
+#![allow(clippy::ptr_arg)] // https://github.com/rust-lang/rust-clippy/issues/10612
+#![allow(clippy::needless_late_init)]
+#![allow(clippy::box_collection)]
+#![warn(clippy::assigning_clones)]
+
+use std::borrow::ToOwned;
+use std::ops::{Add, Deref, DerefMut};
+
+// Clone
+pub struct HasCloneFrom;
+
+impl Clone for HasCloneFrom {
+    fn clone(&self) -> Self {
+        Self
+    }
+    fn clone_from(&mut self, source: &Self) {
+        *self = HasCloneFrom;
+    }
+}
+
+fn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) {
+    mut_thing.clone_from(&value_thing);
+}
+
+fn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing.clone_from(ref_thing);
+}
+
+fn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing.clone_from(ref_thing);
+}
+
+fn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(&mut mut_thing, ref_thing);
+}
+
+fn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    Clone::clone_from(mut_thing, ref_thing);
+}
+
+fn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be kept as necessary for a receiver
+    (mut_thing + &mut HasCloneFrom).clone_from(ref_thing);
+}
+
+fn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be removed since they are not needed in a function argument
+    mut_thing.clone_from(ref_thing + ref_thing);
+}
+
+fn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom {
+    let mut a = HasCloneFrom;
+    for _ in 1..10 {
+        a.clone_from(&b);
+    }
+    a
+}
+
+fn assign_to_late_init_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = HasCloneFrom;
+    a = b.clone();
+}
+
+fn assign_to_uninit_var(b: HasCloneFrom) {
+    let a;
+    a = b.clone();
+}
+
+fn assign_to_uninit_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = b.clone();
+}
+
+#[derive(Clone)]
+pub struct HasDeriveClone;
+
+fn ignore_derive_clone(a: &mut HasDeriveClone, b: &HasDeriveClone) {
+    // Should not be linted, since the Clone impl is derived
+    *a = b.clone();
+}
+
+pub struct HasCloneImpl;
+
+impl Clone for HasCloneImpl {
+    fn clone(&self) -> Self {
+        Self
+    }
+}
+
+fn ignore_missing_clone_from(a: &mut HasCloneImpl, b: &HasCloneImpl) {
+    // Should not be linted, since the Clone impl doesn't override clone_from
+    *a = b.clone();
+}
+
+struct FakeClone;
+
+impl FakeClone {
+    /// This looks just like `Clone::clone`
+    fn clone(&self) -> Self {
+        FakeClone
+    }
+}
+
+fn ignore_fake_clone() {
+    let mut a = FakeClone;
+    let b = FakeClone;
+    // Should not be linted, since the Clone impl doesn't come from std
+    a = b.clone();
+}
+
+fn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {
+    // Should not be linted, since we don't know the actual clone impl
+    *a = b.clone();
+}
+
+macro_rules! clone_inside {
+    ($a:expr, $b: expr) => {
+        $a = $b.clone();
+    };
+}
+
+fn clone_inside_macro() {
+    let mut a = String::new();
+    let b = String::new();
+    clone_inside!(a, b);
+}
+
+// ToOwned
+fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {
+    ref_str.clone_into(mut_string);
+}
+
+fn owned_method_val(mut mut_string: String, ref_str: &str) {
+    ref_str.clone_into(&mut mut_string);
+}
+
+struct HasDeref {
+    a: String,
+}
+
+impl Deref for HasDeref {
+    type Target = String;
+    fn deref(&self) -> &Self::Target {
+        &self.a
+    }
+}
+
+impl DerefMut for HasDeref {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.a
+    }
+}
+
+fn owned_method_box(mut_box_string: &mut Box<String>, ref_str: &str) {
+    ref_str.clone_into(&mut (*mut_box_string));
+}
+
+fn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) {
+    ref_str.clone_into(&mut (*mut_box_string));
+}
+
+fn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) {
+    ToOwned::clone_into(ref_str, mut_thing);
+}
+
+fn owned_function_val(mut mut_thing: String, ref_str: &str) {
+    ToOwned::clone_into(ref_str, &mut mut_thing);
+}
+
+struct FakeToOwned;
+impl FakeToOwned {
+    /// This looks just like `ToOwned::to_owned`
+    fn to_owned(&self) -> Self {
+        FakeToOwned
+    }
+}
+
+fn fake_to_owned() {
+    let mut a = FakeToOwned;
+    let b = FakeToOwned;
+    // Should not be linted, since the ToOwned impl doesn't come from std
+    a = b.to_owned();
+}
+
+fn main() {}
+
+/// Trait implementation to allow producing a `Thing` with a low-precedence expression.
+impl Add for HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&Thing` with a low-precedence expression.
+impl<'a> Add for &'a HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&mut Thing` with a low-precedence expression.
+impl<'a> Add for &'a mut HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a mut HasCloneFrom) -> Self {
+        self
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assigning_clones.rs b/src/tools/clippy/tests/ui/assigning_clones.rs
new file mode 100644
index 00000000000..b9f994d3e03
--- /dev/null
+++ b/src/tools/clippy/tests/ui/assigning_clones.rs
@@ -0,0 +1,222 @@
+#![allow(unused)]
+#![allow(clippy::redundant_clone)]
+#![allow(clippy::ptr_arg)] // https://github.com/rust-lang/rust-clippy/issues/10612
+#![allow(clippy::needless_late_init)]
+#![allow(clippy::box_collection)]
+#![warn(clippy::assigning_clones)]
+
+use std::borrow::ToOwned;
+use std::ops::{Add, Deref, DerefMut};
+
+// Clone
+pub struct HasCloneFrom;
+
+impl Clone for HasCloneFrom {
+    fn clone(&self) -> Self {
+        Self
+    }
+    fn clone_from(&mut self, source: &Self) {
+        *self = HasCloneFrom;
+    }
+}
+
+fn clone_method_rhs_val(mut_thing: &mut HasCloneFrom, value_thing: HasCloneFrom) {
+    *mut_thing = value_thing.clone();
+}
+
+fn clone_method_rhs_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = ref_thing.clone();
+}
+
+fn clone_method_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing = ref_thing.clone();
+}
+
+fn clone_function_lhs_mut_ref(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = Clone::clone(ref_thing);
+}
+
+fn clone_function_lhs_val(mut mut_thing: HasCloneFrom, ref_thing: &HasCloneFrom) {
+    mut_thing = Clone::clone(ref_thing);
+}
+
+fn clone_function_through_trait(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = Clone::clone(ref_thing);
+}
+
+fn clone_function_through_type(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = HasCloneFrom::clone(ref_thing);
+}
+
+fn clone_function_fully_qualified(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    *mut_thing = <HasCloneFrom as Clone>::clone(ref_thing);
+}
+
+fn clone_method_lhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be kept as necessary for a receiver
+    *(mut_thing + &mut HasCloneFrom) = ref_thing.clone();
+}
+
+fn clone_method_rhs_complex(mut_thing: &mut HasCloneFrom, ref_thing: &HasCloneFrom) {
+    // These parens should be removed since they are not needed in a function argument
+    *mut_thing = (ref_thing + ref_thing).clone();
+}
+
+fn assign_to_init_mut_var(b: HasCloneFrom) -> HasCloneFrom {
+    let mut a = HasCloneFrom;
+    for _ in 1..10 {
+        a = b.clone();
+    }
+    a
+}
+
+fn assign_to_late_init_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = HasCloneFrom;
+    a = b.clone();
+}
+
+fn assign_to_uninit_var(b: HasCloneFrom) {
+    let a;
+    a = b.clone();
+}
+
+fn assign_to_uninit_mut_var(b: HasCloneFrom) {
+    let mut a;
+    a = b.clone();
+}
+
+#[derive(Clone)]
+pub struct HasDeriveClone;
+
+fn ignore_derive_clone(a: &mut HasDeriveClone, b: &HasDeriveClone) {
+    // Should not be linted, since the Clone impl is derived
+    *a = b.clone();
+}
+
+pub struct HasCloneImpl;
+
+impl Clone for HasCloneImpl {
+    fn clone(&self) -> Self {
+        Self
+    }
+}
+
+fn ignore_missing_clone_from(a: &mut HasCloneImpl, b: &HasCloneImpl) {
+    // Should not be linted, since the Clone impl doesn't override clone_from
+    *a = b.clone();
+}
+
+struct FakeClone;
+
+impl FakeClone {
+    /// This looks just like `Clone::clone`
+    fn clone(&self) -> Self {
+        FakeClone
+    }
+}
+
+fn ignore_fake_clone() {
+    let mut a = FakeClone;
+    let b = FakeClone;
+    // Should not be linted, since the Clone impl doesn't come from std
+    a = b.clone();
+}
+
+fn ignore_generic_clone<T: Clone>(a: &mut T, b: &T) {
+    // Should not be linted, since we don't know the actual clone impl
+    *a = b.clone();
+}
+
+macro_rules! clone_inside {
+    ($a:expr, $b: expr) => {
+        $a = $b.clone();
+    };
+}
+
+fn clone_inside_macro() {
+    let mut a = String::new();
+    let b = String::new();
+    clone_inside!(a, b);
+}
+
+// ToOwned
+fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {
+    *mut_string = ref_str.to_owned();
+}
+
+fn owned_method_val(mut mut_string: String, ref_str: &str) {
+    mut_string = ref_str.to_owned();
+}
+
+struct HasDeref {
+    a: String,
+}
+
+impl Deref for HasDeref {
+    type Target = String;
+    fn deref(&self) -> &Self::Target {
+        &self.a
+    }
+}
+
+impl DerefMut for HasDeref {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.a
+    }
+}
+
+fn owned_method_box(mut_box_string: &mut Box<String>, ref_str: &str) {
+    **mut_box_string = ref_str.to_owned();
+}
+
+fn owned_method_deref(mut_box_string: &mut HasDeref, ref_str: &str) {
+    **mut_box_string = ref_str.to_owned();
+}
+
+fn owned_function_mut_ref(mut_thing: &mut String, ref_str: &str) {
+    *mut_thing = ToOwned::to_owned(ref_str);
+}
+
+fn owned_function_val(mut mut_thing: String, ref_str: &str) {
+    mut_thing = ToOwned::to_owned(ref_str);
+}
+
+struct FakeToOwned;
+impl FakeToOwned {
+    /// This looks just like `ToOwned::to_owned`
+    fn to_owned(&self) -> Self {
+        FakeToOwned
+    }
+}
+
+fn fake_to_owned() {
+    let mut a = FakeToOwned;
+    let b = FakeToOwned;
+    // Should not be linted, since the ToOwned impl doesn't come from std
+    a = b.to_owned();
+}
+
+fn main() {}
+
+/// Trait implementation to allow producing a `Thing` with a low-precedence expression.
+impl Add for HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&Thing` with a low-precedence expression.
+impl<'a> Add for &'a HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a HasCloneFrom) -> Self {
+        self
+    }
+}
+/// Trait implementation to allow producing a `&mut Thing` with a low-precedence expression.
+impl<'a> Add for &'a mut HasCloneFrom {
+    type Output = Self;
+    fn add(self, _: &'a mut HasCloneFrom) -> Self {
+        self
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assigning_clones.stderr b/src/tools/clippy/tests/ui/assigning_clones.stderr
new file mode 100644
index 00000000000..b76323f3606
--- /dev/null
+++ b/src/tools/clippy/tests/ui/assigning_clones.stderr
@@ -0,0 +1,107 @@
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:24:5
+   |
+LL |     *mut_thing = value_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(&value_thing)`
+   |
+   = note: `-D clippy::assigning-clones` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::assigning_clones)]`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:28:5
+   |
+LL |     *mut_thing = ref_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:32:5
+   |
+LL |     mut_thing = ref_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:36:5
+   |
+LL |     *mut_thing = Clone::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:40:5
+   |
+LL |     mut_thing = Clone::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(&mut mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:44:5
+   |
+LL |     *mut_thing = Clone::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:48:5
+   |
+LL |     *mut_thing = HasCloneFrom::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:52:5
+   |
+LL |     *mut_thing = <HasCloneFrom as Clone>::clone(ref_thing);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `Clone::clone_from(mut_thing, ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:57:5
+   |
+LL |     *(mut_thing + &mut HasCloneFrom) = ref_thing.clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `(mut_thing + &mut HasCloneFrom).clone_from(ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:62:5
+   |
+LL |     *mut_thing = (ref_thing + ref_thing).clone();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_from()`: `mut_thing.clone_from(ref_thing + ref_thing)`
+
+error: assigning the result of `Clone::clone()` may be inefficient
+  --> tests/ui/assigning_clones.rs:68:9
+   |
+LL |         a = b.clone();
+   |         ^^^^^^^^^^^^^ help: use `clone_from()`: `a.clone_from(&b)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:145:5
+   |
+LL |     *mut_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(mut_string)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:149:5
+   |
+LL |     mut_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut mut_string)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:170:5
+   |
+LL |     **mut_box_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:174:5
+   |
+LL |     **mut_box_string = ref_str.to_owned();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:178:5
+   |
+LL |     *mut_thing = ToOwned::to_owned(ref_str);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, mut_thing)`
+
+error: assigning the result of `ToOwned::to_owned()` may be inefficient
+  --> tests/ui/assigning_clones.rs:182:5
+   |
+LL |     mut_thing = ToOwned::to_owned(ref_str);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, &mut mut_thing)`
+
+error: aborting due to 17 previous errors
+
diff --git a/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs b/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs
index b56abccbd41..e920e58d6ec 100644
--- a/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs
+++ b/src/tools/clippy/tests/ui/crashes/unreachable-array-or-slice.rs
@@ -3,6 +3,6 @@ struct Foo(isize, isize, isize, isize);
 pub fn main() {
     let Self::anything_here_kills_it(a, b, ..) = Foo(5, 5, 5, 5);
     match [5, 5, 5, 5] {
-        [..] => { }
+        [..] => {},
     }
 }
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
index aa7a95405e0..6f42487bbf4 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.fixed
@@ -153,4 +153,30 @@ pub enum MissingEqNonExhaustive3 {
     Bar,
 }
 
+mod struct_gen {
+    // issue 9413
+    pub trait Group {
+        type Element: Eq + PartialEq;
+    }
+
+    pub trait Suite {
+        type Group: Group;
+    }
+
+    #[derive(PartialEq, Eq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Foo<C: Suite>(<C::Group as Group>::Element);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
+
+    // issue 9319
+    #[derive(PartialEq, Eq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Oof<T: Fn()>(T);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Rab<T: Fn()>(T);
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
index 90ac7a7989e..24f687c6c9d 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.rs
@@ -153,4 +153,30 @@ pub enum MissingEqNonExhaustive3 {
     Bar,
 }
 
+mod struct_gen {
+    // issue 9413
+    pub trait Group {
+        type Element: Eq + PartialEq;
+    }
+
+    pub trait Suite {
+        type Group: Group;
+    }
+
+    #[derive(PartialEq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Foo<C: Suite>(<C::Group as Group>::Element);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Bar<C: Suite>(i32, <C::Group as Group>::Element);
+
+    // issue 9319
+    #[derive(PartialEq)]
+    //~^ ERROR: you are deriving `PartialEq` and can implement `Eq`
+    pub struct Oof<T: Fn()>(T);
+
+    #[derive(PartialEq, Eq)]
+    pub struct Rab<T: Fn()>(T);
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
index 42b9895121f..3d92112dc36 100644
--- a/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
+++ b/src/tools/clippy/tests/ui/derive_partial_eq_without_eq.stderr
@@ -67,5 +67,17 @@ error: you are deriving `PartialEq` and can implement `Eq`
 LL |     #[derive(PartialEq)]
    |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
 
-error: aborting due to 11 previous errors
+error: you are deriving `PartialEq` and can implement `Eq`
+  --> tests/ui/derive_partial_eq_without_eq.rs:166:14
+   |
+LL |     #[derive(PartialEq)]
+   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
+
+error: you are deriving `PartialEq` and can implement `Eq`
+  --> tests/ui/derive_partial_eq_without_eq.rs:174:14
+   |
+LL |     #[derive(PartialEq)]
+   |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
+
+error: aborting due to 13 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 16f7bafd44b..178d4a1aa2b 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -230,3 +230,8 @@ fn issue_11568() {}
 
 /// There is no try (`do()` or `do_not()`).
 fn parenthesized_word() {}
+
+/// `ABes`
+/// OSes
+/// UXes
+fn plural_acronym_test() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 4058b2bad74..01edb44c64c 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -230,3 +230,8 @@ fn issue_11568() {}
 
 /// There is no try (do() or do_not()).
 fn parenthesized_word() {}
+
+/// ABes
+/// OSes
+/// UXes
+fn plural_acronym_test() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
index 7db9ff2b83b..ac876306b39 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
@@ -341,5 +341,16 @@ help: try
 LL | /// There is no try (do() or `do_not()`).
    |                              ~~~~~~~~~~
 
-error: aborting due to 31 previous errors
+error: item in documentation is missing backticks
+  --> tests/ui/doc/doc-fixable.rs:234:5
+   |
+LL | /// ABes
+   |     ^^^^
+   |
+help: try
+   |
+LL | /// `ABes`
+   |     ~~~~~~
+
+error: aborting due to 32 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.fixed b/src/tools/clippy/tests/ui/doc/issue_9473.fixed
new file mode 100644
index 00000000000..276ce7620ca
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/issue_9473.fixed
@@ -0,0 +1,9 @@
+#![warn(clippy::doc_markdown)]
+
+// Should not warn!
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>.
+pub struct Foo(u32);
+
+// Should warn.
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].
+pub struct FooBar(u32);
diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.rs b/src/tools/clippy/tests/ui/doc/issue_9473.rs
new file mode 100644
index 00000000000..52527f7106d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/issue_9473.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::doc_markdown)]
+
+// Should not warn!
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>.
+pub struct Foo(u32);
+
+// Should warn.
+/// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].
+pub struct FooBar(u32);
diff --git a/src/tools/clippy/tests/ui/doc/issue_9473.stderr b/src/tools/clippy/tests/ui/doc/issue_9473.stderr
new file mode 100644
index 00000000000..35aa2884cc1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/issue_9473.stderr
@@ -0,0 +1,15 @@
+error: item in documentation is missing backticks
+  --> tests/ui/doc/issue_9473.rs:8:58
+   |
+LL | /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[FooBar].
+   |                                                          ^^^^^^
+   |
+   = note: `-D clippy::doc-markdown` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_markdown)]`
+help: try
+   |
+LL | /// Blah blah blah <code>[FooBar]&lt;[FooBar]&gt;</code>[`FooBar`].
+   |                                                          ~~~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/else_if_without_else.rs b/src/tools/clippy/tests/ui/else_if_without_else.rs
index eb5e2266540..e7786f7dd27 100644
--- a/src/tools/clippy/tests/ui/else_if_without_else.rs
+++ b/src/tools/clippy/tests/ui/else_if_without_else.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::all)]
 #![warn(clippy::else_if_without_else)]
 
diff --git a/src/tools/clippy/tests/ui/else_if_without_else.stderr b/src/tools/clippy/tests/ui/else_if_without_else.stderr
index 80355cb2dba..3bb840f39e7 100644
--- a/src/tools/clippy/tests/ui/else_if_without_else.stderr
+++ b/src/tools/clippy/tests/ui/else_if_without_else.stderr
@@ -1,5 +1,5 @@
 error: `if` expression with an `else if`, but without a final `else`
-  --> tests/ui/else_if_without_else.rs:45:12
+  --> tests/ui/else_if_without_else.rs:47:12
    |
 LL |       } else if bla2() {
    |  ____________^
@@ -13,7 +13,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::else_if_without_else)]`
 
 error: `if` expression with an `else if`, but without a final `else`
-  --> tests/ui/else_if_without_else.rs:54:12
+  --> tests/ui/else_if_without_else.rs:56:12
    |
 LL |       } else if bla3() {
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/empty_docs.rs b/src/tools/clippy/tests/ui/empty_docs.rs
index c47a603e71b..272fab7d5ca 100644
--- a/src/tools/clippy/tests/ui/empty_docs.rs
+++ b/src/tools/clippy/tests/ui/empty_docs.rs
@@ -1,5 +1,7 @@
 #![allow(unused)]
 #![warn(clippy::empty_docs)]
+#![allow(clippy::mixed_attributes_style)]
+
 mod outer {
     //!
 
diff --git a/src/tools/clippy/tests/ui/empty_docs.stderr b/src/tools/clippy/tests/ui/empty_docs.stderr
index 3f1d071fb13..f12aead6aa7 100644
--- a/src/tools/clippy/tests/ui/empty_docs.stderr
+++ b/src/tools/clippy/tests/ui/empty_docs.stderr
@@ -1,5 +1,5 @@
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:4:5
+  --> tests/ui/empty_docs.rs:6:5
    |
 LL |     //!
    |     ^^^
@@ -9,7 +9,7 @@ LL |     //!
    = help: to override `-D warnings` add `#[allow(clippy::empty_docs)]`
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:12:5
+  --> tests/ui/empty_docs.rs:14:5
    |
 LL |     ///
    |     ^^^
@@ -17,7 +17,7 @@ LL |     ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:14:9
+  --> tests/ui/empty_docs.rs:16:9
    |
 LL |         ///
    |         ^^^
@@ -25,7 +25,7 @@ LL |         ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:25:5
+  --> tests/ui/empty_docs.rs:27:5
    |
 LL |     #[doc = ""]
    |     ^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     #[doc = ""]
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:28:5
+  --> tests/ui/empty_docs.rs:30:5
    |
 LL | /     #[doc = ""]
 LL | |     #[doc = ""]
@@ -42,7 +42,7 @@ LL | |     #[doc = ""]
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:35:5
+  --> tests/ui/empty_docs.rs:37:5
    |
 LL |     ///
    |     ^^^
@@ -50,7 +50,7 @@ LL |     ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:48:13
+  --> tests/ui/empty_docs.rs:50:13
    |
 LL |             /*! */
    |             ^^^^^^
@@ -58,7 +58,7 @@ LL |             /*! */
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:56:13
+  --> tests/ui/empty_docs.rs:58:13
    |
 LL |             ///
    |             ^^^
@@ -66,7 +66,7 @@ LL |             ///
    = help: consider removing or filling it
 
 error: empty doc comment
-  --> tests/ui/empty_docs.rs:64:9
+  --> tests/ui/empty_docs.rs:66:9
    |
 LL |         ///
    |         ^^^
diff --git a/src/tools/clippy/tests/ui/entry.fixed b/src/tools/clippy/tests/ui/entry.fixed
index 4099fe7e139..71ec13f4610 100644
--- a/src/tools/clippy/tests/ui/entry.fixed
+++ b/src/tools/clippy/tests/ui/entry.fixed
@@ -165,4 +165,15 @@ pub fn issue_10331() {
     }
 }
 
+/// Issue 11935
+/// Do not suggest using entries if the map is used inside the `insert` expression.
+pub fn issue_11935() {
+    let mut counts: HashMap<u64, u64> = HashMap::new();
+    if !counts.contains_key(&1) {
+        counts.insert(1, 1);
+    } else {
+        counts.insert(1, counts.get(&1).unwrap() + 1);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/entry.rs b/src/tools/clippy/tests/ui/entry.rs
index 409be0aa060..86092b7c055 100644
--- a/src/tools/clippy/tests/ui/entry.rs
+++ b/src/tools/clippy/tests/ui/entry.rs
@@ -169,4 +169,15 @@ pub fn issue_10331() {
     }
 }
 
+/// Issue 11935
+/// Do not suggest using entries if the map is used inside the `insert` expression.
+pub fn issue_11935() {
+    let mut counts: HashMap<u64, u64> = HashMap::new();
+    if !counts.contains_key(&1) {
+        counts.insert(1, 1);
+    } else {
+        counts.insert(1, counts.get(&1).unwrap() + 1);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
index 06229a52a18..f38b34c5a7c 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
@@ -6,7 +6,7 @@
     clippy::deref_addrof,
     clippy::unnecessary_mut_passed,
     dead_code,
-    non_local_definitions,
+    non_local_definitions
 )]
 
 use core::slice;
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
index c2bf45ab2e9..2e701ada5ac 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
@@ -6,7 +6,7 @@
     clippy::deref_addrof,
     clippy::unnecessary_mut_passed,
     dead_code,
-    non_local_definitions,
+    non_local_definitions
 )]
 
 use core::slice;
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.rs b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
index 2045b1eebcd..620cffb4f04 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.rs
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.rs
@@ -2,6 +2,7 @@
 //@aux-build:proc_macros.rs
 
 #![warn(clippy::field_reassign_with_default)]
+#![allow(clippy::assigning_clones)]
 
 #[macro_use]
 extern crate proc_macro_derive;
diff --git a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
index bc032834920..ae909475c6f 100644
--- a/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
+++ b/src/tools/clippy/tests/ui/field_reassign_with_default.stderr
@@ -1,11 +1,11 @@
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:56:5
+  --> tests/ui/field_reassign_with_default.rs:57:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:55:5
+  --> tests/ui/field_reassign_with_default.rs:56:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,121 +13,121 @@ LL |     let mut a: A = Default::default();
    = help: to override `-D warnings` add `#[allow(clippy::field_reassign_with_default)]`
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:96:5
+  --> tests/ui/field_reassign_with_default.rs:97:5
    |
 LL |     a.j = 43;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:95:5
+  --> tests/ui/field_reassign_with_default.rs:96:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:101:5
+  --> tests/ui/field_reassign_with_default.rs:102:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:100:5
+  --> tests/ui/field_reassign_with_default.rs:101:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:107:5
+  --> tests/ui/field_reassign_with_default.rs:108:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:106:5
+  --> tests/ui/field_reassign_with_default.rs:107:5
    |
 LL |     let mut a = A::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:117:5
+  --> tests/ui/field_reassign_with_default.rs:118:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:116:5
+  --> tests/ui/field_reassign_with_default.rs:117:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:121:5
+  --> tests/ui/field_reassign_with_default.rs:122:5
    |
 LL |     a.i = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:120:5
+  --> tests/ui/field_reassign_with_default.rs:121:5
    |
 LL |     let mut a: A = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:143:5
+  --> tests/ui/field_reassign_with_default.rs:144:5
    |
 LL |     a.i = vec![1];
    |     ^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:142:5
+  --> tests/ui/field_reassign_with_default.rs:143:5
    |
 LL |     let mut a: C = C::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:161:5
+  --> tests/ui/field_reassign_with_default.rs:162:5
    |
 LL |     a.i = true;
    |     ^^^^^^^^^^^
    |
 note: consider initializing the variable with `Wrapper::<bool> { i: true }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:160:5
+  --> tests/ui/field_reassign_with_default.rs:161:5
    |
 LL |     let mut a: Wrapper<bool> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:164:5
+  --> tests/ui/field_reassign_with_default.rs:165:5
    |
 LL |     a.i = 42;
    |     ^^^^^^^^^
    |
 note: consider initializing the variable with `WrapperMulti::<i32, i64> { i: 42, ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:163:5
+  --> tests/ui/field_reassign_with_default.rs:164:5
    |
 LL |     let mut a: WrapperMulti<i32, i64> = Default::default();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:235:13
+  --> tests/ui/field_reassign_with_default.rs:236:13
    |
 LL |             f.name = name.len();
    |             ^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:234:13
+  --> tests/ui/field_reassign_with_default.rs:235:13
    |
 LL |             let mut f = ImplDropAllCopy::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: field assignment outside of initializer for an instance created with Default::default()
-  --> tests/ui/field_reassign_with_default.rs:251:13
+  --> tests/ui/field_reassign_with_default.rs:252:13
    |
 LL |             f.name = name.len();
    |             ^^^^^^^^^^^^^^^^^^^^
    |
 note: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments
-  --> tests/ui/field_reassign_with_default.rs:250:13
+  --> tests/ui/field_reassign_with_default.rs:251:13
    |
 LL |             let mut f = NoDropAllCopy::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/identity_op.fixed b/src/tools/clippy/tests/ui/identity_op.fixed
index 660e9a21b18..b18d8560f6f 100644
--- a/src/tools/clippy/tests/ui/identity_op.fixed
+++ b/src/tools/clippy/tests/ui/identity_op.fixed
@@ -134,7 +134,7 @@ fn main() {
     //~^ ERROR: this operation has no effect
     f(if b { 1 } else { 2 } + 3);
     //~^ ERROR: this operation has no effect
-    
+
     const _: i32 = { 2 * 4 } + 3;
     //~^ ERROR: this operation has no effect
     const _: i32 = { 1 + 2 * 3 } + 3;
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index bbef531e9dc..f1f01b42447 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -134,7 +134,7 @@ fn main() {
     //~^ ERROR: this operation has no effect
     f(0 + if b { 1 } else { 2 } + 3);
     //~^ ERROR: this operation has no effect
-    
+
     const _: i32 = { 2 * 4 } + 0 + 3;
     //~^ ERROR: this operation has no effect
     const _: i32 = 0 + { 1 + 2 * 3 } + 3;
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
index 2ababad7fc7..27ee2f91594 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![feature(inline_const)]
 #![warn(clippy::indexing_slicing)]
 // We also check the out_of_bounds_indexing lint here, because it lints similar things and
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index 06a4defcb93..5f62ec9b556 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -1,5 +1,5 @@
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:14:20
+  --> tests/ui/indexing_slicing_index.rs:16:20
    |
 LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-restriction-lint-in-const` default is false.
    |                    ^^^^^^^^^^
@@ -10,19 +10,19 @@ LL | const REF: &i32 = &ARR[idx()]; // This should be linted, since `suppress-re
    = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
 
 error[E0080]: evaluation of `main::{constant#3}` failed
-  --> tests/ui/indexing_slicing_index.rs:46:14
+  --> tests/ui/indexing_slicing_index.rs:48:14
    |
 LL |     const { &ARR[idx4()] };
    |              ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
 
 note: erroneous constant encountered
-  --> tests/ui/indexing_slicing_index.rs:46:5
+  --> tests/ui/indexing_slicing_index.rs:48:5
    |
 LL |     const { &ARR[idx4()] };
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:27:5
+  --> tests/ui/indexing_slicing_index.rs:29:5
    |
 LL |     x[index];
    |     ^^^^^^^^
@@ -30,7 +30,7 @@ LL |     x[index];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:30:5
+  --> tests/ui/indexing_slicing_index.rs:32:5
    |
 LL |     x[4];
    |     ^^^^
@@ -39,13 +39,13 @@ LL |     x[4];
    = help: to override `-D warnings` add `#[allow(clippy::out_of_bounds_indexing)]`
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:32:5
+  --> tests/ui/indexing_slicing_index.rs:34:5
    |
 LL |     x[1 << 3];
    |     ^^^^^^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:43:14
+  --> tests/ui/indexing_slicing_index.rs:45:14
    |
 LL |     const { &ARR[idx()] };
    |              ^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     const { &ARR[idx()] };
    = note: the suggestion might not be applicable in constant blocks
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:46:14
+  --> tests/ui/indexing_slicing_index.rs:48:14
    |
 LL |     const { &ARR[idx4()] };
    |              ^^^^^^^^^^^
@@ -63,13 +63,13 @@ LL |     const { &ARR[idx4()] };
    = note: the suggestion might not be applicable in constant blocks
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:53:5
+  --> tests/ui/indexing_slicing_index.rs:55:5
    |
 LL |     y[4];
    |     ^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:56:5
+  --> tests/ui/indexing_slicing_index.rs:58:5
    |
 LL |     v[0];
    |     ^^^^
@@ -77,7 +77,7 @@ LL |     v[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:58:5
+  --> tests/ui/indexing_slicing_index.rs:60:5
    |
 LL |     v[10];
    |     ^^^^^
@@ -85,7 +85,7 @@ LL |     v[10];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:60:5
+  --> tests/ui/indexing_slicing_index.rs:62:5
    |
 LL |     v[1 << 3];
    |     ^^^^^^^^^
@@ -93,13 +93,13 @@ LL |     v[1 << 3];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:68:5
+  --> tests/ui/indexing_slicing_index.rs:70:5
    |
 LL |     x[N];
    |     ^^^^
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:71:5
+  --> tests/ui/indexing_slicing_index.rs:73:5
    |
 LL |     v[N];
    |     ^^^^
@@ -107,7 +107,7 @@ LL |     v[N];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui/indexing_slicing_index.rs:73:5
+  --> tests/ui/indexing_slicing_index.rs:75:5
    |
 LL |     v[M];
    |     ^^^^
@@ -115,7 +115,7 @@ LL |     v[M];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: index is out of bounds
-  --> tests/ui/indexing_slicing_index.rs:77:13
+  --> tests/ui/indexing_slicing_index.rs:79:13
    |
 LL |     let _ = x[4];
    |             ^^^^
diff --git a/src/tools/clippy/tests/ui/let_underscore_untyped.rs b/src/tools/clippy/tests/ui/let_underscore_untyped.rs
index bd94a3ada18..6275b6f970a 100644
--- a/src/tools/clippy/tests/ui/let_underscore_untyped.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_untyped.rs
@@ -73,3 +73,5 @@ fn main() {
     #[allow(clippy::let_underscore_untyped)]
     let _ = a();
 }
+
+async fn dont_lint_async_prototype(_: u8) {}
diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs
index 5d94660ec89..1fb252e3f97 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else.rs
@@ -1,3 +1,4 @@
+#![feature(try_blocks)]
 #![allow(unused_braces, unused_variables, dead_code)]
 #![allow(
     clippy::collapsible_else_if,
@@ -446,3 +447,12 @@ struct U<T> {
     w: T,
     x: T,
 }
+
+fn issue12337() {
+    // We want to generally silence question_mark lints within try blocks, since `?` has different
+    // behavior to `return`, and question_mark calls into manual_let_else logic, so make sure that
+    // we still emit a lint for manual_let_else
+    let _: Option<()> = try {
+        let v = if let Some(v_some) = g() { v_some } else { return };
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr
index b6433fc460c..7012c6b8891 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else.stderr
@@ -1,5 +1,5 @@
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:27:5
+  --> tests/ui/manual_let_else.rs:28:5
    |
 LL |     let v = if let Some(v_some) = g() { v_some } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
@@ -8,7 +8,7 @@ LL |     let v = if let Some(v_some) = g() { v_some } else { return };
    = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:30:5
+  --> tests/ui/manual_let_else.rs:31:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -26,7 +26,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:37:5
+  --> tests/ui/manual_let_else.rs:38:5
    |
 LL | /     let v = if let Some(v) = g() {
 LL | |
@@ -47,25 +47,25 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:49:9
+  --> tests/ui/manual_let_else.rs:50:9
    |
 LL |         let v = if let Some(v_some) = g() { v_some } else { continue };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { continue };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:51:9
+  --> tests/ui/manual_let_else.rs:52:9
    |
 LL |         let v = if let Some(v_some) = g() { v_some } else { break };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { break };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:56:5
+  --> tests/ui/manual_let_else.rs:57:5
    |
 LL |     let v = if let Some(v_some) = g() { v_some } else { panic!() };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { panic!() };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:60:5
+  --> tests/ui/manual_let_else.rs:61:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -83,7 +83,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:68:5
+  --> tests/ui/manual_let_else.rs:69:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -101,7 +101,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:76:5
+  --> tests/ui/manual_let_else.rs:77:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -121,7 +121,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:85:5
+  --> tests/ui/manual_let_else.rs:86:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -141,7 +141,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:94:5
+  --> tests/ui/manual_let_else.rs:95:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -168,7 +168,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:110:5
+  --> tests/ui/manual_let_else.rs:111:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -190,7 +190,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:121:5
+  --> tests/ui/manual_let_else.rs:122:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -217,7 +217,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:137:5
+  --> tests/ui/manual_let_else.rs:138:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -239,7 +239,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:148:5
+  --> tests/ui/manual_let_else.rs:149:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -257,7 +257,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:156:5
+  --> tests/ui/manual_let_else.rs:157:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -278,7 +278,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:166:5
+  --> tests/ui/manual_let_else.rs:167:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -299,7 +299,7 @@ LL +     } };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:176:5
+  --> tests/ui/manual_let_else.rs:177:5
    |
 LL | /     let v = if let Some(v_some) = g() {
 LL | |
@@ -328,7 +328,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:194:5
+  --> tests/ui/manual_let_else.rs:195:5
    |
 LL | /     let (v, w) = if let Some(v_some) = g().map(|v| (v, 42)) {
 LL | |
@@ -346,7 +346,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:202:5
+  --> tests/ui/manual_let_else.rs:203:5
    |
 LL | /     let (w, S { v }) = if let (Some(v_some), w_some) = (g().map(|_| S { v: 0 }), 0) {
 LL | |
@@ -364,7 +364,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:212:13
+  --> tests/ui/manual_let_else.rs:213:13
    |
 LL |             let $n = if let Some(v) = $e { v } else { return };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some($n) = g() else { return };`
@@ -375,19 +375,19 @@ LL |     create_binding_if_some!(w, g());
    = note: this error originates in the macro `create_binding_if_some` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:221:5
+  --> tests/ui/manual_let_else.rs:222:5
    |
 LL |     let v = if let Variant::A(a, 0) = e() { a } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(v, 0) = e() else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:225:5
+  --> tests/ui/manual_let_else.rs:226:5
    |
 LL |     let mut v = if let Variant::B(b) = e() { b } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::B(mut v) = e() else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:230:5
+  --> tests/ui/manual_let_else.rs:231:5
    |
 LL | /     let v = if let Ok(Some(Variant::B(b))) | Err(Some(Variant::A(b, _))) = nested {
 LL | |
@@ -405,19 +405,19 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:237:5
+  --> tests/ui/manual_let_else.rs:238:5
    |
 LL |     let v = if let Variant::A(.., a) = e() { a } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Variant::A(.., v) = e() else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:241:5
+  --> tests/ui/manual_let_else.rs:242:5
    |
 LL |     let w = if let (Some(v), ()) = (g(), ()) { v } else { return };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let (Some(w), ()) = (g(), ()) else { return };`
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:245:5
+  --> tests/ui/manual_let_else.rs:246:5
    |
 LL | /     let w = if let Some(S { v: x }) = Some(S { v: 0 }) {
 LL | |
@@ -435,7 +435,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:253:5
+  --> tests/ui/manual_let_else.rs:254:5
    |
 LL | /     let v = if let Some(S { v: x }) = Some(S { v: 0 }) {
 LL | |
@@ -453,7 +453,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:261:5
+  --> tests/ui/manual_let_else.rs:262:5
    |
 LL | /     let (x, S { v }, w) = if let Some(U { v, w, x }) = None::<U<S<()>>> {
 LL | |
@@ -471,7 +471,7 @@ LL +     };
    |
 
 error: this could be rewritten as `let...else`
-  --> tests/ui/manual_let_else.rs:378:5
+  --> tests/ui/manual_let_else.rs:379:5
    |
 LL | /     let _ = match ff {
 LL | |
@@ -480,5 +480,11 @@ LL | |         _ => macro_call!(),
 LL | |     };
    | |______^ help: consider writing: `let Some(_) = ff else { macro_call!() };`
 
-error: aborting due to 30 previous errors
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else.rs:456:9
+   |
+LL |         let v = if let Some(v_some) = g() { v_some } else { return };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
index 8146091a2bb..c917fa7f2d0 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.rs
@@ -1,5 +1,6 @@
-#![warn(clippy::needless_range_loop, clippy::manual_memcpy)]
-#![allow(clippy::useless_vec)]
+#![warn(clippy::manual_memcpy)]
+#![allow(clippy::assigning_clones, clippy::useless_vec, clippy::needless_range_loop)]
+
 //@no-rustfix
 const LOOP_OFFSET: usize = 5000;
 
@@ -158,6 +159,59 @@ pub fn manual_copy(src: &[i32], dst: &mut [i32], dst2: &mut [i32]) {
         //~^ ERROR: it looks like you're manually copying between slices
         dst[i] = src[i];
     }
+
+    // Don't trigger lint for following multi-dimensional arrays
+    let src = [[0; 5]; 5];
+    for i in 0..4 {
+        dst[i] = src[i + 1][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][3];
+    }
+
+    let src = [0; 5];
+    let mut dst = [[0; 5]; 5];
+    for i in 0..5 {
+        dst[i][i] = src[i];
+    }
+
+    let src = [[[0; 5]; 5]; 5];
+    let mut dst = [0; 5];
+    for i in 0..5 {
+        dst[i] = src[i][i][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][i][0];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][0][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[0][i][i];
+    }
+    for i in 0..5 {
+        dst[i] = src[0][i][1];
+    }
+    for i in 0..5 {
+        dst[i] = src[i][0][1];
+    }
+
+    // Trigger lint
+    let src = [[0; 5]; 5];
+    let mut dst = [0; 5];
+    for i in 0..5 {
+        //~^ ERROR: it looks like you're manually copying between slices
+        dst[i] = src[0][i];
+    }
+
+    let src = [[[0; 5]; 5]; 5];
+    for i in 0..5 {
+        //~^ ERROR: it looks like you're manually copying between slices
+        dst[i] = src[0][1][i];
+    }
 }
 
 #[warn(clippy::needless_range_loop, clippy::manual_memcpy)]
diff --git a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
index 55cca1fb584..803053b2db2 100644
--- a/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
+++ b/src/tools/clippy/tests/ui/manual_memcpy/without_loop_counters.stderr
@@ -1,5 +1,5 @@
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:8:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:9:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -12,7 +12,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::manual_memcpy)]`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:15:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:16:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -21,7 +21,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[10..(src.len() + 10)].copy_from_slice(&src[..]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:21:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:22:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -30,7 +30,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..src.len()].copy_from_slice(&src[10..(src.len() + 10)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:27:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:28:5
    |
 LL | /     for i in 11..src.len() {
 LL | |
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[11..src.len()].copy_from_slice(&src[(11 - 10)..(src.len() - 10)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:33:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:34:5
    |
 LL | /     for i in 0..dst.len() {
 LL | |
@@ -48,7 +48,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..dst.len()]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:47:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:48:5
    |
 LL | /     for i in 10..256 {
 LL | |
@@ -64,7 +64,7 @@ LL +     dst2[(10 + 500)..(256 + 500)].copy_from_slice(&src[10..256]);
    |
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:60:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:61:5
    |
 LL | /     for i in 10..LOOP_OFFSET {
 LL | |
@@ -73,7 +73,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[(10 + LOOP_OFFSET)..(LOOP_OFFSET + LOOP_OFFSET)].copy_from_slice(&src[(10 - some_var)..(LOOP_OFFSET - some_var)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:74:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:75:5
    |
 LL | /     for i in 0..src_vec.len() {
 LL | |
@@ -82,7 +82,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst_vec[..src_vec.len()].copy_from_slice(&src_vec[..]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:104:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:105:5
    |
 LL | /     for i in from..from + src.len() {
 LL | |
@@ -91,7 +91,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[from..(from + src.len())].copy_from_slice(&src[..(from + src.len() - from)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:109:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:110:5
    |
 LL | /     for i in from..from + 3 {
 LL | |
@@ -100,7 +100,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[from..(from + 3)].copy_from_slice(&src[..(from + 3 - from)]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:115:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:116:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -109,7 +109,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:121:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:122:5
    |
 LL | /     for i in 0..0 {
 LL | |
@@ -118,7 +118,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..0].copy_from_slice(&src[..0]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:145:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:146:5
    |
 LL | /     for i in 0..4 {
 LL | |
@@ -127,7 +127,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[..4]);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:151:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:152:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -136,7 +136,7 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..5].copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:157:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:158:5
    |
 LL | /     for i in 0..5 {
 LL | |
@@ -145,7 +145,25 @@ LL | |     }
    | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src);`
 
 error: it looks like you're manually copying between slices
-  --> tests/ui/manual_memcpy/without_loop_counters.rs:165:5
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:205:5
+   |
+LL | /     for i in 0..5 {
+LL | |
+LL | |         dst[i] = src[0][i];
+LL | |     }
+   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0]);`
+
+error: it looks like you're manually copying between slices
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:211:5
+   |
+LL | /     for i in 0..5 {
+LL | |
+LL | |         dst[i] = src[0][1][i];
+LL | |     }
+   | |_____^ help: try replacing the loop by: `dst.copy_from_slice(&src[0][1]);`
+
+error: it looks like you're manually copying between slices
+  --> tests/ui/manual_memcpy/without_loop_counters.rs:219:5
    |
 LL | /     for i in 0..src.len() {
 LL | |
@@ -153,5 +171,5 @@ LL | |         dst[i] = src[i].clone();
 LL | |     }
    | |_____^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..]);`
 
-error: aborting due to 16 previous errors
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_retain.fixed b/src/tools/clippy/tests/ui/manual_retain.fixed
index 5540029bf6b..e359dfbb98c 100644
--- a/src/tools/clippy/tests/ui/manual_retain.fixed
+++ b/src/tools/clippy/tests/ui/manual_retain.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::manual_retain)]
 #![allow(unused, clippy::redundant_clone)]
 use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
diff --git a/src/tools/clippy/tests/ui/manual_retain.rs b/src/tools/clippy/tests/ui/manual_retain.rs
index cee641d9d65..931814f08b7 100644
--- a/src/tools/clippy/tests/ui/manual_retain.rs
+++ b/src/tools/clippy/tests/ui/manual_retain.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::manual_retain)]
 #![allow(unused, clippy::redundant_clone)]
 use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
diff --git a/src/tools/clippy/tests/ui/manual_retain.stderr b/src/tools/clippy/tests/ui/manual_retain.stderr
index c25c804df75..fdbbc53e4df 100644
--- a/src/tools/clippy/tests/ui/manual_retain.stderr
+++ b/src/tools/clippy/tests/ui/manual_retain.stderr
@@ -1,5 +1,5 @@
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:25:5
+  --> tests/ui/manual_retain.rs:27:5
    |
 LL |     binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
@@ -8,43 +8,43 @@ LL |     binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
    = help: to override `-D warnings` add `#[allow(clippy::manual_retain)]`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:26:5
+  --> tests/ui/manual_retain.rs:28:5
    |
 LL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:27:5
+  --> tests/ui/manual_retain.rs:29:5
    |
 LL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:31:5
+  --> tests/ui/manual_retain.rs:33:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:32:5
+  --> tests/ui/manual_retain.rs:34:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:62:5
+  --> tests/ui/manual_retain.rs:64:5
    |
 LL |     btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:63:5
+  --> tests/ui/manual_retain.rs:65:5
    |
 LL |     btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:64:5
+  --> tests/ui/manual_retain.rs:66:5
    |
 LL | /     btree_map = btree_map
 LL | |         .into_iter()
@@ -53,49 +53,49 @@ LL | |         .collect();
    | |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:89:5
+  --> tests/ui/manual_retain.rs:91:5
    |
 LL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:90:5
+  --> tests/ui/manual_retain.rs:92:5
    |
 LL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:91:5
+  --> tests/ui/manual_retain.rs:93:5
    |
 LL |     btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:95:5
+  --> tests/ui/manual_retain.rs:97:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:96:5
+  --> tests/ui/manual_retain.rs:98:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:126:5
+  --> tests/ui/manual_retain.rs:128:5
    |
 LL |     hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:127:5
+  --> tests/ui/manual_retain.rs:129:5
    |
 LL |     hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:128:5
+  --> tests/ui/manual_retain.rs:130:5
    |
 LL | /     hash_map = hash_map
 LL | |         .into_iter()
@@ -104,133 +104,133 @@ LL | |         .collect();
    | |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:152:5
+  --> tests/ui/manual_retain.rs:154:5
    |
 LL |     hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:153:5
+  --> tests/ui/manual_retain.rs:155:5
    |
 LL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:154:5
+  --> tests/ui/manual_retain.rs:156:5
    |
 LL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:158:5
+  --> tests/ui/manual_retain.rs:160:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:159:5
+  --> tests/ui/manual_retain.rs:161:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:188:5
+  --> tests/ui/manual_retain.rs:190:5
    |
 LL |     s = s.chars().filter(|&c| c != 'o').to_owned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:200:5
+  --> tests/ui/manual_retain.rs:202:5
    |
 LL |     vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:201:5
+  --> tests/ui/manual_retain.rs:203:5
    |
 LL |     vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:202:5
+  --> tests/ui/manual_retain.rs:204:5
    |
 LL |     vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:206:5
+  --> tests/ui/manual_retain.rs:208:5
    |
 LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:207:5
+  --> tests/ui/manual_retain.rs:209:5
    |
 LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:229:5
+  --> tests/ui/manual_retain.rs:231:5
    |
 LL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:230:5
+  --> tests/ui/manual_retain.rs:232:5
    |
 LL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:231:5
+  --> tests/ui/manual_retain.rs:233:5
    |
 LL |     vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:288:5
+  --> tests/ui/manual_retain.rs:290:5
    |
 LL |     vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|(x, y)| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:292:5
+  --> tests/ui/manual_retain.rs:294:5
    |
 LL |     tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(_, n)| *n > 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:309:5
+  --> tests/ui/manual_retain.rs:311:5
    |
 LL |     vec = vec.iter().filter(|&&x| x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:310:5
+  --> tests/ui/manual_retain.rs:312:5
    |
 LL |     vec = vec.iter().filter(|&&x| x == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:311:5
+  --> tests/ui/manual_retain.rs:313:5
    |
 LL |     vec = vec.into_iter().filter(|&x| x == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:314:5
+  --> tests/ui/manual_retain.rs:316:5
    |
 LL |     vec = vec.iter().filter(|&x| *x == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:315:5
+  --> tests/ui/manual_retain.rs:317:5
    |
 LL |     vec = vec.iter().filter(|&x| *x == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> tests/ui/manual_retain.rs:316:5
+  --> tests/ui/manual_retain.rs:318:5
    |
 LL |     vec = vec.into_iter().filter(|x| *x == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
diff --git a/src/tools/clippy/tests/ui/many_single_char_names.rs b/src/tools/clippy/tests/ui/many_single_char_names.rs
index 68578340d90..2af45eaab8a 100644
--- a/src/tools/clippy/tests/ui/many_single_char_names.rs
+++ b/src/tools/clippy/tests/ui/many_single_char_names.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![allow(clippy::too_many_arguments, clippy::diverging_sub_expression)]
 #![warn(clippy::many_single_char_names)]
 
diff --git a/src/tools/clippy/tests/ui/many_single_char_names.stderr b/src/tools/clippy/tests/ui/many_single_char_names.stderr
index 131836ef7c8..3b2460b5c07 100644
--- a/src/tools/clippy/tests/ui/many_single_char_names.stderr
+++ b/src/tools/clippy/tests/ui/many_single_char_names.stderr
@@ -1,5 +1,5 @@
 error: 5 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:5:9
+  --> tests/ui/many_single_char_names.rs:7:9
    |
 LL |     let a: i32;
    |         ^
@@ -14,7 +14,7 @@ LL |             let e: i32;
    = help: to override `-D warnings` add `#[allow(clippy::many_single_char_names)]`
 
 error: 6 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:5:9
+  --> tests/ui/many_single_char_names.rs:7:9
    |
 LL |     let a: i32;
    |         ^
@@ -28,7 +28,7 @@ LL |             let f: i32;
    |                 ^
 
 error: 5 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:5:9
+  --> tests/ui/many_single_char_names.rs:7:9
    |
 LL |     let a: i32;
    |         ^
@@ -40,13 +40,13 @@ LL |             e => panic!(),
    |             ^
 
 error: 8 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:34:13
+  --> tests/ui/many_single_char_names.rs:36:13
    |
 LL | fn bindings(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
    |             ^       ^       ^       ^       ^       ^       ^       ^
 
 error: 8 bindings with single-character names in scope
-  --> tests/ui/many_single_char_names.rs:38:10
+  --> tests/ui/many_single_char_names.rs:40:10
    |
 LL |     let (a, b, c, d, e, f, g, h): (bool, bool, bool, bool, bool, bool, bool, bool) = unimplemented!();
    |          ^  ^  ^  ^  ^  ^  ^  ^
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
index 3917bb9e03d..2dccadd9fce 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![feature(custom_inner_attributes)]
 #![clippy::msrv = "invalid.version"]
 //~^ ERROR: `invalid.version` is not a valid Rust version
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
index cf0d08a5d21..b4cb1b5713f 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
@@ -1,35 +1,35 @@
 error: `invalid.version` is not a valid Rust version
-  --> tests/ui/min_rust_version_invalid_attr.rs:2:1
+  --> tests/ui/min_rust_version_invalid_attr.rs:4:1
    |
 LL | #![clippy::msrv = "invalid.version"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `invalid.version` is not a valid Rust version
-  --> tests/ui/min_rust_version_invalid_attr.rs:7:1
+  --> tests/ui/min_rust_version_invalid_attr.rs:9:1
    |
 LL | #[clippy::msrv = "invalid.version"]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `clippy::msrv` is defined multiple times
-  --> tests/ui/min_rust_version_invalid_attr.rs:14:5
+  --> tests/ui/min_rust_version_invalid_attr.rs:16:5
    |
 LL |     #![clippy::msrv = "1.10.1"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first definition found here
-  --> tests/ui/min_rust_version_invalid_attr.rs:12:5
+  --> tests/ui/min_rust_version_invalid_attr.rs:14:5
    |
 LL |     #![clippy::msrv = "1.40"]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `clippy::msrv` is defined multiple times
-  --> tests/ui/min_rust_version_invalid_attr.rs:19:9
+  --> tests/ui/min_rust_version_invalid_attr.rs:21:9
    |
 LL |         #![clippy::msrv = "1.0.0"]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first definition found here
-  --> tests/ui/min_rust_version_invalid_attr.rs:18:9
+  --> tests/ui/min_rust_version_invalid_attr.rs:20:9
    |
 LL |         #![clippy::msrv = "1"]
    |         ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.rs b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
new file mode 100644
index 00000000000..ad93e3019fa
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
@@ -0,0 +1,39 @@
+#![warn(clippy::mixed_attributes_style)]
+
+#[allow(unused)] //~ ERROR: item has both inner and outer attributes
+fn foo1() {
+    #![allow(unused)]
+}
+
+#[allow(unused)]
+#[allow(unused)]
+fn foo2() {}
+
+fn foo3() {
+    #![allow(unused)]
+    #![allow(unused)]
+}
+
+/// linux
+//~^ ERROR: item has both inner and outer attributes
+fn foo4() {
+    //! windows
+}
+
+/// linux
+/// windows
+fn foo5() {}
+
+fn foo6() {
+    //! linux
+    //! windows
+}
+
+#[allow(unused)] //~ ERROR: item has both inner and outer attributes
+mod bar {
+    #![allow(unused)]
+}
+
+fn main() {
+    // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.stderr b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
new file mode 100644
index 00000000000..d1d5cd3f47f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
@@ -0,0 +1,30 @@
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:3:1
+   |
+LL | / #[allow(unused)]
+LL | | fn foo1() {
+LL | |     #![allow(unused)]
+   | |_____________________^
+   |
+   = note: `-D clippy::mixed-attributes-style` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]`
+
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:17:1
+   |
+LL | / /// linux
+LL | |
+LL | | fn foo4() {
+LL | |     //! windows
+   | |_______________^
+
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:32:1
+   |
+LL | / #[allow(unused)]
+LL | | mod bar {
+LL | |     #![allow(unused)]
+   | |_____________________^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/mut_mut.rs b/src/tools/clippy/tests/ui/mut_mut.rs
index 72a171119f3..288b003405d 100644
--- a/src/tools/clippy/tests/ui/mut_mut.rs
+++ b/src/tools/clippy/tests/ui/mut_mut.rs
@@ -1,4 +1,6 @@
 //@aux-build:proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::mut_mut)]
 #![allow(unused)]
 #![allow(
diff --git a/src/tools/clippy/tests/ui/mut_mut.stderr b/src/tools/clippy/tests/ui/mut_mut.stderr
index 810c0c96743..73f2410a252 100644
--- a/src/tools/clippy/tests/ui/mut_mut.stderr
+++ b/src/tools/clippy/tests/ui/mut_mut.stderr
@@ -1,5 +1,5 @@
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:14:11
+  --> tests/ui/mut_mut.rs:16:11
    |
 LL | fn fun(x: &mut &mut u32) -> bool {
    |           ^^^^^^^^^^^^^
@@ -8,13 +8,13 @@ LL | fn fun(x: &mut &mut u32) -> bool {
    = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]`
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:31:17
+  --> tests/ui/mut_mut.rs:33:17
    |
 LL |     let mut x = &mut &mut 1u32;
    |                 ^^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:46:25
+  --> tests/ui/mut_mut.rs:48:25
    |
 LL |     let mut z = inline!(&mut $(&mut 3u32));
    |                         ^
@@ -22,37 +22,37 @@ LL |     let mut z = inline!(&mut $(&mut 3u32));
    = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: this expression mutably borrows a mutable reference. Consider reborrowing
-  --> tests/ui/mut_mut.rs:33:21
+  --> tests/ui/mut_mut.rs:35:21
    |
 LL |         let mut y = &mut x;
    |                     ^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:37:32
+  --> tests/ui/mut_mut.rs:39:32
    |
 LL |         let y: &mut &mut u32 = &mut &mut 2;
    |                                ^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:37:16
+  --> tests/ui/mut_mut.rs:39:16
    |
 LL |         let y: &mut &mut u32 = &mut &mut 2;
    |                ^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:42:37
+  --> tests/ui/mut_mut.rs:44:37
    |
 LL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;
    |                                     ^^^^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:42:16
+  --> tests/ui/mut_mut.rs:44:16
    |
 LL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;
    |                ^^^^^^^^^^^^^^^^^^
 
 error: generally you want to avoid `&mut &mut _` if possible
-  --> tests/ui/mut_mut.rs:42:21
+  --> tests/ui/mut_mut.rs:44:21
    |
 LL |         let y: &mut &mut &mut u32 = &mut &mut &mut 2;
    |                     ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/no_effect_replace.rs b/src/tools/clippy/tests/ui/no_effect_replace.rs
index e4fd5caae2a..2a940d87fb9 100644
--- a/src/tools/clippy/tests/ui/no_effect_replace.rs
+++ b/src/tools/clippy/tests/ui/no_effect_replace.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::no_effect_replace)]
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/no_effect_replace.stderr b/src/tools/clippy/tests/ui/no_effect_replace.stderr
index ded86c5c5b8..ad2dcd2cc9b 100644
--- a/src/tools/clippy/tests/ui/no_effect_replace.stderr
+++ b/src/tools/clippy/tests/ui/no_effect_replace.stderr
@@ -1,5 +1,5 @@
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:4:13
+  --> tests/ui/no_effect_replace.rs:6:13
    |
 LL |     let _ = "12345".replace('1', "1");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,43 +8,43 @@ LL |     let _ = "12345".replace('1', "1");
    = help: to override `-D warnings` add `#[allow(clippy::no_effect_replace)]`
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:7:13
+  --> tests/ui/no_effect_replace.rs:9:13
    |
 LL |     let _ = "12345".replace("12", "12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:9:13
+  --> tests/ui/no_effect_replace.rs:11:13
    |
 LL |     let _ = String::new().replace("12", "12");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:12:13
+  --> tests/ui/no_effect_replace.rs:14:13
    |
 LL |     let _ = "12345".replacen('1', "1", 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:14:13
+  --> tests/ui/no_effect_replace.rs:16:13
    |
 LL |     let _ = "12345".replacen("12", "12", 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:16:13
+  --> tests/ui/no_effect_replace.rs:18:13
    |
 LL |     let _ = String::new().replacen("12", "12", 1);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:23:13
+  --> tests/ui/no_effect_replace.rs:25:13
    |
 LL |     let _ = "hello".replace(&x.f(), &x.f());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: replacing text with itself
-  --> tests/ui/no_effect_replace.rs:27:13
+  --> tests/ui/no_effect_replace.rs:29:13
    |
 LL |     let _ = "hello".replace(&y(), &y());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed b/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
index 165702b3041..7d1be412e54 100644
--- a/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.fixed
@@ -1,4 +1,5 @@
 #![allow(clippy::clone_on_copy, unused)]
+#![allow(clippy::assigning_clones)]
 #![no_main]
 
 // lint
diff --git a/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs b/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
index 3b07dd5ce62..beae05efb2f 100644
--- a/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.rs
@@ -1,4 +1,5 @@
 #![allow(clippy::clone_on_copy, unused)]
+#![allow(clippy::assigning_clones)]
 #![no_main]
 
 // lint
diff --git a/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr b/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
index 8eff322fa2d..6bfc99d988b 100644
--- a/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
+++ b/src/tools/clippy/tests/ui/non_canonical_clone_impl.stderr
@@ -1,5 +1,5 @@
 error: non-canonical implementation of `clone` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:9:29
+  --> tests/ui/non_canonical_clone_impl.rs:10:29
    |
 LL |       fn clone(&self) -> Self {
    |  _____________________________^
@@ -11,7 +11,7 @@ LL | |     }
    = help: to override `-D warnings` add `#[allow(clippy::non_canonical_clone_impl)]`
 
 error: unnecessary implementation of `clone_from` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:13:5
+  --> tests/ui/non_canonical_clone_impl.rs:14:5
    |
 LL | /     fn clone_from(&mut self, source: &Self) {
 LL | |         source.clone();
@@ -20,7 +20,7 @@ LL | |     }
    | |_____^ help: remove it
 
 error: non-canonical implementation of `clone` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:80:29
+  --> tests/ui/non_canonical_clone_impl.rs:81:29
    |
 LL |       fn clone(&self) -> Self {
    |  _____________________________^
@@ -29,7 +29,7 @@ LL | |     }
    | |_____^ help: change this to: `{ *self }`
 
 error: unnecessary implementation of `clone_from` on a `Copy` type
-  --> tests/ui/non_canonical_clone_impl.rs:84:5
+  --> tests/ui/non_canonical_clone_impl.rs:85:5
    |
 LL | /     fn clone_from(&mut self, source: &Self) {
 LL | |         source.clone();
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs
index 908ef6cb2a0..38157116e91 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs
@@ -1,4 +1,5 @@
 //@no-rustfix: overlapping suggestions
+
 #![feature(lint_reasons)]
 #![allow(
     unused,
@@ -173,3 +174,8 @@ fn issue_5794() {
     if !b == !c {} //~ ERROR: this boolean expression can be simplified
     if !b != !c {} //~ ERROR: this boolean expression can be simplified
 }
+
+fn issue_12371(x: usize) -> bool {
+    // Should not warn!
+    !x != 0
+}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.stderr b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
index 954e2345266..b6af06d845a 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.stderr
@@ -1,5 +1,5 @@
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:18:13
+  --> tests/ui/nonminimal_bool.rs:19:13
    |
 LL |     let _ = !true;
    |             ^^^^^ help: try: `false`
@@ -8,43 +8,43 @@ LL |     let _ = !true;
    = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:21:13
+  --> tests/ui/nonminimal_bool.rs:22:13
    |
 LL |     let _ = !false;
    |             ^^^^^^ help: try: `true`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:23:13
+  --> tests/ui/nonminimal_bool.rs:24:13
    |
 LL |     let _ = !!a;
    |             ^^^ help: try: `a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:25:13
+  --> tests/ui/nonminimal_bool.rs:26:13
    |
 LL |     let _ = false || a;
    |             ^^^^^^^^^^ help: try: `a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:30:13
+  --> tests/ui/nonminimal_bool.rs:31:13
    |
 LL |     let _ = !(!a && b);
    |             ^^^^^^^^^^ help: try: `a || !b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:32:13
+  --> tests/ui/nonminimal_bool.rs:33:13
    |
 LL |     let _ = !(!a || b);
    |             ^^^^^^^^^^ help: try: `a && !b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:34:13
+  --> tests/ui/nonminimal_bool.rs:35:13
    |
 LL |     let _ = !a && !(b && c);
    |             ^^^^^^^^^^^^^^^ help: try: `!(a || b && c)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:43:13
+  --> tests/ui/nonminimal_bool.rs:44:13
    |
 LL |     let _ = a == b && c == 5 && a == b;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = a == b && c == 5;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:45:13
+  --> tests/ui/nonminimal_bool.rs:46:13
    |
 LL |     let _ = a == b || c == 5 || a == b;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     let _ = a == b || c == 5;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:47:13
+  --> tests/ui/nonminimal_bool.rs:48:13
    |
 LL |     let _ = a == b && c == 5 && b == a;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     let _ = a == b && c == 5;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:49:13
+  --> tests/ui/nonminimal_bool.rs:50:13
    |
 LL |     let _ = a != b || !(a != b || c == d);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -96,7 +96,7 @@ LL |     let _ = a != b || c != d;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:51:13
+  --> tests/ui/nonminimal_bool.rs:52:13
    |
 LL |     let _ = a != b && !(a != b && c == d);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -109,43 +109,43 @@ LL |     let _ = a != b && c != d;
    |             ~~~~~~~~~~~~~~~~
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:82:8
+  --> tests/ui/nonminimal_bool.rs:83:8
    |
 LL |     if matches!(true, true) && true {
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(true, true)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:162:8
+  --> tests/ui/nonminimal_bool.rs:163:8
    |
 LL |     if !(12 == a) {}
    |        ^^^^^^^^^^ help: try: `12 != a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:163:8
+  --> tests/ui/nonminimal_bool.rs:164:8
    |
 LL |     if !(a == 12) {}
    |        ^^^^^^^^^^ help: try: `a != 12`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:164:8
+  --> tests/ui/nonminimal_bool.rs:165:8
    |
 LL |     if !(12 != a) {}
    |        ^^^^^^^^^^ help: try: `12 == a`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:165:8
+  --> tests/ui/nonminimal_bool.rs:166:8
    |
 LL |     if !(a != 12) {}
    |        ^^^^^^^^^^ help: try: `a == 12`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:169:8
+  --> tests/ui/nonminimal_bool.rs:170:8
    |
 LL |     if !b == true {}
    |        ^^^^^^^^^^ help: try: `b != true`
 
 error: this comparison might be written more concisely
-  --> tests/ui/nonminimal_bool.rs:169:8
+  --> tests/ui/nonminimal_bool.rs:170:8
    |
 LL |     if !b == true {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `b != true`
@@ -154,61 +154,61 @@ LL |     if !b == true {}
    = help: to override `-D warnings` add `#[allow(clippy::bool_comparison)]`
 
 error: equality checks against true are unnecessary
-  --> tests/ui/nonminimal_bool.rs:169:8
+  --> tests/ui/nonminimal_bool.rs:170:8
    |
 LL |     if !b == true {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:170:8
+  --> tests/ui/nonminimal_bool.rs:171:8
    |
 LL |     if !b != true {}
    |        ^^^^^^^^^^ help: try: `b == true`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/nonminimal_bool.rs:170:8
+  --> tests/ui/nonminimal_bool.rs:171:8
    |
 LL |     if !b != true {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:171:8
+  --> tests/ui/nonminimal_bool.rs:172:8
    |
 LL |     if true == !b {}
    |        ^^^^^^^^^^ help: try: `true != b`
 
 error: this comparison might be written more concisely
-  --> tests/ui/nonminimal_bool.rs:171:8
+  --> tests/ui/nonminimal_bool.rs:172:8
    |
 LL |     if true == !b {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `true != b`
 
 error: equality checks against true are unnecessary
-  --> tests/ui/nonminimal_bool.rs:171:8
+  --> tests/ui/nonminimal_bool.rs:172:8
    |
 LL |     if true == !b {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!b`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:172:8
+  --> tests/ui/nonminimal_bool.rs:173:8
    |
 LL |     if true != !b {}
    |        ^^^^^^^^^^ help: try: `true == b`
 
 error: inequality checks against true can be replaced by a negation
-  --> tests/ui/nonminimal_bool.rs:172:8
+  --> tests/ui/nonminimal_bool.rs:173:8
    |
 LL |     if true != !b {}
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!(!b)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:173:8
+  --> tests/ui/nonminimal_bool.rs:174:8
    |
 LL |     if !b == !c {}
    |        ^^^^^^^^ help: try: `b == c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool.rs:174:8
+  --> tests/ui/nonminimal_bool.rs:175:8
    |
 LL |     if !b != !c {}
    |        ^^^^^^^^ help: try: `b != c`
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
index e27c0350d49..bd4be3e5a44 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
 #![warn(clippy::nonminimal_bool)]
 
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
index 040a6e920a1..4523c7385df 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![allow(unused, clippy::diverging_sub_expression, clippy::needless_if)]
 #![warn(clippy::nonminimal_bool)]
 
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
index ede88ba529c..e32c8dacd2f 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
@@ -1,5 +1,5 @@
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:8:13
+  --> tests/ui/nonminimal_bool_methods.rs:10:13
    |
 LL |     let _ = !a.is_some();
    |             ^^^^^^^^^^^^ help: try: `a.is_none()`
@@ -8,73 +8,73 @@ LL |     let _ = !a.is_some();
    = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:10:13
+  --> tests/ui/nonminimal_bool_methods.rs:12:13
    |
 LL |     let _ = !a.is_none();
    |             ^^^^^^^^^^^^ help: try: `a.is_some()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:12:13
+  --> tests/ui/nonminimal_bool_methods.rs:14:13
    |
 LL |     let _ = !b.is_err();
    |             ^^^^^^^^^^^ help: try: `b.is_ok()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:14:13
+  --> tests/ui/nonminimal_bool_methods.rs:16:13
    |
 LL |     let _ = !b.is_ok();
    |             ^^^^^^^^^^ help: try: `b.is_err()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:16:13
+  --> tests/ui/nonminimal_bool_methods.rs:18:13
    |
 LL |     let _ = !(a.is_some() && !c);
    |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() || c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:17:13
+  --> tests/ui/nonminimal_bool_methods.rs:19:13
    |
 LL |     let _ = !(a.is_some() || !c);
    |             ^^^^^^^^^^^^^^^^^^^^ help: try: `a.is_none() && c`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:18:26
+  --> tests/ui/nonminimal_bool_methods.rs:20:26
    |
 LL |     let _ = !(!c ^ c) || !a.is_some();
    |                          ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:19:25
+  --> tests/ui/nonminimal_bool_methods.rs:21:25
    |
 LL |     let _ = (!c ^ c) || !a.is_some();
    |                         ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:20:23
+  --> tests/ui/nonminimal_bool_methods.rs:22:23
    |
 LL |     let _ = !c ^ c || !a.is_some();
    |                       ^^^^^^^^^^^^ help: try: `a.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:92:8
+  --> tests/ui/nonminimal_bool_methods.rs:94:8
    |
 LL |     if !res.is_ok() {}
    |        ^^^^^^^^^^^^ help: try: `res.is_err()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:93:8
+  --> tests/ui/nonminimal_bool_methods.rs:95:8
    |
 LL |     if !res.is_err() {}
    |        ^^^^^^^^^^^^^ help: try: `res.is_ok()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:96:8
+  --> tests/ui/nonminimal_bool_methods.rs:98:8
    |
 LL |     if !res.is_some() {}
    |        ^^^^^^^^^^^^^^ help: try: `res.is_none()`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:97:8
+  --> tests/ui/nonminimal_bool_methods.rs:99:8
    |
 LL |     if !res.is_none() {}
    |        ^^^^^^^^^^^^^^ help: try: `res.is_some()`
diff --git a/src/tools/clippy/tests/ui/option_option.rs b/src/tools/clippy/tests/ui/option_option.rs
index 9bbdd3aaacc..2f6e4d76145 100644
--- a/src/tools/clippy/tests/ui/option_option.rs
+++ b/src/tools/clippy/tests/ui/option_option.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![deny(clippy::option_option)]
 #![allow(clippy::unnecessary_wraps)]
 
diff --git a/src/tools/clippy/tests/ui/option_option.stderr b/src/tools/clippy/tests/ui/option_option.stderr
index 0cd048e400e..76cb9ae944c 100644
--- a/src/tools/clippy/tests/ui/option_option.stderr
+++ b/src/tools/clippy/tests/ui/option_option.stderr
@@ -1,77 +1,77 @@
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:4:10
+  --> tests/ui/option_option.rs:6:10
    |
 LL | const C: Option<Option<i32>> = None;
    |          ^^^^^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> tests/ui/option_option.rs:1:9
+  --> tests/ui/option_option.rs:3:9
    |
 LL | #![deny(clippy::option_option)]
    |         ^^^^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:6:11
+  --> tests/ui/option_option.rs:8:11
    |
 LL | static S: Option<Option<i32>> = None;
    |           ^^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:9:13
+  --> tests/ui/option_option.rs:11:13
    |
 LL | fn input(_: Option<Option<u8>>) {}
    |             ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:12:16
+  --> tests/ui/option_option.rs:14:16
    |
 LL | fn output() -> Option<Option<u8>> {
    |                ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:17:27
+  --> tests/ui/option_option.rs:19:27
    |
 LL | fn output_nested() -> Vec<Option<Option<u8>>> {
    |                           ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:23:30
+  --> tests/ui/option_option.rs:25:30
    |
 LL | fn output_nested_nested() -> Option<Option<Option<u8>>> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:29:8
+  --> tests/ui/option_option.rs:31:8
    |
 LL |     x: Option<Option<u8>>,
    |        ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:34:23
+  --> tests/ui/option_option.rs:36:23
    |
 LL |     fn struct_fn() -> Option<Option<u8>> {
    |                       ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:41:22
+  --> tests/ui/option_option.rs:43:22
    |
 LL |     fn trait_fn() -> Option<Option<u8>>;
    |                      ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:46:11
+  --> tests/ui/option_option.rs:48:11
    |
 LL |     Tuple(Option<Option<u8>>),
    |           ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:48:17
+  --> tests/ui/option_option.rs:50:17
    |
 LL |     Struct { x: Option<Option<u8>> },
    |                 ^^^^^^^^^^^^^^^^^^
 
 error: consider using `Option<T>` instead of `Option<Option<T>>` or a custom enum if you need to distinguish all 3 cases
-  --> tests/ui/option_option.rs:90:14
+  --> tests/ui/option_option.rs:92:14
    |
 LL |         foo: Option<Option<Cow<'a, str>>>,
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
index fa15c323540..61d37b8ba3a 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
 
 #![warn(clippy::ptr_as_ptr)]
 
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
index 7ab52e63da5..8f2068cd268 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
 
 #![warn(clippy::ptr_as_ptr)]
 
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
index e162f35baf5..e6cd697c7ba 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
@@ -1,5 +1,5 @@
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:18:33
+  --> tests/ui/ptr_as_ptr.rs:19:33
    |
 LL |         *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::issue_11278_a::T<String>) }
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `Box::into_raw(Box::new(o)).cast::<super::issue_11278_a::T<String>>()`
@@ -8,37 +8,37 @@ LL |         *unsafe { Box::from_raw(Box::into_raw(Box::new(o)) as *mut super::i
    = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:27:13
+  --> tests/ui/ptr_as_ptr.rs:28:13
    |
 LL |     let _ = ptr as *const i32;
    |             ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:28:13
+  --> tests/ui/ptr_as_ptr.rs:29:13
    |
 LL |     let _ = mut_ptr as *mut i32;
    |             ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:33:17
+  --> tests/ui/ptr_as_ptr.rs:34:17
    |
 LL |         let _ = *ptr_ptr as *const i32;
    |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:46:25
+  --> tests/ui/ptr_as_ptr.rs:47:25
    |
 LL |     let _: *const i32 = ptr as *const _;
    |                         ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:47:23
+  --> tests/ui/ptr_as_ptr.rs:48:23
    |
 LL |     let _: *mut i32 = mut_ptr as _;
    |                       ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:50:21
+  --> tests/ui/ptr_as_ptr.rs:51:21
    |
 LL |     let _ = inline!($ptr as *const i32);
    |                     ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::<i32>()`
@@ -46,157 +46,157 @@ LL |     let _ = inline!($ptr as *const i32);
    = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:71:13
+  --> tests/ui/ptr_as_ptr.rs:72:13
    |
 LL |     let _ = ptr as *const i32;
    |             ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:72:13
+  --> tests/ui/ptr_as_ptr.rs:73:13
    |
 LL |     let _ = mut_ptr as *mut i32;
    |             ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:79:9
+  --> tests/ui/ptr_as_ptr.rs:80:9
    |
 LL |         ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:83:9
+  --> tests/ui/ptr_as_ptr.rs:84:9
    |
 LL |         std::ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:88:9
+  --> tests/ui/ptr_as_ptr.rs:89:9
    |
 LL |         ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:92:9
+  --> tests/ui/ptr_as_ptr.rs:93:9
    |
 LL |         core::ptr::null_mut() as *mut u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:97:9
+  --> tests/ui/ptr_as_ptr.rs:98:9
    |
 LL |         ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:101:9
+  --> tests/ui/ptr_as_ptr.rs:102:9
    |
 LL |         std::ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:106:9
+  --> tests/ui/ptr_as_ptr.rs:107:9
    |
 LL |         ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:110:9
+  --> tests/ui/ptr_as_ptr.rs:111:9
    |
 LL |         core::ptr::null() as *const u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::<u32>()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:117:9
+  --> tests/ui/ptr_as_ptr.rs:118:9
    |
 LL |         ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:121:9
+  --> tests/ui/ptr_as_ptr.rs:122:9
    |
 LL |         std::ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:126:9
+  --> tests/ui/ptr_as_ptr.rs:127:9
    |
 LL |         ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:130:9
+  --> tests/ui/ptr_as_ptr.rs:131:9
    |
 LL |         core::ptr::null_mut() as *mut _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:135:9
+  --> tests/ui/ptr_as_ptr.rs:136:9
    |
 LL |         ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:139:9
+  --> tests/ui/ptr_as_ptr.rs:140:9
    |
 LL |         std::ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:144:9
+  --> tests/ui/ptr_as_ptr.rs:145:9
    |
 LL |         ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:148:9
+  --> tests/ui/ptr_as_ptr.rs:149:9
    |
 LL |         core::ptr::null() as *const _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:155:9
+  --> tests/ui/ptr_as_ptr.rs:156:9
    |
 LL |         ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:159:9
+  --> tests/ui/ptr_as_ptr.rs:160:9
    |
 LL |         std::ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:164:9
+  --> tests/ui/ptr_as_ptr.rs:165:9
    |
 LL |         ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:168:9
+  --> tests/ui/ptr_as_ptr.rs:169:9
    |
 LL |         core::ptr::null_mut() as _
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:173:9
+  --> tests/ui/ptr_as_ptr.rs:174:9
    |
 LL |         ptr::null() as _
    |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:177:9
+  --> tests/ui/ptr_as_ptr.rs:178:9
    |
 LL |         std::ptr::null() as _
    |         ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:182:9
+  --> tests/ui/ptr_as_ptr.rs:183:9
    |
 LL |         ptr::null() as _
    |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
 
 error: `as` casting between raw pointers without changing its mutability
-  --> tests/ui/ptr_as_ptr.rs:186:9
+  --> tests/ui/ptr_as_ptr.rs:187:9
    |
 LL |         core::ptr::null() as _
    |         ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 2ef006c1419..567472a8af2 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -273,3 +273,13 @@ const fn issue9175(option: Option<()>) -> Option<()> {
     //stuff
     Some(())
 }
+
+fn issue12337() -> Option<i32> {
+    let _: Option<i32> = try {
+        let Some(_) = Some(42) else {
+            return None;
+        };
+        123
+    };
+    Some(42)
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index c170669823f..abf8c270de8 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -313,3 +313,13 @@ const fn issue9175(option: Option<()>) -> Option<()> {
     //stuff
     Some(())
 }
+
+fn issue12337() -> Option<i32> {
+    let _: Option<i32> = try {
+        let Some(_) = Some(42) else {
+            return None;
+        };
+        123
+    };
+    Some(42)
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index ce5c7f2600b..191f7719904 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -111,3 +111,20 @@ fn fp_11274() {
     }
     m!(|x| println!("{x}"));
 }
+
+// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
+// triggers the lint.
+fn issue_12358() {
+    macro_rules! make_closure {
+        () => {
+            (|| || {})
+        };
+        (x) => {
+            make_closure!()()
+        };
+    }
+
+    // The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
+    // different.
+    make_closure!(x)();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
index ac09390e6ea..33a3b90f9cf 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -111,3 +111,20 @@ fn fp_11274() {
     }
     m!(|x| println!("{x}"));
 }
+
+// Issue #12358: When a macro expands into a closure, immediately calling the expanded closure
+// triggers the lint.
+fn issue_12358() {
+    macro_rules! make_closure {
+        () => {
+            (|| || {})
+        };
+        (x) => {
+            make_closure!()()
+        };
+    }
+
+    // The lint would suggest to alter the line below to `make_closure!(x)`, which is semantically
+    // different.
+    make_closure!(x)();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed
index c578e786426..72fc4cb7333 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.fixed
+++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed
@@ -20,7 +20,7 @@ struct Person {
 }
 
 pub struct S {
-    v: String,
+    v: usize,
 }
 
 fn main() {
@@ -59,11 +59,22 @@ fn main() {
     let _ = RangeToInclusive { end };
 
     external! {
-        let v = String::new();
+        let v = 1;
         let _ = S {
             v: v
         };
     }
+
+    let v = 2;
+    macro_rules! internal {
+        ($i:ident) => {
+            let _ = S { v };
+            let _ = S { $i: v };
+            let _ = S { v: $i };
+            let _ = S { $i: $i };
+        };
+    }
+    internal!(v);
 }
 
 fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.rs b/src/tools/clippy/tests/ui/redundant_field_names.rs
index d8c2286d5ad..2617d7e7283 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.rs
+++ b/src/tools/clippy/tests/ui/redundant_field_names.rs
@@ -20,7 +20,7 @@ struct Person {
 }
 
 pub struct S {
-    v: String,
+    v: usize,
 }
 
 fn main() {
@@ -59,11 +59,22 @@ fn main() {
     let _ = RangeToInclusive { end: end };
 
     external! {
-        let v = String::new();
+        let v = 1;
         let _ = S {
             v: v
         };
     }
+
+    let v = 2;
+    macro_rules! internal {
+        ($i:ident) => {
+            let _ = S { v: v };
+            let _ = S { $i: v };
+            let _ = S { v: $i };
+            let _ = S { $i: $i };
+        };
+    }
+    internal!(v);
 }
 
 fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.stderr b/src/tools/clippy/tests/ui/redundant_field_names.stderr
index 53234736207..38c021fdba3 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.stderr
+++ b/src/tools/clippy/tests/ui/redundant_field_names.stderr
@@ -44,10 +44,21 @@ LL |     let _ = RangeToInclusive { end: end };
    |                                ^^^^^^^^ help: replace it with: `end`
 
 error: redundant field names in struct initialization
-  --> tests/ui/redundant_field_names.rs:88:25
+  --> tests/ui/redundant_field_names.rs:71:25
+   |
+LL |             let _ = S { v: v };
+   |                         ^^^^ help: replace it with: `v`
+...
+LL |     internal!(v);
+   |     ------------ in this macro invocation
+   |
+   = note: this error originates in the macro `internal` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: redundant field names in struct initialization
+  --> tests/ui/redundant_field_names.rs:99:25
    |
 LL |     let _ = RangeFrom { start: start };
    |                         ^^^^^^^^^^^^ help: replace it with: `start`
 
-error: aborting due to 8 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
index bc055215708..aebf8712dd9 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.fixed
@@ -1,2 +1,4 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #[clippy::cognitive_complexity = "1"]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
index fdb425363e8..6c18151195f 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.rs
@@ -1,2 +1,4 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #[clippy::cyclomatic_complexity = "1"]
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
index f9108d169c7..fb51313dab6 100644
--- a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
+++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr
@@ -1,5 +1,5 @@
 error: usage of deprecated attribute
-  --> tests/ui/renamed_builtin_attr.rs:1:11
+  --> tests/ui/renamed_builtin_attr.rs:3:11
    |
 LL | #[clippy::cyclomatic_complexity = "1"]
    |           ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity`
diff --git a/src/tools/clippy/tests/ui/single_match.fixed b/src/tools/clippy/tests/ui/single_match.fixed
index 0a49be2dc4f..6df64eb4053 100644
--- a/src/tools/clippy/tests/ui/single_match.fixed
+++ b/src/tools/clippy/tests/ui/single_match.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match)]
 #![allow(
     unused,
diff --git a/src/tools/clippy/tests/ui/single_match.rs b/src/tools/clippy/tests/ui/single_match.rs
index 4e35d265acb..4f005f4e04f 100644
--- a/src/tools/clippy/tests/ui/single_match.rs
+++ b/src/tools/clippy/tests/ui/single_match.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match)]
 #![allow(
     unused,
diff --git a/src/tools/clippy/tests/ui/single_match.stderr b/src/tools/clippy/tests/ui/single_match.stderr
index 40af38879ae..651d0b4911d 100644
--- a/src/tools/clippy/tests/ui/single_match.stderr
+++ b/src/tools/clippy/tests/ui/single_match.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:14:5
+  --> tests/ui/single_match.rs:16:5
    |
 LL | /     match x {
 LL | |         Some(y) => {
@@ -19,7 +19,7 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:22:5
+  --> tests/ui/single_match.rs:24:5
    |
 LL | /     match x {
 LL | |         // Note the missing block braces.
@@ -31,7 +31,7 @@ LL | |     }
    | |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:31:5
+  --> tests/ui/single_match.rs:33:5
    |
 LL | /     match z {
 LL | |         (2..=3, 7..=9) => dummy(),
@@ -40,7 +40,7 @@ LL | |     };
    | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:60:5
+  --> tests/ui/single_match.rs:62:5
    |
 LL | /     match x {
 LL | |         Some(y) => dummy(),
@@ -49,7 +49,7 @@ LL | |     };
    | |_____^ help: try: `if let Some(y) = x { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:65:5
+  --> tests/ui/single_match.rs:67:5
    |
 LL | /     match y {
 LL | |         Ok(y) => dummy(),
@@ -58,7 +58,7 @@ LL | |     };
    | |_____^ help: try: `if let Ok(y) = y { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:72:5
+  --> tests/ui/single_match.rs:74:5
    |
 LL | /     match c {
 LL | |         Cow::Borrowed(..) => dummy(),
@@ -67,7 +67,7 @@ LL | |     };
    | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:93:5
+  --> tests/ui/single_match.rs:95:5
    |
 LL | /     match x {
 LL | |         "test" => println!(),
@@ -76,7 +76,7 @@ LL | |     }
    | |_____^ help: try: `if x == "test" { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:106:5
+  --> tests/ui/single_match.rs:108:5
    |
 LL | /     match x {
 LL | |         Foo::A => println!(),
@@ -85,7 +85,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:112:5
+  --> tests/ui/single_match.rs:114:5
    |
 LL | /     match x {
 LL | |         FOO_C => println!(),
@@ -94,7 +94,7 @@ LL | |     }
    | |_____^ help: try: `if x == FOO_C { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:117:5
+  --> tests/ui/single_match.rs:119:5
    |
 LL | /     match &&x {
 LL | |         Foo::A => println!(),
@@ -103,7 +103,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:123:5
+  --> tests/ui/single_match.rs:125:5
    |
 LL | /     match &x {
 LL | |         Foo::A => println!(),
@@ -112,7 +112,7 @@ LL | |     }
    | |_____^ help: try: `if x == &Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:140:5
+  --> tests/ui/single_match.rs:142:5
    |
 LL | /     match x {
 LL | |         Bar::A => println!(),
@@ -121,7 +121,7 @@ LL | |     }
    | |_____^ help: try: `if let Bar::A = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:148:5
+  --> tests/ui/single_match.rs:150:5
    |
 LL | /     match x {
 LL | |         None => println!(),
@@ -130,7 +130,7 @@ LL | |     };
    | |_____^ help: try: `if let None = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:170:5
+  --> tests/ui/single_match.rs:172:5
    |
 LL | /     match x {
 LL | |         (Some(_), _) => {},
@@ -139,7 +139,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(_), _) = x {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:176:5
+  --> tests/ui/single_match.rs:178:5
    |
 LL | /     match x {
 LL | |         (Some(E::V), _) => todo!(),
@@ -148,7 +148,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:182:5
+  --> tests/ui/single_match.rs:184:5
    |
 LL | /     match (Some(42), Some(E::V), Some(42)) {
 LL | |         (.., Some(E::V), _) => {},
@@ -157,7 +157,7 @@ LL | |     }
    | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:254:5
+  --> tests/ui/single_match.rs:256:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -177,7 +177,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:262:5
+  --> tests/ui/single_match.rs:264:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed
index f3b1de3b44f..2970f5485fa 100644
--- a/src/tools/clippy/tests/ui/single_match_else.fixed
+++ b/src/tools/clippy/tests/ui/single_match_else.fixed
@@ -1,4 +1,6 @@
 //@aux-build: proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs
index ddee2e42ec2..26974b2a48a 100644
--- a/src/tools/clippy/tests/ui/single_match_else.rs
+++ b/src/tools/clippy/tests/ui/single_match_else.rs
@@ -1,4 +1,6 @@
 //@aux-build: proc_macros.rs
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index 63c733e9a7a..48c74c0caea 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:16:13
+  --> tests/ui/single_match_else.rs:18:13
    |
 LL |       let _ = match ExprNode::Butterflies {
    |  _____________^
@@ -22,7 +22,7 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:81:5
+  --> tests/ui/single_match_else.rs:83:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -42,7 +42,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:90:5
+  --> tests/ui/single_match_else.rs:92:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -62,7 +62,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:100:5
+  --> tests/ui/single_match_else.rs:102:5
    |
 LL | /     match Result::<i32, Infallible>::Ok(1) {
 LL | |         Ok(a) => println!("${:?}", a),
@@ -82,7 +82,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:109:5
+  --> tests/ui/single_match_else.rs:111:5
    |
 LL | /     match Cow::from("moo") {
 LL | |         Cow::Owned(a) => println!("${:?}", a),
@@ -102,7 +102,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:119:5
+  --> tests/ui/single_match_else.rs:121:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -125,7 +125,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:130:5
+  --> tests/ui/single_match_else.rs:132:5
    |
 LL | /     match bar {
 LL | |         Some(v) => {
@@ -149,7 +149,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:142:5
+  --> tests/ui/single_match_else.rs:144:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -173,7 +173,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:154:5
+  --> tests/ui/single_match_else.rs:156:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.fixed b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
index a7555704fbe..0a734a65d29 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.fixed
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
@@ -1,4 +1,5 @@
 //@aux-build:proc_macro_derive.rs
+
 #![warn(clippy::std_instead_of_core)]
 #![allow(unused_imports)]
 
@@ -16,12 +17,20 @@ fn std_instead_of_core() {
     use ::core::hash::Hash;
     //~^ ERROR: used import from `std` instead of `core`
     // Don't lint on `env` macro
-    use std::env;
+    use core::env;
 
     // Multiple imports
     use core::fmt::{Debug, Result};
     //~^ ERROR: used import from `std` instead of `core`
 
+    // Multiple imports multiline
+    #[rustfmt::skip]
+    use core::{
+        //~^ ERROR: used import from `std` instead of `core`
+        fmt::Write as _,
+        ptr::read_unaligned,
+    };
+
     // Function calls
     let ptr = core::ptr::null::<u32>();
     //~^ ERROR: used import from `std` instead of `core`
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.rs b/src/tools/clippy/tests/ui/std_instead_of_core.rs
index af7f3399f49..c12c459c7eb 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.rs
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs
@@ -1,4 +1,5 @@
 //@aux-build:proc_macro_derive.rs
+
 #![warn(clippy::std_instead_of_core)]
 #![allow(unused_imports)]
 
@@ -22,6 +23,14 @@ fn std_instead_of_core() {
     use std::fmt::{Debug, Result};
     //~^ ERROR: used import from `std` instead of `core`
 
+    // Multiple imports multiline
+    #[rustfmt::skip]
+    use std::{
+        //~^ ERROR: used import from `std` instead of `core`
+        fmt::Write as _,
+        ptr::read_unaligned,
+    };
+
     // Function calls
     let ptr = std::ptr::null::<u32>();
     //~^ ERROR: used import from `std` instead of `core`
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
index 30dd49dc268..ee42b474a32 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
@@ -1,5 +1,5 @@
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:13:9
+  --> tests/ui/std_instead_of_core.rs:14:9
    |
 LL |     use std::hash::Hasher;
    |         ^^^ help: consider importing the item from `core`: `core`
@@ -8,49 +8,61 @@ LL |     use std::hash::Hasher;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:16:11
+  --> tests/ui/std_instead_of_core.rs:17:11
    |
 LL |     use ::std::hash::Hash;
    |           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:22:9
+  --> tests/ui/std_instead_of_core.rs:20:9
+   |
+LL |     use std::env;
+   |         ^^^ help: consider importing the item from `core`: `core`
+
+error: used import from `std` instead of `core`
+  --> tests/ui/std_instead_of_core.rs:23:9
    |
 LL |     use std::fmt::{Debug, Result};
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:26:15
+  --> tests/ui/std_instead_of_core.rs:28:9
+   |
+LL |     use std::{
+   |         ^^^ help: consider importing the item from `core`: `core`
+
+error: used import from `std` instead of `core`
+  --> tests/ui/std_instead_of_core.rs:35:15
    |
 LL |     let ptr = std::ptr::null::<u32>();
    |               ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:28:21
+  --> tests/ui/std_instead_of_core.rs:37:21
    |
 LL |     let ptr_mut = ::std::ptr::null_mut::<usize>();
    |                     ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:32:16
+  --> tests/ui/std_instead_of_core.rs:41:16
    |
 LL |     let cell = std::cell::Cell::new(8u32);
    |                ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:34:27
+  --> tests/ui/std_instead_of_core.rs:43:27
    |
 LL |     let cell_absolute = ::std::cell::Cell::new(8u32);
    |                           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:43:9
+  --> tests/ui/std_instead_of_core.rs:52:9
    |
 LL |     use std::iter::Iterator;
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `alloc`
-  --> tests/ui/std_instead_of_core.rs:50:9
+  --> tests/ui/std_instead_of_core.rs:59:9
    |
 LL |     use std::vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
@@ -59,13 +71,13 @@ LL |     use std::vec;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`
 
 error: used import from `std` instead of `alloc`
-  --> tests/ui/std_instead_of_core.rs:52:9
+  --> tests/ui/std_instead_of_core.rs:61:9
    |
 LL |     use std::vec::Vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
 
 error: used import from `alloc` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:58:9
+  --> tests/ui/std_instead_of_core.rs:67:9
    |
 LL |     use alloc::slice::from_ref;
    |         ^^^^^ help: consider importing the item from `core`: `core`
@@ -73,5 +85,5 @@ LL |     use alloc::slice::from_ref;
    = note: `-D clippy::alloc-instead-of-core` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`
 
-error: aborting due to 11 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
index 9d9732307c8..60fde6e22cb 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.fixed
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::suspicious_operation_groupings)]
 #![allow(dead_code, unused_parens, clippy::eq_op)]
 
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
index 201b8e657f4..ce37148a853 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::suspicious_operation_groupings)]
 #![allow(dead_code, unused_parens, clippy::eq_op)]
 
diff --git a/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr b/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
index 9d1d8a1f34f..7cb066d57e7 100644
--- a/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_operation_groupings.stderr
@@ -1,5 +1,5 @@
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:15:9
+  --> tests/ui/suspicious_operation_groupings.rs:17:9
    |
 LL |         self.x == other.y && self.y == other.y && self.z == other.z
    |         ^^^^^^^^^^^^^^^^^ help: did you mean: `self.x == other.x`
@@ -8,151 +8,151 @@ LL |         self.x == other.y && self.y == other.y && self.z == other.z
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_operation_groupings)]`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:28:20
+  --> tests/ui/suspicious_operation_groupings.rs:30:20
    |
 LL |     s1.a < s2.a && s1.a < s2.b
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:76:33
+  --> tests/ui/suspicious_operation_groupings.rs:78:33
    |
 LL |     s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d
    |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:81:19
+  --> tests/ui/suspicious_operation_groupings.rs:83:19
    |
 LL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:81:19
+  --> tests/ui/suspicious_operation_groupings.rs:83:19
    |
 LL |     s1.a * s2.a + s1.b * s2.c + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:86:19
+  --> tests/ui/suspicious_operation_groupings.rs:88:19
    |
 LL |     s1.a * s2.a + s2.b * s2.b + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:91:19
+  --> tests/ui/suspicious_operation_groupings.rs:93:19
    |
 LL |     s1.a * s2.a + s1.b * s1.b + s1.c * s2.c
    |                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:96:5
+  --> tests/ui/suspicious_operation_groupings.rs:98:5
    |
 LL |     s1.a * s1.a + s1.b * s2.b + s1.c * s2.c
    |     ^^^^^^^^^^^ help: did you mean: `s1.a * s2.a`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:101:33
+  --> tests/ui/suspicious_operation_groupings.rs:103:33
    |
 LL |     s1.a * s2.a + s1.b * s2.b + s1.c * s1.c
    |                                 ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:114:20
+  --> tests/ui/suspicious_operation_groupings.rs:116:20
    |
 LL |     (s1.a * s2.a + s1.b * s1.b)
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:119:34
+  --> tests/ui/suspicious_operation_groupings.rs:121:34
    |
 LL |     (s1.a * s2.a + s1.b * s2.b + s1.c * s2.b + s1.d * s2.d)
    |                                  ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:124:38
+  --> tests/ui/suspicious_operation_groupings.rs:126:38
    |
 LL |     (s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)
    |                                      ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:129:39
+  --> tests/ui/suspicious_operation_groupings.rs:131:39
    |
 LL |     ((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d))
    |                                       ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:134:42
+  --> tests/ui/suspicious_operation_groupings.rs:136:42
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
    |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:134:42
+  --> tests/ui/suspicious_operation_groupings.rs:136:42
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b)) + ((s1.c * s2.b) + (s1.d * s2.d)))
    |                                          ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:139:40
+  --> tests/ui/suspicious_operation_groupings.rs:141:40
    |
 LL |     (((s1.a * s2.a) + (s1.b * s2.b) + (s1.c * s2.b)) + (s1.d * s2.d))
    |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:144:40
+  --> tests/ui/suspicious_operation_groupings.rs:146:40
    |
 LL |     ((s1.a * s2.a) + ((s1.b * s2.b) + (s1.c * s2.b) + (s1.d * s2.d)))
    |                                        ^^^^^^^^^^^ help: did you mean: `s1.c * s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:149:20
+  --> tests/ui/suspicious_operation_groupings.rs:151:20
    |
 LL |     (s1.a * s2.a + s2.b * s2.b) / 2
    |                    ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:154:35
+  --> tests/ui/suspicious_operation_groupings.rs:156:35
    |
 LL |     i32::swap_bytes(s1.a * s2.a + s2.b * s2.b)
    |                                   ^^^^^^^^^^^ help: did you mean: `s1.b * s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:159:29
+  --> tests/ui/suspicious_operation_groupings.rs:161:29
    |
 LL |     s1.a > 0 && s1.b > 0 && s1.d == s2.c && s1.d == s2.d
    |                             ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:164:17
+  --> tests/ui/suspicious_operation_groupings.rs:166:17
    |
 LL |     s1.a > 0 && s1.d == s2.c && s1.b > 0 && s1.d == s2.d
    |                 ^^^^^^^^^^^^ help: did you mean: `s1.c == s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:173:77
+  --> tests/ui/suspicious_operation_groupings.rs:175:77
    |
 LL |     (n1.inner.0).0 == (n2.inner.0).0 && (n1.inner.1).0 == (n2.inner.1).0 && (n1.inner.2).0 == (n2.inner.1).0
    |                                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean: `(n1.inner.2).0 == (n2.inner.2).0`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:187:25
+  --> tests/ui/suspicious_operation_groupings.rs:189:25
    |
 LL |         s1.a <= s2.a && s1.a <= s2.b
    |                         ^^^^^^^^^^^^ help: did you mean: `s1.b <= s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:193:23
+  --> tests/ui/suspicious_operation_groupings.rs:195:23
    |
 LL |     if s1.a < s2.a && s1.a < s2.b {
    |                       ^^^^^^^^^^^ help: did you mean: `s1.b < s2.b`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:200:48
+  --> tests/ui/suspicious_operation_groupings.rs:202:48
    |
 LL |     -(-(-s1.a * -s2.a) + (-(-s1.b * -s2.b) + -(-s1.c * -s2.b) + -(-s1.d * -s2.d)))
    |                                                ^^^^^^^^^^^^^ help: did you mean: `-s1.c * -s2.c`
 
 error: this sequence of operators looks suspiciously like a bug
-  --> tests/ui/suspicious_operation_groupings.rs:205:27
+  --> tests/ui/suspicious_operation_groupings.rs:207:27
    |
 LL |     -(if -s1.a < -s2.a && -s1.a < -s2.b { s1.c } else { s2.a })
    |                           ^^^^^^^^^^^^^ help: did you mean: `-s1.b < -s2.b`
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
index bbde25b0a88..a6ed59d49c5 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.fixed
@@ -27,4 +27,18 @@ fn main() {
     }
     //~^^^^ ERROR: initializer for `thread_local` value can be made `const`
     //~^^^ ERROR: initializer for `thread_local` value can be made `const`
+
+    thread_local! {
+        static PEEL_ME: i32 = const { 1 };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+        static PEEL_ME_MANY: i32 = const { { let x = 1; x * x } };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+    }
+}
+
+#[clippy::msrv = "1.58"]
+fn f() {
+    thread_local! {
+        static TLS: i32 = 1;
+    }
 }
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
index 3d7aacf2f09..3f0159c5806 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.rs
@@ -27,4 +27,18 @@ fn main() {
     }
     //~^^^^ ERROR: initializer for `thread_local` value can be made `const`
     //~^^^ ERROR: initializer for `thread_local` value can be made `const`
+
+    thread_local! {
+        static PEEL_ME: i32 = { 1 };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+        static PEEL_ME_MANY: i32 = { let x = 1; x * x };
+        //~^ ERROR: initializer for `thread_local` value can be made `const`
+    }
+}
+
+#[clippy::msrv = "1.58"]
+fn f() {
+    thread_local! {
+        static TLS: i32 = 1;
+    }
 }
diff --git a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr
index 9ee52fbbb31..b4f8bd822b0 100644
--- a/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr
+++ b/src/tools/clippy/tests/ui/thread_local_initializer_can_be_made_const.stderr
@@ -25,5 +25,17 @@ error: initializer for `thread_local` value can be made `const`
 LL |         static BUF_4_CAN_BE_MADE_CONST: RefCell<String> = RefCell::new(String::new());
    |                                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { RefCell::new(String::new()) }`
 
-error: aborting due to 4 previous errors
+error: initializer for `thread_local` value can be made `const`
+  --> tests/ui/thread_local_initializer_can_be_made_const.rs:32:31
+   |
+LL |         static PEEL_ME: i32 = { 1 };
+   |                               ^^^^^ help: replace with: `const { 1 }`
+
+error: initializer for `thread_local` value can be made `const`
+  --> tests/ui/thread_local_initializer_can_be_made_const.rs:34:36
+   |
+LL |         static PEEL_ME_MANY: i32 = { let x = 1; x * x };
+   |                                    ^^^^^^^^^^^^^^^^^^^^ help: replace with: `const { { let x = 1; x * x } }`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
index 08b8e786611..2365695d691 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
@@ -82,3 +82,10 @@ fn issue_10449() {
 
     let _x: u8 = unsafe { *(f as *const u8) };
 }
+
+// Pointers cannot be cast to integers in const contexts
+const fn issue_12402<P>(ptr: *const P) {
+    unsafe { transmute::<*const i32, usize>(&42i32) };
+    unsafe { transmute::<fn(*const P), usize>(issue_12402) };
+    let _ = unsafe { transmute::<_, usize>(ptr) };
+}
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
index 92eb765e5f9..cd1607b4c19 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
@@ -82,3 +82,10 @@ fn issue_10449() {
 
     let _x: u8 = unsafe { *std::mem::transmute::<fn(), *const u8>(f) };
 }
+
+// Pointers cannot be cast to integers in const contexts
+const fn issue_12402<P>(ptr: *const P) {
+    unsafe { transmute::<*const i32, usize>(&42i32) };
+    unsafe { transmute::<fn(*const P), usize>(issue_12402) };
+    let _ = unsafe { transmute::<_, usize>(ptr) };
+}
diff --git a/src/tools/clippy/tests/ui/type_complexity.rs b/src/tools/clippy/tests/ui/type_complexity.rs
index be28ee2da0c..b057dc4e89f 100644
--- a/src/tools/clippy/tests/ui/type_complexity.rs
+++ b/src/tools/clippy/tests/ui/type_complexity.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #![warn(clippy::all)]
 #![allow(unused, clippy::needless_pass_by_value, clippy::vec_box, clippy::useless_vec)]
 #![feature(associated_type_defaults)]
diff --git a/src/tools/clippy/tests/ui/type_complexity.stderr b/src/tools/clippy/tests/ui/type_complexity.stderr
index 9e27899e4f9..bfbab8647e8 100644
--- a/src/tools/clippy/tests/ui/type_complexity.stderr
+++ b/src/tools/clippy/tests/ui/type_complexity.stderr
@@ -1,5 +1,5 @@
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:7:12
+  --> tests/ui/type_complexity.rs:9:12
    |
 LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,85 +8,85 @@ LL | const CST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:10:12
+  --> tests/ui/type_complexity.rs:12:12
    |
 LL | static ST: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:14:8
+  --> tests/ui/type_complexity.rs:16:8
    |
 LL |     f: Vec<Vec<Box<(u32, u32, u32, u32)>>>,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:18:11
+  --> tests/ui/type_complexity.rs:20:11
    |
 LL | struct Ts(Vec<Vec<Box<(u32, u32, u32, u32)>>>);
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:22:11
+  --> tests/ui/type_complexity.rs:24:11
    |
 LL |     Tuple(Vec<Vec<Box<(u32, u32, u32, u32)>>>),
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:24:17
+  --> tests/ui/type_complexity.rs:26:17
    |
 LL |     Struct { f: Vec<Vec<Box<(u32, u32, u32, u32)>>> },
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:29:14
+  --> tests/ui/type_complexity.rs:31:14
    |
 LL |     const A: (u32, (u32, (u32, (u32, u32)))) = (0, (0, (0, (0, 0))));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:31:30
+  --> tests/ui/type_complexity.rs:33:30
    |
 LL |     fn impl_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:36:14
+  --> tests/ui/type_complexity.rs:38:14
    |
 LL |     const A: Vec<Vec<Box<(u32, u32, u32, u32)>>>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:38:14
+  --> tests/ui/type_complexity.rs:40:14
    |
 LL |     type B = Vec<Vec<Box<(u32, u32, u32, u32)>>>;
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:40:25
+  --> tests/ui/type_complexity.rs:42:25
    |
 LL |     fn method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>);
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:42:29
+  --> tests/ui/type_complexity.rs:44:29
    |
 LL |     fn def_method(&self, p: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:55:15
+  --> tests/ui/type_complexity.rs:57:15
    |
 LL | fn test1() -> Vec<Vec<Box<(u32, u32, u32, u32)>>> {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:60:14
+  --> tests/ui/type_complexity.rs:62:14
    |
 LL | fn test2(_x: Vec<Vec<Box<(u32, u32, u32, u32)>>>) {}
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: very complex type used. Consider factoring parts into `type` definitions
-  --> tests/ui/type_complexity.rs:64:13
+  --> tests/ui/type_complexity.rs:66:13
    |
 LL |     let _y: Vec<Vec<Box<(u32, u32, u32, u32)>>> = vec![];
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unknown_attribute.rs b/src/tools/clippy/tests/ui/unknown_attribute.rs
index 932f284d5b7..3241742b5d4 100644
--- a/src/tools/clippy/tests/ui/unknown_attribute.rs
+++ b/src/tools/clippy/tests/ui/unknown_attribute.rs
@@ -1,3 +1,5 @@
+//@compile-flags: -Zdeduplicate-diagnostics=yes
+
 #[clippy::unknown]
 //~^ ERROR: usage of unknown attribute
 #[clippy::cognitive_complexity = "1"]
diff --git a/src/tools/clippy/tests/ui/unknown_attribute.stderr b/src/tools/clippy/tests/ui/unknown_attribute.stderr
index d1f8eeb51ae..b306abe0a9d 100644
--- a/src/tools/clippy/tests/ui/unknown_attribute.stderr
+++ b/src/tools/clippy/tests/ui/unknown_attribute.stderr
@@ -1,5 +1,5 @@
 error: usage of unknown attribute
-  --> tests/ui/unknown_attribute.rs:1:11
+  --> tests/ui/unknown_attribute.rs:3:11
    |
 LL | #[clippy::unknown]
    |           ^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.fixed b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
index f52d3250339..288541362cd 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.fixed
@@ -221,4 +221,10 @@ mod fixable {
     fn issue_9603() {
         let _: f32 = -0x400 as f32;
     }
+
+    // Issue #11968: The suggestion for this lint removes the parentheses and leave the code as
+    // `*x.pow(2)` which tries to dereference the return value rather than `x`.
+    fn issue_11968(x: &usize) -> usize {
+        { *x }.pow(2)
+    }
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs
index dfd8b454e6c..eef3a42e351 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs
@@ -221,4 +221,10 @@ mod fixable {
     fn issue_9603() {
         let _: f32 = -0x400 as f32;
     }
+
+    // Issue #11968: The suggestion for this lint removes the parentheses and leave the code as
+    // `*x.pow(2)` which tries to dereference the return value rather than `x`.
+    fn issue_11968(x: &usize) -> usize {
+        (*x as usize).pow(2)
+    }
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.stderr b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
index 935bb71da32..80fd5c13d81 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.stderr
@@ -241,5 +241,11 @@ error: casting to the same type is unnecessary (`f32` -> `f32`)
 LL |         let _num = foo() as f32;
    |                    ^^^^^^^^^^^^ help: try: `foo()`
 
-error: aborting due to 40 previous errors
+error: casting to the same type is unnecessary (`usize` -> `usize`)
+  --> tests/ui/unnecessary_cast.rs:228:9
+   |
+LL |         (*x as usize).pow(2)
+   |         ^^^^^^^^^^^^^ help: try: `{ *x }`
+
+error: aborting due to 41 previous errors