Skip to content

Commit

Permalink
Split for_loops tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarcho committed Jun 10, 2023
1 parent b6fa4d4 commit 974900b
Show file tree
Hide file tree
Showing 18 changed files with 658 additions and 940 deletions.
48 changes: 48 additions & 0 deletions tests/ui/explicit_counter_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,54 @@ fn main() {
for _v in vec {
_index += 1;
}

let vec = [1, 2, 3, 4];
// Potential false positives
let mut _index = 0;
_index = 1;
for _v in &vec {
_index += 1
}

let mut _index = 0;
_index += 1;
for _v in &vec {
_index += 1
}

let mut _index = 0;
for _v in &vec {
_index = 1;
_index += 1
}

let mut _index = 0;
for _v in &vec {
let mut _index = 0;
_index += 1
}

let mut _index = 0;
for _v in &vec {
_index += 1;
_index = 0;
}

let mut _index = 0;
if true {
_index = 1
};
for _v in &vec {
_index += 1
}

let mut _index = 1;
if false {
_index = 0
};
for _v in &vec {
_index += 1
}
}

mod issue_1219 {
Expand Down
10 changes: 5 additions & 5 deletions tests/ui/explicit_counter_loop.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,31 @@ LL | for _v in vec {
| ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()`

error: the variable `count` is used as a loop counter
--> $DIR/explicit_counter_loop.rs:62:9
--> $DIR/explicit_counter_loop.rs:110:9
|
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
--> $DIR/explicit_counter_loop.rs:73:9
--> $DIR/explicit_counter_loop.rs:121:9
|
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
--> $DIR/explicit_counter_loop.rs:131:9
--> $DIR/explicit_counter_loop.rs:179:9
|
LL | for _i in 3..10 {
| ^^^^^^^^^^^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()`

error: the variable `idx_usize` is used as a loop counter
--> $DIR/explicit_counter_loop.rs:171:9
--> $DIR/explicit_counter_loop.rs:219:9
|
LL | for _item in slice {
| ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_usize, _item) in slice.iter().enumerate()`

error: the variable `idx_u32` is used as a loop counter
--> $DIR/explicit_counter_loop.rs:183:9
--> $DIR/explicit_counter_loop.rs:231:9
|
LL | for _item in slice {
| ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_u32, _item) in (0_u32..).zip(slice.iter())`
Expand Down
55 changes: 55 additions & 0 deletions tests/ui/explicit_into_iter_loop.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//@run-rustfix
#![warn(clippy::explicit_into_iter_loop)]

fn main() {
// Issue #4958
fn _takes_iterator<T>(iterator: &T)
where
for<'a> &'a T: IntoIterator<Item = &'a String>,
{
for i in iterator {
println!("{}", i);
}
}

struct T;
impl IntoIterator for &T {
type Item = ();
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
vec![].into_iter()
}
}

let t = T;
let r = &t;
let rr = &&t;

// This case is handled by `explicit_iter_loop`. No idea why.
for _ in t.into_iter() {}

for _ in r {}

// No suggestion for this.
// We'd have to suggest `for _ in *rr {}` which is less clear.
for _ in rr.into_iter() {}

// Issue #6900
struct S;
impl S {
#[allow(clippy::should_implement_trait)]
pub fn into_iter<T>(self) -> I<T> {
unimplemented!()
}
}

struct I<T>(T);
impl<T> Iterator for I<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}

for _ in S.into_iter::<u32>() {}
}
55 changes: 55 additions & 0 deletions tests/ui/explicit_into_iter_loop.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//@run-rustfix
#![warn(clippy::explicit_into_iter_loop)]

fn main() {
// Issue #4958
fn _takes_iterator<T>(iterator: &T)
where
for<'a> &'a T: IntoIterator<Item = &'a String>,
{
for i in iterator.into_iter() {
println!("{}", i);
}
}

struct T;
impl IntoIterator for &T {
type Item = ();
type IntoIter = std::vec::IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
vec![].into_iter()
}
}

let t = T;
let r = &t;
let rr = &&t;

// This case is handled by `explicit_iter_loop`. No idea why.
for _ in t.into_iter() {}

for _ in r.into_iter() {}

// No suggestion for this.
// We'd have to suggest `for _ in *rr {}` which is less clear.
for _ in rr.into_iter() {}

// Issue #6900
struct S;
impl S {
#[allow(clippy::should_implement_trait)]
pub fn into_iter<T>(self) -> I<T> {
unimplemented!()
}
}

struct I<T>(T);
impl<T> Iterator for I<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
unimplemented!()
}
}

