about summary refs log tree commit diff
path: root/src/tools/clippy
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy')
-rw-r--r--src/tools/clippy/.github/workflows/feature_freeze.yml14
-rw-r--r--src/tools/clippy/.github/workflows/lintcheck.yml28
-rw-r--r--src/tools/clippy/.github/workflows/lintcheck_summary.yml106
-rw-r--r--src/tools/clippy/Cargo.toml12
-rw-r--r--src/tools/clippy/book/src/development/infrastructure/backport.md2
-rw-r--r--src/tools/clippy/book/src/development/infrastructure/changelog_update.md32
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md1
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs1
-rw-r--r--src/tools/clippy/clippy_dev/src/fmt.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs87
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/utils.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/missing_headers.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_drop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_clike.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/exhaustive_items.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/exit.rs35
-rw-r--r--src/tools/clippy/clippy_lints/src/fallible_impl_from.rs64
-rw-r--r--src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/from_over_into.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/if_not_else.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/infallible_try_from.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/let_if_seq.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/empty_loop.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs168
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/return_and_then.rs29
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs52
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_trait_methods.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/neg_multiply.rs40
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/op_ref.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/serde_api.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs109
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_async.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs4
-rw-r--r--src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs2
-rw-r--r--src/tools/clippy/clippy_lints_internal/src/symbols.rs2
-rw-r--r--src/tools/clippy/clippy_test_deps/Cargo.lock505
-rw-r--r--src/tools/clippy/clippy_test_deps/Cargo.toml20
-rw-r--r--src/tools/clippy/clippy_test_deps/src/main.rs1
-rw-r--r--src/tools/clippy/clippy_utils/README.md2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs14
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs49
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs86
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs91
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs28
-rw-r--r--src/tools/clippy/clippy_utils/src/source.rs7
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/mod.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs16
-rw-r--r--src/tools/clippy/lintcheck/src/config.rs3
-rw-r--r--src/tools/clippy/lintcheck/src/json.rs105
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs7
-rw-r--r--src/tools/clippy/rust-toolchain.toml2
-rw-r--r--src/tools/clippy/tests/compile-test.rs87
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr14
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr4
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr10
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs11
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.fixed3
-rw-r--r--src/tools/clippy/tests/ui/assign_ops.rs3
-rw-r--r--src/tools/clippy/tests/ui/author/if.stdout3
-rw-r--r--src/tools/clippy/tests/ui/author/struct.stdout3
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.fixed6
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.rs6
-rw-r--r--src/tools/clippy/tests/ui/cast_size.32bit.stderr10
-rw-r--r--src/tools/clippy/tests/ui/cast_size.64bit.stderr10
-rw-r--r--src/tools/clippy/tests/ui/cast_size.rs6
-rw-r--r--src/tools/clippy/tests/ui/coerce_container_to_any.fixed13
-rw-r--r--src/tools/clippy/tests/ui/coerce_container_to_any.rs13
-rw-r--r--src/tools/clippy/tests/ui/coerce_container_to_any.stderr14
-rw-r--r--src/tools/clippy/tests/ui/disallowed_script_idents.rs14
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed6
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs2
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr26
-rw-r--r--src/tools/clippy/tests/ui/empty_loop_intrinsic.rs13
-rw-r--r--src/tools/clippy/tests/ui/exit1_compile_flag_test.rs17
-rw-r--r--src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr11
-rw-r--r--src/tools/clippy/tests/ui/exit2_compile_flag_test.rs15
-rw-r--r--src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr11
-rw-r--r--src/tools/clippy/tests/ui/exit3_compile_flag_test.rs11
-rw-r--r--src/tools/clippy/tests/ui/exit4.rs8
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.fixed44
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.rs44
-rw-r--r--src/tools/clippy/tests/ui/floating_point_mul_add.stderr32
-rw-r--r--src/tools/clippy/tests/ui/manual_is_variant_and.fixed112
-rw-r--r--src/tools/clippy/tests/ui/manual_is_variant_and.rs110
-rw-r--r--src/tools/clippy/tests/ui/manual_is_variant_and.stderr100
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.fixed45
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.rs73
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.stderr72
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed3
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs3
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.stderr2
-rw-r--r--src/tools/clippy/tests/ui/missing_panics_doc.rs28
-rw-r--r--src/tools/clippy/tests/ui/missing_panics_doc.stderr38
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.fixed9
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.rs13
-rw-r--r--src/tools/clippy/tests/ui/needless_bool_assign.stderr13
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.fixed12
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.rs12
-rw-r--r--src/tools/clippy/tests/ui/neg_multiply.stderr8
-rw-r--r--src/tools/clippy/tests/ui/op_ref.fixed34
-rw-r--r--src/tools/clippy/tests/ui/op_ref.rs34
-rw-r--r--src/tools/clippy/tests/ui/op_ref.stderr22
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.fixed20
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.rs20
-rw-r--r--src/tools/clippy/tests/ui/or_fun_call.stderr14
-rw-r--r--src/tools/clippy/tests/ui/partialeq_ne_impl.stderr8
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.rs2
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.stderr11
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed14
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs12
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr28
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.fixed131
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.rs114
-rw-r--r--src/tools/clippy/tests/ui/return_and_then.stderr96
-rw-r--r--src/tools/clippy/tests/ui/same_name_method.stderr16
-rw-r--r--src/tools/clippy/tests/ui/serde.stderr5
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.fixed7
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.rs7
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.stderr30
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs18
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr30
-rw-r--r--src/tools/clippy/tests/ui/swap_with_temporary.fixed46
-rw-r--r--src/tools/clippy/tests/ui/swap_with_temporary.rs46
-rw-r--r--src/tools/clippy/tests/ui/swap_with_temporary.stderr38
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics-clippy.rs3
-rw-r--r--src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr4
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed3
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs3
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.fixed10
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.rs10
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_or.stderr26
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.fixed13
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.rs13
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.fixed8
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.rs8
-rw-r--r--src/tools/clippy/tests/ui/zero_ptr.stderr8
-rw-r--r--src/tools/clippy/triagebot.toml7
-rw-r--r--src/tools/clippy/util/gh-pages/index_template.html40
-rw-r--r--src/tools/clippy/util/gh-pages/script.js6
-rw-r--r--src/tools/clippy/util/gh-pages/style.css26
187 files changed, 3599 insertions, 849 deletions
diff --git a/src/tools/clippy/.github/workflows/feature_freeze.yml b/src/tools/clippy/.github/workflows/feature_freeze.yml
index a5f8d4bc145..7ad58af77d4 100644
--- a/src/tools/clippy/.github/workflows/feature_freeze.yml
+++ b/src/tools/clippy/.github/workflows/feature_freeze.yml
@@ -1,7 +1,11 @@
 name: Feature freeze check
 
 on:
-  pull_request:
+  pull_request_target:
+    types:
+      - opened
+    branches:
+      - master
     paths:
       - 'clippy_lints/src/declared_lints.rs'
 
@@ -9,6 +13,12 @@ jobs:
   auto-comment:
     runs-on: ubuntu-latest
 
+    permissions:
+      pull-requests: write
+
+    # Do not in any case add code that runs anything coming from the  the content
+    # of the pull request, as malicious code would be able to access the private
+    # GitHub token.
     steps:
     - name: Check PR Changes
       id: pr-changes
@@ -19,7 +29,7 @@ jobs:
       run: |
         # Use GitHub API to create a comment on the PR
         PR_NUMBER=${{ github.event.pull_request.number }}
-        COMMENT="**Seems that you are trying to add a new lint!**\nWe are currently in a [feature freeze](https://doc.rust-lang.org/nightly/clippy/development/feature_freeze.html), so we are delaying all lint-adding PRs to August 1st and focusing on bugfixes.\nThanks a lot for your contribution, and sorry for the inconvenience.\nWith ❤ from the Clippy team"
+        COMMENT="**Seems that you are trying to add a new lint!**\nWe are currently in a [feature freeze](https://doc.rust-lang.org/nightly/clippy/development/feature_freeze.html), so we are delaying all lint-adding PRs to September 18 and focusing on bugfixes.\nThanks a lot for your contribution, and sorry for the inconvenience.\nWith ❤ from the Clippy team\n\n@rustbot note Feature-freeze\n@rustbot blocked\n@rustbot label +A-lint\n"
         GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
         COMMENT_URL="https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments"
         curl -s -H "Authorization: token ${GITHUB_TOKEN}" -X POST $COMMENT_URL -d "{\"body\":\"$COMMENT\"}"
diff --git a/src/tools/clippy/.github/workflows/lintcheck.yml b/src/tools/clippy/.github/workflows/lintcheck.yml
index 70c805903d3..003d0395739 100644
--- a/src/tools/clippy/.github/workflows/lintcheck.yml
+++ b/src/tools/clippy/.github/workflows/lintcheck.yml
@@ -128,21 +128,27 @@ jobs:
     - name: Download JSON
       uses: actions/download-artifact@v4
 
+    - name: Store PR number
+      run: echo ${{ github.event.pull_request.number }} > pr.txt
+
     - name: Diff results
-      # GH's summery has a maximum size of 1024k:
-      # https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-markdown-summary
-      # That's why we first log to file and then to the summary and logs
+      # GH's summery has a maximum size of 1MiB:
+      # https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#step-isolation-and-limits
+      # We upload the full diff as an artifact in case it's truncated
       run: |
-        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --truncate >> truncated_diff.md
-        head -c 1024000 truncated_diff.md >> $GITHUB_STEP_SUMMARY
-        cat truncated_diff.md
-        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json >> full_diff.md
+        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --truncate | head -c 1M > $GITHUB_STEP_SUMMARY
+        ./target/debug/lintcheck diff {base,head}/ci_crates_logs.json --write-summary summary.json > full_diff.md
 
     - name: Upload full diff
       uses: actions/upload-artifact@v4
       with:
-        name: diff
-        if-no-files-found: ignore
+        name: full_diff
+        path: full_diff.md
+
+    - name: Upload summary
+      uses: actions/upload-artifact@v4
+      with:
+        name: summary
         path: |
-          full_diff.md
-          truncated_diff.md
+          summary.json
+          pr.txt
diff --git a/src/tools/clippy/.github/workflows/lintcheck_summary.yml b/src/tools/clippy/.github/workflows/lintcheck_summary.yml
new file mode 100644
index 00000000000..52f52e155a0
--- /dev/null
+++ b/src/tools/clippy/.github/workflows/lintcheck_summary.yml
@@ -0,0 +1,106 @@
+name: Lintcheck summary
+
+# The workflow_run event runs in the context of the Clippy repo giving it write
+# access, needed here to create a PR comment when the PR originates from a fork
+#
+# The summary artifact is a JSON file that we verify in this action to prevent
+# the creation of arbitrary comments
+#
+# This action must not checkout/run code from the originating workflow_run
+# or directly interpolate ${{}} untrusted fields into code
+#
+# https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run
+# https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#understanding-the-risk-of-script-injections
+
+on:
+  workflow_run:
+    workflows: [Lintcheck]
+    types: [completed]
+
+# Restrict the default permission scope https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#defining-access-for-the-github_token-scopes
+permissions:
+  pull-requests: write
+
+jobs:
+  download:
+    runs-on: ubuntu-latest
+    if: ${{ github.event.workflow_run.conclusion == 'success' }}
+    steps:
+      - name: Download artifact
+        uses: actions/download-artifact@v4
+        with:
+          name: summary
+          path: untrusted
+          run-id: ${{ github.event.workflow_run.id }}
+          github-token: ${{ github.token }}
+
+      - name: Format comment
+        uses: actions/github-script@v7
+        with:
+          script: |
+            const fs = require("fs");
+            const assert = require("assert/strict");
+
+            function validateName(s) {
+              assert.match(s, /^[a-z0-9_:]+$/);
+              return s;
+            }
+
+            function validateInt(i) {
+              assert.ok(Number.isInteger(i));
+              return i;
+            }
+
+            function tryReadSummary() {
+              try {
+                return JSON.parse(fs.readFileSync("untrusted/summary.json"));
+              } catch {
+                return null;
+              }
+            }
+
+            const prNumber = parseInt(fs.readFileSync("untrusted/pr.txt"), 10);
+            core.exportVariable("PR", prNumber.toString());
+
+            const untrustedSummary = tryReadSummary();
+            if (!Array.isArray(untrustedSummary)) {
+              return;
+            }
+
+            let summary = `Lintcheck changes for ${context.payload.workflow_run.head_sha}
+            
+            | Lint | Added | Removed | Changed |
+            | ---- | ----: | ------: | ------: |
+            `;
+
+            for (const untrustedRow of untrustedSummary) {
+              const name = validateName(untrustedRow.name);
+
+              const added = validateInt(untrustedRow.added);
+              const removed = validateInt(untrustedRow.removed);
+              const changed = validateInt(untrustedRow.changed);
+
+              const id = name.replace("clippy::", "user-content-").replaceAll("_", "-");
+              const url = `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${context.payload.workflow_run.id}#${id}`;
+
+              summary += `| [\`${name}\`](${url}) | ${added} | ${removed} | ${changed} |\n`;
+            }
+
+            summary += "\nThis comment will be updated if you push new changes";
+
+            fs.writeFileSync("summary.md", summary);
+
+      - name: Create/update comment
+        run: |
+          if [[ -f summary.md ]]; then
+             gh pr comment "$PR" --body-file summary.md --edit-last --create-if-none
+          else
+            # There were no changes detected by Lintcheck
+            # - If a comment exists from a previous run that did detect changes, edit it (--edit-last)
+            # - If no comment exists do not create one, the `gh` command exits with an error which
+            #   `|| true` ignores
+            gh pr comment "$PR" --body "No changes for ${{ github.event.workflow_run.head_sha }}" --edit-last || true
+          fi
+        env:
+          GH_TOKEN: ${{ github.token }}
+          GH_REPO: ${{ github.repository }}
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 1278427b5a7..f25f9ab54dd 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -28,13 +28,13 @@ declare_clippy_lint = { path = "declare_clippy_lint" }
 rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
 clippy_lints_internal = { path = "clippy_lints_internal", optional = true }
 tempfile = { version = "3.20", optional = true }
-termize = "0.1"
+termize = "0.2"
 color-print = "0.3.4"
 anstream = "0.6.18"
 
 [dev-dependencies]
 cargo_metadata = "0.18.1"
-ui_test = "0.29.2"
+ui_test = "0.30.2"
 regex = "1.5.5"
 serde = { version = "1.0.145", features = ["derive"] }
 serde_json = "1.0.122"
@@ -45,14 +45,6 @@ itertools = "0.12"
 pulldown-cmark = { version = "0.11", default-features = false, features = ["html"] }
 askama = { version = "0.14", default-features = false, features = ["alloc", "config", "derive"] }
 
-# UI test dependencies
-if_chain = "1.0"
-quote = "1.0.25"
-syn = { version = "2.0", features = ["full"] }
-futures = "0.3"
-parking_lot = "0.12"
-tokio = { version = "1", features = ["io-util"] }
-
 [build-dependencies]
 rustc_tools_util = { path = "rustc_tools_util", version = "0.4.2" }
 
diff --git a/src/tools/clippy/book/src/development/infrastructure/backport.md b/src/tools/clippy/book/src/development/infrastructure/backport.md
index 9526d8af1c9..47ea6a412c5 100644
--- a/src/tools/clippy/book/src/development/infrastructure/backport.md
+++ b/src/tools/clippy/book/src/development/infrastructure/backport.md
@@ -109,4 +109,4 @@ worth backporting this.
 When a PR is backported to Rust `beta`, label the PR with `beta-accepted`. This
 will then get picked up when [writing the changelog].
 
-[writing the changelog]: changelog_update.md#31-include-beta-accepted-prs
+[writing the changelog]: changelog_update.md#4-include-beta-accepted-prs
diff --git a/src/tools/clippy/book/src/development/infrastructure/changelog_update.md b/src/tools/clippy/book/src/development/infrastructure/changelog_update.md
index eede6b78d92..c96ff228b01 100644
--- a/src/tools/clippy/book/src/development/infrastructure/changelog_update.md
+++ b/src/tools/clippy/book/src/development/infrastructure/changelog_update.md
@@ -38,7 +38,7 @@ Usually you want to write the changelog of the **upcoming stable release**. Make
 sure though, that `beta` was already branched in the Rust repository.
 
 To find the commit hash, issue the following command when in a `rust-lang/rust`
-checkout:
+checkout (most of the time on the `upstream/beta` branch):
 ```
 git log --oneline -- src/tools/clippy/ | grep -o "Merge commit '[a-f0-9]*' into .*" | head -1 | sed -e "s/Merge commit '\([a-f0-9]*\)' into .*/\1/g"
 ```
@@ -48,16 +48,13 @@ git log --oneline -- src/tools/clippy/ | grep -o "Merge commit '[a-f0-9]*' into
 Once you've got the correct commit range, run
 
 ```
-util/fetch_prs_between.sh commit1 commit2 > changes.txt
+util/fetch_prs_between.sh start_commit end_commit > changes.txt
 ```
 
-where `commit2` is the commit hash from the previous command and `commit1`
-is the commit hash from the current CHANGELOG file.
+where `end_commit` is the commit hash from the previous command and `start_commit`
+is [the commit hash][beta_section] from the current CHANGELOG file.
 Open `changes.txt` file in your editor of choice.
 
-When updating the changelog it's also a good idea to make sure that `commit1` is
-already correct in the current changelog.
-
 ### 3. Authoring the final changelog
 
 The above script should have dumped all the relevant PRs to the file you
@@ -70,17 +67,7 @@ With the PRs filtered, you can start to take each PR and move the `changelog: `
 content to `CHANGELOG.md`. Adapt the wording as you see fit but try to keep it
 somewhat coherent.
 
-The order should roughly be:
-
-1. New lints
-2. Moves or deprecations of lints
-3. Changes that expand what code existing lints cover
-4. False positive fixes
-5. ICE fixes
-6. Documentation improvements
-7. Others
-
-As section headers, we use:
+The sections order should roughly be:
 
 ```
 ### New Lints
@@ -97,10 +84,10 @@ As section headers, we use:
 ### Others
 ```
 
-Please also be sure to update the Beta/Unreleased sections at the top with the
-relevant commit ranges.
+Please also be sure to update [the `Unreleased/Beta/In Rust Nightly` section][beta_section] at the top with the
+relevant commits ranges and to add the `Rust <version>` section with release date and PR ranges.
 
-#### 3.1 Include `beta-accepted` PRs
+### 4. Include `beta-accepted` PRs
 
 Look for the [`beta-accepted`] label and make sure to also include the PRs with
 that label in the changelog. If you can, remove the `beta-accepted` labels
@@ -109,7 +96,7 @@ that label in the changelog. If you can, remove the `beta-accepted` labels
 > _Note:_ Some of those PRs might even get backported to the previous `beta`.
 > Those have to be included in the changelog of the _previous_ release.
 
-### 4. Update `clippy::version` attributes
+### 5. Update `clippy::version` attributes
 
 Next, make sure to check that the `#[clippy::version]` attributes for the added
 lints contain the correct version. 
@@ -129,3 +116,4 @@ written for. If not, update the version to the changelog version.
 [rust_beta_tools]: https://github.com/rust-lang/rust/tree/beta/src/tools/clippy
 [rust_stable_tools]: https://github.com/rust-lang/rust/releases
 [`beta-accepted`]: https://github.com/rust-lang/rust-clippy/issues?q=label%3Abeta-accepted+
+[beta_section]: https://github.com/rust-lang/rust-clippy/blob/master/CHANGELOG.md#unreleased--beta--in-rust-nightly
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index e9b7f42a183..992ed2c6aaa 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -892,6 +892,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`unnested_or_patterns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnested_or_patterns)
 * [`unused_trait_names`](https://rust-lang.github.io/rust-clippy/master/index.html#unused_trait_names)
 * [`use_self`](https://rust-lang.github.io/rust-clippy/master/index.html#use_self)
+* [`zero_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#zero_ptr)
 
 
 ## `pass-by-value-size-limit`
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 841facdca06..555f54bcfb8 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -794,6 +794,7 @@ define_Conf! {
         unnested_or_patterns,
         unused_trait_names,
         use_self,
+        zero_ptr,
     )]
     msrv: Msrv = Msrv::default(),
     /// The minimum size (in bytes) to consider a type for passing by reference instead of by value.
diff --git a/src/tools/clippy/clippy_dev/src/fmt.rs b/src/tools/clippy/clippy_dev/src/fmt.rs
index c1b6b370706..bd9e57c9f6d 100644
--- a/src/tools/clippy/clippy_dev/src/fmt.rs
+++ b/src/tools/clippy/clippy_dev/src/fmt.rs
@@ -223,7 +223,7 @@ fn fmt_conf(check: bool) -> Result<(), Error> {
         if check {
             return Err(Error::CheckFailed);
         }
-        fs::write(path, new_text.as_bytes())?;
+        fs::write(path, new_text)?;
     }
     Ok(())
 }
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index 3361443196a..40aadf4589a 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -2,7 +2,6 @@
     rustc_private,
     exit_status_error,
     if_let_guard,
-    let_chains,
     os_str_slice,
     os_string_truncate,
     slice_split_once
diff --git a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
index 8b6bfaebbe5..a9d3015ce5c 100644
--- a/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
+++ b/src/tools/clippy/clippy_lints/src/arbitrary_source_item_ordering.rs
@@ -8,11 +8,13 @@ use clippy_utils::diagnostics::span_lint_and_note;
 use clippy_utils::is_cfg_test;
 use rustc_attr_data_structures::AttributeKind;
 use rustc_hir::{
-    AssocItemKind, Attribute, FieldDef, HirId, ImplItemRef, IsAuto, Item, ItemKind, Mod, QPath, TraitItemRef, TyKind,
+    Attribute, FieldDef, HirId, IsAuto, ImplItemId, Item, ItemKind, Mod, OwnerId, QPath, TraitItemId, TyKind,
     Variant, VariantData,
 };
+use rustc_middle::ty::AssocKind;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
+use rustc_span::Ident;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -194,22 +196,22 @@ impl ArbitrarySourceItemOrdering {
     }
 
     /// Produces a linting warning for incorrectly ordered impl items.
