Skip to content

Commit 204b279

Browse files
committed
lint for into_iter().count()
1 parent 7223ee6 commit 204b279

File tree

4 files changed

+116
-83
lines changed

4 files changed

+116
-83
lines changed

clippy_lints/src/methods/mod.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
16911691
lint_search_is_some(cx, expr, "rposition", arg_lists[1], arg_lists[0], method_spans[1])
16921692
},
16931693
["extend", ..] => lint_extend(cx, expr, arg_lists[0]),
1694-
["count", "iter"] => lint_iter_count(cx, expr, &arg_lists[1], false),
1694+
["count", "into_iter" | "iter"] => lint_iter_count(cx, expr, &arg_lists[1], false),
16951695
["count", "iter_mut"] => lint_iter_count(cx, expr, &arg_lists[1], true),
16961696
["nth", "iter"] => lint_iter_nth(cx, expr, &arg_lists, false),
16971697
["nth", "iter_mut"] => lint_iter_nth(cx, expr, &arg_lists, true),
@@ -2663,6 +2663,13 @@ fn lint_iter_next<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, iter_
26632663

26642664
fn lint_iter_count<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'tcx [Expr<'tcx>], is_mut: bool) {
26652665
let mut_str = if is_mut { "_mut" } else { "" };
2666+
let iter_method = if method_chain_args(expr, &[format!("iter{}", mut_str).as_str(), "count"]).is_some() {
2667+
"iter"
2668+
} else if method_chain_args(expr, &["into_iter", "count"]).is_some() {
2669+
"into_iter"
2670+
} else {
2671+
return;
2672+
};
26662673
if_chain! {
26672674
let caller_type = if derefs_to_slice(cx, &iter_args[0], cx.typeck_results().expr_ty(&iter_args[0])).is_some() {
26682675
Some("slice")
@@ -2682,7 +2689,7 @@ fn lint_iter_count<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, iter_args: &'t
26822689
cx,
26832690
ITER_COUNT,
26842691
expr.span,
2685-
&format!("called `.iter{}().count()` on a `{}`", mut_str, caller_type),
2692+
&format!("called `.{}{}().count()` on a `{}`", iter_method, mut_str, caller_type),
26862693
"try",
26872694
format!(
26882695
"{}.len()",

tests/ui/iter_count.fixed

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
// aux-build:option_helpers.rs
33

44
#![warn(clippy::iter_count)]
5-
#![allow(unused_variables)]
6-
#![allow(unused_mut)]
5+
#![allow(
6+
unused_variables,
7+
array_into_iter,
8+
unused_mut,
9+
clippy::into_iter_on_ref,
10+
clippy::unnecessary_operation
11+
)]
712

813
extern crate option_helpers;
914

@@ -22,37 +27,36 @@ impl HasIter {
2227
fn iter_mut(self) -> IteratorFalsePositives {
2328
IteratorFalsePositives { foo: 0 }
2429
}
30+
31+
fn into_iter(self) -> IteratorFalsePositives {
32+
IteratorFalsePositives { foo: 0 }
33+
}
2534
}
2635

2736
fn main() {
28-
let mut some_vec = vec![0, 1, 2, 3];
37+
let mut vec = vec![0, 1, 2, 3];
2938
let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
30-
let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect();
31-
let mut some_hash_set = HashSet::new();
32-
some_hash_set.insert(1);
33-
34-
{
35-
// Make sure we lint `.iter()` for relevant types.
36-
let bad_vec = some_vec.len();
37-
let bad_slice = &some_vec[..].len();
38-
let bad_boxed_slice = boxed_slice.len();
39-
let bad_vec_deque = some_vec_deque.len();
40-
let bad_hash_set = some_hash_set.len();
41-
}
39+
let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect();
40+
let mut hash_set = HashSet::new();
41+
hash_set.insert(1);
4242

43-
{
44-
// Make sure we lint `.iter_mut()` for relevant types.
45-
let bad_vec = some_vec.len();
46-
}
47-
{
48-
let bad_slice = &some_vec[..].len();
49-
}
50-
{
51-
let bad_vec_deque = some_vec_deque.len();
52-
}
43+
&vec[..].len();
44+
vec.len();
45+
boxed_slice.len();
46+
vec_deque.len();
47+
hash_set.len();
48+
49+
vec.len();
50+
&vec[..].len();
51+
vec_deque.len();
52+
53+
&vec[..].len();
54+
vec.len();
55+
vec_deque.len();
5356

5457
// Make sure we don't lint for non-relevant types.
5558
let false_positive = HasIter;
56-
let ok = false_positive.iter().count();
57-
let ok_mut = false_positive.iter_mut().count();
59+
false_positive.iter().count();
60+
false_positive.iter_mut().count();
61+
false_positive.into_iter().count();
5862
}

tests/ui/iter_count.rs

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
22
// aux-build:option_helpers.rs
33

44
#![warn(clippy::iter_count)]
5-
#![allow(unused_variables)]
6-
#![allow(unused_mut)]
5+
#![allow(
6+
unused_variables,
7+
array_into_iter,
8+
unused_mut,
9+
clippy::into_iter_on_ref,
10+
clippy::unnecessary_operation
11+
)]
712

813
extern crate option_helpers;
914

@@ -22,37 +27,36 @@ impl HasIter {
2227
fn iter_mut(self) -> IteratorFalsePositives {
2328
IteratorFalsePositives { foo: 0 }
2429
}
30+
31+
fn into_iter(self) -> IteratorFalsePositives {
32+
IteratorFalsePositives { foo: 0 }
33+
}
2534
}
2635

