]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/eta_reduction.rs
modify code
[rust.git] / clippy_lints / src / eta_reduction.rs
index 9df92cc5b640667faf06c1f63dcf3b3b634d7541..263bff4873caf4cb45af2f3efdd8bb95dd31bbf1 100644 (file)
@@ -1,8 +1,9 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::higher::VecArgs;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::usage::UsedAfterExprVisitor;
-use clippy_utils::{get_enclosing_loop_or_closure, higher, path_to_local_id};
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::usage::local_used_after_expr;
+use clippy_utils::{get_enclosing_loop_or_closure, higher, path_to_local, path_to_local_id};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
@@ -12,6 +13,7 @@
 use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, ClosureKind, Ty, TypeFoldable};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::symbol::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -39,6 +41,7 @@
     /// ```
     /// where `foo(_)` is a plain function that takes the exact argument type of
     /// `x`.
+    #[clippy::version = "pre 1.29.0"]
     pub REDUNDANT_CLOSURE,
     style,
     "redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)"
@@ -60,6 +63,7 @@
     /// ```rust,ignore
     /// Some('a').map(char::to_uppercase);
     /// ```
+    #[clippy::version = "1.35.0"]
     pub REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
     pedantic,
     "redundant closures for method calls"
@@ -111,14 +115,17 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
             // A type param function ref like `T::f` is not 'static, however
             // it is if cast like `T::f as fn()`. This seems like a rustc bug.
             if !substs.types().any(|t| matches!(t.kind(), ty::Param(_)));
+            let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs();
+            if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc);
+            if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc);
             then {
                 span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| {
                     if let Some(mut snippet) = snippet_opt(cx, callee.span) {
                         if_chain! {
                             if let ty::Closure(_, substs) = callee_ty.peel_refs().kind();
-                            if let ClosureKind::FnMut = substs.as_closure().kind();
+                            if substs.as_closure().kind() == ClosureKind::FnMut;
                             if get_enclosing_loop_or_closure(cx.tcx, expr).is_some()
-                                || UsedAfterExprVisitor::is_found(cx, callee);
+                                || path_to_local(callee).map_or(false, |l| local_used_after_expr(cx, l, callee));
 
                             then {
                                 // Mutable closure is used after current expr; we cannot consume it.
@@ -137,7 +144,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         );
 
         if_chain!(
-            if let ExprKind::MethodCall(path, _, args, _) = body.value.kind;
+            if let ExprKind::MethodCall(path, args, _) = body.value.kind;
             if check_inputs(cx, body.params, args);
             let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap();
             let substs = cx.typeck_results().node_substs(body.value.hir_id);
@@ -169,13 +176,16 @@ fn check_inputs(cx: &LateContext<'_>, params: &[Param<'_>], call_args: &[Expr<'_
         }
         match *cx.typeck_results().expr_adjustments(arg) {
             [] => true,
-            [Adjustment {
-                kind: Adjust::Deref(None),
-                ..
-            }, Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(_, mu2)),
-                ..
-            }] => {
+            [
+                Adjustment {
+                    kind: Adjust::Deref(None),
+                    ..
+                },
+                Adjustment {
+                    kind: Adjust::Borrow(AutoBorrow::Ref(_, mu2)),
+                    ..
+                },
+            ] => {
                 // re-borrow with the same mutability is allowed
                 let ty = cx.typeck_results().expr_ty(arg);
                 matches!(*ty.kind(), ty::Ref(.., mu1) if mu1 == mu2.into())