-    fn lint_impl_item<T: LintContext>(&self, cx: &T, item: &ImplItemRef, before_item: &ImplItemRef) {
+    fn lint_impl_item(&self, cx: &LateContext<'_>, item: ImplItemId, before_item: ImplItemId) {
         span_lint_and_note(
             cx,
             ARBITRARY_SOURCE_ITEM_ORDERING,
-            item.span,
+            cx.tcx.def_span(item.owner_id),
             format!(
                 "incorrect ordering of impl items (defined order: {:?})",
                 self.assoc_types_order
             ),
-            Some(before_item.span),
-            format!("should be placed before `{}`", before_item.ident.name),
+            Some(cx.tcx.def_span(before_item.owner_id)),
+            format!("should be placed before `{}`", cx.tcx.item_name(before_item.owner_id)),
         );
     }
 
     /// Produces a linting warning for incorrectly ordered item members.
-    fn lint_member_name<T: LintContext>(cx: &T, ident: &rustc_span::Ident, before_ident: &rustc_span::Ident) {
+    fn lint_member_name<T: LintContext>(cx: &T, ident: Ident, before_ident: Ident) {
         span_lint_and_note(
             cx,
             ARBITRARY_SOURCE_ITEM_ORDERING,
@@ -220,7 +222,7 @@ impl ArbitrarySourceItemOrdering {
         );
     }
 
-    fn lint_member_item<T: LintContext>(cx: &T, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) {
+    fn lint_member_item(cx: &LateContext<'_>, item: &Item<'_>, before_item: &Item<'_>, msg: &'static str) {
         let span = if let Some(ident) = item.kind.ident() {
             ident.span
         } else {
@@ -245,17 +247,17 @@ impl ArbitrarySourceItemOrdering {
     }
 
     /// Produces a linting warning for incorrectly ordered trait items.
-    fn lint_trait_item<T: LintContext>(&self, cx: &T, item: &TraitItemRef, before_item: &TraitItemRef) {
+    fn lint_trait_item(&self, cx: &LateContext<'_>, item: TraitItemId, before_item: TraitItemId) {
         span_lint_and_note(
             cx,
             ARBITRARY_SOURCE_ITEM_ORDERING,
-            item.span,
+            cx.tcx.def_span(item.owner_id),
             format!(
                 "incorrect ordering of trait items (defined order: {:?})",
                 self.assoc_types_order
             ),
-            Some(before_item.span),
-            format!("should be placed before `{}`", before_item.ident.name),
+            Some(cx.tcx.def_span(before_item.owner_id)),
+            format!("should be placed before `{}`", cx.tcx.item_name(before_item.owner_id)),
         );
     }
 }
@@ -266,7 +268,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
             .tcx
             .hir_attrs(item.hir_id())
             .iter()
-            .any(|attr| matches!(attr, Attribute::Parsed(AttributeKind::Repr{ .. })))
+            .any(|attr| matches!(attr, Attribute::Parsed(AttributeKind::Repr { .. })))
         {
             // Do not lint items with a `#[repr]` attribute as their layout may be imposed by an external API.
             return;
@@ -283,7 +285,7 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                         && cur_v.ident.name.as_str() > variant.ident.name.as_str()
                         && cur_v.span != variant.span
                     {
-                        Self::lint_member_name(cx, &variant.ident, &cur_v.ident);
+                        Self::lint_member_name(cx, variant.ident, cur_v.ident);
                     }
                     cur_v = Some(variant);
                 }
@@ -299,57 +301,61 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
                         && cur_f.ident.name.as_str() > field.ident.name.as_str()
                         && cur_f.span != field.span
                     {
-                        Self::lint_member_name(cx, &field.ident, &cur_f.ident);
+                        Self::lint_member_name(cx, field.ident, cur_f.ident);
                     }
                     cur_f = Some(field);
                 }
             },
-            ItemKind::Trait(is_auto, _safety, _ident, _generics, _generic_bounds, item_ref)
+            ItemKind::Trait(_constness, is_auto, _safety, _ident, _generics, _generic_bounds, item_ref)
                 if self.enable_ordering_for_trait && *is_auto == IsAuto::No =>
             {
-                let mut cur_t: Option<&TraitItemRef> = None;
+                let mut cur_t: Option<(TraitItemId, Ident)> = None;
 
-                for item in *item_ref {
-                    if item.span.in_external_macro(cx.sess().source_map()) {
+                for &item in *item_ref {
+                    let span = cx.tcx.def_span(item.owner_id);
+                    let ident = cx.tcx.item_ident(item.owner_id);
+                    if span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
-                    if let Some(cur_t) = cur_t {
-                        let cur_t_kind = convert_assoc_item_kind(cur_t.kind);
+                    if let Some((cur_t, cur_ident)) = cur_t {
+                        let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id);
                         let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);
-                        let item_kind = convert_assoc_item_kind(item.kind);
+                        let item_kind = convert_assoc_item_kind(cx, item.owner_id);
                         let item_kind_index = self.assoc_types_order.index_of(&item_kind);
 
-                        if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
-                            Self::lint_member_name(cx, &item.ident, &cur_t.ident);
+                        if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() {
+                            Self::lint_member_name(cx, ident, cur_ident);
                         } else if cur_t_kind_index > item_kind_index {
                             self.lint_trait_item(cx, item, cur_t);
                         }
                     }
-                    cur_t = Some(item);
+                    cur_t = Some((item, ident));
                 }
             },
             ItemKind::Impl(trait_impl) if self.enable_ordering_for_impl => {
-                let mut cur_t: Option<&ImplItemRef> = None;
+                let mut cur_t: Option<(ImplItemId, Ident)> = None;
 
-                for item in trait_impl.items {
-                    if item.span.in_external_macro(cx.sess().source_map()) {
+                for &item in trait_impl.items {
+                    let span = cx.tcx.def_span(item.owner_id);
+                    let ident = cx.tcx.item_ident(item.owner_id);
+                    if span.in_external_macro(cx.sess().source_map()) {
                         continue;
                     }
 
-                    if let Some(cur_t) = cur_t {
-                        let cur_t_kind = convert_assoc_item_kind(cur_t.kind);
+                    if let Some((cur_t, cur_ident)) = cur_t {
+                        let cur_t_kind = convert_assoc_item_kind(cx, cur_t.owner_id);
                         let cur_t_kind_index = self.assoc_types_order.index_of(&cur_t_kind);
-                        let item_kind = convert_assoc_item_kind(item.kind);
+                        let item_kind = convert_assoc_item_kind(cx, item.owner_id);
                         let item_kind_index = self.assoc_types_order.index_of(&item_kind);
 
-                        if cur_t_kind == item_kind && cur_t.ident.name.as_str() > item.ident.name.as_str() {
-                            Self::lint_member_name(cx, &item.ident, &cur_t.ident);
+                        if cur_t_kind == item_kind && cur_ident.name.as_str() > ident.name.as_str() {
+                            Self::lint_member_name(cx, ident, cur_ident);
                         } else if cur_t_kind_index > item_kind_index {
                             self.lint_impl_item(cx, item, cur_t);
                         }
                     }
-                    cur_t = Some(item);
+                    cur_t = Some((item, ident));
                 }
             },
             _ => {}, // Catch-all for `ItemKinds` that don't have fields.
@@ -458,18 +464,19 @@ impl<'tcx> LateLintPass<'tcx> for ArbitrarySourceItemOrdering {
     }
 }
 
-/// Converts a [`rustc_hir::AssocItemKind`] to a
-/// [`SourceItemOrderingTraitAssocItemKind`].
+/// Converts a [`ty::AssocKind`] to a [`SourceItemOrderingTraitAssocItemKind`].
 ///
 /// This is implemented here because `rustc_hir` is not a dependency of
 /// `clippy_config`.
-fn convert_assoc_item_kind(value: AssocItemKind) -> SourceItemOrderingTraitAssocItemKind {
+fn convert_assoc_item_kind(cx: &LateContext<'_>, owner_id: OwnerId) -> SourceItemOrderingTraitAssocItemKind {
+    let kind = cx.tcx.associated_item(owner_id.def_id).kind;
+
     #[allow(clippy::enum_glob_use)] // Very local glob use for legibility.
     use SourceItemOrderingTraitAssocItemKind::*;
-    match value {
-        AssocItemKind::Const => Const,
-        AssocItemKind::Type => Type,
-        AssocItemKind::Fn { .. } => Fn,
+    match kind {
+        AssocKind::Const{..} => Const,
+        AssocKind::Type {..}=> Type,
+        AssocKind::Fn { .. } => Fn,
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index bf43234ff50..61c2fc49bd7 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -1,5 +1,6 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
+use clippy_utils::higher::has_let_expr;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::sugg::Sugg;
@@ -646,7 +647,9 @@ impl<'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
         if !e.span.from_expansion() {
             match &e.kind {
-                ExprKind::Binary(binop, _, _) if binop.node == BinOpKind::Or || binop.node == BinOpKind::And => {
+                ExprKind::Binary(binop, _, _)
+                    if binop.node == BinOpKind::Or || binop.node == BinOpKind::And && !has_let_expr(e) =>
+                {
                     self.bool_expr(e);
                 },
                 ExprKind::Unary(UnOp::Not, inner) => {
diff --git a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
index ad0a4f8cdf3..e3b125a8d5b 100644
--- a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -18,7 +18,8 @@ pub(super) fn check<'tcx>(
     cast_to: &'tcx Ty<'_>,
     msrv: Msrv,
 ) -> bool {
-    if matches!(cast_to.kind, TyKind::Ptr(_))
+    if let TyKind::Ptr(target) = cast_to.kind
+        && !matches!(target.ty.kind, TyKind::TraitObject(..))
         && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
         && !is_lint_allowed(cx, BORROW_AS_PTR, expr.hir_id)
     {
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index a2ecb5fb44a..2eebe849232 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::source::snippet;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
-use clippy_utils::{expr_or_init, sym};
+use clippy_utils::{expr_or_init, is_in_const_context, sym};
 use rustc_abi::IntegerType;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::def::{DefKind, Res};
@@ -168,7 +168,9 @@ pub(super) fn check(
 
     span_lint_and_then(cx, CAST_POSSIBLE_TRUNCATION, expr.span, msg, |diag| {
         diag.help("if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...");
-        if !cast_from.is_floating_point() {
+        // TODO: Remove the condition for const contexts when `try_from` and other commonly used methods
+        // become const fn.
+        if !is_in_const_context(cx) && !cast_from.is_floating_point() {
             offer_suggestion(cx, expr, cast_expr, cast_to_span, diag);
         }
     });
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
index 105477093b5..55e27a05f3c 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
@@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
         ty::FnDef(..) | ty::FnPtr(..) => {
             let mut applicability = Applicability::MaybeIncorrect;
 
-            if to_nbits >= cx.tcx.data_layout.pointer_size.bits() && !cast_to.is_usize() {
+            if to_nbits >= cx.tcx.data_layout.pointer_size().bits() && !cast_to.is_usize() {
                 let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
                 span_lint_and_sugg(
                     cx,
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
index 700b7d0d426..4da79205e20 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
@@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
             let mut applicability = Applicability::MaybeIncorrect;
             let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
 
-            if to_nbits < cx.tcx.data_layout.pointer_size.bits() {
+            if to_nbits < cx.tcx.data_layout.pointer_size().bits() {
                 span_lint_and_sugg(
                     cx,
                     FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index daae9a8bb08..37accff5eaa 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -878,7 +878,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             confusing_method_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
             fn_to_numeric_cast::check(cx, expr, cast_from_expr, cast_from, cast_to);
             fn_to_numeric_cast_with_truncation::check(cx, expr, cast_from_expr, cast_from, cast_to);
-            zero_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
+            zero_ptr::check(cx, expr, cast_from_expr, cast_to_hir, self.msrv);
 
             if self.msrv.meets(cx, msrvs::MANUAL_DANGLING_PTR) {
                 manual_dangling_ptr::check(cx, expr, cast_from_expr, cast_to_hir);
diff --git a/src/tools/clippy/clippy_lints/src/casts/utils.rs b/src/tools/clippy/clippy_lints/src/casts/utils.rs
index 318a1646477..d846d78b9ee 100644
--- a/src/tools/clippy/clippy_lints/src/casts/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/utils.rs
@@ -5,7 +5,7 @@ use rustc_middle::ty::{self, AdtDef, IntTy, Ty, TyCtxt, UintTy, VariantDiscr};
 /// integral type.
 pub(super) fn int_ty_to_nbits(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<u64> {
     match ty.kind() {
-        ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(tcx.data_layout.pointer_size.bits()),
+        ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => Some(tcx.data_layout.pointer_size().bits()),
         ty::Int(i) => i.bit_width(),
         ty::Uint(i) => i.bit_width(),
         _ => None,
diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
index a34af6bc226..f4738e7b0d5 100644
--- a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::{is_in_const_context, is_integer_literal, std_or_core};
 use rustc_errors::Applicability;
@@ -7,10 +8,10 @@ use rustc_lint::LateContext;
 
 use super::ZERO_PTR;
 
-pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {
+pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>, msrv: Msrv) {
     if let TyKind::Ptr(ref mut_ty) = to.kind
         && is_integer_literal(from, 0)
-        && !is_in_const_context(cx)
+        && (!is_in_const_context(cx) || msrv.meets(cx, msrvs::PTR_NULL))
         && let Some(std_or_core) = std_or_core(cx)
     {
         let (msg, sugg_fn) = match mut_ty.mutbl {
diff --git a/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs b/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
index 2b659253763..6217fc4c897 100644
--- a/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
+++ b/src/tools/clippy/clippy_lints/src/coerce_container_to_any.rs
@@ -1,9 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet;
+use clippy_utils::sugg::{self, Sugg};
 use clippy_utils::sym;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::adjustment::{Adjust, PointerCoercion};
 use rustc_middle::ty::{self, ExistentialPredicate, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
 
@@ -49,23 +50,18 @@ declare_lint_pass!(CoerceContainerToAny => [COERCE_CONTAINER_TO_ANY]);
 
 impl<'tcx> LateLintPass<'tcx> for CoerceContainerToAny {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
-        // If this expression has an effective type of `&dyn Any` ...
-        {
-            let coerced_ty = cx.typeck_results().expr_ty_adjusted(e);
-
-            let ty::Ref(_, coerced_ref_ty, _) = *coerced_ty.kind() else {
-                return;
-            };
-            if !is_dyn_any(cx.tcx, coerced_ref_ty) {
-                return;
-            }
+        // If this expression was coerced to `&dyn Any` ...
+        if !cx.typeck_results().expr_adjustments(e).last().is_some_and(|adj| {
+            matches!(adj.kind, Adjust::Pointer(PointerCoercion::Unsize)) && is_ref_dyn_any(cx.tcx, adj.target)
+        }) {
+            return;
         }
 
         let expr_ty = cx.typeck_results().expr_ty(e);
         let ty::Ref(_, expr_ref_ty, _) = *expr_ty.kind() else {
             return;
         };
-        // ... but only due to coercion ...
+        // ... but it's not actually `&dyn Any` ...
         if is_dyn_any(cx.tcx, expr_ref_ty) {
             return;
         }
@@ -78,23 +74,37 @@ impl<'tcx> LateLintPass<'tcx> for CoerceContainerToAny {
         }
 
         // ... that's probably not intended.
-        let (span, deref_count) = match e.kind {
+        let (target_expr, deref_count) = match e.kind {
             // If `e` was already an `&` expression, skip `*&` in the suggestion
-            ExprKind::AddrOf(_, _, referent) => (referent.span, depth),
-            _ => (e.span, depth + 1),
+            ExprKind::AddrOf(_, _, referent) => (referent, depth),
+            _ => (e, depth + 1),
         };
+        let ty::Ref(_, _, mutability) = *cx.typeck_results().expr_ty_adjusted(e).kind() else {
+            return;
+        };
+        let sugg = sugg::make_unop(
+            &format!("{}{}", mutability.ref_prefix_str(), str::repeat("*", deref_count)),
+            Sugg::hir(cx, target_expr, ".."),
+        );
         span_lint_and_sugg(
             cx,
             COERCE_CONTAINER_TO_ANY,
             e.span,
-            format!("coercing `{expr_ty}` to `&dyn Any`"),
+            format!("coercing `{expr_ty}` to `{}dyn Any`", mutability.ref_prefix_str()),
             "consider dereferencing",
-            format!("&{}{}", str::repeat("*", deref_count), snippet(cx, span, "x")),
+            sugg.to_string(),
             Applicability::MaybeIncorrect,
         );
     }
 }
 
+fn is_ref_dyn_any(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {
+    let ty::Ref(_, ref_ty, _) = *ty.kind() else {
+        return false;
+    };
+    is_dyn_any(tcx, ref_ty)
+}
+
 fn is_dyn_any(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {
     let ty::Dynamic(traits, ..) = ty.kind() else {
         return false;
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 5c64216dd92..d5d937d9133 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -14,18 +14,25 @@ use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for methods with high cognitive complexity.
+    /// We used to think it measured how hard a method is to understand.
     ///
     /// ### Why is this bad?
-    /// Methods of high cognitive complexity tend to be hard to
-    /// both read and maintain. Also LLVM will tend to optimize small methods better.
+    /// Ideally, we would like to be able to measure how hard a function is
+    /// to understand given its context (what we call its Cognitive Complexity).
+    /// But that's not what this lint does. See "Known problems"
     ///
     /// ### Known problems
-    /// Sometimes it's hard to find a way to reduce the
-    /// complexity.
+    /// The true Cognitive Complexity of a method is not something we can
+    /// calculate using modern technology. This lint has been left in the
+    /// `nursery` so as to not mislead users into using this lint as a
+    /// measurement tool.
     ///
-    /// ### Example
-    /// You'll see it when you get the warning.
+    /// For more detailed information, see [rust-clippy#3793](https://github.com/rust-lang/rust-clippy/issues/3793)
+    ///
+    /// ### Lints to consider instead of this
+    ///
+    /// * [`excessive_nesting`](https://rust-lang.github.io/rust-clippy/master/index.html#excessive_nesting)
+    /// * [`too_many_lines`](https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines)
     #[clippy::version = "1.35.0"]
     pub COGNITIVE_COMPLEXITY,
     nursery,
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 10331b3855b..0a481ddcd12 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -192,7 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
             && !item.span.from_expansion()
             && let Some(def_id) = trait_ref.trait_def_id()
             && cx.tcx.is_diagnostic_item(sym::Default, def_id)
-            && let impl_item_hir = child.id.hir_id()
+            && let impl_item_hir = child.hir_id()
             && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
             && let ImplItemKind::Fn(_, b) = &impl_item.kind
             && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b)
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
index d1a8590c59b..cf964d4b580 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
@@ -89,6 +89,10 @@ impl EarlyLintPass for DisallowedScriptIdents {
             // Fast path for ascii-only idents.
             if !symbol_str.is_ascii()
                 && let Some(script) = symbol_str.chars().find_map(|c| {
+                    if c.is_ascii() {
+                        return None;
+                    }
+
                     c.script_extension()
                         .iter()
                         .find(|script| !self.whitelist.contains(script))
diff --git a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
index 9ee32fced8c..3033ac0d0b0 100644
--- a/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/missing_headers.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
 use clippy_utils::ty::{get_type_diagnostic_name, implements_trait_with_env, is_type_diagnostic_item};
 use clippy_utils::visitors::for_each_expr;
-use clippy_utils::{fulfill_or_allowed, is_doc_hidden, method_chain_args, return_ty};
+use clippy_utils::{fulfill_or_allowed, is_doc_hidden, is_inside_always_const_context, method_chain_args, return_ty};
 use rustc_hir::{BodyId, FnSig, OwnerId, Safety};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
@@ -99,13 +99,16 @@ fn find_panic(cx: &LateContext<'_>, body_id: BodyId) -> Option<Span> {
     let mut panic_span = None;
     let typeck = cx.tcx.typeck_body(body_id);
     for_each_expr(cx, cx.tcx.hir_body(body_id), |expr| {
+        if is_inside_always_const_context(cx.tcx, expr.hir_id) {
+            return ControlFlow::<!>::Continue(());
+        }
+
         if let Some(macro_call) = root_macro_call_first_node(cx, expr)
             && (is_panic(cx, macro_call.def_id)
                 || matches!(
                     cx.tcx.get_diagnostic_name(macro_call.def_id),
                     Some(sym::assert_macro | sym::assert_eq_macro | sym::assert_ne_macro)
                 ))
-            && !cx.tcx.hir_is_inside_const_context(expr.hir_id)
             && !fulfill_or_allowed(cx, MISSING_PANICS_DOC, [expr.hir_id])
             && panic_span.is_none()
         {
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 5ea55e102df..22b781b8929 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -740,7 +740,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
                             );
                         }
                     },
-                    ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) {
+                    ItemKind::Trait(_, _, unsafety, ..) => match (headers.safety, unsafety) {
                         (false, Safety::Unsafe) => span_lint(
                             cx,
                             MISSING_SAFETY_DOC,
@@ -1249,7 +1249,9 @@ fn looks_like_refdef(doc: &str, range: Range<usize>) -> Option<Range<usize>> {
             b'[' => {
                 start = Some(i + offset);
             },
-            b']' if let Some(start) = start => {
+            b']' if let Some(start) = start
+                && doc.as_bytes().get(i + offset + 1) == Some(&b':') =>
+            {
                 return Some(start..i + offset + 1);
             },
             _ => {},
diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs
index d557a36c7ac..4e948701da4 100644
--- a/src/tools/clippy/clippy_lints/src/empty_drop.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs
@@ -41,7 +41,7 @@ impl LateLintPass<'_> for EmptyDrop {
             ..
         }) = item.kind
             && trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait()
-            && let impl_item_hir = child.id.hir_id()
+            && let impl_item_hir = child.hir_id()
             && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
             && let ImplItemKind::Fn(_, b) = &impl_item.kind
             && let Body { value: func_expr, .. } = cx.tcx.hir_body(*b)
diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs
index 098571a5351..c828fc57f76 100644
--- a/src/tools/clippy/clippy_lints/src/enum_clike.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs
@@ -35,7 +35,7 @@ declare_lint_pass!(UnportableVariant => [ENUM_CLIKE_UNPORTABLE_VARIANT]);
 impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
     #[expect(clippy::cast_possible_wrap)]
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
-        if cx.tcx.data_layout.pointer_size.bits() != 64 {
+        if cx.tcx.data_layout.pointer_size().bits() != 64 {
             return;
         }
         if let ItemKind::Enum(_, _, def) = &item.kind {
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 2cb3b32babe..db2fea1aae9 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -1,7 +1,8 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_hir;
 use rustc_abi::ExternAbi;
-use rustc_hir::{AssocItemKind, Body, FnDecl, HirId, HirIdSet, Impl, ItemKind, Node, Pat, PatKind, intravisit};
+use rustc_hir::{Body, FnDecl, HirId, HirIdSet, Node, Pat, PatKind, intravisit};
+use rustc_hir::def::DefKind;
 use rustc_hir_typeck::expr_use_visitor::{Delegate, ExprUseVisitor, PlaceBase, PlaceWithHirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::FakeReadCause;
@@ -84,23 +85,18 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
             .def_id;
 
         let mut trait_self_ty = None;
-        if let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_id) {
+        match cx.tcx.def_kind(parent_id) {
             // If the method is an impl for a trait, don't warn.
-            if let ItemKind::Impl(Impl { of_trait: Some(_), .. }) = item.kind {
-                return;
+            DefKind::Impl { of_trait: true } => {
+                return
             }
 
             // find `self` ty for this trait if relevant
-            if let ItemKind::Trait(_, _, _, _, _, items) = item.kind {
-                for trait_item in items {
-                    if trait_item.id.owner_id.def_id == fn_def_id
-                        // be sure we have `self` parameter in this function
-                        && trait_item.kind == (AssocItemKind::Fn { has_self: true })
-                    {
-                        trait_self_ty = Some(TraitRef::identity(cx.tcx, trait_item.id.owner_id.to_def_id()).self_ty());
-                    }
-                }
+            DefKind::Trait => {
+                trait_self_ty = Some(TraitRef::identity(cx.tcx, parent_id.to_def_id()).self_ty());
             }
+
+            _ => {}
         }
 
         let mut v = EscapeDelegate {
diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
index 7dda3e0fdb9..8ad09279071 100644
--- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
+++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
@@ -1,12 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::indent_of;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_attr_data_structures::AttributeKind;
-use rustc_attr_data_structures::find_attr;
-
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/exit.rs b/src/tools/clippy/clippy_lints/src/exit.rs
index cc8e4d7d9e2..487db69027a 100644
--- a/src/tools/clippy/clippy_lints/src/exit.rs
+++ b/src/tools/clippy/clippy_lints/src/exit.rs
@@ -1,5 +1,4 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::is_entrypoint_fn;
 use rustc_hir::{Expr, ExprKind, Item, ItemKind, OwnerNode};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -7,7 +6,8 @@ use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Detects calls to the `exit()` function which terminates the program.
+    /// Detects calls to the `exit()` function that are not in the `main` function. Calls to `exit()`
+    /// immediately terminate the program.
     ///
     /// ### Why restrict this?
     /// `exit()` immediately terminates the program with no information other than an exit code.
@@ -15,11 +15,24 @@ declare_clippy_lint! {
     ///
     /// Codebases may use this lint to require that all exits are performed either by panicking
     /// (which produces a message, a code location, and optionally a backtrace)
-    /// or by returning from `main()` (which is a single place to look).
+    /// or by calling `exit()` from `main()` (which is a single place to look).
     ///
-    /// ### Example
+    /// ### Good example
     /// ```no_run
-    /// std::process::exit(0)
+    /// fn main() {
+    ///     std::process::exit(0);
+    /// }
+    /// ```
+    ///
+    /// ### Bad example
+    /// ```no_run
+    /// fn main() {
+    ///     other_function();
+    /// }
+    ///
+    /// fn other_function() {
+    ///     std::process::exit(0);
+    /// }
     /// ```
     ///
     /// Use instead:
@@ -36,7 +49,7 @@ declare_clippy_lint! {
     #[clippy::version = "1.41.0"]
     pub EXIT,
     restriction,
-    "detects `std::process::exit` calls"
+    "detects `std::process::exit` calls outside of `main`"
 }
 
 declare_lint_pass!(Exit => [EXIT]);
@@ -48,10 +61,14 @@ impl<'tcx> LateLintPass<'tcx> for Exit {
             && let Some(def_id) = cx.qpath_res(path, path_expr.hir_id).opt_def_id()
             && cx.tcx.is_diagnostic_item(sym::process_exit, def_id)
             && let parent = cx.tcx.hir_get_parent_item(e.hir_id)
-            && let OwnerNode::Item(Item{kind: ItemKind::Fn{ .. }, ..}) = cx.tcx.hir_owner_node(parent)
-            // If the next item up is a function we check if it is an entry point
+            && let OwnerNode::Item(Item{kind: ItemKind::Fn{ ident, .. }, ..}) = cx.tcx.hir_owner_node(parent)
+            // If the next item up is a function we check if it isn't named "main"
             // and only then emit a linter warning
-            && !is_entrypoint_fn(cx, parent.to_def_id())
+
+            // if you instead check for the parent of the `exit()` call being the entrypoint function, as this worked before,
+            // in compilation contexts like --all-targets (which include --tests), you get false positives
+            // because in a test context, main is not the entrypoint function
+            && ident.name != sym::main
         {
             span_lint(cx, EXIT, e.span, "usage of `process::exit`");
         }
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index 68d0cd19c8a..552cd721f4e 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -52,20 +52,20 @@ declare_lint_pass!(FallibleImplFrom => [FALLIBLE_IMPL_FROM]);
 impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
         // check for `impl From<???> for ..`
-        if let hir::ItemKind::Impl(impl_) = &item.kind
+        if let hir::ItemKind::Impl(_) = &item.kind
             && let Some(impl_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id)
             && cx
                 .tcx
                 .is_diagnostic_item(sym::From, impl_trait_ref.skip_binder().def_id)
         {
-            lint_impl_body(cx, item.span, impl_.items);
+            lint_impl_body(cx, item.owner_id, item.span);
         }
     }
 }
 
-fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
+fn lint_impl_body(cx: &LateContext<'_>, item_def_id: hir::OwnerId, impl_span: Span) {
     use rustc_hir::intravisit::{self, Visitor};
-    use rustc_hir::{Expr, ImplItemKind};
+    use rustc_hir::Expr;
 
     struct FindPanicUnwrap<'a, 'tcx> {
         lcx: &'a LateContext<'tcx>,
@@ -96,35 +96,35 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl
         }
     }
 
-    for impl_item in impl_items {
-        if impl_item.ident.name == sym::from
-            && let ImplItemKind::Fn(_, body_id) = cx.tcx.hir_impl_item(impl_item.id).kind
-        {
-            // check the body for `begin_panic` or `unwrap`
-            let body = cx.tcx.hir_body(body_id);
-            let mut fpu = FindPanicUnwrap {
-                lcx: cx,
-                typeck_results: cx.tcx.typeck(impl_item.id.owner_id.def_id),
-                result: Vec::new(),
-            };
-            fpu.visit_expr(body.value);
+    for impl_item in cx.tcx.associated_items(item_def_id)
+        .filter_by_name_unhygienic_and_kind(sym::from, ty::AssocTag::Fn)
+    {
+        let impl_item_def_id= impl_item.def_id.expect_local();
 
-            // if we've found one, lint
-            if !fpu.result.is_empty() {
-                span_lint_and_then(
-                    cx,
-                    FALLIBLE_IMPL_FROM,
-                    impl_span,
-                    "consider implementing `TryFrom` instead",
-                    move |diag| {
-                        diag.help(
-                            "`From` is intended for infallible conversions only. \
-                            Use `TryFrom` if there's a possibility for the conversion to fail",
-                        );
-                        diag.span_note(fpu.result, "potential failure(s)");
-                    },
-                );
-            }
+        // check the body for `begin_panic` or `unwrap`
+        let body = cx.tcx.hir_body_owned_by(impl_item_def_id);
+        let mut fpu = FindPanicUnwrap {
+            lcx: cx,
+            typeck_results: cx.tcx.typeck(impl_item_def_id),
+            result: Vec::new(),
+        };
+        fpu.visit_expr(body.value);
+
+        // if we've found one, lint
+        if !fpu.result.is_empty() {
+            span_lint_and_then(
+                cx,
+                FALLIBLE_IMPL_FROM,
+                impl_span,
+                "consider implementing `TryFrom` instead",
+                move |diag| {
+                    diag.help(
+                        "`From` is intended for infallible conversions only. \
+                        Use `TryFrom` if there's a possibility for the conversion to fail",
+                    );
+                    diag.span_note(fpu.result, "potential failure(s)");
+                },
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
index b3c9e860758..d5abaa547e8 100644
--- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
@@ -2,8 +2,8 @@ use clippy_utils::consts::Constant::{F32, F64, Int};
 use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::{
-    eq_expr_value, get_parent_expr, higher, is_in_const_context, is_inherent_method_call, is_no_std_crate,
-    numeric_literal, peel_blocks, sugg, sym,
+    eq_expr_value, get_parent_expr, has_ambiguous_literal_in_expr, higher, is_in_const_context,
+    is_inherent_method_call, is_no_std_crate, numeric_literal, peel_blocks, sugg, sym,
 };
 use rustc_ast::ast;
 use rustc_errors::Applicability;
@@ -455,7 +455,6 @@ fn is_float_mul_expr<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<(&'
     None
 }
 
-// TODO: Fix rust-lang/rust-clippy#4735
 fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
     if let ExprKind::Binary(
         Spanned {
@@ -491,6 +490,14 @@ fn check_mul_add(cx: &LateContext<'_>, expr: &Expr<'_>) {
             return;
         };
 
+        // Check if any variable in the expression has an ambiguous type (could be f32 or f64)
+        // see: https://github.com/rust-lang/rust-clippy/issues/14897
+        if (matches!(recv.kind, ExprKind::Path(_)) || matches!(recv.kind, ExprKind::Call(_, _)))
+            && has_ambiguous_literal_in_expr(cx, recv)
+        {
+            return;
+        }
+
         span_lint_and_sugg(
             cx,
             SUBOPTIMAL_FLOPS,
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 0c39aae9ca9..16c58ecb455 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -30,6 +30,7 @@ use rustc_span::edition::Edition::Edition2021;
 use rustc_span::{Span, Symbol, sym};
 use rustc_trait_selection::infer::TyCtxtInferExt;
 use rustc_trait_selection::traits::{Obligation, ObligationCause, Selection, SelectionContext};
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -656,7 +657,7 @@ impl<'tcx> FormatArgsExpr<'_, 'tcx> {
                     };
                     let selection = SelectionContext::new(&infcx).select(&obligation);
                     let derived = if let Ok(Some(Selection::UserDefined(data))) = selection {
-                        tcx.has_attr(data.impl_def_id, sym::automatically_derived)
+                        find_attr!(tcx.get_all_attrs(data.impl_def_id), AttributeKind::AutomaticallyDerived(..))
                     } else {
                         false
                     };
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index be887b03ae4..85b40ba7419 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -9,7 +9,7 @@ use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_path};
 use rustc_hir::{
-    FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path,
+    FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemId, Item, ItemKind, PatKind, Path,
     PathSegment, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
@@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto {
                         middle_trait_ref.self_ty()
                     );
                     if let Some(suggestions) =
-                        convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, impl_item_ref)
+                        convert_to_from(cx, into_trait_seg, target_ty.as_unambig_ty(), self_ty, *impl_item_ref)
                     {
                         diag.multipart_suggestion(message, suggestions, Applicability::MachineApplicable);
                     } else {
@@ -164,14 +164,14 @@ fn convert_to_from(
     into_trait_seg: &PathSegment<'_>,
     target_ty: &Ty<'_>,
     self_ty: &Ty<'_>,
-    impl_item_ref: &ImplItemRef,
+    impl_item_ref: ImplItemId,
 ) -> Option<Vec<(Span, String)>> {
     if !target_ty.find_self_aliases().is_empty() {
         // It's tricky to expand self-aliases correctly, we'll ignore it to not cause a
         // bad suggestion/fix.
         return None;
     }
-    let impl_item = cx.tcx.hir_impl_item(impl_item_ref.id);
+    let impl_item = cx.tcx.hir_impl_item(impl_item_ref);
     let ImplItemKind::Fn(ref sig, body_id) = impl_item.kind else {
         return None;
     };
diff --git a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
index 2d22bb157a9..0d6191f2c97 100644
--- a/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/renamed_function_params.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use rustc_errors::{Applicability, MultiSpan};
 use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::hir_id::OwnerId;
-use rustc_hir::{Impl, ImplItem, ImplItemKind, ImplItemRef, ItemKind, Node, TraitRef};
+use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind, Node, TraitRef};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 use rustc_span::symbol::{Ident, kw};
@@ -15,11 +15,10 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, item: &ImplItem<'_>, ignored
         && let parent_node = cx.tcx.parent_hir_node(item.hir_id())
         && let Node::Item(parent_item) = parent_node
         && let ItemKind::Impl(Impl {
-            items,
             of_trait: Some(trait_ref),
             ..
         }) = &parent_item.kind
-        && let Some(did) = trait_item_def_id_of_impl(items, item.owner_id)
+        && let Some(did) = trait_item_def_id_of_impl(cx, item.owner_id)
         && !is_from_ignored_trait(trait_ref, ignored_traits)
     {
         let mut param_idents_iter = cx.tcx.hir_body_param_idents(body_id);
@@ -93,14 +92,8 @@ impl RenamedFnArgs {
 }
 
 /// Get the [`trait_item_def_id`](ImplItemRef::trait_item_def_id) of a relevant impl item.
-fn trait_item_def_id_of_impl(items: &[ImplItemRef], target: OwnerId) -> Option<DefId> {
-    items.iter().find_map(|item| {
-        if item.id.owner_id == target {
-            item.trait_item_def_id
-        } else {
-            None
-        }
-    })
+fn trait_item_def_id_of_impl(cx: &LateContext<'_>, target: OwnerId) -> Option<DefId> {
+    cx.tcx.associated_item(target).trait_item_def_id
 }
 
 fn is_from_ignored_trait(of_trait: &TraitRef<'_>, ignored_traits: &DefIdSet) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/if_not_else.rs b/src/tools/clippy/clippy_lints/src/if_not_else.rs
index ab7a965b367..25fed0d4dd1 100644
--- a/src/tools/clippy/clippy_lints/src/if_not_else.rs
+++ b/src/tools/clippy/clippy_lints/src/if_not_else.rs
@@ -51,7 +51,6 @@ declare_lint_pass!(IfNotElse => [IF_NOT_ELSE]);
 impl LateLintPass<'_> for IfNotElse {
     fn check_expr(&mut self, cx: &LateContext<'_>, e: &Expr<'_>) {
         if let ExprKind::If(cond, cond_inner, Some(els)) = e.kind
-            && let ExprKind::DropTemps(cond) = cond.kind
             && let ExprKind::Block(..) = els.kind
         {
             let (msg, help) = match cond.kind {
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index cab7a9fb709..b3c90f364e8 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -130,7 +130,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                     });
 
                     let mut ctr_vis = ImplicitHasherConstructorVisitor::new(cx, target);
-                    for item in impl_.items.iter().map(|item| cx.tcx.hir_impl_item(item.id)) {
+                    for item in impl_.items.iter().map(|&item| cx.tcx.hir_impl_item(item)) {
                         ctr_vis.visit_impl_item(item);
                     }
 
diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
index 185fc2aa2d4..0fdbf679738 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_add.rs
@@ -41,8 +41,7 @@ declare_lint_pass!(ImplicitSaturatingAdd => [IMPLICIT_SATURATING_ADD]);
 impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if let ExprKind::If(cond, then, None) = expr.kind
-            && let ExprKind::DropTemps(expr1) = cond.kind
-            && let Some((c, op_node, l)) = get_const(cx, expr1)
+            && let Some((c, op_node, l)) = get_const(cx, cond)
             && let BinOpKind::Ne | BinOpKind::Lt = op_node
             && let ExprKind::Block(block, None) = then.kind
             && let Block {
@@ -66,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd {
             && Some(c) == get_int_max(ty)
             && let ctxt = expr.span.ctxt()
             && ex.span.ctxt() == ctxt
-            && expr1.span.ctxt() == ctxt
+            && cond.span.ctxt() == ctxt
             && clippy_utils::SpanlessEq::new(cx).eq_expr(l, target)
             && AssignOpKind::AddAssign == op1.node
             && let ExprKind::Lit(lit) = value.kind
diff --git a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
index b54c289fa7e..e79fcec6e6a 100644
--- a/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
+++ b/src/tools/clippy/clippy_lints/src/infallible_try_from.rs
@@ -1,8 +1,9 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::sym;
 use rustc_errors::MultiSpan;
-use rustc_hir::{AssocItemKind, Item, ItemKind};
+use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::AssocTag;
 use rustc_session::declare_lint_pass;
 
 declare_clippy_lint! {
@@ -51,25 +52,23 @@ impl<'tcx> LateLintPass<'tcx> for InfallibleTryFrom {
         if !cx.tcx.is_diagnostic_item(sym::TryFrom, trait_def_id) {
             return;
         }
-        for ii in imp.items {
-            if ii.kind == AssocItemKind::Type {
-                let ii = cx.tcx.hir_impl_item(ii.id);
-                if ii.ident.name != sym::Error {
-                    continue;
-                }
-                let ii_ty = ii.expect_type();
-                let ii_ty_span = ii_ty.span;
-                let ii_ty = clippy_utils::ty::ty_from_hir_ty(cx, ii_ty);
-                if !ii_ty.is_inhabited_from(cx.tcx, ii.owner_id.to_def_id(), cx.typing_env()) {
-                    let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id()));
-                    span.push_span_label(ii_ty_span, "infallible error type");
-                    span_lint(
-                        cx,
-                        INFALLIBLE_TRY_FROM,
-                        span,
-                        "infallible TryFrom impl; consider implementing From, instead",
-                    );
-                }
+        for ii in cx.tcx.associated_items(item.owner_id.def_id)
+            .filter_by_name_unhygienic_and_kind(sym::Error, AssocTag::Type)
+        {
+            let ii_ty = cx.tcx.type_of(ii.def_id).instantiate_identity();
+            if !ii_ty.is_inhabited_from(cx.tcx, ii.def_id, cx.typing_env()) {
+                let mut span = MultiSpan::from_span(cx.tcx.def_span(item.owner_id.to_def_id()));
+                let ii_ty_span = cx.tcx.hir_node_by_def_id(ii.def_id.expect_local())
+                    .expect_impl_item()
+                    .expect_type()
+                    .span;
+                span.push_span_label(ii_ty_span, "infallible error type");
+                span_lint(
+                    cx,
+                    INFALLIBLE_TRY_FROM,
+                    span,
+                    "infallible TryFrom impl; consider implementing From, instead",
+                );
             }
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
index 900b20aa9cf..03038f0ab49 100644
--- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -139,13 +139,12 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
                 // We can't check inherent impls for slices, but we know that they have an `iter(_mut)` method
                 ty.peel_refs().is_slice() || get_adt_inherent_method(cx, ty, expected_method_name).is_some()
             })
-            && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| {
-                if item.ident.name == sym::IntoIter {
-                    Some(cx.tcx.hir_impl_item(item.id).expect_type().span)
-                } else {
-                    None
-                }
-            })
+            && let Some(iter_assoc_span) = cx.tcx.associated_items(item.owner_id)
+                .filter_by_name_unhygienic_and_kind(sym::IntoIter, ty::AssocTag::Type)
+                .next()
+                .map(|assoc_item| {
+                    cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item().expect_type().span
+                })
             && is_ty_exported(cx, ty)
         {
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index aded31971ce..1bf03480c82 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -10,14 +10,15 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::{
-    AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind,
+    BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, HirId, ImplItem, ImplItemKind,
     ImplicitSelfKind, Item, ItemKind, Mutability, Node, OpaqueTyOrigin, PatExprKind, PatKind, PathSegment, PrimTy,
-    QPath, TraitItemRef, TyKind,
+    QPath, TraitItemId, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, FnSig, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
+use rustc_span::symbol::kw;
 use rustc_span::{Ident, Span, Symbol};
 use rustc_trait_selection::traits::supertrait_def_ids;
 
@@ -124,7 +125,7 @@ declare_lint_pass!(LenZero => [LEN_ZERO, LEN_WITHOUT_IS_EMPTY, COMPARISON_TO_EMP
 
 impl<'tcx> LateLintPass<'tcx> for LenZero {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
-        if let ItemKind::Trait(_, _, ident, _, _, trait_items) = item.kind
+        if let ItemKind::Trait(_, _, _, ident, _, _, trait_items) = item.kind
             && !item.span.from_expansion()
         {
             check_trait_items(cx, item, ident, trait_items);
@@ -264,22 +265,13 @@ fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
     }
 }
 
-fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemRef]) {
-    fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
-        item.ident.name == name
-            && if let AssocItemKind::Fn { has_self } = item.kind {
-                has_self && {
-                    cx.tcx
-                        .fn_sig(item.id.owner_id)
-                        .skip_binder()
-                        .inputs()
-                        .skip_binder()
-                        .len()
-                        == 1
-                }
-            } else {
-                false
-            }
+fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, ident: Ident, trait_items: &[TraitItemId]) {
+    fn is_named_self(cx: &LateContext<'_>, item: &TraitItemId, name: Symbol) -> bool {
+        cx.tcx.item_name(item.owner_id) == name
+            && matches!(
+                cx.tcx.fn_arg_idents(item.owner_id),
+                [Some(Ident { name: kw::SelfLower, .. })],
+            )
     }
 
     // fill the set with current and super traits
diff --git a/src/tools/clippy/clippy_lints/src/let_if_seq.rs b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
index 5db28e9ae9b..e480c8fbed5 100644
--- a/src/tools/clippy/clippy_lints/src/let_if_seq.rs
+++ b/src/tools/clippy/clippy_lints/src/let_if_seq.rs
@@ -62,15 +62,8 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq {
             if let hir::StmtKind::Let(local) = stmt.kind
                 && let hir::PatKind::Binding(mode, canonical_id, ident, None) = local.pat.kind
                 && let hir::StmtKind::Expr(if_) = next.kind
-                && let hir::ExprKind::If(
-                    hir::Expr {
-                        kind: hir::ExprKind::DropTemps(cond),
-                        ..
-                    },
-                    then,
-                    else_,
-                ) = if_.kind
-                && !is_local_used(cx, *cond, canonical_id)
+                && let hir::ExprKind::If(cond, then, else_) = if_.kind
+                && !is_local_used(cx, cond, canonical_id)
                 && let hir::ExprKind::Block(then, _) = then.kind
                 && let Some(value) = check_assign(cx, canonical_id, then)
                 && !is_local_used(cx, value, canonical_id)
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index caf17c10484..35c9d2fd4eb 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -716,7 +716,7 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
         walk_trait_ref(&mut checker, trait_ref);
     }
     walk_unambig_ty(&mut checker, impl_.self_ty);
-    for item in impl_.items {
+    for &item in impl_.items {
         walk_impl_item_ref(&mut checker, item);
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs b/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs
index 823cf0f4322..e809987d75a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/empty_loop.rs
@@ -1,11 +1,22 @@
 use super::EMPTY_LOOP;
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::{is_in_panic_handler, is_no_std_crate};
+use clippy_utils::{is_in_panic_handler, is_no_std_crate, sym};
 
-use rustc_hir::{Block, Expr};
+use rustc_hir::{Block, Expr, ItemKind, Node};
 use rustc_lint::LateContext;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, loop_block: &Block<'_>) {
+    let parent_hir_id = cx.tcx.parent_hir_id(expr.hir_id);
+    if let Node::Item(parent_node) = cx.tcx.hir_node(parent_hir_id)
+        && matches!(parent_node.kind, ItemKind::Fn { .. })
+        && let attrs = cx.tcx.hir_attrs(parent_hir_id)
+        && attrs.iter().any(|attr| attr.has_name(sym::rustc_intrinsic))
+    {
+        // Intrinsic functions are expanded into an empty loop when lowering the AST
+        // to simplify the job of later passes which might expect any function to have a body.
+        return;
+    }
+
     if loop_block.stmts.is_empty() && loop_block.expr.is_none() && !is_in_panic_handler(cx, expr) {
         let msg = "empty `loop {}` wastes CPU cycles";
         let help = if is_no_std_crate(cx) {
diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
index 9ff82cdcb66..1f9a943f13d 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -245,17 +245,36 @@ fn replace_in_pattern(
         }
 
         match pat.kind {
-            PatKind::Binding(_ann, _id, binding_name, opt_subpt) => {
-                let Some((pat_to_put, binding_mode)) = ident_map.get(&binding_name.name) else {
-                    break 'a;
-                };
-                let sn_pfx = binding_mode.prefix_str();
-                let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
-                if let Some(subpt) = opt_subpt {
-                    let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);
-                    return format!("{sn_pfx}{sn_ptp} @ {subpt}");
+            PatKind::Binding(ann, _id, binding_name, opt_subpt) => {
+                match (ident_map.get(&binding_name.name), opt_subpt) {
+                    (Some((pat_to_put, binding_mode)), opt_subpt) => {
+                        let sn_pfx = binding_mode.prefix_str();
+                        let (sn_ptp, _) = snippet_with_context(cx, pat_to_put.span, span.ctxt(), "", app);
+                        if let Some(subpt) = opt_subpt {
+                            let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);
+                            return format!("{sn_pfx}{sn_ptp} @ {subpt}");
+                        }
+                        return format!("{sn_pfx}{sn_ptp}");
+                    },
+                    (None, Some(subpt)) => {
+                        let subpt = replace_in_pattern(cx, span, ident_map, subpt, app, false);
+                        // scanning for a value that matches is not sensitive to order
+                        #[expect(rustc::potential_query_instability)]
+                        if ident_map.values().any(|(other_pat, _)| {
+                            if let PatKind::Binding(_, _, other_name, _) = other_pat.kind {
+                                other_name == binding_name
+                            } else {
+                                false
+                            }
+                        }) {
+                            // this name is shadowed, and, therefore, not usable
+                            return subpt;
+                        }
+                        let binding_pfx = ann.prefix_str();
+                        return format!("{binding_pfx}{binding_name} @ {subpt}");
+                    },
+                    (None, None) => break 'a,
                 }
-                return format!("{sn_pfx}{sn_ptp}");
             },
             PatKind::Or(pats) => {
                 let patterns = pats
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 51696b38880..2d52a93f34e 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -4,16 +4,15 @@ use clippy_utils::is_doc_hidden;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_indent;
 use itertools::Itertools;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
 use rustc_hir::{Expr, ExprKind, Item, ItemKind, QPath, TyKind, VariantData};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
-use rustc_attr_data_structures::find_attr;
-use rustc_attr_data_structures::AttributeKind;
+use rustc_span::def_id::LocalDefId;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index ede68f30941..ae277da089f 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -332,9 +332,7 @@ impl<'a> NormalizedPat<'a> {
                 // TODO: Handle negative integers. They're currently treated as a wild match.
                 PatExprKind::Lit { lit, negated: false } => match lit.node {
                     LitKind::Str(sym, _) => Self::LitStr(sym),
-                    LitKind::ByteStr(byte_sym, _) | LitKind::CStr(byte_sym, _) => {
-                        Self::LitBytes(byte_sym)
-                    }
+                    LitKind::ByteStr(byte_sym, _) | LitKind::CStr(byte_sym, _) => Self::LitBytes(byte_sym),
                     LitKind::Byte(val) => Self::LitInt(val.into()),
                     LitKind::Char(val) => Self::LitInt(val.into()),
                     LitKind::Int(val, _) => Self::LitInt(val.get()),
diff --git a/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs b/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs
index 045363058d1..d664eaaac70 100644
--- a/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/from_iter_instead_of_collect.rs
@@ -4,6 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{is_path_diagnostic_item, sugg};
+use rustc_ast::join_path_idents;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{self as hir, Expr, ExprKind, GenericArg, QPath, TyKind};
@@ -47,7 +48,7 @@ fn build_full_type(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, app: &mut Applica
         && let QPath::Resolved(None, ty_path) = &ty_qpath
         && let Res::Def(_, ty_did) = ty_path.res
     {
-        let mut ty_str = itertools::join(ty_path.segments.iter().map(|s| s.ident), "::");
+        let mut ty_str = join_path_idents(ty_path.segments.iter().map(|seg| seg.ident));
         let mut first = true;
         let mut append = |arg: &str| {
             write!(&mut ty_str, "{}{arg}", [", ", "<"][usize::from(first)]).unwrap();
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
index 4a61c223d2c..93325ca488e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_is_variant_and.rs
@@ -1,14 +1,16 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::get_parent_expr;
 use clippy_utils::msrvs::{self, Msrv};
-use clippy_utils::source::{snippet, snippet_opt};
+use clippy_utils::source::{snippet, snippet_with_applicability};
+use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::{get_parent_expr, sym};
+use rustc_ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
-use rustc_hir::{BinOpKind, Expr, ExprKind, QPath};
+use rustc_hir::{BinOpKind, Closure, Expr, ExprKind, QPath};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::{BytePos, Span, sym};
+use rustc_span::{Span, Symbol};
 
 use super::MANUAL_IS_VARIANT_AND;
 
@@ -62,54 +64,154 @@ pub(super) fn check(
     );
 }
 
-fn emit_lint(cx: &LateContext<'_>, op: BinOpKind, parent: &Expr<'_>, method_span: Span, is_option: bool) {
-    if let Some(before_map_snippet) = snippet_opt(cx, parent.span.with_hi(method_span.lo()))
-        && let Some(after_map_snippet) = snippet_opt(cx, method_span.with_lo(method_span.lo() + BytePos(3)))
-    {
-        span_lint_and_sugg(
-            cx,
-            MANUAL_IS_VARIANT_AND,
-            parent.span,
-            format!(
-                "called `.map() {}= {}()`",
-                if op == BinOpKind::Eq { '=' } else { '!' },
-                if is_option { "Some" } else { "Ok" },
-            ),
-            "use",
-            if is_option && op == BinOpKind::Ne {
-                format!("{before_map_snippet}is_none_or{after_map_snippet}",)
-            } else {
+#[derive(Clone, Copy, PartialEq)]
+enum Flavor {
+    Option,
+    Result,
+}
+
+impl Flavor {
+    const fn symbol(self) -> Symbol {
+        match self {
+            Self::Option => sym::Option,
+            Self::Result => sym::Result,
+        }
+    }
+
+    const fn positive(self) -> Symbol {
+        match self {
+            Self::Option => sym::Some,
+            Self::Result => sym::Ok,
+        }
+    }
+}
+
+#[derive(Clone, Copy, PartialEq)]
+enum Op {
+    Eq,
+    Ne,
+}
+
+impl std::fmt::Display for Op {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::Eq => write!(f, "=="),
+            Self::Ne => write!(f, "!="),
+        }
+    }
+}
+
+impl TryFrom<BinOpKind> for Op {
+    type Error = ();
+    fn try_from(op: BinOpKind) -> Result<Self, Self::Error> {
+        match op {
+            BinOpKind::Eq => Ok(Self::Eq),
+            BinOpKind::Ne => Ok(Self::Ne),
+            _ => Err(()),
+        }
+    }
+}
+
+/// Represents the argument of the `.map()` function, as a closure or as a path
+/// in case η-reduction is used.
+enum MapFunc<'hir> {
+    Closure(&'hir Closure<'hir>),
+    Path(&'hir Expr<'hir>),
+}
+
+impl<'hir> TryFrom<&'hir Expr<'hir>> for MapFunc<'hir> {
+    type Error = ();
+
+    fn try_from(expr: &'hir Expr<'hir>) -> Result<Self, Self::Error> {
+        match expr.kind {
+            ExprKind::Closure(closure) => Ok(Self::Closure(closure)),
+            ExprKind::Path(_) => Ok(Self::Path(expr)),
+            _ => Err(()),
+        }
+    }
+}
+
+impl<'hir> MapFunc<'hir> {
+    /// Build a suggestion suitable for use in a `.map()`-like function. η-expansion will be applied
+    /// as needed.
+    fn sugg(self, cx: &LateContext<'hir>, invert: bool, app: &mut Applicability) -> String {
+        match self {
+            Self::Closure(closure) => {
+                let body = Sugg::hir_with_applicability(cx, cx.tcx.hir_body(closure.body).value, "..", app);
                 format!(
-                    "{}{before_map_snippet}{}{after_map_snippet}",
-                    if op == BinOpKind::Eq { "" } else { "!" },
-                    if is_option { "is_some_and" } else { "is_ok_and" },
+                    "{} {}",
+                    snippet_with_applicability(cx, closure.fn_decl_span, "|..|", app),
+                    if invert { !body } else { body }
                 )
             },
-            Applicability::MachineApplicable,
-        );
+            Self::Path(expr) => {
+                let path = snippet_with_applicability(cx, expr.span, "_", app);
+                if invert {
+                    format!("|x| !{path}(x)")
+                } else {
+                    path.to_string()
+                }
+            },
+        }
     }
 }
 
+fn emit_lint<'tcx>(
+    cx: &LateContext<'tcx>,
+    span: Span,
+    op: Op,
+    flavor: Flavor,
+    in_some_or_ok: bool,
+    map_func: MapFunc<'tcx>,
+    recv: &Expr<'_>,
+) {
+    let mut app = Applicability::MachineApplicable;
+    let recv = snippet_with_applicability(cx, recv.span, "_", &mut app);
+
+    let (invert_expr, method, invert_body) = match (flavor, op) {
+        (Flavor::Option, Op::Eq) => (false, "is_some_and", !in_some_or_ok),
+        (Flavor::Option, Op::Ne) => (false, "is_none_or", in_some_or_ok),
+        (Flavor::Result, Op::Eq) => (false, "is_ok_and", !in_some_or_ok),
+        (Flavor::Result, Op::Ne) => (true, "is_ok_and", !in_some_or_ok),
+    };
+    span_lint_and_sugg(
+        cx,
+        MANUAL_IS_VARIANT_AND,
+        span,
+        format!("called `.map() {op} {pos}()`", pos = flavor.positive(),),
+        "use",
+        format!(
+            "{inversion}{recv}.{method}({body})",
+            inversion = if invert_expr { "!" } else { "" },
+            body = map_func.sugg(cx, invert_body, &mut app),
+        ),
+        app,
+    );
+}
+
 pub(super) fn check_map(cx: &LateContext<'_>, expr: &Expr<'_>) {
     if let Some(parent_expr) = get_parent_expr(cx, expr)
         && let ExprKind::Binary(op, left, right) = parent_expr.kind
-        && matches!(op.node, BinOpKind::Eq | BinOpKind::Ne)
         && op.span.eq_ctxt(expr.span)
+        && let Ok(op) = Op::try_from(op.node)
     {
         // Check `left` and `right` expression in any order, and for `Option` and `Result`
         for (expr1, expr2) in [(left, right), (right, left)] {
-            for item in [sym::Option, sym::Result] {
-                if let ExprKind::Call(call, ..) = expr1.kind
+            for flavor in [Flavor::Option, Flavor::Result] {
+                if let ExprKind::Call(call, [arg]) = expr1.kind
+                    && let ExprKind::Lit(lit) = arg.kind
+                    && let LitKind::Bool(bool_cst) = lit.node
                     && let ExprKind::Path(QPath::Resolved(_, path)) = call.kind
                     && let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), _) = path.res
                     && let ty = cx.typeck_results().expr_ty(expr1)
                     && let ty::Adt(adt, args) = ty.kind()
-                    && cx.tcx.is_diagnostic_item(item, adt.did())
+                    && cx.tcx.is_diagnostic_item(flavor.symbol(), adt.did())
                     && args.type_at(0).is_bool()
-                    && let ExprKind::MethodCall(_, recv, _, span) = expr2.kind
-                    && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), item)
+                    && let ExprKind::MethodCall(_, recv, [map_expr], _) = expr2.kind
+                    && is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), flavor.symbol())
+                    && let Ok(map_func) = MapFunc::try_from(map_expr)
                 {
-                    return emit_lint(cx, op.node, parent_expr, span, item == sym::Option);
+                    return emit_lint(cx, parent_expr.span, op, flavor, bool_cst, map_func, recv);
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 2139466ce74..6ce7dd3d4d0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -136,7 +136,7 @@ pub(super) fn check<'tcx>(
         fun_span: Option<Span>,
     ) -> bool {
         // (path, fn_has_argument, methods, suffix)
-        const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 5] = [
+        const KNOW_TYPES: [(Symbol, bool, &[Symbol], &str); 7] = [
             (sym::BTreeEntry, false, &[sym::or_insert], "with"),
             (sym::HashMapEntry, false, &[sym::or_insert], "with"),
             (
@@ -146,7 +146,9 @@ pub(super) fn check<'tcx>(
                 "else",
             ),
             (sym::Option, false, &[sym::get_or_insert], "with"),
+            (sym::Option, true, &[sym::and], "then"),
             (sym::Result, true, &[sym::map_or, sym::or, sym::unwrap_or], "else"),
+            (sym::Result, true, &[sym::and], "then"),
         ];
 
         if KNOW_TYPES.iter().any(|k| k.2.contains(&name))
diff --git a/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
index df8544f9220..54f38a322b8 100644
--- a/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/return_and_then.rs
@@ -1,5 +1,5 @@
 use rustc_errors::Applicability;
-use rustc_hir as hir;
+use rustc_hir::{self as hir, Node};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, GenericArg, Ty};
 use rustc_span::sym;
@@ -9,7 +9,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{indent_of, reindent_multiline, snippet_with_applicability};
 use clippy_utils::ty::get_type_diagnostic_name;
 use clippy_utils::visitors::for_each_unconsumed_temporary;
-use clippy_utils::{get_parent_expr, peel_blocks};
+use clippy_utils::{peel_blocks, potential_return_of_enclosing_body};
 
 use super::RETURN_AND_THEN;
 
@@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
     recv: &'tcx hir::Expr<'tcx>,
     arg: &'tcx hir::Expr<'_>,
 ) {
-    if cx.tcx.hir_get_fn_id_for_return_block(expr.hir_id).is_none() {
+    if !potential_return_of_enclosing_body(cx, expr) {
         return;
     }
 
@@ -55,15 +55,28 @@ pub(super) fn check<'tcx>(
         None => &body_snip,
     };
 
-    // If suggestion is going to get inserted as part of a `return` expression, it must be blockified.
-    let sugg = if let Some(parent_expr) = get_parent_expr(cx, expr) {
-        let base_indent = indent_of(cx, parent_expr.span);
+    // If suggestion is going to get inserted as part of a `return` expression or as a match expression
+    // arm, it must be blockified.
+    let (parent_span_for_indent, opening_paren, closing_paren) = match cx.tcx.parent_hir_node(expr.hir_id) {
+        Node::Expr(parent_expr) if matches!(parent_expr.kind, hir::ExprKind::Break(..)) => {
+            (Some(parent_expr.span), "(", ")")
+        },
+        Node::Expr(parent_expr) => (Some(parent_expr.span), "", ""),
+        Node::Arm(match_arm) => (Some(match_arm.span), "", ""),
+        _ => (None, "", ""),
+    };
+    let sugg = if let Some(span) = parent_span_for_indent {
+        let base_indent = indent_of(cx, span);
         let inner_indent = base_indent.map(|i| i + 4);
         format!(
             "{}\n{}\n{}",
-            reindent_multiline(&format!("{{\nlet {arg_snip} = {recv_snip}?;"), true, inner_indent),
+            reindent_multiline(
+                &format!("{opening_paren}{{\nlet {arg_snip} = {recv_snip}?;"),
+                true,
+                inner_indent
+            ),
             reindent_multiline(inner, false, inner_indent),
-            reindent_multiline("}", false, base_indent),
+            reindent_multiline(&format!("}}{closing_paren}"), false, base_indent),
         )
     } else {
         format!(
diff --git a/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs b/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs
index de729fb343a..e378cbd6ae0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/swap_with_temporary.rs
@@ -4,6 +4,7 @@ use rustc_ast::BorrowKind;
 use rustc_errors::{Applicability, Diag};
 use rustc_hir::{Expr, ExprKind, Node, QPath};
 use rustc_lint::LateContext;
+use rustc_middle::ty::adjustment::Adjust;
 use rustc_span::sym;
 
 use super::SWAP_WITH_TEMPORARY;
@@ -11,12 +12,12 @@ use super::SWAP_WITH_TEMPORARY;
 const MSG_TEMPORARY: &str = "this expression returns a temporary value";
 const MSG_TEMPORARY_REFMUT: &str = "this is a mutable reference to a temporary value";
 
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>]) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, func: &Expr<'_>, args: &'tcx [Expr<'_>]) {
     if let ExprKind::Path(QPath::Resolved(_, func_path)) = func.kind
         && let Some(func_def_id) = func_path.res.opt_def_id()
         && cx.tcx.is_diagnostic_item(sym::mem_swap, func_def_id)
     {
-        match (ArgKind::new(&args[0]), ArgKind::new(&args[1])) {
+        match (ArgKind::new(cx, &args[0]), ArgKind::new(cx, &args[1])) {
             (ArgKind::RefMutToTemp(left_temp), ArgKind::RefMutToTemp(right_temp)) => {
                 emit_lint_useless(cx, expr, &args[0], &args[1], left_temp, right_temp);
             },
@@ -28,10 +29,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args
 }
 
 enum ArgKind<'tcx> {
-    // Mutable reference to a place, coming from a macro
-    RefMutToPlaceAsMacro(&'tcx Expr<'tcx>),
-    // Place behind a mutable reference
-    RefMutToPlace(&'tcx Expr<'tcx>),
+    // Mutable reference to a place, coming from a macro, and number of dereferences to use
+    RefMutToPlaceAsMacro(&'tcx Expr<'tcx>, usize),
+    // Place behind a mutable reference, and number of dereferences to use
+    RefMutToPlace(&'tcx Expr<'tcx>, usize),
     // Temporary value behind a mutable reference
     RefMutToTemp(&'tcx Expr<'tcx>),
     // Any other case
@@ -39,13 +40,29 @@ enum ArgKind<'tcx> {
 }
 
 impl<'tcx> ArgKind<'tcx> {
-    fn new(arg: &'tcx Expr<'tcx>) -> Self {
-        if let ExprKind::AddrOf(BorrowKind::Ref, _, target) = arg.kind {
-            if target.is_syntactic_place_expr() {
+    /// Build a new `ArgKind` from `arg`. There must be no false positive when returning a
+    /// `ArgKind::RefMutToTemp` variant, as this may cause a spurious lint to be emitted.
+    fn new(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Self {
+        if let ExprKind::AddrOf(BorrowKind::Ref, _, target) = arg.kind
+            && let adjustments = cx.typeck_results().expr_adjustments(arg)
+            && adjustments
+                .first()
+                .is_some_and(|adj| matches!(adj.kind, Adjust::Deref(None)))
+            && adjustments
+                .last()
+                .is_some_and(|adj| matches!(adj.kind, Adjust::Borrow(_)))
+        {
+            let extra_derefs = adjustments[1..adjustments.len() - 1]
+                .iter()
+                .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
+                .count();
+            // If a deref is used, `arg` might be a place expression. For example, a mutex guard
+            // would dereference into the mutex content which is probably not temporary.
+            if target.is_syntactic_place_expr() || extra_derefs > 0 {
                 if arg.span.from_expansion() {
-                    ArgKind::RefMutToPlaceAsMacro(arg)
+                    ArgKind::RefMutToPlaceAsMacro(arg, extra_derefs)
                 } else {
-                    ArgKind::RefMutToPlace(target)
+                    ArgKind::RefMutToPlace(target, extra_derefs)
                 }
             } else {
                 ArgKind::RefMutToTemp(target)
@@ -106,10 +123,15 @@ fn emit_lint_assign(cx: &LateContext<'_>, expr: &Expr<'_>, target: &ArgKind<'_>,
                 let mut applicability = Applicability::MachineApplicable;
                 let ctxt = expr.span.ctxt();
                 let assign_target = match target {
-                    ArgKind::Expr(target) | ArgKind::RefMutToPlaceAsMacro(target) => {
-                        Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability).deref()
-                    },
-                    ArgKind::RefMutToPlace(target) => Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability),
+                    ArgKind::Expr(target) => Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability).deref(),
+                    ArgKind::RefMutToPlaceAsMacro(arg, derefs) => (0..*derefs).fold(
+                        Sugg::hir_with_context(cx, arg, ctxt, "_", &mut applicability).deref(),
+                        |sugg, _| sugg.deref(),
+                    ),
+                    ArgKind::RefMutToPlace(target, derefs) => (0..*derefs).fold(
+                        Sugg::hir_with_context(cx, target, ctxt, "_", &mut applicability),
+                        |sugg, _| sugg.deref(),
+                    ),
                     ArgKind::RefMutToTemp(_) => unreachable!(),
                 };
                 let assign_source = Sugg::hir_with_context(cx, temp, ctxt, "_", &mut applicability);
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
index b90748dd158..4a9007c607c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_map_or.rs
@@ -62,7 +62,8 @@ pub(super) fn check<'a>(
 
     let ext_def_span = def.span.until(map.span);
 
-    let (sugg, method, applicability) = if let ExprKind::Closure(map_closure) = map.kind
+    let (sugg, method, applicability) = if cx.typeck_results().expr_adjustments(recv).is_empty()
+            && let ExprKind::Closure(map_closure) = map.kind
             && let closure_body = cx.tcx.hir_body(map_closure.body)
             && let closure_body_value = closure_body.value.peel_blocks()
             && let ExprKind::Binary(op, l, r) = closure_body_value.kind
diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
index d4d33029dbd..760ecf07589 100644
--- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
@@ -8,7 +8,7 @@ use rustc_ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    Block, Expr, ExprKind, Impl, ImplItem, ImplItemKind, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData,
+    Block, Expr, ExprKind, Impl, Item, ItemKind, LangItem, Node, QPath, TyKind, VariantData,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{Ty, TypeckResults};
@@ -200,7 +200,7 @@ fn check_struct<'tcx>(
 impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         // is this an `impl Debug for X` block?
-        if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind
+        if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, .. }) = item.kind
             && let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res
             && let TyKind::Path(QPath::Resolved(_, self_path)) = &self_ty.kind
             // make sure that the self type is either a struct, an enum or a union
@@ -212,9 +212,8 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
             && !cx.tcx.is_automatically_derived(item.owner_id.to_def_id())
             && !item.span.from_expansion()
             // find `Debug::fmt` function
-            && let Some(fmt_item) = items.iter().find(|i| i.ident.name == sym::fmt)
-            && let ImplItem { kind: ImplItemKind::Fn(_, body_id), .. } = cx.tcx.hir_impl_item(fmt_item.id)
-            && let body = cx.tcx.hir_body(*body_id)
+            && let Some(fmt_item) = cx.tcx.associated_items(item.owner_id).filter_by_name_unhygienic(sym::fmt).next()
+            && let body = cx.tcx.hir_body_owned_by(fmt_item.def_id.expect_local())
             && let ExprKind::Block(block, _) = body.value.kind
             // inspect `self`
             && let self_ty = cx.tcx.type_of(self_path_did).skip_binder().peel_refs()
@@ -222,7 +221,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
             && let Some(self_def_id) = self_adt.did().as_local()
             && let Node::Item(self_item) = cx.tcx.hir_node_by_def_id(self_def_id)
             // NB: can't call cx.typeck_results() as we are not in a body
-            && let typeck_results = cx.tcx.typeck_body(*body_id)
+            && let typeck_results = cx.tcx.typeck_body(body.id())
             && should_lint(cx, typeck_results, block)
             // we intentionally only lint structs, see lint description
             && let ItemKind::Struct(_, _, data) = &self_item.kind
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 25c95d23436..c4a3d10299b 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -101,19 +101,19 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
                 let attrs = cx.tcx.hir_attrs(it.hir_id());
                 check_missing_inline_attrs(cx, attrs, it.span, desc);
             },
-            hir::ItemKind::Trait(ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => {
+            hir::ItemKind::Trait(ref _constness, ref _is_auto, ref _unsafe, _ident, _generics, _bounds, trait_items) => {
                 // note: we need to check if the trait is exported so we can't use
                 // `LateLintPass::check_trait_item` here.
-                for tit in trait_items {
-                    let tit_ = cx.tcx.hir_trait_item(tit.id);
+                for &tit in trait_items {
+                    let tit_ = cx.tcx.hir_trait_item(tit);
                     match tit_.kind {
                         hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
                         hir::TraitItemKind::Fn(..) => {
-                            if cx.tcx.defaultness(tit.id.owner_id).has_value() {
+                            if cx.tcx.defaultness(tit.owner_id).has_value() {
                                 // trait method with default body needs inline in case
                                 // an impl is not provided
                                 let desc = "a default trait method";
-                                let item = cx.tcx.hir_trait_item(tit.id);
+                                let item = cx.tcx.hir_trait_item(tit);
                                 let attrs = cx.tcx.hir_attrs(item.hir_id());
                                 check_missing_inline_attrs(cx, attrs, item.span, desc);
                             }
diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
index e266c36b6e7..fa61d0fa11a 100644
--- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
@@ -61,15 +61,14 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
         if !is_lint_allowed(cx, MISSING_TRAIT_METHODS, item.hir_id())
             && span_is_local(item.span)
             && let ItemKind::Impl(Impl {
-                items,
                 of_trait: Some(trait_ref),
                 ..
             }) = item.kind
             && let Some(trait_id) = trait_ref.trait_def_id()
         {
-            let trait_item_ids: DefIdSet = items
-                .iter()
-                .filter_map(|impl_item| impl_item.trait_item_def_id)
+            let trait_item_ids: DefIdSet = cx.tcx.associated_items(item.owner_id)
+                .in_definition_order()
+                .filter_map(|assoc_item| assoc_item.trait_item_def_id)
                 .collect();
 
             for assoc in cx
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index 3ed4b1c2ea9..b3aa1a7286a 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -199,11 +199,16 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
                 let mut applicability = Applicability::MachineApplicable;
                 let cond = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability);
                 let lhs = snippet_with_applicability(cx, lhs_a.span, "..", &mut applicability);
-                let sugg = if a == b {
+                let mut sugg = if a == b {
                     format!("{cond}; {lhs} = {a:?};")
                 } else {
                     format!("{lhs} = {};", if a { cond } else { !cond })
                 };
+
+                if is_else_clause(cx.tcx, e) {
+                    sugg = format!("{{ {sugg} }}");
+                }
+
                 span_lint_and_sugg(
                     cx,
                     NEEDLESS_BOOL_ASSIGN,
diff --git a/src/tools/clippy/clippy_lints/src/neg_multiply.rs b/src/tools/clippy/clippy_lints/src/neg_multiply.rs
index 442280f9998..946114e1041 100644
--- a/src/tools/clippy/clippy_lints/src/neg_multiply.rs
+++ b/src/tools/clippy/clippy_lints/src/neg_multiply.rs
@@ -1,13 +1,13 @@
 use clippy_utils::consts::{self, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet_with_context;
+use clippy_utils::get_parent_expr;
+use clippy_utils::source::{snippet, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::Span;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -33,6 +33,19 @@ declare_clippy_lint! {
 
 declare_lint_pass!(NegMultiply => [NEG_MULTIPLY]);
 
+fn is_in_parens_with_postfix(cx: &LateContext<'_>, mul_expr: &Expr<'_>) -> bool {
+    if let Some(parent) = get_parent_expr(cx, mul_expr) {
+        let mult_snippet = snippet(cx, mul_expr.span, "");
+        if has_enclosing_paren(&mult_snippet)
+            && let ExprKind::MethodCall(_, _, _, _) = parent.kind
+        {
+            return true;
+        }
+    }
+
+    false
+}
+
 impl<'tcx> LateLintPass<'tcx> for NegMultiply {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if let ExprKind::Binary(ref op, left, right) = e.kind
@@ -40,15 +53,15 @@ impl<'tcx> LateLintPass<'tcx> for NegMultiply {
         {
             match (&left.kind, &right.kind) {
                 (&ExprKind::Unary(..), &ExprKind::Unary(..)) => {},
-                (&ExprKind::Unary(UnOp::Neg, lit), _) => check_mul(cx, e.span, lit, right),
-                (_, &ExprKind::Unary(UnOp::Neg, lit)) => check_mul(cx, e.span, lit, left),
+                (&ExprKind::Unary(UnOp::Neg, lit), _) => check_mul(cx, e, lit, right),
+                (_, &ExprKind::Unary(UnOp::Neg, lit)) => check_mul(cx, e, lit, left),
                 _ => {},
             }
         }
     }
 }
 
-fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
+fn check_mul(cx: &LateContext<'_>, mul_expr: &Expr<'_>, lit: &Expr<'_>, exp: &Expr<'_>) {
     const F16_ONE: u16 = 1.0_f16.to_bits();
     const F128_ONE: u128 = 1.0_f128.to_bits();
     if let ExprKind::Lit(l) = lit.kind
@@ -63,8 +76,19 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
         && cx.typeck_results().expr_ty(exp).is_numeric()
     {
         let mut applicability = Applicability::MachineApplicable;
-        let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability);
-        let suggestion = if !from_macro && cx.precedence(exp) < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
+        let (snip, from_macro) = snippet_with_context(cx, exp.span, mul_expr.span.ctxt(), "..", &mut applicability);
+
+        let needs_parens_for_postfix = is_in_parens_with_postfix(cx, mul_expr);
+
+        let suggestion = if needs_parens_for_postfix {
+            // Special case: when the multiplication is in parentheses followed by a method call
+            // we need to preserve the grouping but negate the inner expression.
+            // Consider this expression: `((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0)`
+            // We need to end up with: `(-(a.delta - 0.5).abs()).total_cmp(&1.0)`
+            // Otherwise, without the parentheses we would try to negate an Ordering:
+            // `-(a.delta - 0.5).abs().total_cmp(&1.0)`
+            format!("(-{snip})")
+        } else if !from_macro && cx.precedence(exp) < ExprPrecedence::Prefix && !has_enclosing_paren(&snip) {
             format!("-({snip})")
         } else {
             format!("-{snip}")
@@ -72,7 +96,7 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
         span_lint_and_sugg(
             cx,
             NEG_MULTIPLY,
-            span,
+            mul_expr.span,
             "this multiplication by -1 can be written more succinctly",
             "consider using",
             suggestion,
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index 4b73a4455f5..3b86f1d1f59 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -6,6 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::HirIdSet;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::ty::AssocKind;
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
 
@@ -61,18 +62,18 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
             of_trait: None,
             generics,
             self_ty: impl_self_ty,
-            items,
             ..
         }) = item.kind
         {
-            for assoc_item in *items {
-                if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
-                    let impl_item = cx.tcx.hir_impl_item(assoc_item.id);
+            for assoc_item in cx.tcx.associated_items(item.owner_id.def_id)
+                .filter_by_name_unhygienic(sym::new)
+            {
+                if let AssocKind::Fn { has_self: false, .. } = assoc_item.kind {
+                    let impl_item = cx.tcx.hir_node_by_def_id(assoc_item.def_id.expect_local()).expect_impl_item();
                     if impl_item.span.in_external_macro(cx.sess().source_map()) {
                         return;
                     }
                     if let hir::ImplItemKind::Fn(ref sig, _) = impl_item.kind {
-                        let name = impl_item.ident.name;
                         let id = impl_item.owner_id;
                         if sig.header.is_unsafe() {
                             // can't be implemented for unsafe new
@@ -88,11 +89,9 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                             return;
                         }
                         if sig.decl.inputs.is_empty()
-                            && name == sym::new
                             && cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id)
-                            && let self_def_id = cx.tcx.hir_get_parent_item(id.into())
-                            && let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity()
-                            && self_ty == return_ty(cx, id)
+                            && let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
+                            && self_ty == return_ty(cx, impl_item.owner_id)
                             && let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default)
                         {
                             if self.impling_types.is_none() {
@@ -111,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                             // Check if a Default implementation exists for the Self type, regardless of
                             // generics
                             if let Some(ref impling_types) = self.impling_types
-                                && let self_def = cx.tcx.type_of(self_def_id).instantiate_identity()
+                                && let self_def = cx.tcx.type_of(item.owner_id).instantiate_identity()
                                 && let Some(self_def) = self_def.ty_adt_def()
                                 && let Some(self_local_did) = self_def.did().as_local()
                                 && let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 02c48166131..72e6503e7e4 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::source::SpanRangeExt;
-use clippy_utils::ty::has_drop;
+use clippy_utils::ty::{expr_type_is_certain, has_drop};
 use clippy_utils::{
     in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
 };
@@ -340,11 +340,13 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
         },
         ExprKind::Array(v) | ExprKind::Tup(v) => Some(v.iter().collect()),
         ExprKind::Repeat(inner, _)
-        | ExprKind::Cast(inner, _)
         | ExprKind::Type(inner, _)
         | ExprKind::Unary(_, inner)
         | ExprKind::Field(inner, _)
         | ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])),
+        ExprKind::Cast(inner, _) if expr_type_is_certain(cx, inner) => {
+            reduce_expression(cx, inner).or_else(|| Some(vec![inner]))
+        },
         ExprKind::Struct(_, fields, ref base) => {
             if has_drop(cx, cx.typeck_results().expr_ty(expr)) {
                 None
diff --git a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
index 0faa7b9e646..21e1ab0f4f2 100644
--- a/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/op_ref.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::get_enclosing_block;
-use clippy_utils::source::snippet;
+use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::{implements_trait, is_copy};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
@@ -61,12 +61,13 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of both operands",
                         |diag| {
-                            let lsnip = snippet(cx, l.span, "...").to_string();
-                            let rsnip = snippet(cx, r.span, "...").to_string();
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), "...", &mut applicability);
+                            let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), "...", &mut applicability);
                             diag.multipart_suggestion(
                                 "use the values directly",
-                                vec![(left.span, lsnip), (right.span, rsnip)],
-                                Applicability::MachineApplicable,
+                                vec![(left.span, lsnip.to_string()), (right.span, rsnip.to_string())],
+                                applicability,
                             );
                         },
                     );
@@ -80,13 +81,9 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of left operand",
                         |diag| {
-                            let lsnip = snippet(cx, l.span, "...").to_string();
-                            diag.span_suggestion(
-                                left.span,
-                                "use the left value directly",
-                                lsnip,
-                                Applicability::MachineApplicable,
-                            );
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), "...", &mut applicability);
+                            diag.span_suggestion(left.span, "use the left value directly", lsnip, applicability);
                         },
                     );
                 } else if !lcpy
@@ -99,7 +96,8 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of right operand",
                         |diag| {
-                            let rsnip = snippet(cx, r.span, "...").to_string();
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), "...", &mut applicability);
                             diag.span_suggestion(
                                 right.span,
                                 "use the right value directly",
@@ -131,7 +129,8 @@ pub(crate) fn check<'tcx>(
                         e.span,
                         "needlessly taken reference of left operand",
                         |diag| {
-                            let lsnip = snippet(cx, l.span, "...").to_string();
+                            let mut applicability = Applicability::MachineApplicable;
+                            let (lsnip, _) = snippet_with_context(cx, l.span, e.span.ctxt(), "...", &mut applicability);
                             diag.span_suggestion(
                                 left.span,
                                 "use the left value directly",
@@ -158,7 +157,8 @@ pub(crate) fn check<'tcx>(
                     && implements_trait(cx, cx.typeck_results().expr_ty(left), trait_id, &[rty.into()])
                 {
                     span_lint_and_then(cx, OP_REF, e.span, "taken reference of right operand", |diag| {
-                        let rsnip = snippet(cx, r.span, "...").to_string();
+                        let mut applicability = Applicability::MachineApplicable;
+                        let (rsnip, _) = snippet_with_context(cx, r.span, e.span.ctxt(), "...", &mut applicability);
                         diag.span_suggestion(
                             right.span,
                             "use the right value directly",
diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
index 8eaf65e6306..301b2cd4bf2 100644
--- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs
@@ -43,12 +43,12 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl {
             && trait_ref.path.res.def_id() == eq_trait
         {
             for impl_item in *impl_items {
-                if impl_item.ident.name == sym::ne {
+                if cx.tcx.item_name(impl_item.owner_id) == sym::ne {
                     span_lint_hir(
                         cx,
                         PARTIALEQ_NE_IMPL,
-                        impl_item.id.hir_id(),
-                        impl_item.span,
+                        impl_item.hir_id(),
+                        cx.tcx.def_span(impl_item.owner_id),
                         "re-implementing `PartialEq::ne` is unnecessary",
                     );
                 }
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 84597269a58..1c23fe998ad 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -5,9 +5,7 @@ use hir::Param;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
-use rustc_hir::{
-    ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, Node, intravisit as hir_visit,
-};
+use rustc_hir::{ClosureKind, CoroutineDesugaring, CoroutineKind, CoroutineSource, ExprKind, intravisit as hir_visit};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty;
@@ -198,15 +196,15 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                             hint = hint.asyncify();
                         }
 
-                        let is_in_fn_call_arg = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id) {
-                            matches!(expr.kind, ExprKind::Call(_, _))
-                        } else {
-                            false
-                        };
-
-                        // avoid clippy::double_parens
-                        if !is_in_fn_call_arg {
-                            hint = hint.maybe_paren();
+                        // If the closure body is a block with a single expression, suggest just the inner expression,
+                        // not the block. Example: `(|| { Some(true) })()` should suggest
+                        // `Some(true)`
+                        if let ExprKind::Block(block, _) = body.kind
+                            && block.stmts.is_empty()
+                            && let Some(expr) = block.expr
+                        {
+                            hint = Sugg::hir_with_context(cx, expr, full_expr.span.ctxt(), "..", &mut applicability)
+                                .maybe_paren();
                         }
 
                         diag.span_suggestion(full_expr.span, "try doing something like", hint, applicability);
diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs
index 226e8ff6adb..85fde780e68 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -3,7 +3,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::AssocItem;
+use rustc_middle::ty::{AssocKind, AssocItem};
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
@@ -54,7 +54,6 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
             if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. })
                 && let item = cx.tcx.hir_item(id)
                 && let ItemKind::Impl(Impl {
-                    items,
                     of_trait,
                     self_ty,
                     ..
@@ -115,13 +114,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                             }
                         };
 
-                        for impl_item_ref in (*items)
-                            .iter()
-                            .filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. }))
-                        {
-                            let method_name = impl_item_ref.ident.name;
-                            methods_in_trait.remove(&method_name);
-                            check_trait_method(method_name, impl_item_ref.span);
+                        for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() {
+                            if let AssocKind::Fn { name, .. } = assoc_item.kind {
+                                methods_in_trait.remove(&name);
+                                check_trait_method(name, cx.tcx.def_span(assoc_item.def_id));
+                            }
                         }
 
                         for method_name in methods_in_trait {
@@ -129,14 +126,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                         }
                     },
                     None => {
-                        for impl_item_ref in (*items)
-                            .iter()
-                            .filter(|impl_item_ref| matches!(impl_item_ref.kind, rustc_hir::AssocItemKind::Fn { .. }))
-                        {
-                            let method_name = impl_item_ref.ident.name;
-                            let impl_span = impl_item_ref.span;
-                            let hir_id = impl_item_ref.id.hir_id();
-                            if let Some(trait_spans) = existing_name.trait_methods.get(&method_name) {
+                        for assoc_item in cx.tcx.associated_items(id.owner_id).in_definition_order() {
+                            let AssocKind::Fn { name, .. } = assoc_item.kind else { continue };
+                            let impl_span = cx.tcx.def_span(assoc_item.def_id);
+                            let hir_id = cx.tcx.local_def_id_to_hir_id(assoc_item.def_id.expect_local());
+                            if let Some(trait_spans) = existing_name.trait_methods.get(&name) {
                                 span_lint_hir_and_then(
                                     cx,
                                     SAME_NAME_METHOD,
@@ -148,12 +142,12 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                                         // iterate on trait_spans?
                                         diag.span_note(
                                             trait_spans[0],
-                                            format!("existing `{method_name}` defined here"),
+                                            format!("existing `{name}` defined here"),
                                         );
                                     },
                                 );
                             }
-                            existing_name.impl_methods.insert(method_name, (impl_span, hir_id));
+                            existing_name.impl_methods.insert(name, (impl_span, hir_id));
                         }
                     },
                 }
diff --git a/src/tools/clippy/clippy_lints/src/serde_api.rs b/src/tools/clippy/clippy_lints/src/serde_api.rs
index b36a5d6d502..2de22e4b6a3 100644
--- a/src/tools/clippy/clippy_lints/src/serde_api.rs
+++ b/src/tools/clippy/clippy_lints/src/serde_api.rs
@@ -36,9 +36,9 @@ impl<'tcx> LateLintPass<'tcx> for SerdeApi {
                 let mut seen_str = None;
                 let mut seen_string = None;
                 for item in *items {
-                    match item.ident.name {
-                        sym::visit_str => seen_str = Some(item.span),
-                        sym::visit_string => seen_string = Some(item.span),
+                    match cx.tcx.item_name(item.owner_id) {
+                        sym::visit_str => seen_str = Some(cx.tcx.def_span(item.owner_id)),
+                        sym::visit_string => seen_string = Some(cx.tcx.def_span(item.owner_id)),
                         _ => {},
                     }
                 }
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 442b3250d86..cf70e883bd0 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -1,10 +1,10 @@
 use clippy_config::Conf;
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::msrvs::Msrv;
 use rustc_attr_data_structures::{StabilityLevel, StableSince};
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Block, Body, HirId, Path, PathSegment};
 use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
@@ -88,49 +88,52 @@ declare_clippy_lint! {
 }
 
 pub struct StdReexports {
-    lint_point: (Span, Option<LintPoint>),
+    lint_points: Option<(Span, Vec<LintPoint>)>,
     msrv: Msrv,
 }
 
 impl StdReexports {
     pub fn new(conf: &'static Conf) -> Self {
         Self {
-            lint_point: Default::default(),
+            lint_points: Option::default(),
             msrv: conf.msrv,
         }
     }
 
-    fn lint_if_finish(&mut self, cx: &LateContext<'_>, (span, item): (Span, Option<LintPoint>)) {
-        if span.source_equal(self.lint_point.0) {
-            return;
+    fn lint_if_finish(&mut self, cx: &LateContext<'_>, krate: Span, lint_point: LintPoint) {
+        match &mut self.lint_points {
+            Some((prev_krate, prev_lints)) if prev_krate.overlaps(krate) => {
+                prev_lints.push(lint_point);
+            },
+            _ => emit_lints(cx, self.lint_points.replace((krate, vec![lint_point]))),
         }
-
-        if !self.lint_point.0.is_dummy() {
-            emit_lints(cx, &self.lint_point);
-        }
-
-        self.lint_point = (span, item);
     }
 }
 
 impl_lint_pass!(StdReexports => [STD_INSTEAD_OF_CORE, STD_INSTEAD_OF_ALLOC, ALLOC_INSTEAD_OF_CORE]);
 
-type LintPoint = (&'static Lint, &'static str, &'static str);
+#[derive(Debug)]
+enum LintPoint {
+    Available(Span, &'static Lint, &'static str, &'static str),
+    Conflict,
+}
 
 impl<'tcx> LateLintPass<'tcx> for StdReexports {
     fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, _: HirId) {
-        if let Res::Def(_, def_id) = path.res
+        if let Res::Def(def_kind, def_id) = path.res
             && let Some(first_segment) = get_first_segment(path)
             && is_stable(cx, def_id, self.msrv)
             && !path.span.in_external_macro(cx.sess().source_map())
             && !is_from_proc_macro(cx, &first_segment.ident)
+            && !matches!(def_kind, DefKind::Macro(_))
+            && let Some(last_segment) = path.segments.last()
         {
             let (lint, used_mod, replace_with) = match first_segment.ident.name {
                 sym::std => match cx.tcx.crate_name(def_id.krate) {
                     sym::core => (STD_INSTEAD_OF_CORE, "std", "core"),
                     sym::alloc => (STD_INSTEAD_OF_ALLOC, "std", "alloc"),
                     _ => {
-                        self.lint_if_finish(cx, (first_segment.ident.span, None));
+                        self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);
                         return;
                     },
                 },
@@ -138,44 +141,84 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     if cx.tcx.crate_name(def_id.krate) == sym::core {
                         (ALLOC_INSTEAD_OF_CORE, "alloc", "core")
                     } else {
-                        self.lint_if_finish(cx, (first_segment.ident.span, None));
+                        self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);
                         return;
                     }
                 },
-                _ => return,
+                _ => {
+                    self.lint_if_finish(cx, first_segment.ident.span, LintPoint::Conflict);
+                    return;
+                },
             };
 
-            self.lint_if_finish(cx, (first_segment.ident.span, Some((lint, used_mod, replace_with))));
+            self.lint_if_finish(
+                cx,
+                first_segment.ident.span,
+                LintPoint::Available(last_segment.ident.span, lint, used_mod, replace_with),
+            );
         }
     }
 
     fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &Block<'tcx>) {
-        self.lint_if_finish(cx, Default::default());
+        emit_lints(cx, self.lint_points.take());
     }
 
     fn check_body_post(&mut self, cx: &LateContext<'tcx>, _: &Body<'tcx>) {
-        self.lint_if_finish(cx, Default::default());
+        emit_lints(cx, self.lint_points.take());
     }
 
     fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
-        self.lint_if_finish(cx, Default::default());
+        emit_lints(cx, self.lint_points.take());
     }
 }
 
-fn emit_lints(cx: &LateContext<'_>, (span, item): &(Span, Option<LintPoint>)) {
-    let Some((lint, used_mod, replace_with)) = item else {
+fn emit_lints(cx: &LateContext<'_>, lint_points: Option<(Span, Vec<LintPoint>)>) {
+    let Some((krate_span, lint_points)) = lint_points else {
         return;
     };
 
-    span_lint_and_sugg(
-        cx,
-        lint,
-        *span,
-        format!("used import from `{used_mod}` instead of `{replace_with}`"),
-        format!("consider importing the item from `{replace_with}`"),
-        (*replace_with).to_string(),
-        Applicability::MachineApplicable,
-    );
+    let mut lint: Option<(&'static Lint, &'static str, &'static str)> = None;
+    let mut has_conflict = false;
+    for lint_point in &lint_points {
+        match lint_point {
+            LintPoint::Available(_, l, used_mod, replace_with)
+                if lint.is_none_or(|(prev_l, ..)| l.name == prev_l.name) =>
+            {
+                lint = Some((l, used_mod, replace_with));
+            },
+            _ => {
+                has_conflict = true;
+                break;
+            },
+        }
+    }
+
+    if !has_conflict && let Some((lint, used_mod, replace_with)) = lint {
+        span_lint_and_sugg(
+            cx,
+            lint,
+            krate_span,
+            format!("used import from `{used_mod}` instead of `{replace_with}`"),
+            format!("consider importing the item from `{replace_with}`"),
+            (*replace_with).to_string(),
+            Applicability::MachineApplicable,
+        );
+        return;
+    }
+
+    for lint_point in lint_points {
+        let LintPoint::Available(span, lint, used_mod, replace_with) = lint_point else {
+            continue;
+        };
+        span_lint_and_help(
+            cx,
+            lint,
+            span,
+            format!("used import from `{used_mod}` instead of `{replace_with}`"),
+            None,
+            format!("consider importing the item from `{replace_with}`"),
+        );
+    }
 }
 
 /// Returns the first named segment of a [`Path`].
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 45e54302e32..9182a55081f 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -112,7 +112,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
         // special handling for self trait bounds as these are not considered generics
         // ie. trait Foo: Display {}
         if let Item {
-            kind: ItemKind::Trait(_, _, _, _, bounds, ..),
+            kind: ItemKind::Trait(_, _, _, _, _, bounds, ..),
             ..
         } = item
         {
@@ -133,7 +133,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
                     ..
                 }) = segments.first()
                 && let Some(Node::Item(Item {
-                    kind: ItemKind::Trait(_, _, _, _, self_bounds, _),
+                    kind: ItemKind::Trait(_, _, _, _, _, self_bounds, _),
                     ..
                 })) = cx.tcx.hir_get_if_local(*def_id)
             {
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index 6cc4b589a72..cf603c6190b 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -9,7 +9,7 @@ use clippy_utils::visitors::{Descend, for_each_expr};
 use hir::HirId;
 use rustc_hir as hir;
 use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource};
-use rustc_lexer::{TokenKind, tokenize};
+use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, RelativeBytePos, Span, SyntaxContext};
@@ -143,7 +143,8 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
         if let Some(tail) = block.expr
             && !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, tail.hir_id)
             && !tail.span.in_external_macro(cx.tcx.sess.source_map())
-            && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, tail.span, tail.hir_id)
+            && let HasSafetyComment::Yes(pos) =
+                stmt_has_safety_comment(cx, tail.span, tail.hir_id, self.accept_comment_above_attributes)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, tail, pos)
         {
             span_lint_and_then(
@@ -167,7 +168,8 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
         };
         if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, stmt.hir_id)
             && !stmt.span.in_external_macro(cx.tcx.sess.source_map())
-            && let HasSafetyComment::Yes(pos) = stmt_has_safety_comment(cx, stmt.span, stmt.hir_id)
+            && let HasSafetyComment::Yes(pos) =
+                stmt_has_safety_comment(cx, stmt.span, stmt.hir_id, self.accept_comment_above_attributes)
             && let Some(help_span) = expr_has_unnecessary_safety_comment(cx, expr, pos)
         {
             span_lint_and_then(
@@ -540,7 +542,12 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
 
 /// Checks if the lines immediately preceding the item contain a safety comment.
 #[allow(clippy::collapsible_match)]
-fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> HasSafetyComment {
+fn stmt_has_safety_comment(
+    cx: &LateContext<'_>,
+    span: Span,
+    hir_id: HirId,
+    accept_comment_above_attributes: bool,
+) -> HasSafetyComment {
     match span_from_macro_expansion_has_safety_comment(cx, span) {
         HasSafetyComment::Maybe => (),
         has_safety_comment => return has_safety_comment,
@@ -555,6 +562,13 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H
         _ => return HasSafetyComment::Maybe,
     };
 
+    // if span_with_attrs_has_safety_comment(cx, span, hir_id, accept_comment_above_attrib
+    // }
+    let mut span = span;
+    if accept_comment_above_attributes {
+        span = include_attrs_in_span(cx, hir_id, span);
+    }
+
     let source_map = cx.sess().source_map();
     if let Some(comment_start) = comment_start
         && let Ok(unsafe_line) = source_map.lookup_line(span.lo())
@@ -746,7 +760,7 @@ fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos
     loop {
         if line.starts_with("/*") {
             let src = &src[line_start..line_starts.last().unwrap().to_usize()];
-            let mut tokens = tokenize(src);
+            let mut tokens = tokenize(src, FrontmatterAllowed::No);
             return (src[..tokens.next().unwrap().len as usize]
                 .to_ascii_uppercase()
                 .contains("SAFETY:")
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index 8ceaa3dc58e..e67afc7f5a8 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -169,7 +169,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         let iter = self
             .unused_async_fns
             .iter()
-            .filter(|UnusedAsyncFn { def_id, .. }| (!self.async_fns_as_value.contains(def_id)));
+            .filter(|UnusedAsyncFn { def_id, .. }| !self.async_fns_as_value.contains(def_id));
 
         for fun in iter {
             span_lint_hir_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
index 02281b9e922..944cd91a7fd 100644
--- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
+++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
@@ -131,7 +131,7 @@ impl LateLintPass<'_> for UpperCaseAcronyms {
             return;
         }
         match it.kind {
-            ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, ident, ..) => {
+            ItemKind::TyAlias(ident, ..) | ItemKind::Struct(ident, ..) | ItemKind::Trait(_, _, _, ident, ..) => {
                 check_ident(cx, &ident, it.hir_id(), self.upper_case_acronyms_aggressive);
             },
             ItemKind::Enum(ident, _, ref enumdef) => {
diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
index 8f314ce7a60..6629a67f78b 100644
--- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::SpanRangeExt;
 use itertools::Itertools;
 use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_lexer::{TokenKind, tokenize};
+use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, hygiene};
@@ -82,7 +82,7 @@ fn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool {
         .all(|sp| {
             sp.check_source_text(cx, |src| {
                 // text should be either `, name` or `, name =`
-                let mut iter = tokenize(src).filter(|t| {
+                let mut iter = tokenize(src, FrontmatterAllowed::No).filter(|t| {
                     !matches!(
                         t.kind,
                         TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace
diff --git a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
index a1dacd359a0..88b099c477f 100644
--- a/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/derive_deserialize_allowing_unknown.rs
@@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for DeriveDeserializeAllowingUnknown {
         }
 
         // Is it derived?
-        if !cx.tcx.has_attr(item.owner_id, sym::automatically_derived) {
+        if !find_attr!(cx.tcx.get_all_attrs(item.owner_id), AttributeKind::AutomaticallyDerived(..)) {
             return;
         }
 
diff --git a/src/tools/clippy/clippy_lints_internal/src/symbols.rs b/src/tools/clippy/clippy_lints_internal/src/symbols.rs
index 7b5d58824c3..74712097e71 100644
--- a/src/tools/clippy/clippy_lints_internal/src/symbols.rs
+++ b/src/tools/clippy/clippy_lints_internal/src/symbols.rs
@@ -65,7 +65,7 @@ pub struct Symbols {
 impl_lint_pass!(Symbols => [INTERNING_LITERALS, SYMBOL_AS_STR]);
 
 impl Symbols {
-    fn lit_suggestion(&self, lit: &Lit) -> Option<(Span, String)> {
+    fn lit_suggestion(&self, lit: Lit) -> Option<(Span, String)> {
         if let LitKind::Str(name, _) = lit.node {
             let sugg = if let Some((prefix, name)) = self.symbol_map.get(&name.as_u32()) {
                 format!("{prefix}::{name}")
diff --git a/src/tools/clippy/clippy_test_deps/Cargo.lock b/src/tools/clippy/clippy_test_deps/Cargo.lock
new file mode 100644
index 00000000000..a591dae3a1a
--- /dev/null
+++ b/src/tools/clippy/clippy_test_deps/Cargo.lock
@@ -0,0 +1,505 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "addr2line"
+version = "0.24.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "backtrace"
+version = "0.3.75"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002"
+dependencies = [
+ "addr2line",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+ "windows-targets",
+]
+
+[[package]]
+name = "bitflags"
+version = "2.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
+
+[[package]]
+name = "bytes"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
+
+[[package]]
+name = "clippy_test_deps"
+version = "0.1.0"
+dependencies = [
+ "futures",
+ "if_chain",
+ "itertools",
+ "parking_lot",
+ "quote",
+ "regex",
+ "serde",
+ "syn",
+ "tokio",
+]
+
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
+name = "futures"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
+
+[[package]]
+name = "futures-task"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
+
+[[package]]
+name = "futures-util"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "gimli"
+version = "0.31.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
+
+[[package]]
+name = "if_chain"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed"
+
+[[package]]
+name = "io-uring"
+version = "0.7.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+]
+
+[[package]]
+name = "itertools"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.174"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
+
+[[package]]
+name = "lock_api"
+version = "0.4.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
+dependencies = [
+ "adler2",
+]
+
+[[package]]
+name = "mio"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
+dependencies = [
+ "libc",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "object"
+version = "0.36.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-targets",
+]
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.95"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.5.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
+
+[[package]]
+name = "scopeguard"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
+
+[[package]]
+name = "serde"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.219"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+
+[[package]]
+name = "syn"
+version = "2.0.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tokio"
+version = "1.46.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
+dependencies = [
+ "backtrace",
+ "bytes",
+ "io-uring",
+ "libc",
+ "mio",
+ "pin-project-lite",
+ "slab",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
+
+[[package]]
+name = "wasi"
+version = "0.11.1+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/src/tools/clippy/clippy_test_deps/Cargo.toml b/src/tools/clippy/clippy_test_deps/Cargo.toml
new file mode 100644
index 00000000000..a23ffcaf2f9
--- /dev/null
+++ b/src/tools/clippy/clippy_test_deps/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "clippy_test_deps"
+version = "0.1.0"
+edition = "2021"
+
+# Add dependencies here to make them available in ui tests.
+
+[dependencies]
+regex = "1.5.5"
+serde = { version = "1.0.145", features = ["derive"] }
+if_chain = "1.0"
+quote = "1.0.25"
+syn = { version = "2.0", features = ["full"] }
+futures = "0.3"
+parking_lot = "0.12"
+tokio = { version = "1", features = ["io-util"] }
+itertools = "0.12"
+
+# Make sure we are not part of the rustc workspace.
+[workspace]
diff --git a/src/tools/clippy/clippy_test_deps/src/main.rs b/src/tools/clippy/clippy_test_deps/src/main.rs
new file mode 100644
index 00000000000..f328e4d9d04
--- /dev/null
+++ b/src/tools/clippy/clippy_test_deps/src/main.rs
@@ -0,0 +1 @@
+fn main() {}
diff --git a/src/tools/clippy/clippy_utils/README.md b/src/tools/clippy/clippy_utils/README.md
index 649748d1534..645b644d9f4 100644
--- a/src/tools/clippy/clippy_utils/README.md
+++ b/src/tools/clippy/clippy_utils/README.md
@@ -8,7 +8,7 @@ This crate is only guaranteed to build with this `nightly` toolchain:
 
 <!-- begin autogenerated nightly -->
 ```
-nightly-2025-06-26
+nightly-2025-07-10
 ```
 <!-- end autogenerated nightly -->
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index 42254ec8e92..96f0273c439 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -444,6 +444,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         },
         (
             Trait(box ast::Trait {
+                constness: lc,
                 is_auto: la,
                 safety: lu,
                 ident: li,
@@ -452,6 +453,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 items: lis,
             }),
             Trait(box ast::Trait {
+                constness: rc,
                 is_auto: ra,
                 safety: ru,
                 ident: ri,
@@ -460,7 +462,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 items: ris,
             }),
         ) => {
-            la == ra
+            matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)
+                && la == ra
                 && matches!(lu, Safety::Default) == matches!(ru, Safety::Default)
                 && eq_id(*li, *ri)
                 && eq_generics(lg, rg)
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 4c7a589e185..34472eaab93 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -1,5 +1,8 @@
+use crate::source::SpanRangeExt;
+use crate::{sym, tokenize_with_text};
 use rustc_ast::attr;
 use rustc_ast::attr::AttributeExt;
+use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_errors::Applicability;
 use rustc_lexer::TokenKind;
 use rustc_lint::LateContext;
@@ -7,10 +10,6 @@ use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
 use rustc_span::{Span, Symbol};
 use std::str::FromStr;
-use rustc_attr_data_structures::find_attr;
-use crate::source::SpanRangeExt;
-use crate::{sym, tokenize_with_text};
-use rustc_attr_data_structures::AttributeKind;
 
 /// Deprecation status of attributes known by Clippy.
 pub enum DeprecationStatus {
@@ -168,7 +167,8 @@ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
     adt.is_variant_list_non_exhaustive()
         || find_attr!(tcx.get_all_attrs(adt.did()), AttributeKind::NonExhaustive(..))
         || adt.variants().iter().any(|variant_def| {
-            variant_def.is_field_list_non_exhaustive() || find_attr!(tcx.get_all_attrs(variant_def.def_id), AttributeKind::NonExhaustive(..))
+            variant_def.is_field_list_non_exhaustive()
+                || find_attr!(tcx.get_all_attrs(variant_def.def_id), AttributeKind::NonExhaustive(..))
         })
         || adt
             .all_fields()
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index ce61fffe0de..dc31ed08fb7 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -252,11 +252,11 @@ fn item_search_pat(item: &Item<'_>) -> (Pat, Pat) {
         ItemKind::Struct(_, _, VariantData::Struct { .. }) => (Pat::Str("struct"), Pat::Str("}")),
         ItemKind::Struct(..) => (Pat::Str("struct"), Pat::Str(";")),
         ItemKind::Union(..) => (Pat::Str("union"), Pat::Str("}")),
-        ItemKind::Trait(_, Safety::Unsafe, ..)
+        ItemKind::Trait(_, _, Safety::Unsafe, ..)
         | ItemKind::Impl(Impl {
             safety: Safety::Unsafe, ..
         }) => (Pat::Str("unsafe"), Pat::Str("}")),
-        ItemKind::Trait(IsAuto::Yes, ..) => (Pat::Str("auto"), Pat::Str("}")),
+        ItemKind::Trait(_, IsAuto::Yes, ..) => (Pat::Str("auto"), Pat::Str("}")),
         ItemKind::Trait(..) => (Pat::Str("trait"), Pat::Str("}")),
         ItemKind::Impl(_) => (Pat::Str("impl"), Pat::Str("}")),
         _ => return (Pat::Str(""), Pat::Str("")),
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 09299c869dc..25afa12e95d 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
     BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, PatExpr, PatExprKind, QPath, UnOp,
 };
-use rustc_lexer::tokenize;
+use rustc_lexer::{FrontmatterAllowed, tokenize};
 use rustc_lint::LateContext;
 use rustc_middle::mir::ConstValue;
 use rustc_middle::mir::interpret::{Scalar, alloc_range};
@@ -304,9 +304,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
     match *lit {
         LitKind::Str(ref is, _) => Constant::Str(is.to_string()),
         LitKind::Byte(b) => Constant::Int(u128::from(b)),
-        LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => {
-            Constant::Binary(s.as_byte_str().to_vec())
-        }
+        LitKind::ByteStr(ref s, _) | LitKind::CStr(ref s, _) => Constant::Binary(s.as_byte_str().to_vec()),
         LitKind::Char(c) => Constant::Char(c),
         LitKind::Int(n, _) => Constant::Int(n.get()),
         LitKind::Float(ref is, LitFloatType::Suffixed(fty)) => match fty {
@@ -568,9 +566,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                 } else {
                     match &lit.node {
                         LitKind::Str(is, _) => Some(is.is_empty()),
-                        LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => {
-                            Some(s.as_byte_str().is_empty())
-                        }
+                        LitKind::ByteStr(s, _) | LitKind::CStr(s, _) => Some(s.as_byte_str().is_empty()),
                         _ => None,
                     }
                 }
@@ -715,7 +711,7 @@ impl<'tcx> ConstEvalCtxt<'tcx> {
                     && let Some(src) = src.as_str()
                 {
                     use rustc_lexer::TokenKind::{BlockComment, LineComment, OpenBrace, Semi, Whitespace};
-                    if !tokenize(src)
+                    if !tokenize(src, FrontmatterAllowed::No)
                         .map(|t| t.kind)
                         .filter(|t| !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi))
                         .eq([OpenBrace])
@@ -918,7 +914,7 @@ fn mir_is_empty<'tcx>(tcx: TyCtxt<'tcx>, result: mir::Const<'tcx>) -> Option<boo
                     // Get the length from the slice, using the same formula as
                     // [`ConstValue::try_get_slice_bytes_for_diagnostics`].
                     let a = tcx.global_alloc(alloc_id).unwrap_memory().inner();
-                    let ptr_size = tcx.data_layout.pointer_size;
+                    let ptr_size = tcx.data_layout.pointer_size();
                     if a.size() < offset + 2 * ptr_size {
                         // (partially) dangling reference
                         return None;
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index 6971b488013..4e0b00df950 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -54,7 +54,7 @@ impl<'tcx> ForLoop<'tcx> {
     }
 }
 
-/// An `if` expression without `DropTemps`
+/// An `if` expression without `let`
 pub struct If<'hir> {
     /// `if` condition
     pub cond: &'hir Expr<'hir>,
@@ -66,16 +66,10 @@ pub struct If<'hir> {
 
 impl<'hir> If<'hir> {
     #[inline]
-    /// Parses an `if` expression
+    /// Parses an `if` expression without `let`
     pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {
-        if let ExprKind::If(
-            Expr {
-                kind: ExprKind::DropTemps(cond),
-                ..
-            },
-            then,
-            r#else,
-        ) = expr.kind
+        if let ExprKind::If(cond, then, r#else) = expr.kind
+            && !has_let_expr(cond)
         {
             Some(Self { cond, then, r#else })
         } else {
@@ -198,18 +192,10 @@ impl<'hir> IfOrIfLet<'hir> {
     /// Parses an `if` or `if let` expression
     pub const fn hir(expr: &Expr<'hir>) -> Option<Self> {
         if let ExprKind::If(cond, then, r#else) = expr.kind {
-            if let ExprKind::DropTemps(new_cond) = cond.kind {
-                return Some(Self {
-                    cond: new_cond,
-                    then,
-                    r#else,
-                });
-            }
-            if let ExprKind::Let(..) = cond.kind {
-                return Some(Self { cond, then, r#else });
-            }
+            Some(Self { cond, then, r#else })
+        } else {
+            None
         }
-        None
     }
 }
 
@@ -343,15 +329,7 @@ impl<'hir> While<'hir> {
             Block {
                 expr:
                     Some(Expr {
-                        kind:
-                            ExprKind::If(
-                                Expr {
-                                    kind: ExprKind::DropTemps(condition),
-                                    ..
-                                },
-                                body,
-                                _,
-                            ),
+                        kind: ExprKind::If(condition, body, _),
                         ..
                     }),
                 ..
@@ -360,6 +338,7 @@ impl<'hir> While<'hir> {
             LoopSource::While,
             span,
         ) = expr.kind
+            && !has_let_expr(condition)
         {
             return Some(Self { condition, body, span });
         }
@@ -493,3 +472,13 @@ pub fn get_vec_init_kind<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -
     }
     None
 }
+
+/// Checks that a condition doesn't have a `let` expression, to keep `If` and `While` from accepting
+/// `if let` and `while let`.
+pub const fn has_let_expr<'tcx>(cond: &'tcx Expr<'tcx>) -> bool {
+    match &cond.kind {
+        ExprKind::Let(_) => true,
+        ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
+        _ => false,
+    }
+}
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 0ca494f16e3..f0d7fb89c44 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -2,6 +2,7 @@ use crate::consts::ConstEvalCtxt;
 use crate::macros::macro_backtrace;
 use crate::source::{SpanRange, SpanRangeExt, walk_span_to_context};
 use crate::tokenize_with_text;
+use rustc_ast::ast;
 use rustc_ast::ast::InlineAsmTemplatePiece;
 use rustc_data_structures::fx::FxHasher;
 use rustc_hir::MatchSource::TryDesugar;
@@ -9,10 +10,10 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
     AssocItemConstraint, BinOpKind, BindingMode, Block, BodyId, Closure, ConstArg, ConstArgKind, Expr, ExprField,
     ExprKind, FnRetTy, GenericArg, GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeKind,
-    Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, StructTailExpr,
-    TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
+    Node, Pat, PatExpr, PatExprKind, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind,
+    StructTailExpr, TraitBoundModifiers, Ty, TyKind, TyPat, TyPatKind,
 };
-use rustc_lexer::{TokenKind, tokenize};
+use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
 use rustc_lint::LateContext;
 use rustc_middle::ty::TypeckResults;
 use rustc_span::{BytePos, ExpnKind, MacroKind, Symbol, SyntaxContext, sym};
@@ -686,7 +687,7 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &'
             // `{}` => `()`
             ([], None)
                 if block.span.check_source_text(cx, |src| {
-                    tokenize(src)
+                    tokenize(src, FrontmatterAllowed::No)
                         .map(|t| t.kind)
                         .filter(|t| {
                             !matches!(
@@ -1004,8 +1005,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     self.hash_expr(e);
                 }
             },
-            ExprKind::Match(e, arms, s) => {
-                self.hash_expr(e);
+            ExprKind::Match(scrutinee, arms, _) => {
+                self.hash_expr(scrutinee);
 
                 for arm in *arms {
                     self.hash_pat(arm.pat);
@@ -1014,8 +1015,6 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     }
                     self.hash_expr(arm.body);
                 }
-
-                s.hash(&mut self.s);
             },
             ExprKind::MethodCall(path, receiver, args, _fn_span) => {
                 self.hash_name(path.ident.name);
@@ -1058,8 +1057,8 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
             ExprKind::Use(expr, _) => {
                 self.hash_expr(expr);
             },
-            ExprKind::Unary(lop, le) => {
-                std::mem::discriminant(lop).hash(&mut self.s);
+            ExprKind::Unary(l_op, le) => {
+                std::mem::discriminant(l_op).hash(&mut self.s);
                 self.hash_expr(le);
             },
             ExprKind::UnsafeBinderCast(kind, expr, ty) => {
@@ -1394,3 +1393,70 @@ fn eq_span_tokens(
     }
     f(cx, left.into_range(), right.into_range(), pred)
 }
+
+/// Returns true if the expression contains ambiguous literals (unsuffixed float or int literals)
+/// that could be interpreted as either f32/f64 or i32/i64 depending on context.
+pub fn has_ambiguous_literal_in_expr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    match expr.kind {
+        ExprKind::Path(ref qpath) => {
+            if let Res::Local(hir_id) = cx.qpath_res(qpath, expr.hir_id)
+                && let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id)
+                && local.ty.is_none()
+                && let Some(init) = local.init
+            {
+                return has_ambiguous_literal_in_expr(cx, init);
+            }
+            false
+        },
+        ExprKind::Lit(lit) => matches!(
+            lit.node,
+            ast::LitKind::Float(_, ast::LitFloatType::Unsuffixed) | ast::LitKind::Int(_, ast::LitIntType::Unsuffixed)
+        ),
+
+        ExprKind::Array(exprs) | ExprKind::Tup(exprs) => exprs.iter().any(|e| has_ambiguous_literal_in_expr(cx, e)),
+
+        ExprKind::Assign(lhs, rhs, _) | ExprKind::AssignOp(_, lhs, rhs) | ExprKind::Binary(_, lhs, rhs) => {
+            has_ambiguous_literal_in_expr(cx, lhs) || has_ambiguous_literal_in_expr(cx, rhs)
+        },
+
+        ExprKind::Unary(_, e)
+        | ExprKind::Cast(e, _)
+        | ExprKind::Type(e, _)
+        | ExprKind::DropTemps(e)
+        | ExprKind::AddrOf(_, _, e)
+        | ExprKind::Field(e, _)
+        | ExprKind::Index(e, _, _)
+        | ExprKind::Yield(e, _) => has_ambiguous_literal_in_expr(cx, e),
+
+        ExprKind::MethodCall(_, receiver, args, _) | ExprKind::Call(receiver, args) => {
+            has_ambiguous_literal_in_expr(cx, receiver) || args.iter().any(|e| has_ambiguous_literal_in_expr(cx, e))
+        },
+
+        ExprKind::Closure(Closure { body, .. }) => {
+            let body = cx.tcx.hir_body(*body);
+            let closure_expr = crate::peel_blocks(body.value);
+            has_ambiguous_literal_in_expr(cx, closure_expr)
+        },
+
+        ExprKind::Block(blk, _) => blk.expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e)),
+
+        ExprKind::If(cond, then_expr, else_expr) => {
+            has_ambiguous_literal_in_expr(cx, cond)
+                || has_ambiguous_literal_in_expr(cx, then_expr)
+                || else_expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e))
+        },
+
+        ExprKind::Match(scrutinee, arms, _) => {
+            has_ambiguous_literal_in_expr(cx, scrutinee)
+                || arms.iter().any(|arm| has_ambiguous_literal_in_expr(cx, arm.body))
+        },
+
+        ExprKind::Loop(body, ..) => body.expr.is_some_and(|e| has_ambiguous_literal_in_expr(cx, e)),
+
+        ExprKind::Ret(opt_expr) | ExprKind::Break(_, opt_expr) => {
+            opt_expr.as_ref().is_some_and(|e| has_ambiguous_literal_in_expr(cx, e))
+        },
+
+        _ => false,
+    }
+}
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index c01f0ffaac9..ff1ee663f9b 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -77,7 +77,8 @@ pub mod visitors;
 pub use self::attrs::*;
 pub use self::check_proc_macro::{is_from_proc_macro, is_span_if, is_span_match};
 pub use self::hir_utils::{
-    HirEqInterExpr, SpanlessEq, SpanlessHash, both, count_eq, eq_expr_value, hash_expr, hash_stmt, is_bool, over,
+    HirEqInterExpr, SpanlessEq, SpanlessHash, both, count_eq, eq_expr_value, has_ambiguous_literal_in_expr, hash_expr,
+    hash_stmt, is_bool, over,
 };
 
 use core::mem;
@@ -88,6 +89,7 @@ use std::sync::{Mutex, MutexGuard, OnceLock};
 
 use itertools::Itertools;
 use rustc_abi::Integer;
+use rustc_ast::join_path_syms;
 use rustc_ast::ast::{self, LitKind, RangeLimits};
 use rustc_attr_data_structures::{AttributeKind, find_attr};
 use rustc_data_structures::fx::FxHashMap;
@@ -106,7 +108,7 @@ use rustc_hir::{
     Param, Pat, PatExpr, PatExprKind, PatKind, Path, PathSegment, QPath, Stmt, StmtKind, TraitFn, TraitItem,
     TraitItemKind, TraitRef, TyKind, UnOp, def,
 };
-use rustc_lexer::{TokenKind, tokenize};
+use rustc_lexer::{FrontmatterAllowed, TokenKind, tokenize};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::hir::place::PlaceBase;
@@ -1784,9 +1786,9 @@ pub fn in_automatically_derived(tcx: TyCtxt<'_>, id: HirId) -> bool {
     tcx.hir_parent_owner_iter(id)
         .filter(|(_, node)| matches!(node, OwnerNode::Item(item) if matches!(item.kind, ItemKind::Impl(_))))
         .any(|(id, _)| {
-            has_attr(
+            find_attr!(
                 tcx.hir_attrs(tcx.local_def_id_to_hir_id(id.def_id)),
-                sym::automatically_derived,
+                AttributeKind::AutomaticallyDerived(..)
             )
         })
 }
@@ -2764,7 +2766,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'tcx>) -> ExprUseCtx
 /// Tokenizes the input while keeping the text associated with each token.
 pub fn tokenize_with_text(s: &str) -> impl Iterator<Item = (TokenKind, &str, InnerSpan)> {
     let mut pos = 0;
-    tokenize(s).map(move |t| {
+    tokenize(s, FrontmatterAllowed::No).map(move |t| {
         let end = pos + t.len;
         let range = pos as usize..end as usize;
         let inner = InnerSpan::new(range.start, range.end);
@@ -2779,7 +2781,7 @@ pub fn span_contains_comment(sm: &SourceMap, span: Span) -> bool {
     let Ok(snippet) = sm.span_to_snippet(span) else {
         return false;
     };
-    return tokenize(&snippet).any(|token| {
+    return tokenize(&snippet, FrontmatterAllowed::No).any(|token| {
         matches!(
             token.kind,
             TokenKind::BlockComment { .. } | TokenKind::LineComment { .. }
@@ -3244,8 +3246,8 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
                 // a::b::c  ::d::sym refers to
                 // e::f::sym:: ::
                 // result should be super::super::super::super::e::f
-                if let DefPathData::TypeNs(s) = l {
-                    path.push(s.to_string());
+                if let DefPathData::TypeNs(sym) = l {
+                    path.push(sym);
                 }
                 if let DefPathData::TypeNs(_) = r {
                     go_up_by += 1;
@@ -3255,7 +3257,7 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
             // a::b::sym:: ::    refers to
             // c::d::e  ::f::sym
             // when looking at `f`
-            Left(DefPathData::TypeNs(sym)) => path.push(sym.to_string()),
+            Left(DefPathData::TypeNs(sym)) => path.push(sym),
             // consider:
             // a::b::c  ::d::sym refers to
             // e::f::sym:: ::
@@ -3267,17 +3269,17 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
 
     if go_up_by > max_super {
         // `super` chain would be too long, just use the absolute path instead
-        once(String::from("crate"))
-            .chain(to.data.iter().filter_map(|el| {
+        join_path_syms(
+            once(kw::Crate).chain(to.data.iter().filter_map(|el| {
                 if let DefPathData::TypeNs(sym) = el.data {
-                    Some(sym.to_string())
+                    Some(sym)
                 } else {
                     None
                 }
             }))
-            .join("::")
+        )
     } else {
-        repeat_n(String::from("super"), go_up_by).chain(path).join("::")
+        join_path_syms(repeat_n(kw::Super, go_up_by).chain(path))
     }
 }
 
@@ -3497,3 +3499,64 @@ pub fn is_expr_default<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) ->
         false
     }
 }
+
+/// Checks if `expr` may be directly used as the return value of its enclosing body.
+/// The following cases are covered:
+/// - `expr` as the last expression of the body, or of a block that can be used as the return value
+/// - `return expr`
+/// - then or else part of a `if` in return position
+/// - arm body of a `match` in a return position
+/// - `break expr` or `break 'label expr` if the loop or block being exited is used as a return
+///   value
+///
+/// Contrary to [`TyCtxt::hir_get_fn_id_for_return_block()`], if `expr` is part of a
+/// larger expression, for example a field expression of a `struct`, it will not be
+/// considered as matching the condition and will return `false`.
+///
+/// Also, even if `expr` is assigned to a variable which is later returned, this function
+/// will still return `false` because `expr` is not used *directly* as the return value
+/// as it goes through the intermediate variable.
+pub fn potential_return_of_enclosing_body(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    let enclosing_body_owner = cx
+        .tcx
+        .local_def_id_to_hir_id(cx.tcx.hir_enclosing_body_owner(expr.hir_id));
+    let mut prev_id = expr.hir_id;
+    let mut skip_until_id = None;
+    for (hir_id, node) in cx.tcx.hir_parent_iter(expr.hir_id) {
+        if hir_id == enclosing_body_owner {
+            return true;
+        }
+        if let Some(id) = skip_until_id {
+            prev_id = hir_id;
+            if id == hir_id {
+                skip_until_id = None;
+            }
+            continue;
+        }
+        match node {
+            Node::Block(Block { expr, .. }) if expr.is_some_and(|expr| expr.hir_id == prev_id) => {},
+            Node::Arm(arm) if arm.body.hir_id == prev_id => {},
+            Node::Expr(expr) => match expr.kind {
+                ExprKind::Ret(_) => return true,
+                ExprKind::If(_, then, opt_else)
+                    if then.hir_id == prev_id || opt_else.is_some_and(|els| els.hir_id == prev_id) => {},
+                ExprKind::Match(_, arms, _) if arms.iter().any(|arm| arm.hir_id == prev_id) => {},
+                ExprKind::Block(block, _) if block.hir_id == prev_id => {},
+                ExprKind::Break(
+                    Destination {
+                        target_id: Ok(target_id),
+                        ..
+                    },
+                    _,
+                ) => skip_until_id = Some(target_id),
+                _ => break,
+            },
+            _ => break,
+        }
+        prev_id = hir_id;
+    }
+
+    // `expr` is used as part of "something" and is not returned directly from its
+    // enclosing body.
+    false
+}
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 7a0bef1a9bb..24ed4c3a8be 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -74,7 +74,7 @@ msrv_aliases! {
     1,28,0 { FROM_BOOL, REPEAT_WITH, SLICE_FROM_REF }
     1,27,0 { ITERATOR_TRY_FOLD }
     1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN }
-    1,24,0 { IS_ASCII_DIGIT }
+    1,24,0 { IS_ASCII_DIGIT, PTR_NULL }
     1,18,0 { HASH_MAP_RETAIN, HASH_SET_RETAIN }
     1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
     1,16,0 { STR_REPEAT }
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 8bbcb220210..c681806517a 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::Namespace::{MacroNS, TypeNS, ValueNS};
 use rustc_hir::def::{DefKind, Namespace, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
-use rustc_hir::{ImplItemRef, ItemKind, Node, OwnerId, TraitItemRef, UseKind};
+use rustc_hir::{ItemKind, Node, UseKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::{FloatTy, IntTy, Ty, TyCtxt, UintTy};
@@ -284,14 +284,6 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n
         _ => return None,
     };
 
-    let res = |ident: Ident, owner_id: OwnerId| {
-        if ident.name == name && ns.matches(tcx.def_kind(owner_id).ns()) {
-            Some(owner_id.to_def_id())
-        } else {
-            None
-        }
-    };
-
     match item_kind {
         ItemKind::Mod(_, r#mod) => r#mod.item_ids.iter().find_map(|&item_id| {
             let item = tcx.hir_item(item_id);
@@ -307,17 +299,19 @@ fn local_item_child_by_name(tcx: TyCtxt<'_>, local_id: LocalDefId, ns: PathNS, n
                 } else {
                     None
                 }
+            } else if let Some(ident) = item.kind.ident()
+                && ident.name == name
+                && ns.matches(tcx.def_kind(item.owner_id).ns())
+            {
+                Some(item.owner_id.to_def_id())
             } else {
-                res(item.kind.ident()?, item_id.owner_id)
+                None
             }
         }),
-        ItemKind::Impl(r#impl) => r#impl
-            .items
-            .iter()
-            .find_map(|&ImplItemRef { ident, id, .. }| res(ident, id.owner_id)),
-        ItemKind::Trait(.., trait_item_refs) => trait_item_refs
-            .iter()
-            .find_map(|&TraitItemRef { ident, id, .. }| res(ident, id.owner_id)),
+        ItemKind::Impl(..) | ItemKind::Trait(..)
+            => tcx.associated_items(local_id).filter_by_name_unhygienic(name)
+                .find(|assoc_item| ns.matches(Some(assoc_item.namespace())))
+                .map(|assoc_item| assoc_item.def_id),
         _ => None,
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/source.rs b/src/tools/clippy/clippy_utils/src/source.rs
index 7f2bf99daff..7d21336be1c 100644
--- a/src/tools/clippy/clippy_utils/src/source.rs
+++ b/src/tools/clippy/clippy_utils/src/source.rs
@@ -7,7 +7,7 @@ use std::sync::Arc;
 use rustc_ast::{LitKind, StrStyle};
 use rustc_errors::Applicability;
 use rustc_hir::{BlockCheckMode, Expr, ExprKind, UnsafeSource};
-use rustc_lexer::{LiteralKind, TokenKind, tokenize};
+use rustc_lexer::{FrontmatterAllowed, LiteralKind, TokenKind, tokenize};
 use rustc_lint::{EarlyContext, LateContext};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
@@ -277,7 +277,7 @@ fn map_range(
 }
 
 fn ends_with_line_comment_or_broken(text: &str) -> bool {
-    let Some(last) = tokenize(text).last() else {
+    let Some(last) = tokenize(text, FrontmatterAllowed::No).last() else {
         return false;
     };
     match last.kind {
@@ -310,7 +310,8 @@ fn with_leading_whitespace_inner(lines: &[RelativeBytePos], src: &str, range: Ra
         && ends_with_line_comment_or_broken(&start[prev_start..])
         && let next_line = lines.partition_point(|&pos| pos.to_usize() < range.end)
         && let next_start = lines.get(next_line).map_or(src.len(), |&x| x.to_usize())
-        && tokenize(src.get(range.end..next_start)?).any(|t| !matches!(t.kind, TokenKind::Whitespace))
+        && tokenize(src.get(range.end..next_start)?, FrontmatterAllowed::No)
+            .any(|t| !matches!(t.kind, TokenKind::Whitespace))
     {
         Some(range.start)
     } else {
diff --git a/src/tools/clippy/clippy_utils/src/ty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/mod.rs
index bffbcf073ab..fe208c032f4 100644
--- a/src/tools/clippy/clippy_utils/src/ty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/mod.rs
@@ -889,7 +889,7 @@ impl AdtVariantInfo {
                     .enumerate()
                     .map(|(i, f)| (i, approx_ty_size(cx, f.ty(cx.tcx, subst))))
                     .collect::<Vec<_>>();
-                fields_size.sort_by(|(_, a_size), (_, b_size)| (a_size.cmp(b_size)));
+                fields_size.sort_by(|(_, a_size), (_, b_size)| a_size.cmp(b_size));
 
                 Self {
                     ind: i,
@@ -898,7 +898,7 @@ impl AdtVariantInfo {
                 }
             })
             .collect::<Vec<_>>();
-        variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
+        variants_size.sort_by(|a, b| b.size.cmp(&a.size));
         variants_size
     }
 }
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index fc6e30a9804..ba5cbc73836 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -1,3 +1,5 @@
+use crate::msrvs::Msrv;
+use crate::qualify_min_const_fn::is_stable_const_fn;
 use crate::ty::needs_ordered_drop;
 use crate::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
@@ -343,17 +345,17 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
                     .cx
                     .qpath_res(p, hir_id)
                     .opt_def_id()
-                    .is_some_and(|id| self.cx.tcx.is_const_fn(id)) => {},
+                    .is_some_and(|id| is_stable_const_fn(self.cx, id, Msrv::default())) => {},
                 ExprKind::MethodCall(..)
                     if self
                         .cx
                         .typeck_results()
                         .type_dependent_def_id(e.hir_id)
-                        .is_some_and(|id| self.cx.tcx.is_const_fn(id)) => {},
+                        .is_some_and(|id| is_stable_const_fn(self.cx, id, Msrv::default())) => {},
                 ExprKind::Binary(_, lhs, rhs)
                     if self.cx.typeck_results().expr_ty(lhs).peel_refs().is_primitive_ty()
                         && self.cx.typeck_results().expr_ty(rhs).peel_refs().is_primitive_ty() => {},
-                ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_ref() => (),
+                ExprKind::Unary(UnOp::Deref, e) if self.cx.typeck_results().expr_ty(e).is_raw_ptr() => (),
                 ExprKind::Unary(_, e) if self.cx.typeck_results().expr_ty(e).peel_refs().is_primitive_ty() => (),
                 ExprKind::Index(base, _, _)
                     if matches!(
@@ -388,7 +390,8 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
                 | ExprKind::Repeat(..)
                 | ExprKind::Struct(..)
                 | ExprKind::Tup(_)
-                | ExprKind::Type(..) => (),
+                | ExprKind::Type(..)
+                | ExprKind::UnsafeBinderCast(..) => (),
 
                 _ => {
                     return ControlFlow::Break(());
@@ -676,10 +679,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
                     helper(typeck, true, else_expr, f)?;
                 }
             },
-            ExprKind::Type(e, _) => {
-                helper(typeck, consume, e, f)?;
-            },
-            ExprKind::UnsafeBinderCast(_, e, _) => {
+            ExprKind::Type(e, _) | ExprKind::UnsafeBinderCast(_, e, _) => {
                 helper(typeck, consume, e, f)?;
             },
 
diff --git a/src/tools/clippy/lintcheck/src/config.rs b/src/tools/clippy/lintcheck/src/config.rs
index 83c3d7aba02..3b2ebf0c28a 100644
--- a/src/tools/clippy/lintcheck/src/config.rs
+++ b/src/tools/clippy/lintcheck/src/config.rs
@@ -68,6 +68,9 @@ pub(crate) enum Commands {
         /// This will limit the number of warnings that will be printed for each lint
         #[clap(long)]
         truncate: bool,
+        /// Write the diff summary to a JSON file if there are any changes
+        #[clap(long, value_name = "PATH")]
+        write_summary: Option<PathBuf>,
     },
     /// Create a lintcheck crates TOML file containing the top N popular crates
     Popular {
diff --git a/src/tools/clippy/lintcheck/src/json.rs b/src/tools/clippy/lintcheck/src/json.rs
index 8ea0a41ed36..808997ff022 100644
--- a/src/tools/clippy/lintcheck/src/json.rs
+++ b/src/tools/clippy/lintcheck/src/json.rs
@@ -4,8 +4,8 @@
 //! loading warnings from JSON files, and generating human-readable diffs
 //! between different linting runs.
 
-use std::fs;
-use std::path::Path;
+use std::path::{Path, PathBuf};
+use std::{fmt, fs};
 
 use itertools::{EitherOrBoth, Itertools};
 use serde::{Deserialize, Serialize};
@@ -17,7 +17,6 @@ const DEFAULT_LIMIT_PER_LINT: usize = 300;
 /// Target for total warnings to display across all lints when truncating output.
 const TRUNCATION_TOTAL_TARGET: usize = 1000;
 
-/// Representation of a single Clippy warning for JSON serialization.
 #[derive(Debug, Deserialize, Serialize)]
 struct LintJson {
     /// The lint name e.g. `clippy::bytes_nth`
@@ -29,7 +28,6 @@ struct LintJson {
 }
 
 impl LintJson {
-    /// Returns a tuple of name and `file_line` for sorting and comparison.
     fn key(&self) -> impl Ord + '_ {
         (self.name.as_str(), self.file_line.as_str())
     }
@@ -40,6 +38,57 @@ impl LintJson {
     }
 }
 
+#[derive(Debug, Serialize)]
+struct SummaryRow {
+    name: String,
+    added: usize,
+    removed: usize,
+    changed: usize,
+}
+
+#[derive(Debug, Serialize)]
+struct Summary(Vec<SummaryRow>);
+
+impl fmt::Display for Summary {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(
+            "\
+| Lint | Added | Removed | Changed |
+| ---- | ----: | ------: | ------: |
+",
+        )?;
+
+        for SummaryRow {
+            name,
+            added,
+            changed,
+            removed,
+        } in &self.0
+        {
+            let html_id = to_html_id(name);
+            writeln!(f, "| [`{name}`](#{html_id}) | {added} | {changed} | {removed} |")?;
+        }
+
+        Ok(())
+    }
+}
+
+impl Summary {
+    fn new(lints: &[LintWarnings]) -> Self {
+        Summary(
+            lints
+                .iter()
+                .map(|lint| SummaryRow {
+                    name: lint.name.clone(),
+                    added: lint.added.len(),
+                    removed: lint.removed.len(),
+                    changed: lint.changed.len(),
+                })
+                .collect(),
+        )
+    }
+}
+
 /// Creates the log file output for [`crate::config::OutputFormat::Json`]
 pub(crate) fn output(clippy_warnings: Vec<ClippyWarning>) -> String {
     let mut lints: Vec<LintJson> = clippy_warnings
@@ -74,7 +123,7 @@ fn load_warnings(path: &Path) -> Vec<LintJson> {
 ///
 /// Compares warnings from `old_path` and `new_path`, then displays a summary table
 /// and detailed information about added, removed, and changed warnings.
-pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
+pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool, write_summary: Option<PathBuf>) {
     let old_warnings = load_warnings(old_path);
     let new_warnings = load_warnings(new_path);
 
@@ -108,13 +157,16 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
         }
     }
 
-    print_summary_table(&lint_warnings);
-    println!();
-
     if lint_warnings.is_empty() {
         return;
     }
 
+    let summary = Summary::new(&lint_warnings);
+    if let Some(path) = write_summary {
+        let json = serde_json::to_string(&summary).unwrap();
+        fs::write(path, json).unwrap();
+    }
+
     let truncate_after = if truncate {
         // Max 15 ensures that we at least have five messages per lint
         DEFAULT_LIMIT_PER_LINT
@@ -126,6 +178,7 @@ pub(crate) fn diff(old_path: &Path, new_path: &Path, truncate: bool) {
         usize::MAX
     };
 
+    println!("{summary}");
     for lint in lint_warnings {
         print_lint_warnings(&lint, truncate_after);
     }
@@ -140,13 +193,11 @@ struct LintWarnings {
     changed: Vec<(LintJson, LintJson)>,
 }
 
-/// Prints a formatted report for a single lint type with its warnings.
 fn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {
     let name = &lint.name;
     let html_id = to_html_id(name);
 
-    // The additional anchor is added for non GH viewers that don't prefix ID's
-    println!(r#"## `{name}` <a id="user-content-{html_id}"></a>"#);
+    println!(r#"<h2 id="{html_id}"><code>{name}</code></h2>"#);
     println!();
 
     print!(
@@ -162,22 +213,6 @@ fn print_lint_warnings(lint: &LintWarnings, truncate_after: usize) {
     print_changed_diff(&lint.changed, truncate_after / 3);
 }
 
-/// Prints a summary table of all lints with counts of added, removed, and changed warnings.
-fn print_summary_table(lints: &[LintWarnings]) {
-    println!("| Lint                                       | Added   | Removed | Changed |");
-    println!("| ------------------------------------------ | ------: | ------: | ------: |");
-
-    for lint in lints {
-        println!(
-            "| {:<62} | {:>7} | {:>7} | {:>7} |",
-            format!("[`{}`](#user-content-{})", lint.name, to_html_id(&lint.name)),
-            lint.added.len(),
-            lint.removed.len(),
-            lint.changed.len()
-        );
-    }
-}
-
 /// Prints a section of warnings with a header and formatted code blocks.
 fn print_warnings(title: &str, warnings: &[LintJson], truncate_after: usize) {
     if warnings.is_empty() {
@@ -248,17 +283,16 @@ fn truncate<T>(list: &[T], truncate_after: usize) -> &[T] {
     }
 }
 
-/// Prints a level 3 heading with an appropriate HTML ID for linking.
 fn print_h3(lint: &str, title: &str) {
     let html_id = to_html_id(lint);
-    // We have to use HTML here to be able to manually add an id.
-    println!(r#"### {title} <a id="user-content-{html_id}-{title}"></a>"#);
+    // We have to use HTML here to be able to manually add an id, GitHub doesn't add them automatically
+    println!(r#"<h3 id="{html_id}-{title}">{title}</h3>"#);
 }
 
-/// GitHub's markdown parsers doesn't like IDs with `::` and `_`. This simplifies
-/// the lint name for the HTML ID.
+/// Creates a custom ID allowed by GitHub, they must start with `user-content-` and cannot contain
+/// `::`/`_`
 fn to_html_id(lint_name: &str) -> String {
-    lint_name.replace("clippy::", "").replace('_', "-")
+    lint_name.replace("clippy::", "user-content-").replace('_', "-")
 }
 
 /// This generates the `x added` string for the start of the job summery.
@@ -270,9 +304,6 @@ fn count_string(lint: &str, label: &str, count: usize) -> String {
         format!("0 {label}")
     } else {
         let html_id = to_html_id(lint);
-        // GitHub's job summaries don't add HTML ids to headings. That's why we
-        // manually have to add them. GitHub prefixes these manual ids with
-        // `user-content-` and that's how we end up with these awesome links :D
-        format!("[{count} {label}](#user-content-{html_id}-{label})")
+        format!("[{count} {label}](#{html_id}-{label})")
     }
 }
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index eb390eecbcc..3a60cfa79f4 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -303,7 +303,12 @@ fn main() {
     let config = LintcheckConfig::new();
 
     match config.subcommand {
-        Some(Commands::Diff { old, new, truncate }) => json::diff(&old, &new, truncate),
+        Some(Commands::Diff {
+            old,
+            new,
+            truncate,
+            write_summary,
+        }) => json::diff(&old, &new, truncate, write_summary),
         Some(Commands::Popular { output, number }) => popular_crates::fetch(output, number).unwrap(),
         None => lintcheck(config),
     }
diff --git a/src/tools/clippy/rust-toolchain.toml b/src/tools/clippy/rust-toolchain.toml
index 124756a3600..f46e079db3f 100644
--- a/src/tools/clippy/rust-toolchain.toml
+++ b/src/tools/clippy/rust-toolchain.toml
@@ -1,6 +1,6 @@
 [toolchain]
 # begin autogenerated nightly
-channel = "nightly-2025-06-26"
+channel = "nightly-2025-07-10"
 # end autogenerated nightly
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index cefe654fef6..57d623b2cfc 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -16,8 +16,10 @@ use test_utils::IS_RUSTC_TEST_SUITE;
 use ui_test::custom_flags::Flag;
 use ui_test::custom_flags::edition::Edition;
 use ui_test::custom_flags::rustfix::RustfixMode;
+use ui_test::dependencies::DependencyBuilder;
 use ui_test::spanned::Spanned;
-use ui_test::{Args, CommandBuilder, Config, Match, error_on_output_conflict, status_emitter};
+use ui_test::status_emitter::StatusEmitter;
+use ui_test::{Args, CommandBuilder, Config, Match, error_on_output_conflict};
 
 use std::collections::{BTreeMap, HashMap};
 use std::env::{self, set_var, var_os};
@@ -27,46 +29,26 @@ use std::path::{Path, PathBuf};
 use std::sync::mpsc::{Sender, channel};
 use std::{fs, iter, thread};
 
-// Test dependencies may need an `extern crate` here to ensure that they show up
-// in the depinfo file (otherwise cargo thinks they are unused)
-extern crate futures;
-extern crate if_chain;
-extern crate itertools;
-extern crate parking_lot;
-extern crate quote;
-extern crate syn;
-extern crate tokio;
-
 mod test_utils;
 
-/// All crates used in UI tests are listed here
-static TEST_DEPENDENCIES: &[&str] = &[
-    "clippy_config",
-    "clippy_lints",
-    "clippy_utils",
-    "futures",
-    "if_chain",
-    "itertools",
-    "parking_lot",
-    "quote",
-    "regex",
-    "serde_derive",
-    "serde",
-    "syn",
-    "tokio",
-];
-
-/// Produces a string with an `--extern` flag for all UI test crate
-/// dependencies.
+/// All crates used in internal UI tests are listed here.
+/// We directly re-use these crates from their normal clippy builds, so we don't have them
+/// in `clippy_test_devs`. That saves a lot of time but also means they don't work in a stage 1
+/// test in rustc bootstrap.
+static INTERNAL_TEST_DEPENDENCIES: &[&str] = &["clippy_config", "clippy_lints", "clippy_utils"];
+
+/// Produces a string with an `--extern` flag for all `INTERNAL_TEST_DEPENDENCIES`.
 ///
 /// The dependency files are located by parsing the depinfo file for this test
 /// module. This assumes the `-Z binary-dep-depinfo` flag is enabled. All test
 /// dependencies must be added to Cargo.toml at the project root. Test
 /// dependencies that are not *directly* used by this test module require an
 /// `extern crate` declaration.
-fn extern_flags() -> Vec<String> {
+fn internal_extern_flags() -> Vec<String> {
+    let current_exe_path = env::current_exe().unwrap();
+    let deps_path = current_exe_path.parent().unwrap();
     let current_exe_depinfo = {
-        let mut path = env::current_exe().unwrap();
+        let mut path = current_exe_path.clone();
         path.set_extension("d");
         fs::read_to_string(path).unwrap()
     };
@@ -88,7 +70,7 @@ fn extern_flags() -> Vec<String> {
             Some((name, path_str))
         };
         if let Some((name, path)) = parse_name_path()
-            && TEST_DEPENDENCIES.contains(&name)
+            && INTERNAL_TEST_DEPENDENCIES.contains(&name)
         {
             // A dependency may be listed twice if it is available in sysroot,
             // and the sysroot dependencies are listed first. As of the writing,
@@ -96,7 +78,7 @@ fn extern_flags() -> Vec<String> {
             crates.insert(name, path);
         }
     }
-    let not_found: Vec<&str> = TEST_DEPENDENCIES
+    let not_found: Vec<&str> = INTERNAL_TEST_DEPENDENCIES
         .iter()
         .copied()
         .filter(|n| !crates.contains_key(n))
@@ -111,6 +93,7 @@ fn extern_flags() -> Vec<String> {
     crates
         .into_iter()
         .map(|(name, path)| format!("--extern={name}={path}"))
+        .chain([format!("-Ldependency={}", deps_path.display())])
         .collect()
 }
 
@@ -119,7 +102,6 @@ const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
 
 struct TestContext {
     args: Args,
-    extern_flags: Vec<String>,
     diagnostic_collector: Option<DiagnosticCollector>,
     collector_thread: Option<thread::JoinHandle<()>>,
 }
@@ -134,7 +116,6 @@ impl TestContext {
             .unzip();
         Self {
             args,
-            extern_flags: extern_flags(),
             diagnostic_collector,
             collector_thread,
         }
@@ -144,8 +125,17 @@ impl TestContext {
         let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into()));
         let mut config = Config {
             output_conflict_handling: error_on_output_conflict,
+            // Pre-fill filters with TESTNAME; will be later extended with `self.args`.
             filter_files: env::var("TESTNAME")
-                .map(|filters| filters.split(',').map(str::to_string).collect())
+                .map(|filters| {
+                    filters
+                        .split(',')
+                        // Make sure that if TESTNAME is empty we produce the empty list here,
+                        // not a list containing an empty string.
+                        .filter(|s| !s.is_empty())
+                        .map(str::to_string)
+                        .collect()
+                })
                 .unwrap_or_default(),
             target: None,
             bless_command: Some(if IS_RUSTC_TEST_SUITE {
@@ -158,6 +148,15 @@ impl TestContext {
         };
         let defaults = config.comment_defaults.base();
         defaults.set_custom("edition", Edition("2024".into()));
+        defaults.set_custom(
+            "dependencies",
+            DependencyBuilder {
+                program: CommandBuilder::cargo(),
+                crate_manifest_path: Path::new("clippy_test_deps").join("Cargo.toml"),
+                build_std: None,
+                bless_lockfile: self.args.bless,
+            },
+        );
         defaults.exit_status = None.into();
         if mandatory_annotations {
             defaults.require_annotations = Some(Spanned::dummy(true)).into();
@@ -182,12 +181,10 @@ impl TestContext {
                 "-Zui-testing",
                 "-Zdeduplicate-diagnostics=no",
                 "-Dwarnings",
-                &format!("-Ldependency={}", deps_path.display()),
             ]
             .map(OsString::from),
         );
 
-        config.program.args.extend(self.extern_flags.iter().map(OsString::from));
         // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
         config.program.envs.push(("RUSTC_ICE".into(), Some("0".into())));
 
@@ -217,7 +214,7 @@ fn run_ui(cx: &TestContext) {
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
@@ -227,13 +224,17 @@ fn run_internal_tests(cx: &TestContext) {
         return;
     }
     let mut config = cx.base_config("ui-internal", true);
+    config
+        .program
+        .args
+        .extend(internal_extern_flags().iter().map(OsString::from));
     config.bless_command = Some("cargo uitest --features internal -- -- --bless".into());
 
     ui_test::run_tests_generic(
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
@@ -257,7 +258,7 @@ fn run_ui_toml(cx: &TestContext) {
                 .envs
                 .push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
         },
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
@@ -304,7 +305,7 @@ fn run_ui_cargo(cx: &TestContext) {
                 .then(|| ui_test::default_any_file_filter(path, config) && !ignored_32bit(path))
         },
         |_config, _file_contents| {},
-        status_emitter::Text::from(cx.args.format),
+        Box::<dyn StatusEmitter>::from(cx.args.format),
     )
     .unwrap();
 }
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
index a3c35a31c33..87e4b0c5c7d 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default.stderr
@@ -136,13 +136,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5
    |
 LL |     const A: bool;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5
    |
 LL |     type SomeType;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11
@@ -172,13 +172,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5
    |
 LL |     const A: bool = false;
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5
    |
 LL |     type SomeType = ();
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr
index a3c35a31c33..87e4b0c5c7d 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.default_exp.stderr
@@ -136,13 +136,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5
    |
 LL |     const A: bool;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5
    |
 LL |     type SomeType;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11
@@ -172,13 +172,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5
    |
 LL |     const A: bool = false;
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5
    |
 LL |     type SomeType = ();
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr
index 3fdd706fc62..40505e2a1c4 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.ord_within.stderr
@@ -211,13 +211,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:155:5
    |
 LL |     const A: bool;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:153:5
    |
 LL |     type SomeType;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:171:11
@@ -247,13 +247,13 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:189:5
    |
 LL |     const A: bool = false;
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:187:5
    |
 LL |     type SomeType = ();
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed.rs:207:11
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr
index 730f12c38a0..d8db2243d41 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.var_1.stderr
@@ -28,25 +28,25 @@ error: incorrect ordering of impl items (defined order: [Fn, Type, Const])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5
    |
 LL |     type SomeType = ();
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `A`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:117:5
    |
 LL |     const A: bool = false;
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: incorrect ordering of impl items (defined order: [Fn, Type, Const])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:122:5
    |
 LL |     fn a() {}
-   |     ^^^^^^^^^
+   |     ^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:119:5
    |
 LL |     type SomeType = ();
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: incorrect ordering of items (must be alphabetically ordered)
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:149:8
@@ -76,13 +76,13 @@ error: incorrect ordering of trait items (defined order: [Fn, Type, Const])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5
    |
 LL |     type SomeType;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `A`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:161:5
    |
 LL |     const A: bool;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: incorrect ordering of trait items (defined order: [Fn, Type, Const])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:166:5
@@ -94,7 +94,7 @@ note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_mixed_var_1.rs:163:5
    |
 LL |     type SomeType;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr
index 77596ba2394..7f6bddf8005 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.only_impl.stderr
@@ -16,25 +16,25 @@ error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5
    |
 LL |     type SomeType = i8;
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `a`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:43:5
    |
 LL |     fn a() {}
-   |     ^^^^^^^^^
+   |     ^^^^^^
 
 error: incorrect ordering of impl items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:49:5
    |
 LL |     const A: bool = true;
-   |     ^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_impl.rs:46:5
    |
 LL |     type SomeType = i8;
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr
index 3d903330be8..a7cff238b78 100644
--- a/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr
+++ b/src/tools/clippy/tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.only_trait.stderr
@@ -28,13 +28,13 @@ error: incorrect ordering of trait items (defined order: [Const, Type, Fn])
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:45:5
    |
 LL |     const A: bool;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
    |
 note: should be placed before `SomeType`
   --> tests/ui-toml/arbitrary_source_item_ordering/ordering_only_trait.rs:43:5
    |
 LL |     type SomeType;
-   |     ^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^
 
 error: aborting due to 3 previous errors
 
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 20cdff5fcd1..cebfc48a884 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
@@ -450,5 +450,13 @@ help: consider removing the safety comment
 LL |     // SAFETY: unnecessary_safety_comment triggers here
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 52 previous errors
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:733:12
+   |
+LL |     return unsafe { h() };
+   |            ^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 53 previous errors
 
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 91a02bc3d7c..a2d7c1b6c79 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
@@ -723,4 +723,15 @@ fn issue_13039() {
     _ = unsafe { foo() }
 }
 
+fn rfl_issue15034() -> i32 {
+    unsafe fn h() -> i32 {
+        1i32
+    }
+    // This shouldn't lint with accept-comment-above-attributes! Thus fixing a false positive!
+    // SAFETY: My safety comment!
+    #[allow(clippy::unnecessary_cast)]
+    return unsafe { h() };
+    //~[disabled]^ ERROR: unsafe block missing a safety comment
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/assign_ops.fixed b/src/tools/clippy/tests/ui/assign_ops.fixed
index 99beea850a2..eee61f949e7 100644
--- a/src/tools/clippy/tests/ui/assign_ops.fixed
+++ b/src/tools/clippy/tests/ui/assign_ops.fixed
@@ -84,8 +84,7 @@ mod issue14871 {
         const ONE: Self;
     }
 
-    #[const_trait]
-    pub trait NumberConstants {
+    pub const trait NumberConstants {
         fn constant(value: usize) -> Self;
     }
 
diff --git a/src/tools/clippy/tests/ui/assign_ops.rs b/src/tools/clippy/tests/ui/assign_ops.rs
index 900d5ad38e0..13ffcee0a3c 100644
--- a/src/tools/clippy/tests/ui/assign_ops.rs
+++ b/src/tools/clippy/tests/ui/assign_ops.rs
@@ -84,8 +84,7 @@ mod issue14871 {
         const ONE: Self;
     }
 
-    #[const_trait]
-    pub trait NumberConstants {
+    pub const trait NumberConstants {
         fn constant(value: usize) -> Self;
     }
 
diff --git a/src/tools/clippy/tests/ui/author/if.stdout b/src/tools/clippy/tests/ui/author/if.stdout
index da359866bff..dbff55634ea 100644
--- a/src/tools/clippy/tests/ui/author/if.stdout
+++ b/src/tools/clippy/tests/ui/author/if.stdout
@@ -1,8 +1,7 @@
 if let StmtKind::Let(local) = stmt.kind
     && let Some(init) = local.init
     && let ExprKind::If(cond, then, Some(else_expr)) = init.kind
-    && let ExprKind::DropTemps(expr) = cond.kind
-    && let ExprKind::Lit(ref lit) = expr.kind
+    && let ExprKind::Lit(ref lit) = cond.kind
     && let LitKind::Bool(true) = lit.node
     && let ExprKind::Block(block, None) = then.kind
     && block.stmts.len() == 1
diff --git a/src/tools/clippy/tests/ui/author/struct.stdout b/src/tools/clippy/tests/ui/author/struct.stdout
index 1e8fbafd30c..2dedab56dce 100644
--- a/src/tools/clippy/tests/ui/author/struct.stdout
+++ b/src/tools/clippy/tests/ui/author/struct.stdout
@@ -2,8 +2,7 @@ if let ExprKind::Struct(qpath, fields, None) = expr.kind
     && fields.len() == 1
     && fields[0].ident.as_str() == "field"
     && let ExprKind::If(cond, then, Some(else_expr)) = fields[0].expr.kind
-    && let ExprKind::DropTemps(expr1) = cond.kind
-    && let ExprKind::Lit(ref lit) = expr1.kind
+    && let ExprKind::Lit(ref lit) = cond.kind
     && let LitKind::Bool(true) = lit.node
     && let ExprKind::Block(block, None) = then.kind
     && block.stmts.is_empty()
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
index 3ba2eea59f0..3f6e5245b87 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
@@ -47,3 +47,9 @@ fn implicit_cast() {
     // Do not lint references to temporaries
     core::ptr::eq(&0i32, &1i32);
 }
+
+fn issue_15141() {
+    let a = String::new();
+    // Don't lint cast to dyn trait pointers
+    let b = &a as *const dyn std::any::Any;
+}
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.rs b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
index 8cdd0512da5..20f4f40e001 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
@@ -47,3 +47,9 @@ fn implicit_cast() {
     // Do not lint references to temporaries
     core::ptr::eq(&0i32, &1i32);
 }
+
+fn issue_15141() {
+    let a = String::new();
+    // Don't lint cast to dyn trait pointers
+    let b = &a as *const dyn std::any::Any;
+}
diff --git a/src/tools/clippy/tests/ui/cast_size.32bit.stderr b/src/tools/clippy/tests/ui/cast_size.32bit.stderr
index cb1620e36a2..5811cb3607b 100644
--- a/src/tools/clippy/tests/ui/cast_size.32bit.stderr
+++ b/src/tools/clippy/tests/ui/cast_size.32bit.stderr
@@ -177,6 +177,14 @@ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bi
 LL |     9_999_999_999_999_999usize as f64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: casting `usize` to `u16` may truncate the value
+  --> tests/ui/cast_size.rs:71:20
+   |
+LL |     const N: u16 = M as u16;
+   |                    ^^^^^^^^
+   |
+   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
+
 error: literal out of range for `usize`
   --> tests/ui/cast_size.rs:63:5
    |
@@ -186,5 +194,5 @@ LL |     9_999_999_999_999_999usize as f64;
    = note: the literal `9_999_999_999_999_999usize` does not fit into the type `usize` whose range is `0..=4294967295`
    = note: `#[deny(overflowing_literals)]` on by default
 
-error: aborting due to 19 previous errors
+error: aborting due to 20 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_size.64bit.stderr b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
index b6000a52abb..ba1419583ae 100644
--- a/src/tools/clippy/tests/ui/cast_size.64bit.stderr
+++ b/src/tools/clippy/tests/ui/cast_size.64bit.stderr
@@ -177,5 +177,13 @@ error: casting `usize` to `f64` causes a loss of precision on targets with 64-bi
 LL |     9_999_999_999_999_999usize as f64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 18 previous errors
+error: casting `usize` to `u16` may truncate the value
+  --> tests/ui/cast_size.rs:71:20
+   |
+LL |     const N: u16 = M as u16;
+   |                    ^^^^^^^^
+   |
+   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
+
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_size.rs b/src/tools/clippy/tests/ui/cast_size.rs
index e5bef2a99d5..ecc58669419 100644
--- a/src/tools/clippy/tests/ui/cast_size.rs
+++ b/src/tools/clippy/tests/ui/cast_size.rs
@@ -65,3 +65,9 @@ fn main() {
     //~[32bit]^^ ERROR: literal out of range for `usize`
     // 999_999_999_999_999_999_999_999_999_999u128 as f128;
 }
+
+fn issue15163() {
+    const M: usize = 100;
+    const N: u16 = M as u16;
+    //~^ cast_possible_truncation
+}
diff --git a/src/tools/clippy/tests/ui/coerce_container_to_any.fixed b/src/tools/clippy/tests/ui/coerce_container_to_any.fixed
index ae9d3ef9656..b5b3f15b4de 100644
--- a/src/tools/clippy/tests/ui/coerce_container_to_any.fixed
+++ b/src/tools/clippy/tests/ui/coerce_container_to_any.fixed
@@ -3,7 +3,7 @@
 use std::any::Any;
 
 fn main() {
-    let x: Box<dyn Any> = Box::new(());
+    let mut x: Box<dyn Any> = Box::new(());
     let ref_x = &x;
 
     f(&*x);
@@ -15,12 +15,23 @@ fn main() {
     let _: &dyn Any = &*x;
     //~^ coerce_container_to_any
 
+    let _: &dyn Any = &*x;
+    //~^ coerce_container_to_any
+
+    let _: &mut dyn Any = &mut *x;
+    //~^ coerce_container_to_any
+
     f(&42);
     f(&Box::new(()));
     f(&Box::new(Box::new(())));
+    let ref_x = &x;
     f(&**ref_x);
     f(&*x);
     let _: &dyn Any = &*x;
+
+    // https://github.com/rust-lang/rust-clippy/issues/15045
+    #[allow(clippy::needless_borrow)]
+    (&x).downcast_ref::<()>().unwrap();
 }
 
 fn f(_: &dyn Any) {}
diff --git a/src/tools/clippy/tests/ui/coerce_container_to_any.rs b/src/tools/clippy/tests/ui/coerce_container_to_any.rs
index 9948bd48e0d..4d6527bb552 100644
--- a/src/tools/clippy/tests/ui/coerce_container_to_any.rs
+++ b/src/tools/clippy/tests/ui/coerce_container_to_any.rs
@@ -3,7 +3,7 @@
 use std::any::Any;
 
 fn main() {
-    let x: Box<dyn Any> = Box::new(());
+    let mut x: Box<dyn Any> = Box::new(());
     let ref_x = &x;
 
     f(&x);
@@ -15,12 +15,23 @@ fn main() {
     let _: &dyn Any = &x;
     //~^ coerce_container_to_any
 
+    let _: &dyn Any = &mut x;
+    //~^ coerce_container_to_any
+
+    let _: &mut dyn Any = &mut x;
+    //~^ coerce_container_to_any
+
     f(&42);
     f(&Box::new(()));
     f(&Box::new(Box::new(())));
+    let ref_x = &x;
     f(&**ref_x);
     f(&*x);
     let _: &dyn Any = &*x;
+
+    // https://github.com/rust-lang/rust-clippy/issues/15045
+    #[allow(clippy::needless_borrow)]
+    (&x).downcast_ref::<()>().unwrap();
 }
 
 fn f(_: &dyn Any) {}
diff --git a/src/tools/clippy/tests/ui/coerce_container_to_any.stderr b/src/tools/clippy/tests/ui/coerce_container_to_any.stderr
index 00ab77e0ce0..26389c9186e 100644
--- a/src/tools/clippy/tests/ui/coerce_container_to_any.stderr
+++ b/src/tools/clippy/tests/ui/coerce_container_to_any.stderr
@@ -19,5 +19,17 @@ error: coercing `&std::boxed::Box<dyn std::any::Any>` to `&dyn Any`
 LL |     let _: &dyn Any = &x;
    |                       ^^ help: consider dereferencing: `&*x`
 
-error: aborting due to 3 previous errors
+error: coercing `&mut std::boxed::Box<dyn std::any::Any>` to `&dyn Any`
+  --> tests/ui/coerce_container_to_any.rs:18:23
+   |
+LL |     let _: &dyn Any = &mut x;
+   |                       ^^^^^^ help: consider dereferencing: `&*x`
+
+error: coercing `&mut std::boxed::Box<dyn std::any::Any>` to `&mut dyn Any`
+  --> tests/ui/coerce_container_to_any.rs:21:27
+   |
+LL |     let _: &mut dyn Any = &mut x;
+   |                           ^^^^^^ help: consider dereferencing: `&mut *x`
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/disallowed_script_idents.rs b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
index 08fd1d9669e..dae380045ae 100644
--- a/src/tools/clippy/tests/ui/disallowed_script_idents.rs
+++ b/src/tools/clippy/tests/ui/disallowed_script_idents.rs
@@ -15,3 +15,17 @@ fn main() {
     let カウンタ = 10;
     //~^ disallowed_script_idents
 }
+
+fn issue15116() {
+    const ÄÖÜ: u8 = 0;
+    const _ÄÖÜ: u8 = 0;
+    const Ä_ÖÜ: u8 = 0;
+    const ÄÖ_Ü: u8 = 0;
+    const ÄÖÜ_: u8 = 0;
+    let äöüß = 1;
+    let _äöüß = 1;
+    let ä_öüß = 1;
+    let äö_üß = 1;
+    let äöü_ß = 1;
+    let äöüß_ = 1;
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed
index 065f4486e39..5c57c58fbc0 100644
--- a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.fixed
@@ -72,8 +72,6 @@ pub struct NotEmptyTight;
 
 /// ## Heading
 ///
-/// - [x][] - Done
-//~^ ERROR: link reference defined in list item
-/// - [ ][] - Not Done
-//~^ ERROR: link reference defined in list item
+/// - [x] - Done
+/// - [ ] - Not Done
 pub struct GithubCheckboxes;
diff --git a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs
index c7eab50c8b3..06b6ba49e19 100644
--- a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs
+++ b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.rs
@@ -73,7 +73,5 @@ pub struct NotEmptyTight;
 /// ## Heading
 ///
 /// - [x] - Done
-//~^ ERROR: link reference defined in list item
 /// - [ ] - Not Done
-//~^ ERROR: link reference defined in list item
 pub struct GithubCheckboxes;
diff --git a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr
index 5a815dabf4d..27314c7e968 100644
--- a/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc_nested_refdef_list_item.stderr
@@ -144,29 +144,5 @@ help: for an intra-doc link, add `[]` between the label and the colon
 LL | /// - [link][]: def "title"
    |             ++
 
-error: link reference defined in list item
-  --> tests/ui/doc/doc_nested_refdef_list_item.rs:75:7
-   |
-LL | /// - [x] - Done
-   |       ^^^
-   |
-   = help: link definitions are not shown in rendered documentation
-help: for an intra-doc link, add `[]` between the label and the colon
-   |
-LL | /// - [x][] - Done
-   |          ++
-
-error: link reference defined in list item
-  --> tests/ui/doc/doc_nested_refdef_list_item.rs:77:7
-   |
-LL | /// - [ ] - Not Done
-   |       ^^^
-   |
-   = help: link definitions are not shown in rendered documentation
-help: for an intra-doc link, add `[]` between the label and the colon
-   |
-LL | /// - [ ][] - Not Done
-   |          ++
-
-error: aborting due to 14 previous errors
+error: aborting due to 12 previous errors
 
diff --git a/src/tools/clippy/tests/ui/empty_loop_intrinsic.rs b/src/tools/clippy/tests/ui/empty_loop_intrinsic.rs
new file mode 100644
index 00000000000..a550e560965
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_loop_intrinsic.rs
@@ -0,0 +1,13 @@
+//@check-pass
+
+#![warn(clippy::empty_loop)]
+#![feature(intrinsics)]
+#![feature(rustc_attrs)]
+
+// From issue #15200
+#[rustc_intrinsic]
+#[rustc_nounwind]
+/// # Safety
+pub const unsafe fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/exit1_compile_flag_test.rs b/src/tools/clippy/tests/ui/exit1_compile_flag_test.rs
new file mode 100644
index 00000000000..9f83ed32533
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit1_compile_flag_test.rs
@@ -0,0 +1,17 @@
+//@compile-flags: --test
+#![warn(clippy::exit)]
+
+fn not_main() {
+    if true {
+        std::process::exit(4);
+        //~^ exit
+    }
+}
+
+fn main() {
+    if true {
+        std::process::exit(2);
+    };
+    not_main();
+    std::process::exit(1);
+}
diff --git a/src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr b/src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr
new file mode 100644
index 00000000000..6e33c39f0d7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit1_compile_flag_test.stderr
@@ -0,0 +1,11 @@
+error: usage of `process::exit`
+  --> tests/ui/exit1_compile_flag_test.rs:6:9
+   |
+LL |         std::process::exit(4);
+   |         ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::exit` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::exit)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/exit2_compile_flag_test.rs b/src/tools/clippy/tests/ui/exit2_compile_flag_test.rs
new file mode 100644
index 00000000000..0b994ebc56c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit2_compile_flag_test.rs
@@ -0,0 +1,15 @@
+//@compile-flags: --test
+#![warn(clippy::exit)]
+
+fn also_not_main() {
+    std::process::exit(3);
+    //~^ exit
+}
+
+fn main() {
+    if true {
+        std::process::exit(2);
+    };
+    also_not_main();
+    std::process::exit(1);
+}
diff --git a/src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr b/src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr
new file mode 100644
index 00000000000..51eb26e9c2a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit2_compile_flag_test.stderr
@@ -0,0 +1,11 @@
+error: usage of `process::exit`
+  --> tests/ui/exit2_compile_flag_test.rs:5:5
+   |
+LL |     std::process::exit(3);
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::exit` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::exit)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/exit3_compile_flag_test.rs b/src/tools/clippy/tests/ui/exit3_compile_flag_test.rs
new file mode 100644
index 00000000000..f8131ead2da
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit3_compile_flag_test.rs
@@ -0,0 +1,11 @@
+//@ check-pass
+//@compile-flags: --test
+
+#![warn(clippy::exit)]
+
+fn main() {
+    if true {
+        std::process::exit(2);
+    };
+    std::process::exit(1);
+}
diff --git a/src/tools/clippy/tests/ui/exit4.rs b/src/tools/clippy/tests/ui/exit4.rs
new file mode 100644
index 00000000000..821a26fd78b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/exit4.rs
@@ -0,0 +1,8 @@
+//@ check-pass
+//@compile-flags: --test
+
+#![warn(clippy::exit)]
+
+fn main() {
+    std::process::exit(0)
+}
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
index 83aeddb2a1f..884bae00432 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.fixed
@@ -69,3 +69,47 @@ fn _issue11831() {
 
     let _ = a + b * c;
 }
+
+fn _issue14897() {
+    let x = 1.0;
+    let _ = x * 2.0 + 0.5; // should not suggest mul_add
+    let _ = 0.5 + x * 2.0; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+    let _ = 1.2 + x * 1.2; // should not suggest mul_add
+
+    let x = -1.0;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = { 4.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = if 1 > 2 { 1.0 } else { 2.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 2.4 + 1.2;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let f = || 4.0;
+    let x = f();
+    let _ = 0.5 + f() * 1.2; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 0.1;
+    let y = x;
+    let z = y;
+    let _ = 0.5 + z * 1.2; // should not suggest mul_add
+
+    let _ = 2.0f64.mul_add(x, 0.5);
+    //~^ suboptimal_flops
+    let _ = 2.0f64.mul_add(x, 0.5);
+    //~^ suboptimal_flops
+
+    let _ = 2.0f64.mul_add(4.0, x);
+    //~^ suboptimal_flops
+
+    let y: f64 = 1.0;
+    let _ = y.mul_add(2.0, 0.5);
+    //~^ suboptimal_flops
+    let _ = 1.0f64.mul_add(2.0, 0.5);
+    //~^ suboptimal_flops
+}
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.rs b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
index 039ee8d053f..9ceb2ec9606 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.rs
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.rs
@@ -69,3 +69,47 @@ fn _issue11831() {
 
     let _ = a + b * c;
 }
+
+fn _issue14897() {
+    let x = 1.0;
+    let _ = x * 2.0 + 0.5; // should not suggest mul_add
+    let _ = 0.5 + x * 2.0; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+    let _ = 1.2 + x * 1.2; // should not suggest mul_add
+
+    let x = -1.0;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = { 4.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = if 1 > 2 { 1.0 } else { 2.0 };
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 2.4 + 1.2;
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let f = || 4.0;
+    let x = f();
+    let _ = 0.5 + f() * 1.2; // should not suggest mul_add
+    let _ = 0.5 + x * 1.2; // should not suggest mul_add
+
+    let x = 0.1;
+    let y = x;
+    let z = y;
+    let _ = 0.5 + z * 1.2; // should not suggest mul_add
+
+    let _ = 0.5 + 2.0 * x;
+    //~^ suboptimal_flops
+    let _ = 2.0 * x + 0.5;
+    //~^ suboptimal_flops
+
+    let _ = x + 2.0 * 4.0;
+    //~^ suboptimal_flops
+
+    let y: f64 = 1.0;
+    let _ = y * 2.0 + 0.5;
+    //~^ suboptimal_flops
+    let _ = 1.0 * 2.0 + 0.5;
+    //~^ suboptimal_flops
+}
diff --git a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
index 6482127bcc0..dad65ddf2ec 100644
--- a/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
+++ b/src/tools/clippy/tests/ui/floating_point_mul_add.stderr
@@ -79,5 +79,35 @@ error: multiply and add expressions can be calculated more efficiently and accur
 LL |     let _ = a - (b * u as f64);
    |             ^^^^^^^^^^^^^^^^^^ help: consider using: `b.mul_add(-(u as f64), a)`
 
-error: aborting due to 13 previous errors
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:102:13
+   |
+LL |     let _ = 0.5 + 2.0 * x;
+   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:104:13
+   |
+LL |     let _ = 2.0 * x + 0.5;
+   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(x, 0.5)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:107:13
+   |
+LL |     let _ = x + 2.0 * 4.0;
+   |             ^^^^^^^^^^^^^ help: consider using: `2.0f64.mul_add(4.0, x)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:111:13
+   |
+LL |     let _ = y * 2.0 + 0.5;
+   |             ^^^^^^^^^^^^^ help: consider using: `y.mul_add(2.0, 0.5)`
+
+error: multiply and add expressions can be calculated more efficiently and accurately
+  --> tests/ui/floating_point_mul_add.rs:113:13
+   |
+LL |     let _ = 1.0 * 2.0 + 0.5;
+   |             ^^^^^^^^^^^^^^^ help: consider using: `1.0f64.mul_add(2.0, 0.5)`
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.fixed b/src/tools/clippy/tests/ui/manual_is_variant_and.fixed
index 6425f32c09c..65a9cfa6e64 100644
--- a/src/tools/clippy/tests/ui/manual_is_variant_and.fixed
+++ b/src/tools/clippy/tests/ui/manual_is_variant_and.fixed
@@ -61,7 +61,7 @@ fn option_methods() {
 
     let _ = Some(2).is_some_and(|x| x % 2 == 0);
     //~^ manual_is_variant_and
-    let _ = Some(2).is_none_or(|x| x % 2 == 0);
+    let _ = Some(2).is_none_or(|x| x % 2 != 0);
     //~^ manual_is_variant_and
     let _ = Some(2).is_some_and(|x| x % 2 == 0);
     //~^ manual_is_variant_and
@@ -116,3 +116,113 @@ fn main() {
     option_methods();
     result_methods();
 }
+
+fn issue15202() {
+    let xs = [None, Some(b'_'), Some(b'1')];
+    for x in xs {
+        let a1 = x.is_none_or(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_none_or(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_some_and(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_some_and(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    let xs = [Err("foo"), Ok(b'_'), Ok(b'1')];
+    for x in xs {
+        let a1 = !x.is_ok_and(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = !x.is_ok_and(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_ok_and(|b| b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.is_ok_and(|b| !b.is_ascii_digit());
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+}
+
+mod with_func {
+    fn iad(b: u8) -> bool {
+        b.is_ascii_digit()
+    }
+
+    fn check_option(b: Option<u8>) {
+        let a1 = b.is_some_and(iad);
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_some_and(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_none_or(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_none_or(iad);
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(iad);
+        assert_eq!(a1, a2);
+    }
+
+    fn check_result(b: Result<u8, ()>) {
+        let a1 = b.is_ok_and(iad);
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.is_ok_and(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = !b.is_ok_and(iad);
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = !b.is_ok_and(|x| !iad(x));
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.rs b/src/tools/clippy/tests/ui/manual_is_variant_and.rs
index e069e97a04d..85b45d654a7 100644
--- a/src/tools/clippy/tests/ui/manual_is_variant_and.rs
+++ b/src/tools/clippy/tests/ui/manual_is_variant_and.rs
@@ -125,3 +125,113 @@ fn main() {
     option_methods();
     result_methods();
 }
+
+fn issue15202() {
+    let xs = [None, Some(b'_'), Some(b'1')];
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Some(true);
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Some(false);
+        //~^ manual_is_variant_and
+        let a2 = x.is_none_or(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Some(true);
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Some(false);
+        //~^ manual_is_variant_and
+        let a2 = x.is_some_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    let xs = [Err("foo"), Ok(b'_'), Ok(b'1')];
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = !x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+
+    for x in xs {
+        let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = x.is_ok_and(|b| !b.is_ascii_digit());
+        assert_eq!(a1, a2);
+    }
+}
+
+mod with_func {
+    fn iad(b: u8) -> bool {
+        b.is_ascii_digit()
+    }
+
+    fn check_option(b: Option<u8>) {
+        let a1 = b.map(iad) == Some(true);
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) == Some(false);
+        //~^ manual_is_variant_and
+        let a2 = b.is_some_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Some(true);
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Some(false);
+        //~^ manual_is_variant_and
+        let a2 = b.is_none_or(iad);
+        assert_eq!(a1, a2);
+    }
+
+    fn check_result(b: Result<u8, ()>) {
+        let a1 = b.map(iad) == Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) == Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Ok(true);
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(iad);
+        assert_eq!(a1, a2);
+
+        let a1 = b.map(iad) != Ok(false);
+        //~^ manual_is_variant_and
+        let a2 = !b.is_ok_and(|x| !iad(x));
+        assert_eq!(a1, a2);
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_is_variant_and.stderr b/src/tools/clippy/tests/ui/manual_is_variant_and.stderr
index f770319a268..da36b5a07d2 100644
--- a/src/tools/clippy/tests/ui/manual_is_variant_and.stderr
+++ b/src/tools/clippy/tests/ui/manual_is_variant_and.stderr
@@ -54,7 +54,7 @@ error: called `.map() != Some()`
   --> tests/ui/manual_is_variant_and.rs:70:13
    |
 LL |     let _ = Some(2).map(|x| x % 2 == 0) != Some(true);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Some(2).is_none_or(|x| x % 2 != 0)`
 
 error: called `.map() == Some()`
   --> tests/ui/manual_is_variant_and.rs:72:13
@@ -126,5 +126,101 @@ error: called `map(<f>).unwrap_or_default()` on a `Result` value
 LL |     let _ = res2.map(char::is_alphanumeric).unwrap_or_default(); // should lint
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `is_ok_and(char::is_alphanumeric)`
 
-error: aborting due to 15 previous errors
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:132:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| !b.is_ascii_digit())`
+
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:139:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_none_or(|b| b.is_ascii_digit())`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:146:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| b.is_ascii_digit())`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:153:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_some_and(|b| !b.is_ascii_digit())`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:161:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| b.is_ascii_digit())`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:168:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) != Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!x.is_ok_and(|b| !b.is_ascii_digit())`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:175:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| b.is_ascii_digit())`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:182:18
+   |
+LL |         let a1 = x.map(|b| b.is_ascii_digit()) == Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `x.is_ok_and(|b| !b.is_ascii_digit())`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:195:18
+   |
+LL |         let a1 = b.map(iad) == Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(iad)`
+
+error: called `.map() == Some()`
+  --> tests/ui/manual_is_variant_and.rs:200:18
+   |
+LL |         let a1 = b.map(iad) == Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_some_and(|x| !iad(x))`
+
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:205:18
+   |
+LL |         let a1 = b.map(iad) != Some(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(|x| !iad(x))`
+
+error: called `.map() != Some()`
+  --> tests/ui/manual_is_variant_and.rs:210:18
+   |
+LL |         let a1 = b.map(iad) != Some(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_none_or(iad)`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:217:18
+   |
+LL |         let a1 = b.map(iad) == Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(iad)`
+
+error: called `.map() == Ok()`
+  --> tests/ui/manual_is_variant_and.rs:222:18
+   |
+LL |         let a1 = b.map(iad) == Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `b.is_ok_and(|x| !iad(x))`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:227:18
+   |
+LL |         let a1 = b.map(iad) != Ok(true);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(iad)`
+
+error: called `.map() != Ok()`
+  --> tests/ui/manual_is_variant_and.rs:232:18
+   |
+LL |         let a1 = b.map(iad) != Ok(false);
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: use: `!b.is_ok_and(|x| !iad(x))`
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.fixed b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
index 588ba5edd8f..15f604aec29 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.fixed
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
@@ -137,3 +137,48 @@ fn not_fire() {
 fn issue11579() {
     let Some(msg) = Some("hi") else { unreachable!("can't happen") };
 }
+
+#[derive(Clone, Copy)]
+struct Issue9939<T> {
+    avalanche: T,
+}
+
+fn issue9939() {
+    let issue = Some(Issue9939 { avalanche: 1 });
+    let Some(Issue9939 { avalanche: tornado }) = issue else { unreachable!("can't happen") };
+    let issue = Some(Issue9939 { avalanche: true });
+    let Some(Issue9939 { avalanche: acid_rain }) = issue else { unreachable!("can't happen") };
+    assert_eq!(tornado, 1);
+    assert!(acid_rain);
+
+    // without shadowing
+    let _x @ Some(Issue9939 { avalanche: _y }) = issue else { unreachable!("can't happen") };
+
+    // with shadowing
+    let Some(Issue9939 { avalanche: _x }) = issue else { unreachable!("can't happen") };
+}
+
+#[derive(Clone, Copy)]
+struct Issue9939b<T, U> {
+    earthquake: T,
+    hurricane: U,
+}
+
+fn issue9939b() {
+    let issue = Some(Issue9939b {
+        earthquake: true,
+        hurricane: 1,
+    });
+    let issue @ Some(Issue9939b { earthquake: flood, hurricane: drought }) = issue else { unreachable!("can't happen") };
+    assert_eq!(drought, 1);
+    assert!(flood);
+    assert!(issue.is_some());
+
+    // without shadowing
+    let _x @ Some(Issue9939b { earthquake: erosion, hurricane: _y }) = issue else { unreachable!("can't happen") };
+    assert!(erosion);
+
+    // with shadowing
+    let Some(Issue9939b { earthquake: erosion, hurricane: _x }) = issue else { unreachable!("can't happen") };
+    assert!(erosion);
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.rs b/src/tools/clippy/tests/ui/manual_let_else_match.rs
index 6416753bac1..44a044b142b 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.rs
@@ -177,3 +177,76 @@ fn issue11579() {
         _ => unreachable!("can't happen"),
     };
 }
+
+#[derive(Clone, Copy)]
+struct Issue9939<T> {
+    avalanche: T,
+}
+
+fn issue9939() {
+    let issue = Some(Issue9939 { avalanche: 1 });
+    let tornado = match issue {
+        //~^ manual_let_else
+        Some(Issue9939 { avalanche }) => avalanche,
+        _ => unreachable!("can't happen"),
+    };
+    let issue = Some(Issue9939 { avalanche: true });
+    let acid_rain = match issue {
+        //~^ manual_let_else
+        Some(Issue9939 { avalanche: tornado }) => tornado,
+        _ => unreachable!("can't happen"),
+    };
+    assert_eq!(tornado, 1);
+    assert!(acid_rain);
+
+    // without shadowing
+    let _y = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939 { avalanche }) => avalanche,
+        None => unreachable!("can't happen"),
+    };
+
+    // with shadowing
+    let _x = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939 { avalanche }) => avalanche,
+        None => unreachable!("can't happen"),
+    };
+}
+
+#[derive(Clone, Copy)]
+struct Issue9939b<T, U> {
+    earthquake: T,
+    hurricane: U,
+}
+
+fn issue9939b() {
+    let issue = Some(Issue9939b {
+        earthquake: true,
+        hurricane: 1,
+    });
+    let (issue, drought, flood) = match issue {
+        //~^ manual_let_else
+        flood @ Some(Issue9939b { earthquake, hurricane }) => (flood, hurricane, earthquake),
+        None => unreachable!("can't happen"),
+    };
+    assert_eq!(drought, 1);
+    assert!(flood);
+    assert!(issue.is_some());
+
+    // without shadowing
+    let (_y, erosion) = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+        None => unreachable!("can't happen"),
+    };
+    assert!(erosion);
+
+    // with shadowing
+    let (_x, erosion) = match issue {
+        //~^ manual_let_else
+        _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+        None => unreachable!("can't happen"),
+    };
+    assert!(erosion);
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.stderr b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
index 393562c629b..ed6117ebffb 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
@@ -101,5 +101,75 @@ LL | |         _ => unreachable!("can't happen"),
 LL | |     };
    | |______^ help: consider writing: `let Some(msg) = Some("hi") else { unreachable!("can't happen") };`
 
-error: aborting due to 10 previous errors
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:188:5
+   |
+LL | /     let tornado = match issue {
+LL | |
+LL | |         Some(Issue9939 { avalanche }) => avalanche,
+LL | |         _ => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: tornado }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:194:5
+   |
+LL | /     let acid_rain = match issue {
+LL | |
+LL | |         Some(Issue9939 { avalanche: tornado }) => tornado,
+LL | |         _ => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: acid_rain }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:203:5
+   |
+LL | /     let _y = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939 { avalanche }) => avalanche,
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let _x @ Some(Issue9939 { avalanche: _y }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:210:5
+   |
+LL | /     let _x = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939 { avalanche }) => avalanche,
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939 { avalanche: _x }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:228:5
+   |
+LL | /     let (issue, drought, flood) = match issue {
+LL | |
+LL | |         flood @ Some(Issue9939b { earthquake, hurricane }) => (flood, hurricane, earthquake),
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let issue @ Some(Issue9939b { earthquake: flood, hurricane: drought }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:238:5
+   |
+LL | /     let (_y, erosion) = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let _x @ Some(Issue9939b { earthquake: erosion, hurricane: _y }) = issue else { unreachable!("can't happen") };`
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else_match.rs:246:5
+   |
+LL | /     let (_x, erosion) = match issue {
+LL | |
+LL | |         _x @ Some(Issue9939b { earthquake, hurricane }) => (hurricane, earthquake),
+LL | |         None => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(Issue9939b { earthquake: erosion, hurricane: _x }) = issue else { unreachable!("can't happen") };`
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed
index f1d5579a723..c113c1caaa6 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.fixed
@@ -3,8 +3,7 @@
 
 // Reduced test case from https://github.com/rust-lang/rust-clippy/issues/14658
 
-#[const_trait]
-trait ConstTrait {
+const trait ConstTrait {
     fn method(self);
 }
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs
index d495759526d..69248bc52d5 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.rs
@@ -3,8 +3,7 @@
 
 // Reduced test case from https://github.com/rust-lang/rust-clippy/issues/14658
 
-#[const_trait]
-trait ConstTrait {
+const trait ConstTrait {
     fn method(self);
 }
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.stderr b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.stderr
index b994b88fac6..7ea009cfc9b 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.stderr
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/const_trait.stderr
@@ -1,5 +1,5 @@
 error: this could be a `const fn`
-  --> tests/ui/missing_const_for_fn/const_trait.rs:24:1
+  --> tests/ui/missing_const_for_fn/const_trait.rs:23:1
    |
 LL | / fn can_be_const() {
 LL | |     0u64.method();
diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.rs b/src/tools/clippy/tests/ui/missing_panics_doc.rs
index ffdae8504f7..d016e099e30 100644
--- a/src/tools/clippy/tests/ui/missing_panics_doc.rs
+++ b/src/tools/clippy/tests/ui/missing_panics_doc.rs
@@ -250,3 +250,31 @@ pub fn issue_12760<const N: usize>() {
         }
     }
 }
+
+/// This needs documenting
+pub fn unwrap_expect_etc_in_const() {
+    let a = const { std::num::NonZeroUsize::new(1).unwrap() };
+    // This should still pass the lint even if it is guaranteed to panic at compile-time
+    let b = const { std::num::NonZeroUsize::new(0).unwrap() };
+}
+
+/// This needs documenting
+pub const fn unwrap_expect_etc_in_const_fn_fails() {
+    //~^ missing_panics_doc
+    let a = std::num::NonZeroUsize::new(1).unwrap();
+}
+
+/// This needs documenting
+pub const fn assert_in_const_fn_fails() {
+    //~^ missing_panics_doc
+    let x = 0;
+    if x == 0 {
+        panic!();
+    }
+}
+
+/// This needs documenting
+pub const fn in_const_fn<const N: usize>(n: usize) {
+    //~^ missing_panics_doc
+    assert!(N > n);
+}
diff --git a/src/tools/clippy/tests/ui/missing_panics_doc.stderr b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
index 7f0acf8de9b..85a00914427 100644
--- a/src/tools/clippy/tests/ui/missing_panics_doc.stderr
+++ b/src/tools/clippy/tests/ui/missing_panics_doc.stderr
@@ -180,5 +180,41 @@ note: first possible panic found here
 LL |         *v.last().expect("passed an empty thing")
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 15 previous errors
+error: docs for function which may panic missing `# Panics` section
+  --> tests/ui/missing_panics_doc.rs:262:1
+   |
+LL | pub const fn unwrap_expect_etc_in_const_fn_fails() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first possible panic found here
+  --> tests/ui/missing_panics_doc.rs:264:13
+   |
+LL |     let a = std::num::NonZeroUsize::new(1).unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: docs for function which may panic missing `# Panics` section
+  --> tests/ui/missing_panics_doc.rs:268:1
+   |
+LL | pub const fn assert_in_const_fn_fails() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first possible panic found here
+  --> tests/ui/missing_panics_doc.rs:272:9
+   |
+LL |         panic!();
+   |         ^^^^^^^^
+
+error: docs for function which may panic missing `# Panics` section
+  --> tests/ui/missing_panics_doc.rs:277:1
+   |
+LL | pub const fn in_const_fn<const N: usize>(n: usize) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first possible panic found here
+  --> tests/ui/missing_panics_doc.rs:279:5
+   |
+LL |     assert!(N > n);
+   |     ^^^^^^^^^^^^^^
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.fixed b/src/tools/clippy/tests/ui/needless_bool_assign.fixed
index e0c717ecda2..d6fab4c51b5 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.fixed
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.fixed
@@ -33,3 +33,12 @@ fn main() {
         b = true;
     }
 }
+
+fn issue15063(x: bool, y: bool) {
+    let mut z = false;
+
+    if x && y {
+        todo!()
+    } else { z = x || y; }
+    //~^^^^^ needless_bool_assign
+}
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.rs b/src/tools/clippy/tests/ui/needless_bool_assign.rs
index 3e4fecefa78..c504f61f4dd 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.rs
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.rs
@@ -45,3 +45,16 @@ fn main() {
         b = true;
     }
 }
+
+fn issue15063(x: bool, y: bool) {
+    let mut z = false;
+
+    if x && y {
+        todo!()
+    } else if x || y {
+        z = true;
+    } else {
+        z = false;
+    }
+    //~^^^^^ needless_bool_assign
+}
diff --git a/src/tools/clippy/tests/ui/needless_bool_assign.stderr b/src/tools/clippy/tests/ui/needless_bool_assign.stderr
index f33a4bc0c59..1d09b8b25a0 100644
--- a/src/tools/clippy/tests/ui/needless_bool_assign.stderr
+++ b/src/tools/clippy/tests/ui/needless_bool_assign.stderr
@@ -51,5 +51,16 @@ LL | |     }
    = note: `-D clippy::if-same-then-else` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::if_same_then_else)]`
 
-error: aborting due to 4 previous errors
+error: this if-then-else expression assigns a bool literal
+  --> tests/ui/needless_bool_assign.rs:54:12
+   |
+LL |       } else if x || y {
+   |  ____________^
+LL | |         z = true;
+LL | |     } else {
+LL | |         z = false;
+LL | |     }
+   | |_____^ help: you can reduce it to: `{ z = x || y; }`
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/neg_multiply.fixed b/src/tools/clippy/tests/ui/neg_multiply.fixed
index ff6e08300e2..32d466e88fc 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.fixed
+++ b/src/tools/clippy/tests/ui/neg_multiply.fixed
@@ -82,3 +82,15 @@ fn float() {
 
     -1.0 * -1.0; // should be ok
 }
+
+struct Y {
+    delta: f64,
+}
+
+fn nested() {
+    let a = Y { delta: 1.0 };
+    let b = Y { delta: 1.0 };
+    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);
+    //~^ neg_multiply
+    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);
+}
diff --git a/src/tools/clippy/tests/ui/neg_multiply.rs b/src/tools/clippy/tests/ui/neg_multiply.rs
index b0f4e85c78e..241a72c6d99 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.rs
+++ b/src/tools/clippy/tests/ui/neg_multiply.rs
@@ -82,3 +82,15 @@ fn float() {
 
     -1.0 * -1.0; // should be ok
 }
+
+struct Y {
+    delta: f64,
+}
+
+fn nested() {
+    let a = Y { delta: 1.0 };
+    let b = Y { delta: 1.0 };
+    let _ = ((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0);
+    //~^ neg_multiply
+    let _ = (-(a.delta - 0.5).abs()).total_cmp(&1.0);
+}
diff --git a/src/tools/clippy/tests/ui/neg_multiply.stderr b/src/tools/clippy/tests/ui/neg_multiply.stderr
index 2ef7e32ce05..f4fb6d3ce54 100644
--- a/src/tools/clippy/tests/ui/neg_multiply.stderr
+++ b/src/tools/clippy/tests/ui/neg_multiply.stderr
@@ -97,5 +97,11 @@ error: this multiplication by -1 can be written more succinctly
 LL |     (3.0_f32 as f64) * -1.0;
    |     ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `-(3.0_f32 as f64)`
 
-error: aborting due to 16 previous errors
+error: this multiplication by -1 can be written more succinctly
+  --> tests/ui/neg_multiply.rs:93:13
+   |
+LL |     let _ = ((a.delta - 0.5).abs() * -1.0).total_cmp(&1.0);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-(a.delta - 0.5).abs())`
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/op_ref.fixed b/src/tools/clippy/tests/ui/op_ref.fixed
index f412190b9fd..4bf4b91888c 100644
--- a/src/tools/clippy/tests/ui/op_ref.fixed
+++ b/src/tools/clippy/tests/ui/op_ref.fixed
@@ -110,3 +110,37 @@ mod issue_2597 {
         &array[idx] < val
     }
 }
+
+#[allow(clippy::needless_if)]
+fn issue15063() {
+    use std::ops::BitAnd;
+
+    macro_rules! mac {
+        ($e:expr) => {
+            $e.clone()
+        };
+    }
+
+    let x = 1;
+    if x == mac!(1) {}
+    //~^ op_ref
+
+    #[derive(Copy, Clone)]
+    struct Y(i32);
+    impl BitAnd for Y {
+        type Output = Y;
+        fn bitand(self, rhs: Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    impl<'a> BitAnd<&'a Y> for Y {
+        type Output = Y;
+        fn bitand(self, rhs: &'a Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    let x = Y(1);
+    let y = Y(2);
+    let z = x & mac!(y);
+    //~^ op_ref
+}
diff --git a/src/tools/clippy/tests/ui/op_ref.rs b/src/tools/clippy/tests/ui/op_ref.rs
index a4bbd86c7e9..9a192661aaf 100644
--- a/src/tools/clippy/tests/ui/op_ref.rs
+++ b/src/tools/clippy/tests/ui/op_ref.rs
@@ -110,3 +110,37 @@ mod issue_2597 {
         &array[idx] < val
     }
 }
+
+#[allow(clippy::needless_if)]
+fn issue15063() {
+    use std::ops::BitAnd;
+
+    macro_rules! mac {
+        ($e:expr) => {
+            $e.clone()
+        };
+    }
+
+    let x = 1;
+    if &x == &mac!(1) {}
+    //~^ op_ref
+
+    #[derive(Copy, Clone)]
+    struct Y(i32);
+    impl BitAnd for Y {
+        type Output = Y;
+        fn bitand(self, rhs: Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    impl<'a> BitAnd<&'a Y> for Y {
+        type Output = Y;
+        fn bitand(self, rhs: &'a Y) -> Y {
+            Y(self.0 & rhs.0)
+        }
+    }
+    let x = Y(1);
+    let y = Y(2);
+    let z = x & &mac!(y);
+    //~^ op_ref
+}
diff --git a/src/tools/clippy/tests/ui/op_ref.stderr b/src/tools/clippy/tests/ui/op_ref.stderr
index 51c2963a9ee..8a58b154c81 100644
--- a/src/tools/clippy/tests/ui/op_ref.stderr
+++ b/src/tools/clippy/tests/ui/op_ref.stderr
@@ -36,5 +36,25 @@ LL |         let _ = two + &three;
    |                       |
    |                       help: use the right value directly: `three`
 
-error: aborting due to 4 previous errors
+error: needlessly taken reference of both operands
+  --> tests/ui/op_ref.rs:125:8
+   |
+LL |     if &x == &mac!(1) {}
+   |        ^^^^^^^^^^^^^^
+   |
+help: use the values directly
+   |
+LL -     if &x == &mac!(1) {}
+LL +     if x == mac!(1) {}
+   |
+
+error: taken reference of right operand
+  --> tests/ui/op_ref.rs:144:13
+   |
+LL |     let z = x & &mac!(y);
+   |             ^^^^--------
+   |                 |
+   |                 help: use the right value directly: `mac!(y)`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/or_fun_call.fixed b/src/tools/clippy/tests/ui/or_fun_call.fixed
index 34f3e046841..bcd2602edb6 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.fixed
+++ b/src/tools/clippy/tests/ui/or_fun_call.fixed
@@ -439,4 +439,24 @@ fn test_option_get_or_insert() {
     //~^ or_fun_call
 }
 
+fn test_option_and() {
+    // assume that this is slow call
+    fn g() -> Option<u8> {
+        Some(99)
+    }
+    let mut x = Some(42_u8);
+    let _ = x.and_then(|_| g());
+    //~^ or_fun_call
+}
+
+fn test_result_and() {
+    // assume that this is slow call
+    fn g() -> Result<u8, ()> {
+        Ok(99)
+    }
+    let mut x: Result<u8, ()> = Ok(42);
+    let _ = x.and_then(|_| g());
+    //~^ or_fun_call
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.rs b/src/tools/clippy/tests/ui/or_fun_call.rs
index dc57bd6060a..8d1202ebf91 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.rs
+++ b/src/tools/clippy/tests/ui/or_fun_call.rs
@@ -439,4 +439,24 @@ fn test_option_get_or_insert() {
     //~^ or_fun_call
 }
 
+fn test_option_and() {
+    // assume that this is slow call
+    fn g() -> Option<u8> {
+        Some(99)
+    }
+    let mut x = Some(42_u8);
+    let _ = x.and(g());
+    //~^ or_fun_call
+}
+
+fn test_result_and() {
+    // assume that this is slow call
+    fn g() -> Result<u8, ()> {
+        Ok(99)
+    }
+    let mut x: Result<u8, ()> = Ok(42);
+    let _ = x.and(g());
+    //~^ or_fun_call
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/or_fun_call.stderr b/src/tools/clippy/tests/ui/or_fun_call.stderr
index 0f159fe8bff..585ee2d0e19 100644
--- a/src/tools/clippy/tests/ui/or_fun_call.stderr
+++ b/src/tools/clippy/tests/ui/or_fun_call.stderr
@@ -264,5 +264,17 @@ error: function call inside of `get_or_insert`
 LL |     let _ = x.get_or_insert(g());
    |               ^^^^^^^^^^^^^^^^^^ help: try: `get_or_insert_with(g)`
 
-error: aborting due to 41 previous errors
+error: function call inside of `and`
+  --> tests/ui/or_fun_call.rs:448:15
+   |
+LL |     let _ = x.and(g());
+   |               ^^^^^^^^ help: try: `and_then(|_| g())`
+
+error: function call inside of `and`
+  --> tests/ui/or_fun_call.rs:458:15
+   |
+LL |     let _ = x.and(g());
+   |               ^^^^^^^^ help: try: `and_then(|_| g())`
+
+error: aborting due to 43 previous errors
 
diff --git a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr
index dc01a375060..0f700654f7c 100644
--- a/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr
+++ b/src/tools/clippy/tests/ui/partialeq_ne_impl.stderr
@@ -1,12 +1,8 @@
 error: re-implementing `PartialEq::ne` is unnecessary
   --> tests/ui/partialeq_ne_impl.rs:9:5
    |
-LL | /     fn ne(&self, _: &Foo) -> bool {
-LL | |
-LL | |
-LL | |         false
-LL | |     }
-   | |_____^
+LL |     fn ne(&self, _: &Foo) -> bool {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::partialeq-ne-impl` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::partialeq_ne_impl)]`
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index 65f3f05d6cb..578641e910d 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.rs
+++ b/src/tools/clippy/tests/ui/ptr_arg.rs
@@ -312,7 +312,7 @@ mod issue_9218 {
 
     // Inferred to be `&'a str`, afaik.
     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
-        //~^ ERROR: lifetime flowing from input to output with different syntax
+        //~^ ERROR: eliding a lifetime that's named elsewhere is confusing
         todo!()
     }
 }
diff --git a/src/tools/clippy/tests/ui/ptr_arg.stderr b/src/tools/clippy/tests/ui/ptr_arg.stderr
index 600343754e1..fd9ceddfe11 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.stderr
+++ b/src/tools/clippy/tests/ui/ptr_arg.stderr
@@ -231,18 +231,19 @@ error: writing `&String` instead of `&str` involves a new object where a slice w
 LL |     fn good(v1: &String, v2: &String) {
    |                              ^^^^^^^ help: change this to: `&str`
 
-error: lifetime flowing from input to output with different syntax can be confusing
+error: eliding a lifetime that's named elsewhere is confusing
   --> tests/ui/ptr_arg.rs:314:36
    |
 LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &str {
-   |                                    ^^     ^^           ---- the lifetime gets resolved as `'a`
+   |                                    ^^     ^^           ---- the same lifetime is elided here
    |                                    |      |
-   |                                    |      these lifetimes flow to the output
-   |                                    these lifetimes flow to the output
+   |                                    |      the lifetime is named here
+   |                                    the lifetime is named here
    |
+   = help: the same lifetime is referred to in inconsistent ways, making the signature confusing
    = note: `-D mismatched-lifetime-syntaxes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(mismatched_lifetime_syntaxes)]`
-help: one option is to consistently use `'a`
+help: consistently use `'a`
    |
 LL |     fn cow_good_ret_ty<'a>(input: &'a Cow<'a, str>) -> &'a str {
    |                                                         ++
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 099c118e64e..9f6643e8d52 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -60,7 +60,7 @@ fn issue9956() {
     //~^ redundant_closure_call
 
     // immediately calling only one closure, so we can't remove the other ones
-    let a = (|| || 123);
+    let a = || || 123;
     //~^ redundant_closure_call
     dbg!(a()());
 
@@ -144,3 +144,15 @@ fn issue_12358() {
     // different.
     make_closure!(x)();
 }
+
+#[rustfmt::skip]
+fn issue_9583() {
+    Some(true) == Some(true);
+     //~^ redundant_closure_call
+    Some(true) == Some(true);
+    //~^ redundant_closure_call
+    Some(if 1 > 2 {1} else {2}) == Some(2);
+    //~^ redundant_closure_call
+    Some( 1 > 2 ) == Some(true);
+    //~^ redundant_closure_call
+}
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 da5dd7ef263..34f22878678 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -144,3 +144,15 @@ fn issue_12358() {
     // different.
     make_closure!(x)();
 }
+
+#[rustfmt::skip]
+fn issue_9583() {
+    (|| { Some(true) })() == Some(true);
+     //~^ redundant_closure_call
+    (|| Some(true))() == Some(true);
+    //~^ redundant_closure_call
+    (|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);
+    //~^ redundant_closure_call
+    (|| { Some( 1 > 2 ) })() == Some(true);
+    //~^ redundant_closure_call
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
index 2c35aafbe31..a5591cf7813 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.stderr
@@ -95,7 +95,7 @@ error: try not to call a closure in the expression where it is declared
   --> tests/ui/redundant_closure_call_fixable.rs:63:13
    |
 LL |     let a = (|| || || 123)();
-   |             ^^^^^^^^^^^^^^^^ help: try doing something like: `(|| || 123)`
+   |             ^^^^^^^^^^^^^^^^ help: try doing something like: `|| || 123`
 
 error: try not to call a closure in the expression where it is declared
   --> tests/ui/redundant_closure_call_fixable.rs:68:13
@@ -145,5 +145,29 @@ error: try not to call a closure in the expression where it is declared
 LL |     std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `13_i32 + 36_i32`
 
-error: aborting due to 17 previous errors
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:150:5
+   |
+LL |     (|| { Some(true) })() == Some(true);
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`
+
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:152:5
+   |
+LL |     (|| Some(true))() == Some(true);
+   |     ^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(true)`
+
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:154:5
+   |
+LL |     (|| { Some(if 1 > 2 {1} else {2}) })() == Some(2);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some(if 1 > 2 {1} else {2})`
+
+error: try not to call a closure in the expression where it is declared
+  --> tests/ui/redundant_closure_call_fixable.rs:156:5
+   |
+LL |     (|| { Some( 1 > 2 ) })() == Some(true);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `Some( 1 > 2 )`
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/return_and_then.fixed b/src/tools/clippy/tests/ui/return_and_then.fixed
index 8d9481d1595..8ee259b97f3 100644
--- a/src/tools/clippy/tests/ui/return_and_then.fixed
+++ b/src/tools/clippy/tests/ui/return_and_then.fixed
@@ -99,6 +99,92 @@ fn main() {
         };
         None
     }
+
+    #[expect(clippy::diverging_sub_expression)]
+    fn with_return_in_expression() -> Option<i32> {
+        _ = (
+            return {
+                let x = Some("")?;
+                if x.len() > 2 { Some(3) } else { None }
+            },
+            //~^ return_and_then
+            10,
+        );
+    }
+
+    fn inside_if(a: bool, i: Option<u32>) -> Option<u32> {
+        if a {
+            let i = i?;
+            if i > 3 { Some(i) } else { None }
+            //~^ return_and_then
+        } else {
+            Some(42)
+        }
+    }
+
+    fn inside_match(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => {
+                let i = i?;
+                if i > 3 { Some(i) } else { None }
+            },
+            //~^ return_and_then
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    fn inside_match_and_block_and_if(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => {
+                let a = a * 3;
+                if a.is_multiple_of(2) {
+                    let i = i?;
+                    if i > 3 { Some(i) } else { None }
+                    //~^ return_and_then
+                } else {
+                    Some(10)
+                }
+            },
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    #[expect(clippy::never_loop)]
+    fn with_break(i: Option<u32>) -> Option<u32> {
+        match i {
+            Some(1) => loop {
+                break ({
+                    let i = i?;
+                    if i > 3 { Some(i) } else { None }
+                });
+                //~^ return_and_then
+            },
+            Some(2) => 'foo: loop {
+                loop {
+                    break 'foo ({
+                        let i = i?;
+                        if i > 3 { Some(i) } else { None }
+                    });
+                    //~^ return_and_then
+                }
+            },
+            Some(3) => 'bar: {
+                break 'bar ({
+                    let i = i?;
+                    if i > 3 { Some(i) } else { None }
+                });
+                //~^ return_and_then
+            },
+            Some(4) => 'baz: loop {
+                _ = loop {
+                    break i.and_then(|i| if i > 3 { Some(i) } else { None });
+                };
+            },
+            _ => None,
+        }
+    }
 }
 
 fn gen_option(n: i32) -> Option<i32> {
@@ -124,3 +210,48 @@ mod issue14781 {
         Ok(())
     }
 }
+
+mod issue15111 {
+    #[derive(Debug)]
+    struct EvenOdd {
+        even: Option<u32>,
+        odd: Option<u32>,
+    }
+
+    impl EvenOdd {
+        fn new(i: Option<u32>) -> Self {
+            Self {
+                even: i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }),
+                odd: i.and_then(|i| if i.is_multiple_of(2) { None } else { Some(i) }),
+            }
+        }
+    }
+
+    fn with_if_let(i: Option<u32>) -> u32 {
+        if let Some(x) = i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }) {
+            x
+        } else {
+            std::hint::black_box(0)
+        }
+    }
+
+    fn main() {
+        let _ = EvenOdd::new(Some(2));
+    }
+}
+
+mod issue14927 {
+    use std::path::Path;
+    struct A {
+        pub func: fn(check: bool, a: &Path, b: Option<&Path>),
+    }
+    const MY_A: A = A {
+        func: |check, a, b| {
+            if check {
+                let _ = ();
+            } else if let Some(parent) = b.and_then(|p| p.parent()) {
+                let _ = ();
+            }
+        },
+    };
+}
diff --git a/src/tools/clippy/tests/ui/return_and_then.rs b/src/tools/clippy/tests/ui/return_and_then.rs
index beada921a91..dcb344f142b 100644
--- a/src/tools/clippy/tests/ui/return_and_then.rs
+++ b/src/tools/clippy/tests/ui/return_and_then.rs
@@ -90,6 +90,75 @@ fn main() {
         };
         None
     }
+
+    #[expect(clippy::diverging_sub_expression)]
+    fn with_return_in_expression() -> Option<i32> {
+        _ = (
+            return Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }),
+            //~^ return_and_then
+            10,
+        );
+    }
+
+    fn inside_if(a: bool, i: Option<u32>) -> Option<u32> {
+        if a {
+            i.and_then(|i| if i > 3 { Some(i) } else { None })
+            //~^ return_and_then
+        } else {
+            Some(42)
+        }
+    }
+
+    fn inside_match(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => i.and_then(|i| if i > 3 { Some(i) } else { None }),
+            //~^ return_and_then
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    fn inside_match_and_block_and_if(a: u32, i: Option<u32>) -> Option<u32> {
+        match a {
+            1 | 2 => {
+                let a = a * 3;
+                if a.is_multiple_of(2) {
+                    i.and_then(|i| if i > 3 { Some(i) } else { None })
+                    //~^ return_and_then
+                } else {
+                    Some(10)
+                }
+            },
+            3 | 4 => Some(42),
+            _ => None,
+        }
+    }
+
+    #[expect(clippy::never_loop)]
+    fn with_break(i: Option<u32>) -> Option<u32> {
+        match i {
+            Some(1) => loop {
+                break i.and_then(|i| if i > 3 { Some(i) } else { None });
+                //~^ return_and_then
+            },
+            Some(2) => 'foo: loop {
+                loop {
+                    break 'foo i.and_then(|i| if i > 3 { Some(i) } else { None });
+                    //~^ return_and_then
+                }
+            },
+            Some(3) => 'bar: {
+                break 'bar i.and_then(|i| if i > 3 { Some(i) } else { None });
+                //~^ return_and_then
+            },
+            Some(4) => 'baz: loop {
+                _ = loop {
+                    break i.and_then(|i| if i > 3 { Some(i) } else { None });
+                };
+            },
+            _ => None,
+        }
+    }
 }
 
 fn gen_option(n: i32) -> Option<i32> {
@@ -115,3 +184,48 @@ mod issue14781 {
         Ok(())
     }
 }
+
+mod issue15111 {
+    #[derive(Debug)]
+    struct EvenOdd {
+        even: Option<u32>,
+        odd: Option<u32>,
+    }
+
+    impl EvenOdd {
+        fn new(i: Option<u32>) -> Self {
+            Self {
+                even: i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }),
+                odd: i.and_then(|i| if i.is_multiple_of(2) { None } else { Some(i) }),
+            }
+        }
+    }
+
+    fn with_if_let(i: Option<u32>) -> u32 {
+        if let Some(x) = i.and_then(|i| if i.is_multiple_of(2) { Some(i) } else { None }) {
+            x
+        } else {
+            std::hint::black_box(0)
+        }
+    }
+
+    fn main() {
+        let _ = EvenOdd::new(Some(2));
+    }
+}
+
+mod issue14927 {
+    use std::path::Path;
+    struct A {
+        pub func: fn(check: bool, a: &Path, b: Option<&Path>),
+    }
+    const MY_A: A = A {
+        func: |check, a, b| {
+            if check {
+                let _ = ();
+            } else if let Some(parent) = b.and_then(|p| p.parent()) {
+                let _ = ();
+            }
+        },
+    };
+}
diff --git a/src/tools/clippy/tests/ui/return_and_then.stderr b/src/tools/clippy/tests/ui/return_and_then.stderr
index 5feca882860..33867ea818a 100644
--- a/src/tools/clippy/tests/ui/return_and_then.stderr
+++ b/src/tools/clippy/tests/ui/return_and_then.stderr
@@ -146,5 +146,99 @@ LL +                 if x.len() > 2 { Some(3) } else { None }
 LL ~             };
    |
 
-error: aborting due to 10 previous errors
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:97:20
+   |
+LL |             return Some("").and_then(|x| if x.len() > 2 { Some(3) } else { None }),
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~             return {
+LL +                 let x = Some("")?;
+LL +                 if x.len() > 2 { Some(3) } else { None }
+LL ~             },
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:105:13
+   |
+LL |             i.and_then(|i| if i > 3 { Some(i) } else { None })
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~             let i = i?;
+LL +             if i > 3 { Some(i) } else { None }
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:114:22
+   |
+LL |             1 | 2 => i.and_then(|i| if i > 3 { Some(i) } else { None }),
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~             1 | 2 => {
+LL +                 let i = i?;
+LL +                 if i > 3 { Some(i) } else { None }
+LL ~             },
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:126:21
+   |
+LL |                     i.and_then(|i| if i > 3 { Some(i) } else { None })
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                     let i = i?;
+LL +                     if i > 3 { Some(i) } else { None }
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:141:23
+   |
+LL |                 break i.and_then(|i| if i > 3 { Some(i) } else { None });
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                 break ({
+LL +                     let i = i?;
+LL +                     if i > 3 { Some(i) } else { None }
+LL ~                 });
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:146:32
+   |
+LL |                     break 'foo i.and_then(|i| if i > 3 { Some(i) } else { None });
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                     break 'foo ({
+LL +                         let i = i?;
+LL +                         if i > 3 { Some(i) } else { None }
+LL ~                     });
+   |
+
+error: use the `?` operator instead of an `and_then` call
+  --> tests/ui/return_and_then.rs:151:28
+   |
+LL |                 break 'bar i.and_then(|i| if i > 3 { Some(i) } else { None });
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~                 break 'bar ({
+LL +                     let i = i?;
+LL +                     if i > 3 { Some(i) } else { None }
+LL ~                 });
+   |
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/same_name_method.stderr b/src/tools/clippy/tests/ui/same_name_method.stderr
index b2624ac4d26..bf7456d80e2 100644
--- a/src/tools/clippy/tests/ui/same_name_method.stderr
+++ b/src/tools/clippy/tests/ui/same_name_method.stderr
@@ -2,13 +2,13 @@ error: method's name is the same as an existing method in a trait
   --> tests/ui/same_name_method.rs:20:13
    |
 LL |             fn foo() {}
-   |             ^^^^^^^^^^^
+   |             ^^^^^^^^
    |
 note: existing `foo` defined here
   --> tests/ui/same_name_method.rs:25:13
    |
 LL |             fn foo() {}
-   |             ^^^^^^^^^^^
+   |             ^^^^^^^^
    = note: `-D clippy::same-name-method` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::same_name_method)]`
 
@@ -16,7 +16,7 @@ error: method's name is the same as an existing method in a trait
   --> tests/ui/same_name_method.rs:35:13
    |
 LL |             fn clone() {}
-   |             ^^^^^^^^^^^^^
+   |             ^^^^^^^^^^
    |
 note: existing `clone` defined here
   --> tests/ui/same_name_method.rs:31:18
@@ -28,19 +28,19 @@ error: method's name is the same as an existing method in a trait
   --> tests/ui/same_name_method.rs:46:13
    |
 LL |             fn foo() {}
-   |             ^^^^^^^^^^^
+   |             ^^^^^^^^
    |
 note: existing `foo` defined here
   --> tests/ui/same_name_method.rs:51:13
    |
 LL |             fn foo() {}
-   |             ^^^^^^^^^^^
+   |             ^^^^^^^^
 
 error: method's name is the same as an existing method in a trait
   --> tests/ui/same_name_method.rs:61:13
    |
 LL |             fn foo() {}
-   |             ^^^^^^^^^^^
+   |             ^^^^^^^^
    |
 note: existing `foo` defined here
   --> tests/ui/same_name_method.rs:65:9
@@ -52,7 +52,7 @@ error: method's name is the same as an existing method in a trait
   --> tests/ui/same_name_method.rs:74:13
    |
 LL |             fn foo() {}
-   |             ^^^^^^^^^^^
+   |             ^^^^^^^^
    |
 note: existing `foo` defined here
   --> tests/ui/same_name_method.rs:79:9
@@ -64,7 +64,7 @@ error: method's name is the same as an existing method in a trait
   --> tests/ui/same_name_method.rs:74:13
    |
 LL |             fn foo() {}
-   |             ^^^^^^^^^^^
+   |             ^^^^^^^^
    |
 note: existing `foo` defined here
   --> tests/ui/same_name_method.rs:81:9
diff --git a/src/tools/clippy/tests/ui/serde.stderr b/src/tools/clippy/tests/ui/serde.stderr
index eb6b7c6b0c3..652248e3578 100644
--- a/src/tools/clippy/tests/ui/serde.stderr
+++ b/src/tools/clippy/tests/ui/serde.stderr
@@ -5,10 +5,7 @@ LL | /     fn visit_string<E>(self, _v: String) -> Result<Self::Value, E>
 LL | |
 LL | |     where
 LL | |         E: serde::de::Error,
-LL | |     {
-LL | |         unimplemented!()
-LL | |     }
-   | |_____^
+   | |____________________________^
    |
    = note: `-D clippy::serde-api-misuse` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::serde_api_misuse)]`
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 1820ade422f..603ab0accb0 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.fixed
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
@@ -8,7 +8,6 @@ extern crate alloc;
 #[macro_use]
 extern crate proc_macro_derive;
 
-#[warn(clippy::std_instead_of_core)]
 fn std_instead_of_core() {
     // Regular import
     use core::hash::Hasher;
@@ -90,9 +89,3 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: core::net::IpAddr) {}
 //~^ std_instead_of_core
-
-#[warn(clippy::std_instead_of_core)]
-#[rustfmt::skip]
-fn issue14982() {
-    use std::{collections::HashMap, hash::Hash};
-}
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 32c49330981..b6d4abad9f8 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.rs
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs
@@ -8,7 +8,6 @@ extern crate alloc;
 #[macro_use]
 extern crate proc_macro_derive;
 
-#[warn(clippy::std_instead_of_core)]
 fn std_instead_of_core() {
     // Regular import
     use std::hash::Hasher;
@@ -90,9 +89,3 @@ fn msrv_1_76(_: std::net::IpAddr) {}
 #[clippy::msrv = "1.77"]
 fn msrv_1_77(_: std::net::IpAddr) {}
 //~^ std_instead_of_core
-
-#[warn(clippy::std_instead_of_core)]
-#[rustfmt::skip]
-fn issue14982() {
-    use std::{collections::HashMap, hash::Hash};
-}
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 45d60d235ce..a5f8fbbe37c 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:14:9
+  --> tests/ui/std_instead_of_core.rs:13:9
    |
 LL |     use std::hash::Hasher;
    |         ^^^ help: consider importing the item from `core`: `core`
@@ -8,61 +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:17:11
+  --> tests/ui/std_instead_of_core.rs:16: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:23:9
+  --> tests/ui/std_instead_of_core.rs:22: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:28:9
+  --> tests/ui/std_instead_of_core.rs:27: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
+  --> tests/ui/std_instead_of_core.rs:34: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:37:21
+  --> tests/ui/std_instead_of_core.rs:36: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:41:16
+  --> tests/ui/std_instead_of_core.rs:40: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:43:27
+  --> tests/ui/std_instead_of_core.rs:42: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:48:9
+  --> tests/ui/std_instead_of_core.rs:47:9
    |
 LL |     use std::error::Error;
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:52:9
+  --> tests/ui/std_instead_of_core.rs:51: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:59:9
+  --> tests/ui/std_instead_of_core.rs:58:9
    |
 LL |     use std::vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
@@ -71,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:61:9
+  --> tests/ui/std_instead_of_core.rs:60: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:67:9
+  --> tests/ui/std_instead_of_core.rs:66:9
    |
 LL |     use alloc::slice::from_ref;
    |         ^^^^^ help: consider importing the item from `core`: `core`
@@ -86,13 +86,13 @@ LL |     use alloc::slice::from_ref;
    = help: to override `-D warnings` add `#[allow(clippy::alloc_instead_of_core)]`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:82:9
+  --> tests/ui/std_instead_of_core.rs:81:9
    |
 LL |         std::intrinsics::copy(a, b, 1);
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> tests/ui/std_instead_of_core.rs:91:17
+  --> tests/ui/std_instead_of_core.rs:90:17
    |
 LL | fn msrv_1_77(_: std::net::IpAddr) {}
    |                 ^^^ help: consider importing the item from `core`: `core`
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs
new file mode 100644
index 00000000000..957f472a454
--- /dev/null
+++ b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.rs
@@ -0,0 +1,18 @@
+//@no-rustfix
+
+#![warn(clippy::std_instead_of_core)]
+#![warn(clippy::std_instead_of_alloc)]
+#![allow(unused_imports)]
+
+#[rustfmt::skip]
+fn issue14982() {
+    use std::{collections::HashMap, hash::Hash};
+    //~^ std_instead_of_core
+}
+
+#[rustfmt::skip]
+fn issue15143() {
+    use std::{error::Error, vec::Vec, fs::File};
+    //~^ std_instead_of_core
+    //~| std_instead_of_alloc
+}
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr
new file mode 100644
index 00000000000..0cdec56c992
--- /dev/null
+++ b/src/tools/clippy/tests/ui/std_instead_of_core_unfixable.stderr
@@ -0,0 +1,30 @@
+error: used import from `std` instead of `core`
+  --> tests/ui/std_instead_of_core_unfixable.rs:9:43
+   |
+LL |     use std::{collections::HashMap, hash::Hash};
+   |                                           ^^^^
+   |
+   = help: consider importing the item from `core`
+   = note: `-D clippy::std-instead-of-core` implied by `-D warnings`
+   = 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_unfixable.rs:15:22
+   |
+LL |     use std::{error::Error, vec::Vec, fs::File};
+   |                      ^^^^^
+   |
+   = help: consider importing the item from `core`
+
+error: used import from `std` instead of `alloc`
+  --> tests/ui/std_instead_of_core_unfixable.rs:15:34
+   |
+LL |     use std::{error::Error, vec::Vec, fs::File};
+   |                                  ^^^
+   |
+   = help: consider importing the item from `alloc`
+   = note: `-D clippy::std-instead-of-alloc` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/swap_with_temporary.fixed b/src/tools/clippy/tests/ui/swap_with_temporary.fixed
index 4007d998ba0..4b4b0d4aebd 100644
--- a/src/tools/clippy/tests/ui/swap_with_temporary.fixed
+++ b/src/tools/clippy/tests/ui/swap_with_temporary.fixed
@@ -72,3 +72,49 @@ fn dont_lint_those(s: &mut S, v: &mut [String], w: Option<&mut String>) {
     swap(&mut s.t, v.get_mut(0).unwrap());
     swap(w.unwrap(), &mut s.t);
 }
+
+fn issue15166() {
+    use std::sync::Mutex;
+
+    struct A {
+        thing: Mutex<Vec<u8>>,
+    }
+
+    impl A {
+        fn a(&self) {
+            let mut new_vec = vec![42];
+            // Do not lint here, as neither `new_vec` nor the result of `.lock().unwrap()` are temporaries
+            swap(&mut new_vec, &mut self.thing.lock().unwrap());
+            for v in new_vec {
+                // Do something with v
+            }
+            // Here `vec![42]` is temporary though, and a proper dereference will have to be used in the fix
+            *self.thing.lock().unwrap() = vec![42];
+            //~^ ERROR: swapping with a temporary value is inefficient
+        }
+    }
+}
+
+fn multiple_deref() {
+    let mut v1 = &mut &mut &mut vec![42];
+    ***v1 = vec![];
+    //~^ ERROR: swapping with a temporary value is inefficient
+
+    struct Wrapper<T: ?Sized>(T);
+    impl<T: ?Sized> std::ops::Deref for Wrapper<T> {
+        type Target = T;
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<T: ?Sized> std::ops::DerefMut for Wrapper<T> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    use std::sync::Mutex;
+    let mut v1 = Mutex::new(Wrapper(Wrapper(vec![42])));
+    ***v1.lock().unwrap() = vec![];
+    //~^ ERROR: swapping with a temporary value is inefficient
+}
diff --git a/src/tools/clippy/tests/ui/swap_with_temporary.rs b/src/tools/clippy/tests/ui/swap_with_temporary.rs
index d403c086c0f..8e35e6144d9 100644
--- a/src/tools/clippy/tests/ui/swap_with_temporary.rs
+++ b/src/tools/clippy/tests/ui/swap_with_temporary.rs
@@ -72,3 +72,49 @@ fn dont_lint_those(s: &mut S, v: &mut [String], w: Option<&mut String>) {
     swap(&mut s.t, v.get_mut(0).unwrap());
     swap(w.unwrap(), &mut s.t);
 }
+
+fn issue15166() {
+    use std::sync::Mutex;
+
+    struct A {
+        thing: Mutex<Vec<u8>>,
+    }
+
+    impl A {
+        fn a(&self) {
+            let mut new_vec = vec![42];
+            // Do not lint here, as neither `new_vec` nor the result of `.lock().unwrap()` are temporaries
+            swap(&mut new_vec, &mut self.thing.lock().unwrap());
+            for v in new_vec {
+                // Do something with v
+            }
+            // Here `vec![42]` is temporary though, and a proper dereference will have to be used in the fix
+            swap(&mut vec![42], &mut self.thing.lock().unwrap());
+            //~^ ERROR: swapping with a temporary value is inefficient
+        }
+    }
+}
+
+fn multiple_deref() {
+    let mut v1 = &mut &mut &mut vec![42];
+    swap(&mut ***v1, &mut vec![]);
+    //~^ ERROR: swapping with a temporary value is inefficient
+
+    struct Wrapper<T: ?Sized>(T);
+    impl<T: ?Sized> std::ops::Deref for Wrapper<T> {
+        type Target = T;
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<T: ?Sized> std::ops::DerefMut for Wrapper<T> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    use std::sync::Mutex;
+    let mut v1 = Mutex::new(Wrapper(Wrapper(vec![42])));
+    swap(&mut vec![], &mut v1.lock().unwrap());
+    //~^ ERROR: swapping with a temporary value is inefficient
+}
diff --git a/src/tools/clippy/tests/ui/swap_with_temporary.stderr b/src/tools/clippy/tests/ui/swap_with_temporary.stderr
index 59355771a96..5ca4fccd37a 100644
--- a/src/tools/clippy/tests/ui/swap_with_temporary.stderr
+++ b/src/tools/clippy/tests/ui/swap_with_temporary.stderr
@@ -96,5 +96,41 @@ note: this expression returns a temporary value
 LL |     swap(mac!(refmut y), &mut func());
    |                               ^^^^^^
 
-error: aborting due to 8 previous errors
+error: swapping with a temporary value is inefficient
+  --> tests/ui/swap_with_temporary.rs:92:13
+   |
+LL |             swap(&mut vec![42], &mut self.thing.lock().unwrap());
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `*self.thing.lock().unwrap() = vec![42]`
+   |
+note: this expression returns a temporary value
+  --> tests/ui/swap_with_temporary.rs:92:23
+   |
+LL |             swap(&mut vec![42], &mut self.thing.lock().unwrap());
+   |                       ^^^^^^^^
+
+error: swapping with a temporary value is inefficient
+  --> tests/ui/swap_with_temporary.rs:100:5
+   |
+LL |     swap(&mut ***v1, &mut vec![]);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `***v1 = vec![]`
+   |
+note: this expression returns a temporary value
+  --> tests/ui/swap_with_temporary.rs:100:27
+   |
+LL |     swap(&mut ***v1, &mut vec![]);
+   |                           ^^^^^^
+
+error: swapping with a temporary value is inefficient
+  --> tests/ui/swap_with_temporary.rs:118:5
+   |
+LL |     swap(&mut vec![], &mut v1.lock().unwrap());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use assignment instead: `***v1.lock().unwrap() = vec![]`
+   |
+note: this expression returns a temporary value
+  --> tests/ui/swap_with_temporary.rs:118:15
+   |
+LL |     swap(&mut vec![], &mut v1.lock().unwrap());
+   |               ^^^^^^
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs
index 2e67fb65efc..3bae23f1984 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs
+++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.rs
@@ -4,6 +4,7 @@
 // Normalize the emitted location so this doesn't need
 // updating everytime someone adds or removes a line.
 //@normalize-stderr-test: ".rs:\d+:\d+" -> ".rs:LL:CC"
+//@normalize-stderr-test: "src/tools/clippy/" -> ""
 
 #![warn(clippy::let_and_return, clippy::unnecessary_cast)]
 
@@ -12,7 +13,7 @@ fn main() {
     let a = 3u32;
     let b = a as u32;
     //~^ unnecessary_cast
-    
+
     // Check the provenance of a lint sent through `TyCtxt::node_span_lint()`
     let c = {
         let d = 42;
diff --git a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
index 9d6538112bf..d5533877b45 100644
--- a/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
+++ b/src/tools/clippy/tests/ui/track-diagnostics-clippy.stderr
@@ -4,7 +4,7 @@ error: casting to the same type is unnecessary (`u32` -> `u32`)
 LL |     let b = a as u32;
    |             ^^^^^^^^ help: try: `a`
    |
-   = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs:LL:CC
+   = note: -Ztrack-diagnostics: created at clippy_lints/src/casts/unnecessary_cast.rs:LL:CC
    = note: `-D clippy::unnecessary-cast` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_cast)]`
 
@@ -16,7 +16,7 @@ LL |         let d = 42;
 LL |         d
    |         ^
    |
-   = note: -Ztrack-diagnostics: created at src/tools/clippy/clippy_lints/src/returns.rs:LL:CC
+   = note: -Ztrack-diagnostics: created at clippy_lints/src/returns.rs:LL:CC
    = note: `-D clippy::let-and-return` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::let_and_return)]`
 help: return the expression directly
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
index cf52ecf2f03..88ba5f810b4 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.fixed
@@ -167,8 +167,7 @@ where
 }
 
 // #13476
-#[const_trait]
-trait ConstTrait {}
+const trait ConstTrait {}
 const fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {}
 
 const fn const_trait_bounds_bad<T: [const] ConstTrait>() {}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index 955562f08dc..19a4e70e294 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -167,8 +167,7 @@ where
 }
 
 // #13476
-#[const_trait]
-trait ConstTrait {}
+const trait ConstTrait {}
 const fn const_trait_bounds_good<T: ConstTrait + [const] ConstTrait>() {}
 
 const fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
index ab31721ef51..a56a683de97 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
@@ -59,19 +59,19 @@ LL | fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {
    |                                 ^^^^^^^^^^^^^^^^^ help: try: `Any + Send`
 
 error: these bounds contain repeated elements
-  --> tests/ui/trait_duplication_in_bounds.rs:174:36
+  --> tests/ui/trait_duplication_in_bounds.rs:173:36
    |
 LL | const fn const_trait_bounds_bad<T: [const] ConstTrait + [const] ConstTrait>() {}
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `[const] ConstTrait`
 
 error: these where clauses contain repeated elements
-  --> tests/ui/trait_duplication_in_bounds.rs:181:8
+  --> tests/ui/trait_duplication_in_bounds.rs:180:8
    |
 LL |     T: IntoIterator<Item = U::Owned> + IntoIterator<Item = U::Owned>,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `IntoIterator<Item = U::Owned>`
 
 error: these where clauses contain repeated elements
-  --> tests/ui/trait_duplication_in_bounds.rs:203:8
+  --> tests/ui/trait_duplication_in_bounds.rs:202:8
    |
 LL |     T: AssocConstTrait<ASSOC = 0> + AssocConstTrait<ASSOC = 0>,
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `AssocConstTrait<ASSOC = 0>`
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
index 3c724397284..3109c4af8e2 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.fixed
@@ -130,3 +130,13 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
     //~^ unnecessary_map_or
     x && y
 }
+
+fn issue15180() {
+    let s = std::sync::Mutex::new(Some("foo"));
+    _ = s.lock().unwrap().is_some_and(|s| s == "foo");
+    //~^ unnecessary_map_or
+
+    let s = &&&&Some("foo");
+    _ = s.is_some_and(|s| s == "foo");
+    //~^ unnecessary_map_or
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.rs b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
index e734a27bada..52a55f9fc9e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.rs
@@ -134,3 +134,13 @@ fn issue14201(a: Option<String>, b: Option<String>, s: &String) -> bool {
     //~^ unnecessary_map_or
     x && y
 }
+
+fn issue15180() {
+    let s = std::sync::Mutex::new(Some("foo"));
+    _ = s.lock().unwrap().map_or(false, |s| s == "foo");
+    //~^ unnecessary_map_or
+
+    let s = &&&&Some("foo");
+    _ = s.map_or(false, |s| s == "foo");
+    //~^ unnecessary_map_or
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
index 0f9466a6a6b..99e17e8b34b 100644
--- a/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_map_or.stderr
@@ -326,5 +326,29 @@ LL -     let y = b.map_or(true, |b| b == *s);
 LL +     let y = b.is_none_or(|b| b == *s);
    |
 
-error: aborting due to 26 previous errors
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:140:9
+   |
+LL |     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     _ = s.lock().unwrap().map_or(false, |s| s == "foo");
+LL +     _ = s.lock().unwrap().is_some_and(|s| s == "foo");
+   |
+
+error: this `map_or` can be simplified
+  --> tests/ui/unnecessary_map_or.rs:144:9
+   |
+LL |     _ = s.map_or(false, |s| s == "foo");
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use is_some_and instead
+   |
+LL -     _ = s.map_or(false, |s| s == "foo");
+LL +     _ = s.is_some_and(|s| s == "foo");
+   |
+
+error: aborting due to 28 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
index 645b56fe95e..ac9fa4de20a 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
@@ -144,3 +144,16 @@ const fn foo() {
     assert!([42, 55].len() > get_usize());
     //~^ unnecessary_operation
 }
+
+fn issue15173() {
+    // No lint as `Box::new(None)` alone would be ambiguous
+    Box::new(None) as Box<Option<i32>>;
+}
+
+#[expect(clippy::redundant_closure_call)]
+fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
+    Box::new(move |value| {
+        (|_| handler.clone()())(value);
+        None
+    }) as Box<dyn Fn(i32) -> Option<i32>>;
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs
index 97e90269c5c..a3e6c6288ad 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs
@@ -150,3 +150,16 @@ const fn foo() {
     [42, 55][get_usize()];
     //~^ unnecessary_operation
 }
+
+fn issue15173() {
+    // No lint as `Box::new(None)` alone would be ambiguous
+    Box::new(None) as Box<Option<i32>>;
+}
+
+#[expect(clippy::redundant_closure_call)]
+fn issue15173_original<MsU>(handler: impl FnOnce() -> MsU + Clone + 'static) {
+    Box::new(move |value| {
+        (|_| handler.clone()())(value);
+        None
+    }) as Box<dyn Fn(i32) -> Option<i32>>;
+}
diff --git a/src/tools/clippy/tests/ui/zero_ptr.fixed b/src/tools/clippy/tests/ui/zero_ptr.fixed
index f2375d57f3a..f9d9d2db176 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.fixed
+++ b/src/tools/clippy/tests/ui/zero_ptr.fixed
@@ -16,3 +16,11 @@ fn main() {
     let z = 0;
     let _ = z as *const usize; // this is currently not caught
 }
+
+const fn in_const_context() {
+    #[clippy::msrv = "1.23"]
+    let _: *const usize = 0 as *const _;
+    #[clippy::msrv = "1.24"]
+    let _: *const usize = std::ptr::null();
+    //~^ zero_ptr
+}
diff --git a/src/tools/clippy/tests/ui/zero_ptr.rs b/src/tools/clippy/tests/ui/zero_ptr.rs
index ee01e426a43..41455fee5b5 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.rs
+++ b/src/tools/clippy/tests/ui/zero_ptr.rs
@@ -16,3 +16,11 @@ fn main() {
     let z = 0;
     let _ = z as *const usize; // this is currently not caught
 }
+
+const fn in_const_context() {
+    #[clippy::msrv = "1.23"]
+    let _: *const usize = 0 as *const _;
+    #[clippy::msrv = "1.24"]
+    let _: *const usize = 0 as *const _;
+    //~^ zero_ptr
+}
diff --git a/src/tools/clippy/tests/ui/zero_ptr.stderr b/src/tools/clippy/tests/ui/zero_ptr.stderr
index 8dc781f3625..81269de6c60 100644
--- a/src/tools/clippy/tests/ui/zero_ptr.stderr
+++ b/src/tools/clippy/tests/ui/zero_ptr.stderr
@@ -31,5 +31,11 @@ error: `0 as *mut _` detected
 LL |     foo(0 as *const _, 0 as *mut _);
    |                        ^^^^^^^^^^^ help: try: `std::ptr::null_mut()`
 
-error: aborting due to 5 previous errors
+error: `0 as *const _` detected
+  --> tests/ui/zero_ptr.rs:24:27
+   |
+LL |     let _: *const usize = 0 as *const _;
+   |                           ^^^^^^^^^^^^^ help: try: `std::ptr::null()`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index 4f370758c00..805baf2af6d 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -15,6 +15,8 @@ allow-unauthenticated = [
 
 [close]
 
+[transfer]
+
 [issue-links]
 
 [mentions."clippy_lints/src/doc"]
@@ -43,12 +45,15 @@ reviewed_label = "S-waiting-on-author"
 [autolabel."S-waiting-on-review"]
 new_pr = true
 
+[concern]
+# These labels are set when there are unresolved concerns, removed otherwise
+labels = ["S-waiting-on-concerns"]
+
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
     "matthiaskrgr",
     "Manishearth",
-    "blyxyas",
 ]
 
 [assign.owners]
diff --git a/src/tools/clippy/util/gh-pages/index_template.html b/src/tools/clippy/util/gh-pages/index_template.html
index 865b9523c39..6f380ec8fee 100644
--- a/src/tools/clippy/util/gh-pages/index_template.html
+++ b/src/tools/clippy/util/gh-pages/index_template.html
@@ -149,49 +149,45 @@ Otherwise, have a great day =^.^=
                 <article class="panel panel-default" id="{{lint.id}}"> {# #}
                     <input id="label-{{lint.id}}" type="checkbox"> {# #}
                     <label for="label-{{lint.id}}"> {# #}
-                        <header class="panel-heading"> {# #}
-                            <h2 class="panel-title"> {# #}
-                                <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
-                                    <span>{{lint.id}}</span> {#+ #}
-                                    <a href="#{{lint.id}}" class="lint-anchor anchor label label-default">&para;</a> {#+ #}
-                                    <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
-                                        &#128203; {# #}
-                                    </a> {# #}
-                                </div> {# #}
+                        <h2 class="lint-title"> {# #}
+                            <div class="panel-title-name" id="lint-{{lint.id}}"> {# #}
+                                {{lint.id +}}
+                                <a href="#{{lint.id}}" class="anchor label label-default">&para;</a> {#+ #}
+                                <a href="" class="copy-to-clipboard anchor label label-default"> {# #}
+                                    &#128203; {# #}
+                                </a> {# #}
+                            </div> {# #}
 
-                                <div class="panel-title-addons"> {# #}
-                                    <span class="label label-lint-group label-default label-group-{{lint.group}}">{{lint.group}}</span> {#+ #}
+                            <span class="label label-lint-group label-default label-group-{{lint.group}}">{{lint.group}}</span> {#+ #}
 
-                                    <span class="label label-lint-level label-lint-level-{{lint.level}}">{{lint.level}}</span> {#+ #}
+                            <span class="label label-lint-level label-lint-level-{{lint.level}}">{{lint.level}}</span> {#+ #}
 
-                                    <span class="label label-doc-folding"></span> {# #}
-                                </div> {# #}
-                            </h2> {# #}
-                        </header> {# #}
+                            <span class="label label-doc-folding"></span> {# #}
+                        </h2> {# #}
                     </label> {# #}
 
                     <div class="list-group lint-docs"> {# #}
                         <div class="list-group-item lint-doc-md">{{Self::markdown(lint.docs)}}</div> {# #}
                         <div class="lint-additional-info-container">
                             {# Applicability #}
-                            <div class="lint-additional-info-item"> {# #}
-                                <span> Applicability: </span> {# #}
+                            <div> {# #}
+                                Applicability: {#+ #}
                                 <span class="label label-default label-applicability">{{ lint.applicability_str() }}</span> {# #}
                                 <a href="https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/enum.Applicability.html#variants">(?)</a> {# #}
                             </div>
                             {# Clippy version #}
-                            <div class="lint-additional-info-item"> {# #}
-                                <span>{% if lint.group == "deprecated" %}Deprecated{% else %} Added{% endif +%} in: </span> {# #}
+                            <div> {# #}
+                                {% if lint.group == "deprecated" %}Deprecated{% else %} Added{% endif +%} in: {#+ #}
                                 <span class="label label-default label-version">{{lint.version}}</span> {# #}
                             </div>
                             {# Open related issues #}
-                            <div class="lint-additional-info-item"> {# #}
+                            <div> {# #}
                                 <a href="https://github.com/rust-lang/rust-clippy/issues?q=is%3Aissue+{{lint.id}}">Related Issues</a> {# #}
                             </div>
 
                             {# Jump to source #}
                             {% if let Some(id_location) = lint.id_location %}
-                                <div class="lint-additional-info-item"> {# #}
+                                <div> {# #}
                                     <a href="https://github.com/rust-lang/rust-clippy/blob/master/{{id_location}}">View Source</a> {# #}
                                 </div>
                             {% endif %}
diff --git a/src/tools/clippy/util/gh-pages/script.js b/src/tools/clippy/util/gh-pages/script.js
index 285aa34e701..ee13f1c0cd8 100644
--- a/src/tools/clippy/util/gh-pages/script.js
+++ b/src/tools/clippy/util/gh-pages/script.js
@@ -554,10 +554,10 @@ function addListeners() {
             return;
         }
 
-        if (event.target.classList.contains("lint-anchor")) {
-            lintAnchor(event);
-        } else if (event.target.classList.contains("copy-to-clipboard")) {
+        if (event.target.classList.contains("copy-to-clipboard")) {
             copyToClipboard(event);
+        } else if (event.target.classList.contains("anchor")) {
+            lintAnchor(event);
         }
     });
 
diff --git a/src/tools/clippy/util/gh-pages/style.css b/src/tools/clippy/util/gh-pages/style.css
index 3cc7a919c23..022ea875200 100644
--- a/src/tools/clippy/util/gh-pages/style.css
+++ b/src/tools/clippy/util/gh-pages/style.css
@@ -50,11 +50,25 @@ div.panel div.panel-body  button.open {
 
 .panel-heading { cursor: pointer; }
 
-.panel-title { display: flex; flex-wrap: wrap;}
-.panel-title .label { display: inline-block; }
+.lint-title {
+    cursor: pointer;
+    margin-top: 0;
+    margin-bottom: 0;
+    font-size: 16px;
+    display: flex;
+    flex-wrap: wrap;
+    background: var(--theme-hover);
+    color: var(--fg);
+    border: 1px solid var(--theme-popup-border);
+    padding: 10px 15px;
+    border-top-left-radius: 3px;
+    border-top-right-radius: 3px;
+    gap: 4px;
+}
+
+.lint-title .label { display: inline-block; }
 
 .panel-title-name { flex: 1; min-width: 400px;}
-.panel-title-name span { vertical-align: bottom; }
 
 .panel .panel-title-name .anchor { display: none; }
 .panel:hover .panel-title-name .anchor { display: inline;}
@@ -147,7 +161,7 @@ div.panel div.panel-body  button.open {
         display: flex;
         flex-flow: column;
     }
-    .lint-additional-info-item + .lint-additional-info-item {
+    .lint-additional-info-container > div + div {
         border-top: 1px solid var(--theme-popup-border);
     }
 }
@@ -156,12 +170,12 @@ div.panel div.panel-body  button.open {
         display: flex;
         flex-flow: row;
     }
-    .lint-additional-info-item + .lint-additional-info-item {
+    .lint-additional-info-container > div + div {
         border-left: 1px solid var(--theme-popup-border);
     }
 }
 
-.lint-additional-info-item {
+.lint-additional-info-container > div {
     display: inline-flex;
     min-width: 200px;
     flex-grow: 1;