about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJaeyong Sung <jaeyong0201@gmail.com>2022-03-05 21:39:00 +0900
committerJaeyong Sung <jaeyong0201@gmail.com>2022-03-05 21:39:00 +0900
commit2b0f9aba64005f5dc20e250a327078dea3d3930f (patch)
tree86f30082c33d061c661e084689c29c858cfa3618
parent48d310e8698eea1b9c771bdd18042a921f9f45b7 (diff)
downloadrust-2b0f9aba64005f5dc20e250a327078dea3d3930f.tar.gz
rust-2b0f9aba64005f5dc20e250a327078dea3d3930f.zip
don't lint when implementing trait
-rw-r--r--clippy_lints/src/only_used_in_recursion.rs23
-rw-r--r--tests/ui/only_used_in_recursion.rs28
-rw-r--r--tests/ui/only_used_in_recursion.stderr6
3 files changed, 48 insertions, 9 deletions
diff --git a/clippy_lints/src/only_used_in_recursion.rs b/clippy_lints/src/only_used_in_recursion.rs
index 21102e759e4..bbf3f24566b 100644
--- a/clippy_lints/src/only_used_in_recursion.rs
+++ b/clippy_lints/src/only_used_in_recursion.rs
@@ -6,6 +6,7 @@ use rustc_ast::{walk_list, Label, Mutability};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
+use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
 use rustc_hir::{
     Arm, Block, Body, Expr, ExprKind, Guard, HirId, Let, Local, Pat, PatKind, Path, PathSegment, QPath, Stmt, StmtKind,
@@ -22,13 +23,14 @@ use rustc_span::Span;
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for arguments that are only used in recursion with no side-effects.
+    ///
+    /// ### Why is this bad?
+    /// It could contain a useless calculation and can make function simpler.
+    ///
     /// The arguments can be involved in calculations and assignments but as long as
     /// the calculations have no side-effects (function calls or mutating dereference)
     /// and the assigned variables are also only in recursion, it is useless.
     ///
-    /// ### Why is this bad?
-    /// The could contain a useless calculation and can make function simpler.
-    ///
     /// ### Known problems
     /// In some cases, this would not catch all useless arguments.
     ///
@@ -52,6 +54,8 @@ declare_clippy_lint! {
     /// - some `break` relative operations
     /// - struct pattern binding
     ///
+    /// Also, when you recurse the function name with path segments, it is not possible to detect.
+    ///
     /// ### Example
     /// ```rust
     /// fn f(a: usize, b: usize) -> usize {
@@ -93,9 +97,20 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
         _: &'tcx rustc_hir::FnDecl<'tcx>,
         body: &'tcx Body<'tcx>,
         _: Span,
-        _: HirId,
+        id: HirId,
     ) {
         if let FnKind::ItemFn(ident, ..) | FnKind::Method(ident, ..) = kind {
+            let data = cx.tcx.def_path(cx.tcx.hir().local_def_id(id).to_def_id()).data;
+            if data.len() > 1 {
+                match data.get(data.len() - 2) {
+                    Some(DisambiguatedDefPathData {
+                        data: DefPathData::Impl,
+                        disambiguator,
+                    }) if *disambiguator != 0 => return,
+                    _ => {},
+                }
+            }
+
             let ty_res = cx.typeck_results();
             let param_span = body
                 .params
diff --git a/tests/ui/only_used_in_recursion.rs b/tests/ui/only_used_in_recursion.rs
index a0c40eb0826..799adfd3be2 100644
--- a/tests/ui/only_used_in_recursion.rs
+++ b/tests/ui/only_used_in_recursion.rs
@@ -61,8 +61,28 @@ fn not_primitive_op(a: usize, b: String, c: &str) -> usize {
 struct A;
 
 impl A {
-    fn method(&self, a: usize, b: usize) -> usize {
-        if a == 0 { 1 } else { self.method(a - 1, b + 1) }
+    fn method(a: usize, b: usize) -> usize {
+        if a == 0 { 1 } else { A::method(a - 1, b - 1) }
+    }
+
+    fn method2(&self, a: usize, b: usize) -> usize {
+        if a == 0 { 1 } else { self.method2(a - 1, b + 1) }
+    }
+}
+
+trait B {
+    fn hello(a: usize, b: usize) -> usize;
+
+    fn hello2(&self, a: usize, b: usize) -> usize;
+}
+
+impl B for A {
+    fn hello(a: usize, b: usize) -> usize {
+        if a == 0 { 1 } else { A::hello(a - 1, b + 1) }
+    }
+
+    fn hello2(&self, a: usize, b: usize) -> usize {
+        if a == 0 { 1 } else { self.hello2(a - 1, b + 1) }
     }
 }
 
@@ -70,4 +90,8 @@ fn ignore(a: usize, _: usize) -> usize {
     if a == 1 { 1 } else { ignore(a - 1, 0) }
 }
 
+fn ignore2(a: usize, _b: usize) -> usize {
+    if a == 1 { 1 } else { ignore2(a - 1, _b) }
+}
+
 fn main() {}
diff --git a/tests/ui/only_used_in_recursion.stderr b/tests/ui/only_used_in_recursion.stderr
index ed942e06f26..b2dd99bbe4d 100644
--- a/tests/ui/only_used_in_recursion.stderr
+++ b/tests/ui/only_used_in_recursion.stderr
@@ -61,10 +61,10 @@ LL | fn not_primitive(a: usize, b: String) -> usize {
    |                            ^ help: if this is intentional, prefix with an underscore: `_b`
 
 error: parameter is only used in recursion
-  --> $DIR/only_used_in_recursion.rs:64:32
+  --> $DIR/only_used_in_recursion.rs:68:33
    |
-LL |     fn method(&self, a: usize, b: usize) -> usize {
-   |                                ^ help: if this is intentional, prefix with an underscore: `_b`
+LL |     fn method2(&self, a: usize, b: usize) -> usize {
+   |                                 ^ help: if this is intentional, prefix with an underscore: `_b`
 
 error: aborting due to 11 previous errors