Skip to content

Commit 0cdf6e1

Browse files
committed
Fix while_let_on_iterator dropping loop label when applying fix.
1 parent df1baed commit 0cdf6e1

File tree

5 files changed

+33
-4
lines changed

5 files changed

+33
-4
lines changed

clippy_lints/src/loops/while_let_on_iterator.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_span::symbol::sym;
1414
use rustc_span::Symbol;
1515

1616
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
17-
if let Some(higher::WhileLet { if_then, let_pat, let_expr, .. }) = higher::WhileLet::hir(expr)
17+
if let Some(higher::WhileLet { if_then, let_pat, let_expr, label, .. }) = higher::WhileLet::hir(expr)
1818
// check for `Some(..)` pattern
1919
&& let PatKind::TupleStruct(ref pat_path, some_pat, _) = let_pat.kind
2020
&& is_res_lang_ctor(cx, cx.qpath_res(pat_path, let_pat.hir_id), LangItem::OptionSome)
@@ -27,6 +27,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
2727
&& !uses_iter(cx, &iter_expr_struct, if_then)
2828
{
2929
let mut applicability = Applicability::MachineApplicable;
30+
31+
let loop_label = label.map_or(String::new(), |l| format!("{}: ", l.ident.name));
32+
3033
let loop_var = if let Some(some_pat) = some_pat.first() {
3134
if is_refutable(cx, some_pat) {
3235
// Refutable patterns don't work with for loops.
@@ -57,7 +60,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
5760
expr.span.with_hi(let_expr.span.hi()),
5861
"this loop could be written as a `for` loop",
5962
"try",
60-
format!("for {loop_var} in {iterator}{by_ref}"),
63+
format!("{loop_label}for {loop_var} in {iterator}{by_ref}"),
6164
applicability,
6265
);
6366
}

clippy_utils/src/higher.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ pub struct WhileLet<'hir> {
367367
pub let_expr: &'hir Expr<'hir>,
368368
/// `while let` loop body
369369
pub if_then: &'hir Expr<'hir>,
370+
pub label: Option<ast::Label>,
370371
/// `while let PAT = EXPR`
371372
/// ^^^^^^^^^^^^^^
372373
pub let_span: Span,
@@ -399,7 +400,7 @@ impl<'hir> WhileLet<'hir> {
399400
}),
400401
..
401402
},
402-
_,
403+
label,
403404
LoopSource::While,
404405
_,
405406
) = expr.kind
@@ -408,6 +409,7 @@ impl<'hir> WhileLet<'hir> {
408409
let_pat,
409410
let_expr,
410411
if_then,
412+
label,
411413
let_span,
412414
});
413415
}

tests/ui/while_let_on_iterator.fixed

+9
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,15 @@ fn fn_once_closure() {
456456
});
457457
}
458458

459+
fn issue13123() {
460+
let mut it = 0..20;
461+
'label: for n in it {
462+
if n % 25 == 0 {
463+
break 'label;
464+
}
465+
}
466+
}
467+
459468
fn main() {
460469
let mut it = 0..20;
461470
for _ in it {

tests/ui/while_let_on_iterator.rs

+9
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,15 @@ fn fn_once_closure() {
456456
});
457457
}
458458

459+
fn issue13123() {
460+
let mut it = 0..20;
461+
'label: while let Some(n) = it.next() {
462+
if n % 25 == 0 {
463+
break 'label;
464+
}
465+
}
466+
}
467+
459468
fn main() {
460469
let mut it = 0..20;
461470
while let Some(..) = it.next() {

tests/ui/while_let_on_iterator.stderr

+7-1
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,14 @@ LL | while let Some(x) = it.next() {
160160
error: this loop could be written as a `for` loop
161161
--> tests/ui/while_let_on_iterator.rs:461:5
162162
|
163+
LL | 'label: while let Some(n) = it.next() {
164+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `'label: for n in it`
165+
166+
error: this loop could be written as a `for` loop
167+
--> tests/ui/while_let_on_iterator.rs:470:5
168+
|
163169
LL | while let Some(..) = it.next() {
164170
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`
165171

166-
error: aborting due to 27 previous errors
172+
error: aborting due to 28 previous errors
167173

0 commit comments

Comments
 (0)