Skip to content

Commit 42e1cf3

Browse files
committed
Auto merge of #3901 - rail-rain:issue_1670, r=flip1995
Fix `explicit_counter_loop` suggestion #1670 This code seems to me to work, but I have two question. * Because range expression desugared in hir, `Sugg::hir` doesn't add parenthesis to range expression. Which function is better to check range do you think, `check_for_loop_explicit_counter` or `hir_from_snippet`? * Do you think we need to distinguish between range expression and struct expression that creates `std::ops::Range*`?
2 parents e226f17 + 2b82c71 commit 42e1cf3

File tree

3 files changed

+46
-15
lines changed

3 files changed

+46
-15
lines changed

clippy_lints/src/loops.rs

+22-6
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,7 @@ fn check_for_loop<'a, 'tcx>(
777777
check_for_loop_range(cx, pat, arg, body, expr);
778778
check_for_loop_reverse_range(cx, arg, expr);
779779
check_for_loop_arg(cx, pat, arg, expr);
780-
check_for_loop_explicit_counter(cx, arg, body, expr);
780+
check_for_loop_explicit_counter(cx, pat, arg, body, expr);
781781
check_for_loop_over_map_kv(cx, pat, arg, body, expr);
782782
check_for_mut_range_bound(cx, arg, body);
783783
detect_manual_memcpy(cx, pat, arg, body, expr);
@@ -1453,6 +1453,7 @@ fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr) {
14531453

14541454
fn check_for_loop_explicit_counter<'a, 'tcx>(
14551455
cx: &LateContext<'a, 'tcx>,
1456+
pat: &'tcx Pat,
14561457
arg: &'tcx Expr,
14571458
body: &'tcx Expr,
14581459
expr: &'tcx Expr,
@@ -1489,16 +1490,31 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
14891490

14901491
if visitor2.state == VarState::Warn {
14911492
if let Some(name) = visitor2.name {
1492-
span_lint(
1493+
let mut applicability = Applicability::MachineApplicable;
1494+
span_lint_and_sugg(
14931495
cx,
14941496
EXPLICIT_COUNTER_LOOP,
14951497
expr.span,
1496-
&format!(
1497-
"the variable `{0}` is used as a loop counter. Consider using `for ({0}, \
1498-
item) in {1}.enumerate()` or similar iterators",
1498+
&format!("the variable `{}` is used as a loop counter.", name),
1499+
"consider using",
1500+
format!(
1501+
"for ({}, {}) in {}.enumerate()",
14991502
name,
1500-
snippet(cx, arg.span, "_")
1503+
snippet_with_applicability(cx, pat.span, "item", &mut applicability),
1504+
if higher::range(cx, arg).is_some() {
1505+
format!(
1506+
"({})",
1507+
snippet_with_applicability(cx, arg.span, "_", &mut applicability)
1508+
)
1509+
} else {
1510+
format!(
1511+
"{}",
1512+
sugg::Sugg::hir_with_applicability(cx, arg, "_", &mut applicability)
1513+
.maybe_par()
1514+
)
1515+
}
15011516
),
1517+
applicability,
15021518
);
15031519
}
15041520
}

tests/ui/explicit_counter_loop.rs

+9
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,12 @@ mod issue_3308 {
113113
}
114114
}
115115
}
116+
117+
mod issue_1670 {
118+
pub fn test() {
119+
let mut count = 0;
120+
for _i in 3..10 {
121+
count += 1;
122+
}
123+
}
124+
}

tests/ui/explicit_counter_loop.stderr

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
1-
error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
1+
error: the variable `_index` is used as a loop counter.
22
--> $DIR/explicit_counter_loop.rs:6:15
33
|
44
LL | for _v in &vec {
5-
| ^^^^
5+
| ^^^^ help: consider using: `for (_index, _v) in (&vec).enumerate()`
66
|
77
= note: `-D clippy::explicit-counter-loop` implied by `-D warnings`
88

9-
error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
9+
error: the variable `_index` is used as a loop counter.
1010
--> $DIR/explicit_counter_loop.rs:12:15
1111
|
1212
LL | for _v in &vec {
13-
| ^^^^
13+
| ^^^^ help: consider using: `for (_index, _v) in (&vec).enumerate()`
1414

15-
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
15+
error: the variable `count` is used as a loop counter.
1616
--> $DIR/explicit_counter_loop.rs:51:19
1717
|
1818
LL | for ch in text.chars() {
19-
| ^^^^^^^^^^^^
19+
| ^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
2020

21-
error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
21+
error: the variable `count` is used as a loop counter.
2222
--> $DIR/explicit_counter_loop.rs:62:19
2323
|
2424
LL | for ch in text.chars() {
25-
| ^^^^^^^^^^^^
25+
| ^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
2626

27-
error: aborting due to 4 previous errors
27+
error: the variable `count` is used as a loop counter.
28+
--> $DIR/explicit_counter_loop.rs:120:19
29+
|
30+
LL | for _i in 3..10 {
31+
| ^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()`
32+
33+
error: aborting due to 5 previous errors
2834

0 commit comments

Comments
 (0)