Skip to content

Commit f30cf51

Browse files
authored
Merge pull request #3135 from JoshMcguigan/explicit_counter_loop-1219
Closes #1219 false positive for explicit_counter_loop
2 parents 2d3298b + 9168746 commit f30cf51

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

clippy_lints/src/loops.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1942,14 +1942,16 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
19421942
}
19431943
}
19441944
} else if is_loop(expr) {
1945-
self.states.clear();
1946-
self.done = true;
1945+
walk_expr(self, expr);
19471946
return;
19481947
} else if is_conditional(expr) {
19491948
self.depth += 1;
19501949
walk_expr(self, expr);
19511950
self.depth -= 1;
19521951
return;
1952+
} else if let ExprKind::Continue(_) = expr.node {
1953+
self.done = true;
1954+
return;
19531955
}
19541956
walk_expr(self, expr);
19551957
}

tests/ui/for_loop.rs

+65
Original file line numberDiff line numberDiff line change
@@ -571,3 +571,68 @@ mod issue_2496 {
571571
unimplemented!()
572572
}
573573
}
574+
575+
mod issue_1219 {
576+
#[warn(clippy::explicit_counter_loop)]
577+
pub fn test() {
578+
// should not trigger the lint because variable is used after the loop #473
579+
let vec = vec![1,2,3];
580+
let mut index = 0;
581+
for _v in &vec { index += 1 }
582+
println!("index: {}", index);
583+
584+
// should not trigger the lint because the count is conditional #1219
585+
let text = "banana";
586+
let mut count = 0;
587+
for ch in text.chars() {
588+
if ch == 'a' {
589+
continue;
590+
}
591+
count += 1;
592+
println!("{}", count);
593+
}
594+
595+
// should not trigger the lint because the count is conditional
596+
let text = "banana";
597+
let mut count = 0;
598+
for ch in text.chars() {
599+
if ch == 'a' {
600+
count += 1;
601+
}
602+
println!("{}", count);
603+
}
604+
605+
// should trigger the lint because the count is not conditional
606+
let text = "banana";
607+
let mut count = 0;
608+
for ch in text.chars() {
609+
count += 1;
610+
if ch == 'a' {
611+
continue;
612+
}
613+
println!("{}", count);
614+
}
615+
616+
// should trigger the lint because the count is not conditional
617+
let text = "banana";
618+
let mut count = 0;
619+
for ch in text.chars() {
620+
count += 1;
621+
for i in 0..2 {
622+
let _ = 123;
623+
}
624+
println!("{}", count);
625+
}
626+
627+
// should not trigger the lint because the count is incremented multiple times
628+
let text = "banana";
629+
let mut count = 0;
630+
for ch in text.chars() {
631+
count += 1;
632+
for i in 0..2 {
633+
count += 1;
634+
}
635+
println!("{}", count);
636+
}
637+
}
638+
}

tests/ui/for_loop.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -487,5 +487,17 @@ error: it looks like you're manually copying between slices
487487
547 | for i in 0..src.len() {
488488
| ^^^^^^^^^^^^ help: try replacing the loop by: `dst[..src.len()].clone_from_slice(&src[..])`
489489

490-
error: aborting due to 59 previous errors
490+
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
491+
--> $DIR/for_loop.rs:608:19
492+
|
493+
608 | for ch in text.chars() {
494+
| ^^^^^^^^^^^^
495+
496+
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
497+
--> $DIR/for_loop.rs:619:19
498+
|
499+
619 | for ch in text.chars() {
500+
| ^^^^^^^^^^^^
501+
502+
error: aborting due to 61 previous errors
491503

0 commit comments

Comments
 (0)