about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tests/ui/while_let_on_iterator.fixed144
-rw-r--r--tests/ui/while_let_on_iterator.rs32
-rw-r--r--tests/ui/while_let_on_iterator.stderr22
3 files changed, 177 insertions, 21 deletions
diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed
new file mode 100644
index 00000000000..447b36048ee
--- /dev/null
+++ b/tests/ui/while_let_on_iterator.fixed
@@ -0,0 +1,144 @@
+// run-rustfix
+
+#![warn(clippy::while_let_on_iterator)]
+#![allow(clippy::never_loop, unreachable_code, unused_mut)]
+
+fn base() {
+    let mut iter = 1..20;
+    for x in iter {
+        println!("{}", x);
+    }
+
+    let mut iter = 1..20;
+    for x in iter {
+        println!("{}", x);
+    }
+
+    let mut iter = 1..20;
+    for _ in iter {}
+
+    let mut iter = 1..20;
+    while let None = iter.next() {} // this is fine (if nonsensical)
+
+    let mut iter = 1..20;
+    if let Some(x) = iter.next() {
+        // also fine
+        println!("{}", x)
+    }
+
+    // the following shouldn't warn because it can't be written with a for loop
+    let mut iter = 1u32..20;
+    while let Some(_) = iter.next() {
+        println!("next: {:?}", iter.next())
+    }
+
+    // neither can this
+    let mut iter = 1u32..20;
+    while let Some(_) = iter.next() {
+        println!("next: {:?}", iter.next());
+    }
+
+    // or this
+    let mut iter = 1u32..20;
+    while let Some(_) = iter.next() {
+        break;
+    }
+    println!("Remaining iter {:?}", iter);
+
+    // or this
+    let mut iter = 1u32..20;
+    while let Some(_) = iter.next() {
+        iter = 1..20;
+    }
+}
+
+// Issue #1188
+fn refutable() {
+    let a = [42, 1337];
+    let mut b = a.iter();
+
+    // consume all the 42s
+    while let Some(&42) = b.next() {}
+
+    let a = [(1, 2, 3)];
+    let mut b = a.iter();
+
+    while let Some(&(1, 2, 3)) = b.next() {}
+
+    let a = [Some(42)];
+    let mut b = a.iter();
+
+    while let Some(&None) = b.next() {}
+
+    /* This gives “refutable pattern in `for` loop binding: `&_` not covered”
+    for &42 in b {}
+    for &(1, 2, 3) in b {}
+    for &Option::None in b.next() {}
+    // */
+}
+
+fn nested_loops() {
+    let a = [42, 1337];
+    let mut y = a.iter();
+    loop {
+        // x is reused, so don't lint here
+        while let Some(_) = y.next() {}
+    }
+
+    let mut y = a.iter();
+    for _ in 0..2 {
+        while let Some(_) = y.next() {
+            // y is reused, don't lint
+        }
+    }
+
+    loop {
+        let mut y = a.iter();
+        for _ in y {
+            // use a for loop here
+        }
+    }
+}
+
+fn issue1121() {
+    use std::collections::HashSet;
+    let mut values = HashSet::new();
+    values.insert(1);
+
+    while let Some(&value) = values.iter().next() {
+        values.remove(&value);
+    }
+}
+
+fn issue2965() {
+    // This should not cause an ICE and suggest:
+    //
+    // for _ in values.iter() {}
+    //
+    use std::collections::HashSet;
+    let mut values = HashSet::new();
+    values.insert(1);
+
+    for _ in values.iter() {
+        // FIXME(flip1995): Linting this with the following line uncommented is a FP, see #1654
+        // values.remove(&1);
+    }
+}
+
+fn issue3670() {
+    let array = [Some(0), None, Some(1)];
+    let mut iter = array.iter();
+
+    while let Some(elem) = iter.next() {
+        let _ = elem.or_else(|| *iter.next()?);
+    }
+}
+
+fn main() {
+    base();
+    refutable();
+    nested_loops();
+    issue1121();
+    issue2965();
+    issue3670();
+}
diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs
index 84dfc34db15..56a245aa8c7 100644
--- a/tests/ui/while_let_on_iterator.rs
+++ b/tests/ui/while_let_on_iterator.rs
@@ -1,7 +1,9 @@
+// run-rustfix
+
 #![warn(clippy::while_let_on_iterator)]
