Skip to content

Commit 73db344

Browse files
committed
Use ControlFlow in more visitors
1 parent 0b1bf37 commit 73db344

15 files changed

+222
-144
lines changed

clippy_lints/src/copies.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,9 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo
554554
.stmts
555555
.iter()
556556
.filter(|stmt| !ignore_span.overlaps(stmt.span))
557-
.for_each(|stmt| intravisit::walk_stmt(&mut walker, stmt));
557+
.for_each(|stmt| {
558+
intravisit::walk_stmt(&mut walker, stmt);
559+
});
558560

559561
if let Some(expr) = block.expr {
560562
intravisit::walk_expr(&mut walker, expr);

clippy_lints/src/from_over_into.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use rustc_middle::ty;
1515
use rustc_session::impl_lint_pass;
1616
use rustc_span::symbol::{kw, sym};
1717
use rustc_span::{Span, Symbol};
18+
use std::ops::ControlFlow;
1819

1920
declare_clippy_lint! {
2021
/// ### What it does
@@ -128,31 +129,34 @@ struct SelfFinder<'a, 'tcx> {
128129

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

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

136-
fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) {
138+
fn visit_path(&mut self, path: &Path<'tcx>, _id: HirId) -> ControlFlow<()> {
137139
for segment in path.segments {
138140
match segment.ident.name {
139141
kw::SelfLower => self.lower.push(segment.ident.span),
140142
kw::SelfUpper => self.upper.push(segment.ident.span),
141143
_ => continue,
142144
}
143145

144-
self.invalid |= segment.ident.span.from_expansion();
146+
if segment.ident.span.from_expansion() || self.invalid {
147+
return ControlFlow::Break(());
148+
}
145149
}
146150

147-
if !self.invalid {
148-
walk_path(self, path);
149-
}
151+
walk_path(self, path);
152+
ControlFlow::Continue(())
150153
}
151154

152-
fn visit_name(&mut self, name: Symbol) {
155+
fn visit_name(&mut self, name: Symbol) -> ControlFlow<()> {
153156
if name == sym::val {
154-
self.invalid = true;
157+
return ControlFlow::Break(());
155158
}
159+
ControlFlow::Continue(())
156160
}
157161
}
158162

clippy_lints/src/if_let_mutex.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir::{Expr, ExprKind};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_session::declare_lint_pass;
99
use rustc_span::sym;
10+
use std::ops::ControlFlow;
1011

1112
declare_clippy_lint! {
1213
/// ### What it does
@@ -90,12 +91,14 @@ pub struct OppVisitor<'a, 'tcx> {
9091
}
9192

9293
impl<'tcx> Visitor<'tcx> for OppVisitor<'_, 'tcx> {
93-
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
94+
type Result = ControlFlow<()>;
95+
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> ControlFlow<()> {
9496
if let Some(mutex) = is_mutex_lock_call(self.cx, expr) {
9597
self.found_mutex = Some(mutex);
96-
return;
98+
return ControlFlow::Break(());
9799
}
98100
visit::walk_expr(self, expr);
101+
ControlFlow::Continue(())
99102
}
100103
}
101104

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

108111
impl<'tcx> Visitor<'tcx> for ArmVisitor<'_, 'tcx> {
109-
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
112+
type Result = ControlFlow<()>;
113+
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
110114
if let Some(mutex) = is_mutex_lock_call(self.cx, expr) {
111115
self.found_mutex = Some(mutex);
112-
return;
116+
return ControlFlow::Break(());
113117
}
114118
visit::walk_expr(self, expr);
119+
ControlFlow::Continue(())
115120
}
116121
}
117122

clippy_lints/src/lifetimes.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc_session::declare_lint_pass;
2222
use rustc_span::def_id::LocalDefId;
2323
use rustc_span::symbol::{kw, Ident, Symbol};
2424
use rustc_span::Span;
25+
use std::ops::ControlFlow;
2526

2627
declare_clippy_lint! {
2728
/// ### What it does
@@ -699,10 +700,13 @@ struct BodyLifetimeChecker {
699700
}
700701

701702
impl<'tcx> Visitor<'tcx> for BodyLifetimeChecker {
703+
type Result = ControlFlow<()>;
702704
// for lifetimes as parameters of generics
703-
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
705+
fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) -> ControlFlow<()> {
704706
if !lifetime.is_anonymous() && lifetime.ident.name != kw::StaticLifetime {
705707
self.lifetimes_used_in_body = true;
708+
return ControlFlow::Break(());
706709
}
710+
ControlFlow::Continue(())
707711
}
708712
}

clippy_lints/src/loops/mut_range_bound.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_lint::LateContext;
88
use rustc_middle::mir::FakeReadCause;
99
use rustc_middle::ty;
1010
use rustc_span::Span;
11+
use std::ops::ControlFlow;
1112

1213
pub(super) fn check(cx: &LateContext<'_>, arg: &Expr<'_>, body: &Expr<'_>) {
1314
if let Some(higher::Range {
@@ -114,7 +115,6 @@ impl MutatePairDelegate<'_, '_> {
114115
struct BreakAfterExprVisitor {
115116
hir_id: HirId,
116117
past_expr: bool,
117-
past_candidate: bool,
118118
break_after_expr: bool,
119119
}
120120

@@ -123,7 +123,6 @@ impl BreakAfterExprVisitor {
123123
let mut visitor = BreakAfterExprVisitor {
124124
hir_id,
125125
past_expr: false,
126-
past_candidate: false,
127126
break_after_expr: false,
128127
};
129128

@@ -135,21 +134,18 @@ impl BreakAfterExprVisitor {
135134
}
136135

137136
impl<'tcx> Visitor<'tcx> for BreakAfterExprVisitor {
138-
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
139-
if self.past_candidate {
140-
return;
141-
}
142-
137+
type Result = ControlFlow<()>;
138+
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
143139
if expr.hir_id == self.hir_id {
144140
self.past_expr = true;
145141
} else if self.past_expr {
146142
if matches!(&expr.kind, ExprKind::Break(..)) {
147143
self.break_after_expr = true;
148144
}
149145

150-
self.past_candidate = true;
151-
} else {
152-
intravisit::walk_expr(self, expr);
146+
return ControlFlow::Break(());
153147
}
148+
intravisit::walk_expr(self, expr);
149+
ControlFlow::Continue(())
154150
}
155151
}

clippy_lints/src/loops/while_immutable_condition.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir::def_id::DefIdMap;
77
use rustc_hir::intravisit::{walk_expr, Visitor};
88
use rustc_hir::{Expr, ExprKind, HirIdSet, QPath};
99
use rustc_lint::LateContext;
10+
use std::ops::ControlFlow;
1011

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

6667
impl<'tcx> Visitor<'tcx> for HasBreakOrReturnVisitor {
67-
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
68-
if self.has_break_or_return {
69-
return;
70-
}
71-
68+
type Result = ControlFlow<()>;
69+
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) -> ControlFlow<()> {
7270
match expr.kind {
7371
ExprKind::Ret(_) | ExprKind::Break(_, _) => {
7472
self.has_break_or_return = true;
75-
return;
73+
return ControlFlow::Break(());
7674
},
7775
_ => {},
7876
}
7977

8078
walk_expr(self, expr);
79+
ControlFlow::Continue(())
8180
}
8281
}
8382

clippy_lints/src/loops/while_let_on_iterator.rs

+18-13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_middle::hir::nested_filter::OnlyBodies;
1212
use rustc_middle::ty::adjustment::Adjust;
1313
use rustc_span::symbol::sym;
1414
use rustc_span::Symbol;
15+
use std::ops::ControlFlow;
1516

1617
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
1718
if let Some(higher::WhileLet { if_then, let_pat, let_expr, .. }) = higher::WhileLet::hir(expr)
@@ -204,22 +205,23 @@ fn uses_iter<'tcx>(cx: &LateContext<'tcx>, iter_expr: &IterExpr, container: &'tc
204205
uses_iter: bool,
205206
}
206207
impl<'tcx> Visitor<'tcx> for V<'_, '_, 'tcx> {
207-
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
208-
if self.uses_iter {
209-
// return
210-
} else if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
208+
type Result = ControlFlow<()>;
209+
fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> ControlFlow<()> {
210+
if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
211211
self.uses_iter = true;
212+
return ControlFlow::Break(());
212213
} else if let (e, true) = skip_fields_and_path(e) {
213214
if let Some(e) = e {
214215
self.visit_expr(e);
215216
}
216217
} else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
217218
if is_res_used(self.cx, self.iter_expr.path, id) {
218219
self.uses_iter = true;
220+
return ControlFlow::Break(());
219221
}
220-
} else {
221-
walk_expr(self, e);
222222
}
223+
walk_expr(self, e);
224+
ControlFlow::Continue(())
223225
}
224226
}
225227

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

250-
fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
251-
if self.used_iter {
252-
return;
253-
}
253+
fn visit_expr(&mut self, e: &'tcx Expr<'_>) -> ControlFlow<()> {
254254
if self.after_loop {
255255
if is_expr_same_child_or_parent_field(self.cx, e, &self.iter_expr.fields, self.iter_expr.path) {
256256
self.used_iter = true;
257+
return ControlFlow::Break(());
257258
} else if let (e, true) = skip_fields_and_path(e) {
258259
if let Some(e) = e {
259260
self.visit_expr(e);
260261
}
261262
} else if let ExprKind::Closure(&Closure { body: id, .. }) = e.kind {
262-
self.used_iter = is_res_used(self.cx, self.iter_expr.path, id);
263+
if is_res_used(self.cx, self.iter_expr.path, id) {
264+
self.used_iter = true;
265+
return ControlFlow::Break(());
266+
}
263267
} else {
264268
walk_expr(self, e);
265269
}
266270
} else if self.loop_id == e.hir_id {
267271
self.after_loop = true;
268-
} else {
269-
walk_expr(self, e);
270272
}
273+
274+
walk_expr(self, e);
275+
ControlFlow::Continue(())
271276
}
272277
}
273278

clippy_lints/src/methods/option_map_unwrap_or.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_hir::{ExprKind, HirId, Node, PatKind, Path, QPath};
1010
use rustc_lint::LateContext;
1111
use rustc_middle::hir::nested_filter;
1212
use rustc_span::{sym, Span};
13+
use std::ops::ControlFlow;
1314

1415
use super::MAP_UNWRAP_OR;
1516

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

158159
impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
159160
type NestedFilter = nested_filter::All;
160-
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) {
161+
type Result = ControlFlow<()>;
162+
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) -> ControlFlow<()> {
161163
// If we haven't found a reference yet, check if this references
162164
// one of the locals that was moved in the `unwrap_or` argument.
163165
// We are only interested in exprs that appear before the `unwrap_or` call.
164-
if !self.found_reference {
165-
if expr.span < self.unwrap_or_span
166-
&& let ExprKind::Path(ref path) = expr.kind
167-
&& let QPath::Resolved(_, path) = path
168-
&& let Res::Local(local_id) = path.res
169-
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
170-
&& let PatKind::Binding(_, local_id, ..) = pat.kind
171-
&& self.identifiers.contains(&local_id)
172-
{
173-
self.found_reference = true;
174-
}
175-
rustc_hir::intravisit::walk_expr(self, expr);
166+
if expr.span < self.unwrap_or_span
167+
&& let ExprKind::Path(ref path) = expr.kind
168+
&& let QPath::Resolved(_, path) = path
169+
&& let Res::Local(local_id) = path.res
170+
&& let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
171+
&& let PatKind::Binding(_, local_id, ..) = pat.kind
172+
&& self.identifiers.contains(&local_id)
173+
{
174+
self.found_reference = true;
175+
return ControlFlow::Break(());
176176
}
177+
rustc_hir::intravisit::walk_expr(self, expr);
178+
ControlFlow::Continue(())
177179
}
178180

179181
fn nested_visit_map(&mut self) -> Self::Map {

clippy_lints/src/redundant_closure_call.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_middle::lint::in_external_macro;
1414
use rustc_middle::ty;
1515
use rustc_session::declare_lint_pass;
1616
use rustc_span::ExpnKind;
17+
use std::ops::ControlFlow;
1718

1819
declare_clippy_lint! {
1920
/// ### What it does
@@ -54,12 +55,14 @@ impl ReturnVisitor {
5455
}
5556

5657
impl<'tcx> Visitor<'tcx> for ReturnVisitor {
57-
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
58+
type Result = ControlFlow<()>;
59+
fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> ControlFlow<()> {
5860
if let ExprKind::Ret(_) | ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {
5961
self.found_return = true;
60-
} else {
61-
hir_visit::walk_expr(self, ex);
62+
return ControlFlow::Break(());
6263
}
64+
hir_visit::walk_expr(self, ex);
65+
ControlFlow::Continue(())
6366
}
6467
}
6568

clippy_lints/src/unconditional_recursion.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use rustc_session::impl_lint_pass;
1616
use rustc_span::symbol::{kw, Ident};
1717
use rustc_span::{sym, Span};
1818
use rustc_trait_selection::traits::error_reporting::suggestions::ReturnsVisitor;
19+
use std::ops::ControlFlow;
1920

2021
declare_clippy_lint! {
2122
/// ### What it does
@@ -285,15 +286,13 @@ where
285286
'tcx: 'a,
286287
{
287288
type NestedFilter = nested_filter::OnlyBodies;
289+
type Result = ControlFlow<()>;
288290

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

293-
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
294-
if self.found_default_call {
295-
return;
296-
}
295+
fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> ControlFlow<()> {
297296
walk_expr(self, expr);
298297

299298
if let ExprKind::Call(f, _) = expr.kind
@@ -305,7 +304,9 @@ where
305304
{
306305
self.found_default_call = true;
307306
span_error(self.cx, self.method_span, expr);
307+
return ControlFlow::Break(());
308308
}
309+
ControlFlow::Continue(())
309310
}
310311
}
311312

0 commit comments

Comments
 (0)