Skip to content

Commit ffcd033

Browse files
committed
Avoid to suggest using label
1 parent eefc609 commit ffcd033

File tree

3 files changed

+26
-52
lines changed

3 files changed

+26
-52
lines changed

clippy_lints/src/methods/excessive_for_each.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -31,26 +31,20 @@ pub(super) fn lint(cx: &LateContext<'_>, expr: &'tcx Expr<'_>, args: &[&[Expr<'_
3131
let body = cx.tcx.hir().body(body_id);
3232
if let ExprKind::Block(..) = body.value.kind;
3333
then {
34-
let mut ret_span_collector = RetSpanCollector::new();
35-
ret_span_collector.visit_expr(&body.value);
36-
37-
let label = "'outer";
38-
let loop_label = if ret_span_collector.need_label {
39-
format!("{}: ", label)
40-
} else {
41-
"".to_string()
42-
};
34+
let mut ret_collector = RetCollector::new();
35+
ret_collector.visit_expr(&body.value);
36+
37+
// Skip the lint if `return` is used in `Loop` to avoid a suggest using `'label`.
38+
if ret_collector.ret_in_loop {
39+
return;
40+
}
41+
4342
let sugg =
44-
format!("{}for {} in {} {{ .. }}", loop_label, snippet(cx, body.params[0].pat.span, ""), snippet(cx, for_each_receiver.span, ""));
43+
format!("for {} in {} {{ .. }}", snippet(cx, body.params[0].pat.span, ""), snippet(cx, for_each_receiver.span, ""));
4544

4645
let mut notes = vec![];
47-
for (span, need_label) in ret_span_collector.spans {
48-
let cont_label = if need_label {
49-
format!(" {}", label)
50-
} else {
51-
"".to_string()
52-
};
53-
let note = format!("change `return` to `continue{}` in the loop body", cont_label);
46+
for span in ret_collector.spans {
47+
let note = format!("change `return` to `continue` in the loop body");
5448
notes.push((span, note));
5549
}
5650

@@ -100,34 +94,37 @@ fn is_target_ty(cx: &LateContext<'_>, expr_ty: Ty<'_>) -> bool {
10094
false
10195
}
10296

103-
/// Collect spans of `return` in the closure body.
104-
struct RetSpanCollector {
105-
spans: Vec<(Span, bool)>,
97+
/// This type plays two roles.
98+
/// 1. Collect spans of `return` in the closure body.
99+
/// 2. Detect use of `return` in `Loop` in the closure body.
100+
struct RetCollector {
101+
spans: Vec<Span>,
102+
ret_in_loop: bool,
103+
106104
loop_depth: u16,
107-
need_label: bool,
108105
}
109106

110-
impl RetSpanCollector {
107+
impl RetCollector {
111108
fn new() -> Self {
112109
Self {
113110
spans: Vec::new(),
111+
ret_in_loop: false,
114112
loop_depth: 0,
115-
need_label: false,
116113
}
117114
}
118115
}
119116

120-
impl<'tcx> Visitor<'tcx> for RetSpanCollector {
117+
impl<'tcx> Visitor<'tcx> for RetCollector {
121118
type Map = Map<'tcx>;
122119

123120
fn visit_expr(&mut self, expr: &Expr<'_>) {
124121
match expr.kind {
125122
ExprKind::Ret(..) => {
126-
if self.loop_depth > 0 && !self.need_label {
127-
self.need_label = true
123+
if self.loop_depth > 0 && !self.ret_in_loop {
124+
self.ret_in_loop = true
128125
}
129126

130-
self.spans.push((expr.span, self.loop_depth > 0))
127+
self.spans.push(expr.span)
131128
},
132129

133130
ExprKind::Loop(..) => {

tests/ui/excessive_for_each.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ fn main() {
8282
}
8383
});
8484

85-
// Should trigger this lint with notes that say "change `return` to `continue 'outer`".
85+
// Should NOT trigger this lint in case `return` is used in `Loop` of the closure.
8686
vec.iter().for_each(|v| {
8787
for i in 0..*v {
8888
if i == 10 {

tests/ui/excessive_for_each.stderr

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -122,28 +122,5 @@ note: change `return` to `continue` in the loop body
122122
LL | return;
123123
| ^^^^^^
124124

125-
error: excessive use of `for_each`
126-
--> $DIR/excessive_for_each.rs:86:5
127-
|
128-
LL | / vec.iter().for_each(|v| {
129-
LL | | for i in 0..*v {
130-
LL | | if i == 10 {
131-
LL | | return;
132-
... |
133-
LL | | }
134-
LL | | });
135-
| |______^ help: try: `'outer: for v in vec.iter() { .. }`
136-
|
137-
note: change `return` to `continue 'outer` in the loop body
138-
--> $DIR/excessive_for_each.rs:89:17
139-
|
140-
LL | return;
141-
| ^^^^^^
142-
note: change `return` to `continue` in the loop body
143-
--> $DIR/excessive_for_each.rs:95:13
144-
|
145-
LL | return;
146-
| ^^^^^^
147-
148-
error: aborting due to 15 previous errors
125+
error: aborting due to 14 previous errors
149126

0 commit comments

Comments
 (0)