Skip to content

Commit 2b0f9ab

Browse files
committed
don't lint when implementing trait
1 parent 48d310e commit 2b0f9ab

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

clippy_lints/src/only_used_in_recursion.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use rustc_ast::{walk_list, Label, Mutability};
66
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
77
use rustc_errors::Applicability;
88
use rustc_hir::def::Res;
9+
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
910
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
1011
use rustc_hir::{
1112
Arm, Block, Body, Expr, ExprKind, Guard, HirId, Let, Local, Pat, PatKind, Path, PathSegment, QPath, Stmt, StmtKind,
@@ -22,13 +23,14 @@ use rustc_span::Span;
2223
declare_clippy_lint! {
2324
/// ### What it does
2425
/// Checks for arguments that are only used in recursion with no side-effects.
26+
///
27+
/// ### Why is this bad?
28+
/// It could contain a useless calculation and can make function simpler.
29+
///
2530
/// The arguments can be involved in calculations and assignments but as long as
2631
/// the calculations have no side-effects (function calls or mutating dereference)
2732
/// and the assigned variables are also only in recursion, it is useless.
2833
///
29-
/// ### Why is this bad?
30-
/// The could contain a useless calculation and can make function simpler.
31-
///
3234
/// ### Known problems
3335
/// In some cases, this would not catch all useless arguments.
3436
///
@@ -52,6 +54,8 @@ declare_clippy_lint! {
5254
/// - some `break` relative operations
5355
/// - struct pattern binding
5456
///
57+
/// Also, when you recurse the function name with path segments, it is not possible to detect.
58+
///
5559
/// ### Example
5660
/// ```rust
5761
/// fn f(a: usize, b: usize) -> usize {
@@ -93,9 +97,20 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
9397
_: &'tcx rustc_hir::FnDecl<'tcx>,
9498
body: &'tcx Body<'tcx>,
9599
_: Span,
96-
_: HirId,
100+
id: HirId,
97101
) {
98102
if let FnKind::ItemFn(ident, ..) | FnKind::Method(ident, ..) = kind {
103+
let data = cx.tcx.def_path(cx.tcx.hir().local_def_id(id).to_def_id()).data;
104+
if data.len() > 1 {
105+
match data.get(data.len() - 2) {
106+
Some(DisambiguatedDefPathData {
107+
data: DefPathData::Impl,
108+
disambiguator,
109+
}) if *disambiguator != 0 => return,
110+
_ => {},
111+
}
112+
}
113+
99114
let ty_res = cx.typeck_results();
100115
let param_span = body
101116
.params

tests/ui/only_used_in_recursion.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,37 @@ fn not_primitive_op(a: usize, b: String, c: &str) -> usize {
6161
struct A;
6262

6363
impl A {
64-
fn method(&self, a: usize, b: usize) -> usize {
65-
if a == 0 { 1 } else { self.method(a - 1, b + 1) }
64+
fn method(a: usize, b: usize) -> usize {
65+
if a == 0 { 1 } else { A::method(a - 1, b - 1) }
66+
}
67+
68+
fn method2(&self, a: usize, b: usize) -> usize {
69+
if a == 0 { 1 } else { self.method2(a - 1, b + 1) }
70+
}
71+
}
72+
73+
trait B {
74+
fn hello(a: usize, b: usize) -> usize;
75+
76+
fn hello2(&self, a: usize, b: usize) -> usize;
77+
}
78+
79+
impl B for A {
80+
fn hello(a: usize, b: usize) -> usize {
81+
if a == 0 { 1 } else { A::hello(a - 1, b + 1) }
82+
}
83+
84+
fn hello2(&self, a: usize, b: usize) -> usize {
85+
if a == 0 { 1 } else { self.hello2(a - 1, b + 1) }
6686
}
6787
}
6888

6989
fn ignore(a: usize, _: usize) -> usize {
7090
if a == 1 { 1 } else { ignore(a - 1, 0) }
7191
}
7292

93+
fn ignore2(a: usize, _b: usize) -> usize {
94+
if a == 1 { 1 } else { ignore2(a - 1, _b) }
95+
}
96+
7397
fn main() {}

tests/ui/only_used_in_recursion.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ LL | fn not_primitive(a: usize, b: String) -> usize {
6161
| ^ help: if this is intentional, prefix with an underscore: `_b`
6262

6363
error: parameter is only used in recursion
64-
--> $DIR/only_used_in_recursion.rs:64:32
64+
--> $DIR/only_used_in_recursion.rs:68:33
6565
|
66-
LL | fn method(&self, a: usize, b: usize) -> usize {
67-
| ^ help: if this is intentional, prefix with an underscore: `_b`
66+
LL | fn method2(&self, a: usize, b: usize) -> usize {
67+
| ^ help: if this is intentional, prefix with an underscore: `_b`
6868

6969
error: aborting due to 11 previous errors
7070

0 commit comments

Comments
 (0)