-#![allow(clippy::never_loop)]
+#![allow(clippy::never_loop, unreachable_code, unused_mut)]
 
-fn main() {
+fn base() {
     let mut iter = 1..20;
     while let Option::Some(x) = iter.next() {
         println!("{}", x);
@@ -26,26 +28,26 @@ fn main() {
 
     // the following shouldn't warn because it can't be written with a for loop
     let mut iter = 1u32..20;
-    while let Some(x) = iter.next() {
+    while let Some(_) = iter.next() {
         println!("next: {:?}", iter.next())
     }
 
     // neither can this
     let mut iter = 1u32..20;
-    while let Some(x) = iter.next() {
+    while let Some(_) = iter.next() {
         println!("next: {:?}", iter.next());
     }
 
     // or this
     let mut iter = 1u32..20;
-    while let Some(x) = iter.next() {
+    while let Some(_) = iter.next() {
         break;
     }
     println!("Remaining iter {:?}", iter);
 
     // or this
     let mut iter = 1u32..20;
-    while let Some(x) = iter.next() {
+    while let Some(_) = iter.next() {
         iter = 1..20;
     }
 }
@@ -80,19 +82,19 @@ fn nested_loops() {
     let mut y = a.iter();
     loop {
         // x is reused, so don't lint here
-        while let Some(v) = y.next() {}
+        while let Some(_) = y.next() {}
     }
 
     let mut y = a.iter();
     for _ in 0..2 {
-        while let Some(v) = y.next() {
+        while let Some(_) = y.next() {
             // y is reused, don't lint
         }
     }
 
     loop {
         let mut y = a.iter();
-        while let Some(v) = y.next() {
+        while let Some(_) = y.next() {
             // use a for loop here
         }
     }
@@ -118,7 +120,8 @@ fn issue2965() {
     values.insert(1);
 
     while let Some(..) = values.iter().next() {
-        values.remove(&1);
+        // FIXME(flip1995): Linting this with the following line uncommented is a FP, see #1654
+        // values.remove(&1);
     }
 }
 
@@ -130,3 +133,12 @@ fn issue3670() {
         let _ = elem.or_else(|| *iter.next()?);
     }
 }
+
+fn main() {
+    base();
+    refutable();
+    nested_loops();
+    issue1121();
+    issue2965();
+    issue3670();
+}
diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr
index 03d2ef55066..94caedb43a5 100644
--- a/tests/ui/while_let_on_iterator.stderr
+++ b/tests/ui/while_let_on_iterator.stderr
@@ -1,34 +1,34 @@
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:6:33
+  --> $DIR/while_let_on_iterator.rs:8:5
    |
 LL |     while let Option::Some(x) = iter.next() {
-   |                                 ^^^^^^^^^^^ help: try: `for x in iter { .. }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`
    |
    = note: `-D clippy::while-let-on-iterator` implied by `-D warnings`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:11:25
+  --> $DIR/while_let_on_iterator.rs:13:5
    |
 LL |     while let Some(x) = iter.next() {
-   |                         ^^^^^^^^^^^ help: try: `for x in iter { .. }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:16:25
+  --> $DIR/while_let_on_iterator.rs:18:5
    |
 LL |     while let Some(_) = iter.next() {}
-   |                         ^^^^^^^^^^^ help: try: `for _ in iter { .. }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in iter`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:95:29
+  --> $DIR/while_let_on_iterator.rs:97:9
    |
-LL |         while let Some(v) = y.next() {
-   |                             ^^^^^^^^ help: try: `for v in y { .. }`
+LL |         while let Some(_) = y.next() {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in y`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:120:26
+  --> $DIR/while_let_on_iterator.rs:122:5
    |
 LL |     while let Some(..) = values.iter().next() {
-   |                          ^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in values.iter() { .. }`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in values.iter()`
 
 error: aborting due to 5 previous errors