Skip to content

Commit

Permalink
Use ControlFlow in more visitors
Browse files Browse the repository at this point in the history
  • Loading branch information
blyxyas committed May 21, 2024
1 parent df20752 commit b36cebd
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 144 deletions.
4 changes: 3 additions & 1 deletion clippy_lints/src/copies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,9 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo
.stmts
.iter()
.filter(|stmt| !ignore_span.overlaps(stmt.span))
.for_each(|stmt| intravisit::walk_stmt(&mut walker, stmt));
.for_each(|stmt| {
intravisit::walk_stmt(&mut walker, stmt);
});

if let Some(expr) = block.expr {
intravisit::walk_expr(&mut walker, expr);
Expand Down
18 changes: 11 additions & 7 deletions clippy_lints/src/from_over_into.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use rustc_middle::ty;
use rustc_session::impl_lint_pass;
use rustc_span::symbol::{kw, sym};
use rustc_span::{Span, Symbol};
use std::ops::ControlFlow;

declare_clippy_lint! {
/// ### What it does
Expand Down Expand Up @@ -128,31 +129,34 @@ struct SelfFinder<'a, 'tcx> {

impl<'a, 'tcx> Visitor<'tcx> for SelfFinder<'a, 'tcx> {
type NestedFilter = OnlyBodies;
type Result = ControlFlow<()>;

fn nested_visit_map(&mut self) -> Self::Map {
self.cx.tcx.hir()
}

fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> ControlFlow<()> {
for segment in path.segments {
match segment.ident.name {
kw::SelfLower => self.lower.push(segment.ident.span),
kw::SelfUpper => self.upper.push(segment.ident.span),
_ => continue,
}

self.invalid |= segment.ident.span.from_expansion();
if segment.ident.span.from_expansion() || self.invalid {
return ControlFlow::Break(());
}
}

if !self.invalid {
walk_path(self, path);
}
walk_path(self, path);
ControlFlow::Continue(())
}

fn visit_name(&mut self, name: Symbol) {
fn visit_name(&mut self, name: Symbol) -> ControlFlow<()> {
if name == sym::val {
self.invalid = true;
return ControlFlow::Break(());
}
ControlFlow::Continue(())
}
}

Expand Down
13 changes: 9 additions & 4 deletions clippy_lints/src/if_let_mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::sym;
use std::ops::ControlFlow;

declare_clippy_lint! {
/// ### What it does
Expand Down Expand Up @@ -90,12 +91,14 @@ pub struct OppVisitor<'a, 'tcx> {
}

impl<'tcx> Visitor<'tcx> for OppVisitor<'_, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
type Result = ControlFlow<()>;
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> ControlFlow<()> {
if let Some(mutex) = is_mutex_lock_call(self.cx, expr) {
self.found_mutex = Some(mutex);
return;
return ControlFlow::Break(());
}
visit::walk_expr(self, expr);
ControlFlow::Continue(())
}
}

Expand All @@ -106,12 +109,14 @@ pub struct ArmVisitor<'a, 'tcx> {
}

impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
type Result = ControlFlow<()>;
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
if let Some(mutex) = is_mutex_lock_call(self.cx, expr) {
self.found_mutex = Some(mutex);
return;
return ControlFlow::Break(());
}
visit::walk_expr(self, expr);
ControlFlow::Continue(())
}
}

Expand Down
6 changes: 5 additions & 1 deletion clippy_lints/src/lifetimes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use rustc_session::declare_lint_pass;
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_span::Span;
use std::ops::ControlFlow;

declare_clippy_lint! {
/// ### What it does
Expand Down Expand Up @@ -699,10 +700,13 @@ struct BodyLifetimeChecker {
}

impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
type Result = ControlFlow<()>;
// for lifetimes as parameters of generics
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) -> ControlFlow<()> {
if !lifetime.is_anonymous() && lifetime.ident.name != kw::StaticLifetime {
self.lifetimes_used_in_body = true;
return ControlFlow::Break(());
}
ControlFlow::Continue(())
}
}
16 changes: 6 additions & 10 deletions clippy_lints/src/loops/mut_range_bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use rustc_lint::LateContext;
use rustc_middle::mir::FakeReadCause;
use rustc_middle::ty;
use rustc_span::Span;
use std::ops::ControlFlow;

pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) {
if let Some(higher::Range {
Expand Down Expand Up @@ -114,7 +115,6 @@ impl MutatePairDelegate<'_, '_> {
struct BreakAfterExprVisitor {
hir_id: HirId,
past_expr: bool,
past_candidate: bool,
break_after_expr: bool,
}

Expand All @@ -123,7 +123,6 @@ impl BreakAfterExprVisitor {
let mut visitor = BreakAfterExprVisitor {
hir_id,
past_expr: false,
past_candidate: false,
break_after_expr: false,
};

Expand All @@ -135,21 +134,18 @@ impl BreakAfterExprVisitor {
}

impl<'tcx> Visitor<'tcx> for BreakAfterExprVisitor {
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
if self.past_candidate {
return;
}

type Result = ControlFlow<()>;
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
if expr.hir_id == self.hir_id {
self.past_expr = true;
} else if self.past_expr {
if matches!(&expr.kind, ExprKind::Break(..)) {
self.break_after_expr = true;
}

self.past_candidate = true;
} else {
intravisit::walk_expr(self, expr);
return ControlFlow::Break(());
}
intravisit::walk_expr(self, expr);
ControlFlow::Continue(())
}
}
11 changes: 5 additions & 6 deletions clippy_lints/src/loops/while_immutable_condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use rustc_hir::def_id::DefIdMap;
use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Expr, ExprKind, HirIdSet, QPath};
use rustc_lint::LateContext;
use std::ops::ControlFlow;

pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) {
if constant(cx, cx.typeck_results(), cond).is_some() {
Expand Down Expand Up @@ -64,20 +65,18 @@ struct HasBreakOrReturnVisitor {
}

impl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
if self.has_break_or_return {
return;
}

type Result = ControlFlow<()>;
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> ControlFlow<()> {
match expr.kind {
ExprKind::Ret(_) | ExprKind::Break(_, _) => {
self.has_break_or_return = true;
return;
return ControlFlow::Break(());
},
_ => {},
}

walk_expr(self, expr);
ControlFlow::Continue(())
}
}

Expand Down
31 changes: 18 additions & 13 deletions clippy_lints/src/loops/while_let_on_iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use rustc_middle::hir::nested_filter::OnlyBodies;
use rustc_middle::ty::adjustment::Adjust;
use rustc_span::symbol::sym;
use rustc_span::Symbol;
use std::ops::ControlFlow;

pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
if let Some(higher::WhileLet { if_then, let_pat, let_expr, .. }) = higher::WhileLet::hir(expr)
Expand Down Expand Up @@ -204,22 +205,23 @@ fn uses_iter<'tcx>(cx: &LateContext<'tcx>, iter_expr: &IterExpr, container: &'tc
uses_iter: bool,
}
impl<'tcx> Visitor<'tcx> for V<'_, '_, 'tcx> {
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if self.uses_iter {
// return
} else if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
type Result = ControlFlow<()>;
fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> ControlFlow<()> {
if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
self.uses_iter = true;
return ControlFlow::Break(());
} else if let (e, true) = skip_fields_and_path(e) {
if let Some(e) = e {
self.visit_expr(e);
}
} else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
if is_res_used(self.cx, self.iter_expr.path, id) {
self.uses_iter = true;
return ControlFlow::Break(());
}
} else {
walk_expr(self, e);
}
walk_expr(self, e);
ControlFlow::Continue(())
}
}

Expand All @@ -243,31 +245,34 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
}
impl<'tcx> Visitor<'tcx> for AfterLoopVisitor<'_, '_, 'tcx> {
type NestedFilter = OnlyBodies;
type Result = ControlFlow<()>;
fn nested_visit_map(&mut self) -> Self::Map {
self.cx.tcx.hir()
}

fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
if self.used_iter {
return;
}
fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> ControlFlow<()> {
if self.after_loop {
if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
self.used_iter = true;
return ControlFlow::Break(());
} else if let (e, true) = skip_fields_and_path(e) {
if let Some(e) = e {
self.visit_expr(e);
}
} else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
self.used_iter = is_res_used(self.cx, self.iter_expr.path, id);
if is_res_used(self.cx, self.iter_expr.path, id) {
self.used_iter = true;
return ControlFlow::Break(());
}
} else {
walk_expr(self, e);
}
} else if self.loop_id == e.hir_id {
self.after_loop = true;
} else {
walk_expr(self, e);
}

walk_expr(self, e);
ControlFlow::Continue(())
}
}

Expand Down
28 changes: 15 additions & 13 deletions clippy_lints/src/methods/option_map_unwrap_or.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use rustc_hir::{ExprKind, HirId, Node, PatKind, Path, QPath};
use rustc_lint::LateContext;
use rustc_middle::hir::nested_filter;
use rustc_span::{sym, Span};
use std::ops::ControlFlow;

use super::MAP_UNWRAP_OR;

Expand Down Expand Up @@ -157,23 +158,24 @@ struct ReferenceVisitor<'a, 'tcx> {

impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
type NestedFilter = nested_filter::All;
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) {
type Result = ControlFlow<()>;
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) -> ControlFlow<()> {
// If we haven't found a reference yet, check if this references
// one of the locals that was moved in the `unwrap_or` argument.
// We are only interested in exprs that appear before the `unwrap_or` call.
if !self.found_reference {
if expr.span < self.unwrap_or_span
&& let ExprKind::Path(ref path) = expr.kind
&& let QPath::Resolved(_, path) = path
&& let Res::Local(local_id) = path.res
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
&& let PatKind::Binding(_, local_id, ..) = pat.kind
&& self.identifiers.contains(&local_id)
{
self.found_reference = true;
}
rustc_hir::intravisit::walk_expr(self, expr);
if expr.span < self.unwrap_or_span
&& let ExprKind::Path(ref path) = expr.kind
&& let QPath::Resolved(_, path) = path
&& let Res::Local(local_id) = path.res
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
&& let PatKind::Binding(_, local_id, ..) = pat.kind
&& self.identifiers.contains(&local_id)
{
self.found_reference = true;
return ControlFlow::Break(());
}
rustc_hir::intravisit::walk_expr(self, expr);
ControlFlow::Continue(())
}

fn nested_visit_map(&mut self) -> Self::Map {
Expand Down
9 changes: 6 additions & 3 deletions clippy_lints/src/redundant_closure_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::declare_lint_pass;
use rustc_span::ExpnKind;
use std::ops::ControlFlow;

declare_clippy_lint! {
/// ### What it does
Expand Down Expand Up @@ -54,12 +55,14 @@ impl ReturnVisitor {
}

impl<'tcx> Visitor<'tcx> for ReturnVisitor {
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
type Result = ControlFlow<()>;
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> ControlFlow<()> {
if let ExprKind::Ret(_) | ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {
self.found_return = true;
} else {
hir_visit::walk_expr(self, ex);
return ControlFlow::Break(());
}
hir_visit::walk_expr(self, ex);
ControlFlow::Continue(())
}
}

Expand Down
9 changes: 5 additions & 4 deletions clippy_lints/src/unconditional_recursion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_session::impl_lint_pass;
use rustc_span::symbol::{kw, Ident};
use rustc_span::{sym, Span};
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
use std::ops::ControlFlow;

declare_clippy_lint! {
/// ### What it does
Expand Down Expand Up @@ -285,15 +286,13 @@ where
'tcx: 'a,
{
type NestedFilter = nested_filter::OnlyBodies;
type Result = ControlFlow<()>;

fn nested_visit_map(&mut self) -> Self::Map {
self.map
}

fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
if self.found_default_call {
return;
}
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
walk_expr(self, expr);

if let ExprKind::Call(f, _) = expr.kind
Expand All @@ -305,7 +304,9 @@ where
{
self.found_default_call = true;
span_error(self.cx, self.method_span, expr);
return ControlFlow::Break(());
}
ControlFlow::Continue(())
}
}

Expand Down
Loading

0 comments on commit b36cebd

Please sign in to comment.