]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/only_used_in_recursion.rs
Better handle method/function calls
[rust.git] / clippy_lints / src / only_used_in_recursion.rs
index f946fc11192817a7edbc1056b5c9af01454dbd02..413a740be25a529c0fe8fb64361dd38d567de634 100644 (file)
@@ -1,6 +1,7 @@
 use std::collections::VecDeque;
 
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_lint_allowed;
 use itertools::{izip, Itertools};
 use rustc_ast::{walk_list, Label, Mutability};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -10,8 +11,8 @@
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_hir::intravisit::{walk_expr, walk_stmt, FnKind, Visitor};
 use rustc_hir::{
-    Arm, Block, Body, Expr, ExprKind, Guard, HirId, ImplicitSelfKind, Let, Local, Pat, PatKind, Path, PathSegment,
-    QPath, Stmt, StmtKind, TyKind, UnOp,
+    Arm, Block, Body, Closure, Expr, ExprKind, Guard, HirId, ImplicitSelfKind, Let, Local, Pat, PatKind, Path,
+    PathSegment, QPath, Stmt, StmtKind, TyKind, UnOp,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -33,6 +34,9 @@
     /// and the assigned variables are also only in recursion, it is useless.
     ///
     /// ### Known problems
+    /// Too many code paths in the linting code are currently untested and prone to produce false
+    /// positives or are prone to have performance implications.
+    ///
     /// In some cases, this would not catch all useless arguments.
     ///
     /// ```rust
@@ -83,9 +87,9 @@
     /// #     print!("{}", f(1));
     /// # }
     /// ```
-    #[clippy::version = "1.60.0"]
+    #[clippy::version = "1.61.0"]
     pub ONLY_USED_IN_RECURSION,
-    complexity,
+    nursery,
     "arguments that is only used in recursion can be removed"
 }
 declare_lint_pass!(OnlyUsedInRecursion => [ONLY_USED_IN_RECURSION]);
@@ -100,6 +104,9 @@ fn check_fn(
         _: Span,
         id: HirId,
     ) {
+        if is_lint_allowed(cx, ONLY_USED_IN_RECURSION, id) {
+            return;
+        }
         if let FnKind::ItemFn(ident, ..) | FnKind::Method(ident, ..) = kind {
             let def_id = id.owner.to_def_id();
             let data = cx.tcx.def_path(def_id).data;
@@ -291,8 +298,8 @@ fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
             },
             ExprKind::Match(expr, arms, _) => self.visit_match(expr, arms),
             // since analysing the closure is not easy, just set all variables in it to side-effect
-            ExprKind::Closure(_, _, body_id, _, _) => {
-                let body = self.tcx.hir().body(body_id);
+            ExprKind::Closure(&Closure { body, .. }) => {
+                let body = self.tcx.hir().body(body);
                 self.visit_body(body);
                 let vars = std::mem::take(&mut self.ret_vars);
                 self.add_side_effect(vars);
@@ -589,7 +596,7 @@ fn visit_match(&mut self, expr: &'tcx Expr<'tcx>, arms: &'tcx [Arm<'tcx>]) {
                 let mut vars = std::mem::take(&mut self.ret_vars);
                 let _ = arm.guard.as_ref().map(|guard| {
                     self.visit_expr(match guard {
-                        Guard::If(expr) | Guard::IfLet(_, expr) => expr,
+                        Guard::If(expr) | Guard::IfLet(Let { init: expr, .. }) => expr,
                     });
                     vars.append(&mut self.ret_vars);
                 });