about summary refs log tree commit diff
path: root/clippy_utils
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-14 15:15:28 +0000
committerbors <bors@rust-lang.org>2021-07-14 15:15:28 +0000
commit4acbff9eb05a15008d33fd7558670fc3b2338461 (patch)
tree2785613188c780381e53ccae8a2ea246824bf162 /clippy_utils
parentf07feca40c3eed82592b1e4862f9e67f57a880d1 (diff)
parent4c398e07e042c21a4cf0e953669075275e656543 (diff)
downloadrust-4acbff9eb05a15008d33fd7558670fc3b2338461.tar.gz
rust-4acbff9eb05a15008d33fd7558670fc3b2338461.zip
Auto merge of #7437 - ebobrow:redundant-closure-move, r=flip1995
suggest `&mut` for redundant FnMut closures

fixes #6903

changelog: suggest `&mut` for redundant FnMut closures
Diffstat (limited to 'clippy_utils')
-rw-r--r--clippy_utils/src/usage.rs47
1 files changed, 47 insertions, 0 deletions
diff --git a/clippy_utils/src/usage.rs b/clippy_utils/src/usage.rs
index 2c55021ac88..182d8cb11ea 100644
--- a/clippy_utils/src/usage.rs
+++ b/clippy_utils/src/usage.rs
@@ -199,3 +199,50 @@ pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool {
     recursive_visitor.visit_expr(expression);
     recursive_visitor.seen_return_break_continue
 }
+
+pub struct UsedAfterExprVisitor<'a, 'tcx> {
+    cx: &'a LateContext<'tcx>,
+    expr: &'tcx Expr<'tcx>,
+    definition: HirId,
+    past_expr: bool,
+    used_after_expr: bool,
+}
+impl<'a, 'tcx> UsedAfterExprVisitor<'a, 'tcx> {
+    pub fn is_found(cx: &'a LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
+        utils::path_to_local(expr).map_or(false, |definition| {
+            let mut visitor = UsedAfterExprVisitor {
+                cx,
+                expr,
+                definition,
+                past_expr: false,
+                used_after_expr: false,
+            };
+            utils::get_enclosing_block(cx, definition).map_or(false, |block| {
+                visitor.visit_block(block);
+                visitor.used_after_expr
+            })
+        })
+    }
+}
+
+impl<'a, 'tcx> intravisit::Visitor<'tcx> for UsedAfterExprVisitor<'a, 'tcx> {
+    type Map = Map<'tcx>;
+
+    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
+        NestedVisitorMap::OnlyBodies(self.cx.tcx.hir())
+    }
+
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
+        if self.used_after_expr {
+            return;
+        }
+
+        if expr.hir_id == self.expr.hir_id {
+            self.past_expr = true;
+        } else if self.past_expr && utils::path_to_local_id(expr, self.definition) {
+            self.used_after_expr = true;
+        } else {
+            intravisit::walk_expr(self, expr);
+        }
+    }
+}