Skip to content

Commit 019c0d5

Browse files
committed
Auto merge of #6076 - rail-rain:fix_fp_explicit_counter_loop, r=matthiaskrgr
Fix a FP in `explicit_counter_loop` Fixes #4677 and #6074 Fix a false positive in `explicit_counter_loop` where the loop counter is used after incremented, adjust the test so that counters are incremented at the end of the loop and add the test for this false positive. --- changelog: Fix a false positive in `explicit_counter_loop` where the loop counter is used after incremented
2 parents e636b88 + 5e393c7 commit 019c0d5

File tree

2 files changed

+26
-9
lines changed

2 files changed

+26
-9
lines changed

clippy_lints/src/loops.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2134,7 +2134,7 @@ enum VarState {
21342134
DontWarn,
21352135
}
21362136

2137-
/// Scan a for loop for variables that are incremented exactly once.
2137+
/// Scan a for loop for variables that are incremented exactly once and not used after that.
21382138
struct IncrementVisitor<'a, 'tcx> {
21392139
cx: &'a LateContext<'tcx>, // context reference
21402140
states: FxHashMap<HirId, VarState>, // incremented variables
@@ -2154,6 +2154,10 @@ impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
21542154
if let Some(def_id) = var_def_id(self.cx, expr) {
21552155
if let Some(parent) = get_parent_expr(self.cx, expr) {
21562156
let state = self.states.entry(def_id).or_insert(VarState::Initial);
2157+
if *state == VarState::IncrOnce {
2158+
*state = VarState::DontWarn;
2159+
return;
2160+
}
21572161

21582162
match parent.kind {
21592163
ExprKind::AssignOp(op, ref lhs, ref rhs) => {

tests/ui/explicit_counter_loop.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -38,54 +38,54 @@ mod issue_1219 {
3838
let text = "banana";
3939
let mut count = 0;
4040
for ch in text.chars() {
41+
println!("{}", count);
4142
if ch == 'a' {
4243
continue;
4344
}
4445
count += 1;
45-
println!("{}", count);
4646
}
4747

4848
// should not trigger the lint because the count is conditional
4949
let text = "banana";
5050
let mut count = 0;
5151
for ch in text.chars() {
52+
println!("{}", count);
5253
if ch == 'a' {
5354
count += 1;
5455
}
55-
println!("{}", count);
5656
}
5757

5858
// should trigger the lint because the count is not conditional
5959
let text = "banana";
6060
let mut count = 0;
6161
for ch in text.chars() {
62+
println!("{}", count);
6263
count += 1;
6364
if ch == 'a' {
6465
continue;
6566
}
66-
println!("{}", count);
6767
}
6868

6969
// should trigger the lint because the count is not conditional
7070
let text = "banana";
7171
let mut count = 0;
7272
for ch in text.chars() {
73+
println!("{}", count);
7374
count += 1;
7475
for i in 0..2 {
7576
let _ = 123;
7677
}
77-
println!("{}", count);
7878
}
7979

8080
// should not trigger the lint because the count is incremented multiple times
8181
let text = "banana";
8282
let mut count = 0;
8383
for ch in text.chars() {
84+
println!("{}", count);
8485
count += 1;
8586
for i in 0..2 {
8687
count += 1;
8788
}
88-
println!("{}", count);
8989
}
9090
}
9191
}
@@ -96,30 +96,30 @@ mod issue_3308 {
9696
let mut skips = 0;
9797
let erasures = vec![];
9898
for i in 0..10 {
99+
println!("{}", skips);
99100
while erasures.contains(&(i + skips)) {
100101
skips += 1;
101102
}
102-
println!("{}", skips);
103103
}
104104

105105
// should not trigger the lint because the count is incremented multiple times
106106
let mut skips = 0;
107107
for i in 0..10 {
108+
println!("{}", skips);
108109
let mut j = 0;
109110
while j < 5 {
110111
skips += 1;
111112
j += 1;
112113
}
113-
println!("{}", skips);
114114
}
115115

116116
// should not trigger the lint because the count is incremented multiple times
117117
let mut skips = 0;
118118
for i in 0..10 {
119+
println!("{}", skips);
119120
for j in 0..5 {
120121
skips += 1;
121122
}
122-
println!("{}", skips);
123123
}
124124
}
125125
}
@@ -145,3 +145,16 @@ mod issue_4732 {
145145
let _closure = || println!("index: {}", index);
146146
}
147147
}
148+
149+
mod issue_4677 {
150+
pub fn test() {
151+
let slice = &[1, 2, 3];
152+
153+
// should not trigger the lint because the count is used after incremented
154+
let mut count = 0;
155+
for _i in slice {
156+
count += 1;
157+
println!("{}", count);
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)