about summary refs log tree commit diff
path: root/clippy_lints/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-03 19:07:51 +0000
committerbors <bors@rust-lang.org>2024-04-03 19:07:51 +0000
commite80ca2f3816ed6f4584480d40b8671a15b2225fc (patch)
tree276d3d3dc88262f167cf901374e55aa8fac93978 /clippy_lints/src
parentf9f854f4283c9239769f807f14a7475256c8730d (diff)
parent571118f4b018aad8b15e8f80aa905f0209a27aba (diff)
Auto merge of #12615 - Kobzol:fix-recursive-clone-from, r=blyxyas
Do not suggest `assigning_clones` in `Clone` impl

This PR modifies `assigning_clones` to detect situations where the `clone` call is inside a `Clone` impl, and avoids suggesting the lint in such situations.

r? `@blyxyas`

Fixes: https://github.com/rust-lang/rust-clippy/issues/12600

changelog: Do not invoke `assigning_clones` inside `Clone` impl
Diffstat (limited to 'clippy_lints/src')
-rw-r--r--clippy_lints/src/assigning_clones.rs17
1 files changed, 17 insertions, 0 deletions
diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs
index d7d2dbee433..e1e7d406cd0 100644
--- a/clippy_lints/src/assigning_clones.rs
+++ b/clippy_lints/src/assigning_clones.rs
@@ -181,6 +181,23 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC
         return false;
     }
 
+    // If the call expression is inside an impl block that contains the method invoked by the
+    // call expression, we bail out to avoid suggesting something that could result in endless
+    // recursion.
+    if let Some(local_block_id) = impl_block.as_local()
+        && let Some(block) = cx.tcx.hir_node_by_def_id(local_block_id).as_owner()
+    {
+        let impl_block_owner = block.def_id();
+        if cx
+            .tcx
+            .hir()
+            .parent_id_iter(lhs.hir_id)
+            .any(|parent| parent.owner == impl_block_owner)
+        {
+            return false;
+        }
+    }
+
     // Find the function for which we want to check that it is implemented.
     let provided_fn = match call.target {
         TargetTrait::Clone => cx.tcx.get_diagnostic_item(sym::Clone).and_then(|clone| {