don't lint when implementing trait

This commit is contained in:
Jaeyong Sung 2022-03-05 21:39:00 +09:00
parent 48d310e869
commit 2b0f9aba64
No known key found for this signature in database
GPG Key ID: 2B86898CCB2A5486
3 changed files with 48 additions and 9 deletions

View File

@ -6,6 +6,7 @@
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 @@
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 @@
/// - 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 @@ fn check_fn(
_: &'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

View File

@ -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() {}

View File

@ -61,9 +61,9 @@ 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 {
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