about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/loops/single_element_loop.rs35
-rw-r--r--tests/ui/single_element_loop.fixed12
-rw-r--r--tests/ui/single_element_loop.stderr72
3 files changed, 45 insertions, 74 deletions
diff --git a/clippy_lints/src/loops/single_element_loop.rs b/clippy_lints/src/loops/single_element_loop.rs
index d860b297a02..4773a1454b7 100644
--- a/clippy_lints/src/loops/single_element_loop.rs
+++ b/clippy_lints/src/loops/single_element_loop.rs
@@ -1,6 +1,6 @@
 use super::SINGLE_ELEMENT_LOOP;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{indent_of, snippet_with_applicability};
+use clippy_utils::source::{indent_of, snippet, snippet_with_applicability};
 use clippy_utils::visitors::contains_break_or_continue;
 use rustc_ast::util::parser::PREC_PREFIX;
 use rustc_ast::Mutability;
@@ -87,14 +87,29 @@ pub(super) fn check<'tcx>(
             arg_snip = format!("({arg_snip})").into();
         }
 
-        span_lint_and_sugg(
-            cx,
-            SINGLE_ELEMENT_LOOP,
-            expr.span,
-            "for loop over a single element",
-            "try",
-            format!("{{\n{indent}let {pat_snip} = {prefix}{arg_snip};{block_str}}}"),
-            applicability,
-        );
+        if clippy_utils::higher::Range::hir(arg_expression).is_some() {
+            let range_expr = snippet(cx, arg_expression.span, "?").to_string();
+
+            let sugg = snippet(cx, arg_expression.span, "..");
+            span_lint_and_sugg(
+                cx,
+                SINGLE_ELEMENT_LOOP,
+                arg.span,
+                format!("this loops only once with `{pat_snip}` being `{range_expr}`").as_str(),
+                "did you mean to iterate over the range instead?",
+                sugg.to_string(),
+                Applicability::Unspecified,
+            );
+        } else {
+            span_lint_and_sugg(
+                cx,
+                SINGLE_ELEMENT_LOOP,
+                expr.span,
+                "for loop over a single element",
+                "try",
+                format!("{{\n{indent}let {pat_snip} = {prefix}{arg_snip};{block_str}}}"),
+                applicability,
+            );
+        }
     }
 }
diff --git a/tests/ui/single_element_loop.fixed b/tests/ui/single_element_loop.fixed
index a82eb6afcf5..4e59c763198 100644
--- a/tests/ui/single_element_loop.fixed
+++ b/tests/ui/single_element_loop.fixed
@@ -15,23 +15,19 @@ fn main() {
         dbg!(item);
     }
 
-    {
-        let item = &(0..5);
+    for item in 0..5 {
         dbg!(item);
     }
 
-    {
-        let item = &mut (0..5);
+    for item in 0..5 {
         dbg!(item);
     }
 
-    {
-        let item = 0..5;
+    for item in 0..5 {
         dbg!(item);
     }
 
-    {
-        let item = 0..5;
+    for item in 0..5 {
         dbg!(item);
     }
 
diff --git a/tests/ui/single_element_loop.stderr b/tests/ui/single_element_loop.stderr
index 603dd7406e4..952d704143a 100644
--- a/tests/ui/single_element_loop.stderr
+++ b/tests/ui/single_element_loop.stderr
@@ -32,69 +32,29 @@ LL +         dbg!(item);
 LL +     }
    |
 
-error: for loop over a single element
-  --> $DIR/single_element_loop.rs:16:5
-   |
-LL | /     for item in &[0..5] {
-LL | |         dbg!(item);
-LL | |     }
-   | |_____^
-   |
-help: try
-   |
-LL ~     {
-LL +         let item = &(0..5);
-LL +         dbg!(item);
-LL +     }
+error: this loops only once with `item` being `0..5`
+  --> $DIR/single_element_loop.rs:16:17
    |
+LL |     for item in &[0..5] {
+   |                 ^^^^^^^ help: did you mean to iterate over the range instead?: `0..5`
 
-error: for loop over a single element
-  --> $DIR/single_element_loop.rs:20:5
-   |
-LL | /     for item in [0..5].iter_mut() {
-LL | |         dbg!(item);
-LL | |     }
-   | |_____^
-   |
-help: try
-   |
-LL ~     {
-LL +         let item = &mut (0..5);
-LL +         dbg!(item);
-LL +     }
+error: this loops only once with `item` being `0..5`
+  --> $DIR/single_element_loop.rs:20:17
    |
+LL |     for item in [0..5].iter_mut() {
+   |                 ^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5`
 
-error: for loop over a single element
-  --> $DIR/single_element_loop.rs:24:5
-   |
-LL | /     for item in [0..5] {
-LL | |         dbg!(item);
-LL | |     }
-   | |_____^
-   |
-help: try
-   |
-LL ~     {
-LL +         let item = 0..5;
-LL +         dbg!(item);
-LL +     }
+error: this loops only once with `item` being `0..5`
+  --> $DIR/single_element_loop.rs:24:17
    |
+LL |     for item in [0..5] {
+   |                 ^^^^^^ help: did you mean to iterate over the range instead?: `0..5`
 
-error: for loop over a single element
-  --> $DIR/single_element_loop.rs:28:5
-   |
-LL | /     for item in [0..5].into_iter() {
-LL | |         dbg!(item);
-LL | |     }
-   | |_____^
-   |
-help: try
-   |
-LL ~     {
-LL +         let item = 0..5;
-LL +         dbg!(item);
-LL +     }
+error: this loops only once with `item` being `0..5`
+  --> $DIR/single_element_loop.rs:28:17
    |
+LL |     for item in [0..5].into_iter() {
+   |                 ^^^^^^^^^^^^^^^^^^ help: did you mean to iterate over the range instead?: `0..5`
 
 error: for loop over a single element
   --> $DIR/single_element_loop.rs:47:5