]> git.lizzy.rs Git - rust.git/blobdiff - clippy_utils/src/usage.rs
add eq constraints on associated constants
[rust.git] / clippy_utils / src / usage.rs
index ac885e9994404b605dd5b0d1c91df3cc45c6b970..2066915e1d184a9d6d9d8c96256dddfd057f040c 100644 (file)
@@ -1,10 +1,9 @@
 use crate as utils;
+use crate::visitors::{expr_visitor, expr_visitor_no_bodies};
 use rustc_hir as hir;
-use rustc_hir::def::Res;
-use rustc_hir::intravisit;
-use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
+use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirIdSet;
-use rustc_hir::{Expr, ExprKind, HirId, Path};
+use rustc_hir::{Expr, ExprKind, HirId};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::hir::map::Map;
@@ -35,12 +34,8 @@ pub fn mutated_variables<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) ->
     Some(delegate.used_mutably)
 }
 
-pub fn is_potentially_mutated<'tcx>(variable: &'tcx Path<'_>, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool {
-    if let Res::Local(id) = variable.res {
-        mutated_variables(expr, cx).map_or(true, |mutated| mutated.contains(&id))
-    } else {
-        true
-    }
+pub fn is_potentially_mutated<'tcx>(variable: HirId, expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) -> bool {
+    mutated_variables(expr, cx).map_or(true, |mutated| mutated.contains(&variable))
 }
 
 struct MutVarsDelegate {
@@ -70,7 +65,7 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
     fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
 
     fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) {
-        if let ty::BorrowKind::MutBorrow = bk {
+        if bk == ty::BorrowKind::MutBorrow {
             self.update(cmt);
         }
     }
@@ -83,7 +78,7 @@ fn fake_read(&mut self, _: rustc_typeck::expr_use_visitor::Place<'tcx>, _: FakeR
 }
 
 pub struct ParamBindingIdCollector {
-    binding_hir_ids: Vec<hir::HirId>,
+    pub binding_hir_ids: Vec<hir::HirId>,
 }
 impl<'tcx> ParamBindingIdCollector {
     fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec<hir::HirId> {
@@ -153,96 +148,47 @@ fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap<Self::Map> {
     }
 }
 
-struct ReturnBreakContinueMacroVisitor {
-    seen_return_break_continue: bool,
-}
-
-impl ReturnBreakContinueMacroVisitor {
-    fn new() -> ReturnBreakContinueMacroVisitor {
-        ReturnBreakContinueMacroVisitor {
-            seen_return_break_continue: false,
-        }
-    }
-}
-
-impl<'tcx> Visitor<'tcx> for ReturnBreakContinueMacroVisitor {
-    type Map = Map<'tcx>;
-    fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
-        NestedVisitorMap::None
-    }
-
-    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
-        if self.seen_return_break_continue {
-            // No need to look farther if we've already seen one of them
-            return;
+pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool {
+    let mut seen_return_break_continue = false;
+    expr_visitor_no_bodies(|ex| {
+        if seen_return_break_continue {
+            return false;
         }
         match &ex.kind {
             ExprKind::Ret(..) | ExprKind::Break(..) | ExprKind::Continue(..) => {
-                self.seen_return_break_continue = true;
+                seen_return_break_continue = true;
             },
             // Something special could be done here to handle while or for loop
             // desugaring, as this will detect a break if there's a while loop
             // or a for loop inside the expression.
             _ => {
-                if utils::in_macro(ex.span) {
-                    self.seen_return_break_continue = true;
-                } else {
-                    rustc_hir::intravisit::walk_expr(self, ex);
+                if ex.span.from_expansion() {
+                    seen_return_break_continue = true;
                 }
             },
         }
-    }
-}
-
-pub fn contains_return_break_continue_macro(expression: &Expr<'_>) -> bool {
-    let mut recursive_visitor = ReturnBreakContinueMacroVisitor::new();
-    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;
+        !seen_return_break_continue
+    })
+    .visit_expr(expression);
+    seen_return_break_continue
+}
+
+pub fn local_used_after_expr(cx: &LateContext<'_>, local_id: HirId, after: &Expr<'_>) -> bool {
+    let Some(block) = utils::get_enclosing_block(cx, local_id) else { return false };
+    let mut used_after_expr = false;
+    let mut past_expr = false;
+    expr_visitor(cx, |expr| {
+        if used_after_expr {
+            return false;
         }
 
-        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);
+        if expr.hir_id == after.hir_id {
+            past_expr = true;
+        } else if past_expr && utils::path_to_local_id(expr, local_id) {
+            used_after_expr = true;
         }
-    }
+        !used_after_expr
+    })
+    .visit_block(block);
+    used_after_expr
 }