diff options
| author | Jaeyong Sung <jaeyong0201@gmail.com> | 2022-03-05 21:39:00 +0900 |
|---|---|---|
| committer | Jaeyong Sung <jaeyong0201@gmail.com> | 2022-03-05 21:39:00 +0900 |
| commit | 2b0f9aba64005f5dc20e250a327078dea3d3930f (patch) | |
| tree | 86f30082c33d061c661e084689c29c858cfa3618 | |
| parent | 48d310e8698eea1b9c771bdd18042a921f9f45b7 (diff) | |
| download | rust-2b0f9aba64005f5dc20e250a327078dea3d3930f.tar.gz rust-2b0f9aba64005f5dc20e250a327078dea3d3930f.zip | |
don't lint when implementing trait
| -rw-r--r-- | clippy_lints/src/only_used_in_recursion.rs | 23 | ||||
| -rw-r--r-- | tests/ui/only_used_in_recursion.rs | 28 | ||||
| -rw-r--r-- | tests/ui/only_used_in_recursion.stderr | 6 |
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 |
