about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/loops.rs28
-rw-r--r--tests/ui/explicit_counter_loop.rs9
-rw-r--r--tests/ui/explicit_counter_loop.stderr24
3 files changed, 46 insertions, 15 deletions
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index 0016625631c..c2b44ee7018 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -777,7 +777,7 @@ fn check_for_loop<'a, 'tcx>(
     check_for_loop_range(cx, pat, arg, body, expr);
     check_for_loop_reverse_range(cx, arg, expr);
     check_for_loop_arg(cx, pat, arg, expr);
-    check_for_loop_explicit_counter(cx, arg, body, expr);
+    check_for_loop_explicit_counter(cx, pat, arg, body, expr);
     check_for_loop_over_map_kv(cx, pat, arg, body, expr);
     check_for_mut_range_bound(cx, arg, body);
     detect_manual_memcpy(cx, pat, arg, body, expr);
@@ -1453,6 +1453,7 @@ fn check_arg_type(cx: &LateContext<'_, '_>, pat: &Pat, arg: &Expr) {
 
 fn check_for_loop_explicit_counter<'a, 'tcx>(
     cx: &LateContext<'a, 'tcx>,
+    pat: &'tcx Pat,
     arg: &'tcx Expr,
     body: &'tcx Expr,
     expr: &'tcx Expr,
@@ -1489,16 +1490,31 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
 
                 if visitor2.state == VarState::Warn {
                     if let Some(name) = visitor2.name {
-                        span_lint(
+                        let mut applicability = Applicability::MachineApplicable;
+                        span_lint_and_sugg(
                             cx,
                             EXPLICIT_COUNTER_LOOP,
                             expr.span,
-                            &format!(
-                                "the variable `{0}` is used as a loop counter. Consider using `for ({0}, \
-                                 item) in {1}.enumerate()` or similar iterators",
+                            &format!("the variable `{}` is used as a loop counter.", name),
+                            "consider using",
+                            format!(
+                                "for ({}, {}) in {}.enumerate()",
                                 name,
-                                snippet(cx, arg.span, "_")
+                                snippet_with_applicability(cx, pat.span, "item", &mut applicability),
+                                if higher::range(cx, arg).is_some() {
+                                    format!(
+                                        "({})",
+                                        snippet_with_applicability(cx, arg.span, "_", &mut applicability)
+                                    )
+                                } else {
+                                    format!(
+                                        "{}",
+                                        sugg::Sugg::hir_with_applicability(cx, arg, "_", &mut applicability)
+                                            .maybe_par()
+                                    )
+                                }
                             ),
+                            applicability,
                         );
                     }
                 }
diff --git a/tests/ui/explicit_counter_loop.rs b/tests/ui/explicit_counter_loop.rs
index 5efac85cf22..71ef1e8674a 100644
--- a/tests/ui/explicit_counter_loop.rs
+++ b/tests/ui/explicit_counter_loop.rs
@@ -113,3 +113,12 @@ mod issue_3308 {
         }
     }
 }
+
+mod issue_1670 {
+    pub fn test() {
+        let mut count = 0;
+        for _i in 3..10 {
+            count += 1;
+        }
+    }
+}
diff --git a/tests/ui/explicit_counter_loop.stderr b/tests/ui/explicit_counter_loop.stderr
index b1cfb31432f..5efd51abf18 100644
--- a/tests/ui/explicit_counter_loop.stderr
+++ b/tests/ui/explicit_counter_loop.stderr
@@ -1,28 +1,34 @@
-error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
+error: the variable `_index` is used as a loop counter.
   --> $DIR/explicit_counter_loop.rs:6:15
    |
 LL |     for _v in &vec {
-   |               ^^^^
+   |               ^^^^ help: consider using: `for (_index, _v) in (&vec).enumerate()`
    |
    = note: `-D clippy::explicit-counter-loop` implied by `-D warnings`
 
-error: the variable `_index` is used as a loop counter. Consider using `for (_index, item) in &vec.enumerate()` or similar iterators
+error: the variable `_index` is used as a loop counter.
   --> $DIR/explicit_counter_loop.rs:12:15
    |
 LL |     for _v in &vec {
-   |               ^^^^
+   |               ^^^^ help: consider using: `for (_index, _v) in (&vec).enumerate()`
 
-error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
+error: the variable `count` is used as a loop counter.
   --> $DIR/explicit_counter_loop.rs:51:19
    |
 LL |         for ch in text.chars() {
-   |                   ^^^^^^^^^^^^
+   |                   ^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
 
-error: the variable `count` is used as a loop counter. Consider using `for (count, item) in text.chars().enumerate()` or similar iterators
+error: the variable `count` is used as a loop counter.
   --> $DIR/explicit_counter_loop.rs:62:19
    |
 LL |         for ch in text.chars() {
-   |                   ^^^^^^^^^^^^
+   |                   ^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
 
-error: aborting due to 4 previous errors
+error: the variable `count` is used as a loop counter.
+  --> $DIR/explicit_counter_loop.rs:120:19
+   |
+LL |         for _i in 3..10 {
+   |                   ^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()`
+
+error: aborting due to 5 previous errors