2736
fn main() {
28-
let mut some_vec = vec![0, 1, 2, 3];
37+
let mut vec = vec![0, 1, 2, 3];
2938
let mut boxed_slice: Box<[u8]> = Box::new([0, 1, 2, 3]);
30-
let mut some_vec_deque: VecDeque<_> = some_vec.iter().cloned().collect();
31-
let mut some_hash_set = HashSet::new();
32-
some_hash_set.insert(1);
33-
34-
{
35-
// Make sure we lint `.iter()` for relevant types.
36-
let bad_vec = some_vec.iter().count();
37-
let bad_slice = &some_vec[..].iter().count();
38-
let bad_boxed_slice = boxed_slice.iter().count();
39-
let bad_vec_deque = some_vec_deque.iter().count();
40-
let bad_hash_set = some_hash_set.iter().count();
41-
}
39+
let mut vec_deque: VecDeque<_> = vec.iter().cloned().collect();
40+
let mut hash_set = HashSet::new();
41+
hash_set.insert(1);
4242

43-
{
44-
// Make sure we lint `.iter_mut()` for relevant types.
45-
let bad_vec = some_vec.iter_mut().count();
46-
}
47-
{
48-
let bad_slice = &some_vec[..].iter_mut().count();
49-
}
50-
{
51-
let bad_vec_deque = some_vec_deque.iter_mut().count();
52-
}
43+
&vec[..].iter().count();
44+
vec.iter().count();
45+
boxed_slice.iter().count();
46+
vec_deque.iter().count();
47+
hash_set.iter().count();
48+
49+
vec.iter_mut().count();
50+
&vec[..].iter_mut().count();
51+
vec_deque.iter_mut().count();
52+
53+
&vec[..].into_iter().count();
54+
vec.into_iter().count();
55+
vec_deque.into_iter().count();
5356

5457
// Make sure we don't lint for non-relevant types.
5558
let false_positive = HasIter;
56-
let ok = false_positive.iter().count();
57-
let ok_mut = false_positive.iter_mut().count();
59+
false_positive.iter().count();
60+
false_positive.iter_mut().count();
61+
false_positive.into_iter().count();
5862
}

tests/ui/iter_count.stderr

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,70 @@
1-
error: called `.iter().count()` on a `Vec`
2-
--> $DIR/iter_count.rs:36:23
1+
error: called `.iter().count()` on a `slice`
2+
--> $DIR/iter_count.rs:43:6
33
|
4-
LL | let bad_vec = some_vec.iter().count();
5-
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec.len()`
4+
LL | &vec[..].iter().count();
5+
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`
66
|
77
= note: `-D clippy::iter-count` implied by `-D warnings`
88

9-
error: called `.iter().count()` on a `slice`
10-
--> $DIR/iter_count.rs:37:26
9+
error: called `.iter().count()` on a `Vec`
10+
--> $DIR/iter_count.rs:44:5
1111
|
12-
LL | let bad_slice = &some_vec[..].iter().count();
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[..].len()`
12+
LL | vec.iter().count();
13+
| ^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`
1414

1515
error: called `.iter().count()` on a `slice`
16-
--> $DIR/iter_count.rs:38:31
16+
--> $DIR/iter_count.rs:45:5
1717
|
18-
LL | let bad_boxed_slice = boxed_slice.iter().count();
19-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()`
18+
LL | boxed_slice.iter().count();
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `boxed_slice.len()`
2020

2121
error: called `.iter().count()` on a `VecDeque`
22-
--> $DIR/iter_count.rs:39:29
22+
--> $DIR/iter_count.rs:46:5
2323
|
24-
LL | let bad_vec_deque = some_vec_deque.iter().count();
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec_deque.len()`
24+
LL | vec_deque.iter().count();
25+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`
2626

2727
error: called `.iter().count()` on a `std::iter::Iterator`
28-
--> $DIR/iter_count.rs:40:28
28+
--> $DIR/iter_count.rs:47:5
2929
|
30-
LL | let bad_hash_set = some_hash_set.iter().count();
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_hash_set.len()`
30+
LL | hash_set.iter().count();
31+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `hash_set.len()`
3232

3333
error: called `.iter_mut().count()` on a `Vec`
34-
--> $DIR/iter_count.rs:45:23
34+
--> $DIR/iter_count.rs:49:5
3535
|
36-
LL | let bad_vec = some_vec.iter_mut().count();
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec.len()`
36+
LL | vec.iter_mut().count();
37+
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`
3838

3939
error: called `.iter_mut().count()` on a `slice`
40-
--> $DIR/iter_count.rs:48:26
40+
--> $DIR/iter_count.rs:50:6
4141
|
42-
LL | let bad_slice = &some_vec[..].iter_mut().count();
43-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec[..].len()`
42+
LL | &vec[..].iter_mut().count();
43+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`
4444

4545
error: called `.iter_mut().count()` on a `VecDeque`
46-
--> $DIR/iter_count.rs:51:29
46+
--> $DIR/iter_count.rs:51:5
47+
|
48+
LL | vec_deque.iter_mut().count();
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`
50+
51+
error: called `.into_iter().count()` on a `slice`
52+
--> $DIR/iter_count.rs:53:6
53+
|
54+
LL | &vec[..].into_iter().count();
55+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec[..].len()`
56+
57+
error: called `.into_iter().count()` on a `Vec`
58+
--> $DIR/iter_count.rs:54:5
59+
|
60+
LL | vec.into_iter().count();
61+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.len()`
62+
63+
error: called `.into_iter().count()` on a `VecDeque`
64+
--> $DIR/iter_count.rs:55:5
4765
|
48-
LL | let bad_vec_deque = some_vec_deque.iter_mut().count();
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `some_vec_deque.len()`
66+
LL | vec_deque.into_iter().count();
67+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec_deque.len()`
5068

51-
error: aborting due to 8 previous errors
69+
error: aborting due to 11 previous errors
5270

0 commit comments

Comments
 (0)