for _ in S.into_iter::<u32>() {}
}
16 changes: 16 additions & 0 deletions tests/ui/explicit_into_iter_loop.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: it is more concise to loop over containers instead of using explicit iteration methods
--> $DIR/explicit_into_iter_loop.rs:10:18
|
LL | for i in iterator.into_iter() {
| ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator`
|
= note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`

error: it is more concise to loop over containers instead of using explicit iteration methods
--> $DIR/explicit_into_iter_loop.rs:31:14
|
LL | for _ in r.into_iter() {}
| ^^^^^^^^^^^^^ help: to write this more concisely, try: `r`

error: aborting due to 2 previous errors

140 changes: 140 additions & 0 deletions tests/ui/explicit_iter_loop.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//@run-rustfix
#![deny(clippy::explicit_iter_loop)]
#![allow(
clippy::linkedlist,
clippy::similar_names,
clippy::needless_borrow,
clippy::deref_addrof,
dead_code
)]

use core::slice;
use std::collections::*;

fn main() {
let mut vec = vec![1, 2, 3, 4];

for _ in &vec {}
for _ in &mut vec {}

for _ in &vec {} // these are fine
for _ in &mut vec {} // these are fine

for _ in &[1, 2, 3] {}

for _ in &*(&mut [1, 2, 3]) {}

for _ in &[0; 32] {}
for _ in &[0; 33] {}

let ll: LinkedList<()> = LinkedList::new();
for _ in &ll {}

let vd: VecDeque<()> = VecDeque::new();
for _ in &vd {}

let bh: BinaryHeap<()> = BinaryHeap::new();
for _ in &bh {}

let hm: HashMap<(), ()> = HashMap::new();
for _ in &hm {}

let bt: BTreeMap<(), ()> = BTreeMap::new();
for _ in &bt {}

let hs: HashSet<()> = HashSet::new();
for _ in &hs {}

let bs: BTreeSet<()> = BTreeSet::new();
for _ in &bs {}

struct NoIntoIter();
impl NoIntoIter {
fn iter(&self) -> slice::Iter<u8> {
unimplemented!()
}

fn iter_mut(&mut self) -> slice::IterMut<u8> {
unimplemented!()
}
}
let mut x = NoIntoIter();
for _ in x.iter() {} // no error
for _ in x.iter_mut() {} // no error

struct IntoIterDiffTy;
impl IntoIterator for &'_ IntoIterDiffTy {
type Item = &'static ();
type IntoIter = core::slice::Iter<'static, ()>;
fn into_iter(self) -> Self::IntoIter {
unimplemented!()
}
}
impl IntoIterDiffTy {
fn iter(&self) -> core::slice::Iter<'static, i32> {
unimplemented!()
}
}
let x = IntoIterDiffTy;
for _ in x.iter() {}

struct IntoIterDiffSig;
impl IntoIterator for &'_ IntoIterDiffSig {
type Item = &'static ();
type IntoIter = core::slice::Iter<'static, ()>;
fn into_iter(self) -> Self::IntoIter {
unimplemented!()
}
}
impl IntoIterDiffSig {
fn iter(&self, _: u32) -> core::slice::Iter<'static, ()> {
unimplemented!()
}
}
let x = IntoIterDiffSig;
for _ in x.iter(0) {}

struct IntoIterDiffLt<'a>(&'a ());
impl<'a> IntoIterator for &'a IntoIterDiffLt<'_> {
type Item = &'a ();
type IntoIter = core::slice::Iter<'a, ()>;
fn into_iter(self) -> Self::IntoIter {
unimplemented!()
}
}
impl<'a> IntoIterDiffLt<'a> {
fn iter(&self) -> core::slice::Iter<'a, ()> {
unimplemented!()
}
}
let x = IntoIterDiffLt(&());
for _ in x.iter() {}

struct CustomType;
impl<'a> IntoIterator for &'a CustomType {
type Item = &'a u32;
type IntoIter = core::slice::Iter<'a, u32>;
fn into_iter(self) -> Self::IntoIter {
unimplemented!()
}
}
impl<'a> IntoIterator for &'a mut CustomType {
type Item = &'a mut u32;
type IntoIter = core::slice::IterMut<'a, u32>;
fn into_iter(self) -> Self::IntoIter {
unimplemented!()
}
}
impl CustomType {
fn iter(&self) -> <&'_ Self as IntoIterator>::IntoIter {
panic!()
}

fn iter_mut(&mut self) -> core::slice::IterMut<'_, u32> {
panic!()
}
}
let mut x = CustomType;
for _ in &x {}
for _ in &mut x {}
}
Loading

0 comments on commit 974900b

Please sign in to comment.