diff options
| author | flip1995 <philipp.krones@embecosm.com> | 2021-12-06 12:33:31 +0100 |
|---|---|---|
| committer | flip1995 <philipp.krones@embecosm.com> | 2021-12-06 12:33:31 +0100 |
| commit | 8fea1d94f3bbcc02c3822dd43da9a1133e90f715 (patch) | |
| tree | c571ad0e3fb19726b5e0fbe9df641885ddf0524d /clippy_utils/src/usage.rs | |
| parent | 35a0060aba4bc9ff4e2b8faa20b91762c3109b18 (diff) | |
Merge commit 'a5d597637dcb78dc73f93561ce474f23d4177c35' into clippyup
Diffstat (limited to 'clippy_utils/src/usage.rs')
| -rw-r--r-- | clippy_utils/src/usage.rs | 111 |
1 files changed, 31 insertions, 80 deletions
diff --git a/clippy_utils/src/usage.rs b/clippy_utils/src/usage.rs index 34206b5ae2b..dfe8a66c2a1 100644 --- a/clippy_utils/src/usage.rs +++ b/clippy_utils/src/usage.rs @@ -1,7 +1,7 @@ use crate as utils; +use crate::visitors::{expr_visitor, expr_visitor_no_bodies}; use rustc_hir as hir; -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}; use rustc_infer::infer::TyCtxtInferExt; @@ -148,96 +148,47 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> { } } -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 } |
