diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed new file mode 100644 index 0000000000000..447b36048eed1 --- /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 84dfc34db1509..56a245aa8c7d8 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 03d2ef5506684..94caedb43a511 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