Skip to content

Commit 974900b

Browse files
committed
Split for_loops tests
1 parent b6fa4d4 commit 974900b

18 files changed

+658
-940
lines changed

tests/ui/explicit_counter_loop.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,54 @@ fn main() {
2323
for _v in vec {
2424
_index += 1;
2525
}
26+
27+
let vec = [1, 2, 3, 4];
28+
// Potential false positives
29+
let mut _index = 0;
30+
_index = 1;
31+
for _v in &vec {
32+
_index += 1
33+
}
34+
35+
let mut _index = 0;
36+
_index += 1;
37+
for _v in &vec {
38+
_index += 1
39+
}
40+
41+
let mut _index = 0;
42+
for _v in &vec {
43+
_index = 1;
44+
_index += 1
45+
}
46+
47+
let mut _index = 0;
48+
for _v in &vec {
49+
let mut _index = 0;
50+
_index += 1
51+
}
52+
53+
let mut _index = 0;
54+
for _v in &vec {
55+
_index += 1;
56+
_index = 0;
57+
}
58+
59+
let mut _index = 0;
60+
if true {
61+
_index = 1
62+
};
63+
for _v in &vec {
64+
_index += 1
65+
}
66+
67+
let mut _index = 1;
68+
if false {
69+
_index = 0
70+
};
71+
for _v in &vec {
72+
_index += 1
73+
}
2674
}
2775

2876
mod issue_1219 {

tests/ui/explicit_counter_loop.stderr

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,31 @@ LL | for _v in vec {
2525
| ^^^^^^^^^^^^^ help: consider using: `for (_index, _v) in vec.into_iter().enumerate()`
2626

2727
error: the variable `count` is used as a loop counter
28-
--> $DIR/explicit_counter_loop.rs:62:9
28+
--> $DIR/explicit_counter_loop.rs:110:9
2929
|
3030
LL | for ch in text.chars() {
3131
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
3232

3333
error: the variable `count` is used as a loop counter
34-
--> $DIR/explicit_counter_loop.rs:73:9
34+
--> $DIR/explicit_counter_loop.rs:121:9
3535
|
3636
LL | for ch in text.chars() {
3737
| ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `for (count, ch) in text.chars().enumerate()`
3838

3939
error: the variable `count` is used as a loop counter
40-
--> $DIR/explicit_counter_loop.rs:131:9
40+
--> $DIR/explicit_counter_loop.rs:179:9
4141
|
4242
LL | for _i in 3..10 {
4343
| ^^^^^^^^^^^^^^^ help: consider using: `for (count, _i) in (3..10).enumerate()`
4444

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

5151
error: the variable `idx_u32` is used as a loop counter
52-
--> $DIR/explicit_counter_loop.rs:183:9
52+
--> $DIR/explicit_counter_loop.rs:231:9
5353
|
5454
LL | for _item in slice {
5555
| ^^^^^^^^^^^^^^^^^^ help: consider using: `for (idx_u32, _item) in (0_u32..).zip(slice.iter())`
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//@run-rustfix
2+
#![warn(clippy::explicit_into_iter_loop)]
3+
4+
fn main() {
5+
// Issue #4958
6+
fn _takes_iterator<T>(iterator: &T)
7+
where
8+
for<'a> &'a T: IntoIterator<Item = &'a String>,
9+
{
10+
for i in iterator {
11+
println!("{}", i);
12+
}
13+
}
14+
15+
struct T;
16+
impl IntoIterator for &T {
17+
type Item = ();
18+
type IntoIter = std::vec::IntoIter<Self::Item>;
19+
fn into_iter(self) -> Self::IntoIter {
20+
vec![].into_iter()
21+
}
22+
}
23+
24+
let t = T;
25+
let r = &t;
26+
let rr = &&t;
27+
28+
// This case is handled by `explicit_iter_loop`. No idea why.
29+
for _ in t.into_iter() {}
30+
31+
for _ in r {}
32+
33+
// No suggestion for this.
34+
// We'd have to suggest `for _ in *rr {}` which is less clear.
35+
for _ in rr.into_iter() {}
36+
37+
// Issue #6900
38+
struct S;
39+
impl S {
40+
#[allow(clippy::should_implement_trait)]
41+
pub fn into_iter<T>(self) -> I<T> {
42+
unimplemented!()
43+
}
44+
}
45+
46+
struct I<T>(T);
47+
impl<T> Iterator for I<T> {
48+
type Item = T;
49+
fn next(&mut self) -> Option<Self::Item> {
50+
unimplemented!()
51+
}
52+
}
53+
54+
for _ in S.into_iter::<u32>() {}
55+
}

tests/ui/explicit_into_iter_loop.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//@run-rustfix
2+
#![warn(clippy::explicit_into_iter_loop)]
3+
4+
fn main() {
5+
// Issue #4958
6+
fn _takes_iterator<T>(iterator: &T)
7+
where
8+
for<'a> &'a T: IntoIterator<Item = &'a String>,
9+
{
10+
for i in iterator.into_iter() {
11+
println!("{}", i);
12+
}
13+
}
14+
15+
struct T;
16+
impl IntoIterator for &T {
17+
type Item = ();
18+
type IntoIter = std::vec::IntoIter<Self::Item>;
19+
fn into_iter(self) -> Self::IntoIter {
20+
vec![].into_iter()
21+
}
22+
}
23+
24+
let t = T;
25+
let r = &t;
26+
let rr = &&t;
27+
28+
// This case is handled by `explicit_iter_loop`. No idea why.
29+
for _ in t.into_iter() {}
30+
31+
for _ in r.into_iter() {}
32+
33+
// No suggestion for this.
34+
// We'd have to suggest `for _ in *rr {}` which is less clear.
35+
for _ in rr.into_iter() {}
36+
37+
// Issue #6900
38+
struct S;
39+
impl S {
40+
#[allow(clippy::should_implement_trait)]
41+
pub fn into_iter<T>(self) -> I<T> {
42+
unimplemented!()
43+
}
44+
}
45+
46+
struct I<T>(T);
47+
impl<T> Iterator for I<T> {
48+
type Item = T;
49+
fn next(&mut self) -> Option<Self::Item> {
50+
unimplemented!()
51+
}
52+
}
53+
54+
for _ in S.into_iter::<u32>() {}
55+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error: it is more concise to loop over containers instead of using explicit iteration methods
2+
--> $DIR/explicit_into_iter_loop.rs:10:18
3+
|
4+
LL | for i in iterator.into_iter() {
5+
| ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator`
6+
|
7+
= note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`
8+
9+
error: it is more concise to loop over containers instead of using explicit iteration methods
10+
--> $DIR/explicit_into_iter_loop.rs:31:14
11+
|
12+
LL | for _ in r.into_iter() {}
13+
| ^^^^^^^^^^^^^ help: to write this more concisely, try: `r`
14+
15+
error: aborting due to 2 previous errors
16+

tests/ui/explicit_iter_loop.fixed

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//@run-rustfix
2+
#![deny(clippy::explicit_iter_loop)]
3+
#![allow(
4+
clippy::linkedlist,
5+
clippy::similar_names,
6+
clippy::needless_borrow,
7+
clippy::deref_addrof,
8+
dead_code
9+
)]
10+
11+
use core::slice;
12+
use std::collections::*;
13+
14+
fn main() {
15+
let mut vec = vec![1, 2, 3, 4];
16+
17+
for _ in &vec {}
18+
for _ in &mut vec {}
19+
20+
for _ in &vec {} // these are fine
21+
for _ in &mut vec {} // these are fine
22+
23+
for _ in &[1, 2, 3] {}
24+
25+
for _ in &*(&mut [1, 2, 3]) {}
26+
27+
for _ in &[0; 32] {}
28+
for _ in &[0; 33] {}
29+
30+
let ll: LinkedList<()> = LinkedList::new();
31+
for _ in &ll {}
32+
33+
let vd: VecDeque<()> = VecDeque::new();
34+
for _ in &vd {}
35+
36+
let bh: BinaryHeap<()> = BinaryHeap::new();
37+
for _ in &bh {}
38+
39+
let hm: HashMap<(), ()> = HashMap::new();
40+
for _ in &hm {}
41+
42+
let bt: BTreeMap<(), ()> = BTreeMap::new();
43+
for _ in &bt {}
44+
45+
let hs: HashSet<()> = HashSet::new();
46+
for _ in &hs {}
47+
48+
let bs: BTreeSet<()> = BTreeSet::new();
49+
for _ in &bs {}
50+
51+
struct NoIntoIter();
52+
impl NoIntoIter {
53+
fn iter(&self) -> slice::Iter<u8> {
54+
unimplemented!()
55+
}
56+
57+
fn iter_mut(&mut self) -> slice::IterMut<u8> {
58+
unimplemented!()
59+
}
60+
}
61+
let mut x = NoIntoIter();
62+
for _ in x.iter() {} // no error
63+
for _ in x.iter_mut() {} // no error
64+
65+
struct IntoIterDiffTy;
66+
impl IntoIterator for &'_ IntoIterDiffTy {
67+
type Item = &'static ();
68+
type IntoIter = core::slice::Iter<'static, ()>;
69+
fn into_iter(self) -> Self::IntoIter {
70+
unimplemented!()
71+
}
72+
}
73+
impl IntoIterDiffTy {
74+
fn iter(&self) -> core::slice::Iter<'static, i32> {
75+
unimplemented!()
76+
}
77+
}
78+
let x = IntoIterDiffTy;
79+
for _ in x.iter() {}
80+
81+
struct IntoIterDiffSig;
82+
impl IntoIterator for &'_ IntoIterDiffSig {
83+
type Item = &'static ();
84+
type IntoIter = core::slice::Iter<'static, ()>;
85+
fn into_iter(self) -> Self::IntoIter {
86+
unimplemented!()
87+
}
88+
}
89+
impl IntoIterDiffSig {
90+
fn iter(&self, _: u32) -> core::slice::Iter<'static, ()> {
91+
unimplemented!()
92+
}
93+
}
94+
let x = IntoIterDiffSig;
95+
for _ in x.iter(0) {}
96+
97+
struct IntoIterDiffLt<'a>(&'a ());
98+
impl<'a> IntoIterator for &'a IntoIterDiffLt<'_> {
99+
type Item = &'a ();
100+
type IntoIter = core::slice::Iter<'a, ()>;
101+
fn into_iter(self) -> Self::IntoIter {
102+
unimplemented!()
103+
}
104+
}
105+
impl<'a> IntoIterDiffLt<'a> {
106+
fn iter(&self) -> core::slice::Iter<'a, ()> {
107+
unimplemented!()
108+
}
109+
}
110+
let x = IntoIterDiffLt(&());
111+
for _ in x.iter() {}
112+
113+
struct CustomType;
114+
impl<'a> IntoIterator for &'a CustomType {
115+
type Item = &'a u32;
116+
type IntoIter = core::slice::Iter<'a, u32>;
117+
fn into_iter(self) -> Self::IntoIter {
118+
unimplemented!()
119+
}
120+
}
121+
impl<'a> IntoIterator for &'a mut CustomType {
122+
type Item = &'a mut u32;
123+
type IntoIter = core::slice::IterMut<'a, u32>;
124+
fn into_iter(self) -> Self::IntoIter {
125+
unimplemented!()
126+
}
127+
}
128+
impl CustomType {
129+
fn iter(&self) -> <&'_ Self as IntoIterator>::IntoIter {
130+
panic!()
131+
}
132+
133+
fn iter_mut(&mut self) -> core::slice::IterMut<'_, u32> {
134+
panic!()
135+
}
136+
}
137+
let mut x = CustomType;
138+
for _ in &x {}
139+
for _ in &mut x {}
140+
}

0 commit comments

Comments
 (0)