Skip to content

Commit 8f50346

Browse files
committed
Trigger the lint iff exposure's body is ExprKind::Block.
1 parent 7fbdd8e commit 8f50346

File tree

3 files changed

+115
-58
lines changed

3 files changed

+115
-58
lines changed

clippy_lints/src/methods/excessive_for_each.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ pub(super) fn lint(cx: &LateContext<'_>, expr: &'tcx Expr<'_>, args: &[&[Expr<'_
2828
if match_trait_method(cx, expr, &paths::ITERATOR);
2929
if is_target_ty(cx, cx.typeck_results().expr_ty(iter_receiver));
3030
if let ExprKind::Closure(_, _, body_id, ..) = for_each_arg.kind;
31+
let body = cx.tcx.hir().body(body_id);
32+
if let ExprKind::Block(..) = body.value.kind;
3133
then {
32-
let body = cx.tcx.hir().body(body_id);
3334
let mut ret_span_collector = RetSpanCollector::new();
3435
ret_span_collector.visit_expr(&body.value);
3536

tests/ui/excessive_for_each.rs

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,45 +6,72 @@ use std::collections::*;
66
fn main() {
77
// Should trigger this lint: Vec.
88
let vec: Vec<i32> = Vec::new();
9-
vec.iter().for_each(|v| println!("{}", v));
9+
let mut acc = 0;
10+
vec.iter().for_each(|v| {
11+
acc += v;
12+
});
1013

1114
// Should trigger this lint: &Vec.
1215
let vec_ref = &vec;
13-
vec_ref.iter().for_each(|v| println!("{}", v));
16+
vec_ref.iter().for_each(|v| {
17+
acc += v;
18+
});
1419

1520
// Should trigger this lint: VecDeque.
1621
let vec_deq: VecDeque<i32> = VecDeque::new();
17-
vec_deq.iter().for_each(|v| println!("{}", v));
22+
vec_deq.iter().for_each(|v| {
23+
acc += v;
24+
});
1825

1926
// Should trigger this lint: LinkedList.
2027
let list: LinkedList<i32> = LinkedList::new();
21-
list.iter().for_each(|v| println!("{}", v));
28+
list.iter().for_each(|v| {
29+
acc += v;
30+
});
2231

2332
// Should trigger this lint: HashMap.
2433
let mut hash_map: HashMap<i32, i32> = HashMap::new();
25-
hash_map.iter().for_each(|(k, v)| println!("{}: {}", k, v));
26-
hash_map.iter_mut().for_each(|(k, v)| println!("{}: {}", k, v));
27-
hash_map.keys().for_each(|k| println!("{}", k));
28-
hash_map.values().for_each(|v| println!("{}", v));
34+
hash_map.iter().for_each(|(k, v)| {
35+
acc += k + v;
36+
});
37+
hash_map.iter_mut().for_each(|(k, v)| {
38+
acc += *k + *v;
39+
});
40+
hash_map.keys().for_each(|k| {
41+
acc += k;
42+
});
43+
hash_map.values().for_each(|v| {
44+
acc += v;
45+
});
2946

3047
// Should trigger this lint: HashSet.
3148
let hash_set: HashSet<i32> = HashSet::new();
32-
hash_set.iter().for_each(|v| println!("{}", v));
49+
hash_set.iter().for_each(|v| {
50+
acc += v;
51+
});
3352

3453
// Should trigger this lint: BTreeSet.
3554
let btree_set: BTreeSet<i32> = BTreeSet::new();
36-
btree_set.iter().for_each(|v| println!("{}", v));
55+
btree_set.iter().for_each(|v| {
56+
acc += v;
57+
});
3758

3859
// Should trigger this lint: BinaryHeap.
3960
let binary_heap: BinaryHeap<i32> = BinaryHeap::new();
40-
binary_heap.iter().for_each(|v| println!("{}", v));
61+
binary_heap.iter().for_each(|v| {
62+
acc += v;
63+
});
4164

4265
// Should trigger this lint: Array.
4366
let s = [1, 2, 3];
44-
s.iter().for_each(|v| println!("{}", v));
67+
s.iter().for_each(|v| {
68+
acc += v;
69+
});
4570

4671
// Should trigger this lint. Slice.
47-
vec.as_slice().iter().for_each(|v| println!("{}", v));
72+
vec.as_slice().iter().for_each(|v| {
73+
acc += v;
74+
});
4875

4976
// Should trigger this lint with notes that say "change `return` to `continue`".
5077
vec.iter().for_each(|v| {
@@ -83,6 +110,9 @@ fn main() {
83110
// Should NOT trigger this lint in case the receiver of `iter` is a user defined type.
84111
let my_collection = MyCollection { v: vec![] };
85112
my_collection.iter().for_each(|v| println!("{}", v));
113+
114+
// Should NOT trigger this lint in case the closure body is not a `ExprKind::Block`.
115+
vec.iter().for_each(|x| acc += x);
86116
}
87117

88118
struct MyCollection {

tests/ui/excessive_for_each.stderr

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,111 @@
11
error: excessive use of `for_each`
2-
--> $DIR/excessive_for_each.rs:9:5
2+
--> $DIR/excessive_for_each.rs:10:5
33
|
4-
LL | vec.iter().for_each(|v| println!("{}", v));
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec.iter() { .. }`
4+
LL | / vec.iter().for_each(|v| {
5+
LL | | acc += v;
6+
LL | | });
7+
| |______^ help: try: `for v in vec.iter() { .. }`
68
|
79
= note: `-D clippy::excessive-for-each` implied by `-D warnings`
810

911
error: excessive use of `for_each`
10-
--> $DIR/excessive_for_each.rs:13:5
12+
--> $DIR/excessive_for_each.rs:16:5
1113
|
12-
LL | vec_ref.iter().for_each(|v| println!("{}", v));
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec_ref.iter() { .. }`
14+
LL | / vec_ref.iter().for_each(|v| {
15+
LL | | acc += v;
16+
LL | | });
17+
| |______^ help: try: `for v in vec_ref.iter() { .. }`
1418

1519
error: excessive use of `for_each`
16-
--> $DIR/excessive_for_each.rs:17:5
20+
--> $DIR/excessive_for_each.rs:22:5
1721
|
18-
LL | vec_deq.iter().for_each(|v| println!("{}", v));
19-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec_deq.iter() { .. }`
22+
LL | / vec_deq.iter().for_each(|v| {
23+
LL | | acc += v;
24+
LL | | });
25+
| |______^ help: try: `for v in vec_deq.iter() { .. }`
2026

2127
error: excessive use of `for_each`
22-
--> $DIR/excessive_for_each.rs:21:5
28+
--> $DIR/excessive_for_each.rs:28:5
2329
|
24-
LL | list.iter().for_each(|v| println!("{}", v));
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in list.iter() { .. }`
30+
LL | / list.iter().for_each(|v| {
31+
LL | | acc += v;
32+
LL | | });
33+
| |______^ help: try: `for v in list.iter() { .. }`
2634

2735
error: excessive use of `for_each`
28-
--> $DIR/excessive_for_each.rs:25:5
36+
--> $DIR/excessive_for_each.rs:34:5
2937
|
30-
LL | hash_map.iter().for_each(|(k, v)| println!("{}: {}", k, v));
31-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for (k, v) in hash_map.iter() { .. }`
38+
LL | / hash_map.iter().for_each(|(k, v)| {
39+
LL | | acc += k + v;
40+
LL | | });
41+
| |______^ help: try: `for (k, v) in hash_map.iter() { .. }`
3242

3343
error: excessive use of `for_each`
34-
--> $DIR/excessive_for_each.rs:26:5
44+
--> $DIR/excessive_for_each.rs:37:5
3545
|
36-
LL | hash_map.iter_mut().for_each(|(k, v)| println!("{}: {}", k, v));
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for (k, v) in hash_map.iter_mut() { .. }`
46+
LL | / hash_map.iter_mut().for_each(|(k, v)| {
47+
LL | | acc += *k + *v;
48+
LL | | });
49+
| |______^ help: try: `for (k, v) in hash_map.iter_mut() { .. }`
3850

3951
error: excessive use of `for_each`
40-
--> $DIR/excessive_for_each.rs:27:5
52+
--> $DIR/excessive_for_each.rs:40:5
4153
|
42-
LL | hash_map.keys().for_each(|k| println!("{}", k));
43-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for k in hash_map.keys() { .. }`
54+
LL | / hash_map.keys().for_each(|k| {
55+
LL | | acc += k;
56+
LL | | });
57+
| |______^ help: try: `for k in hash_map.keys() { .. }`
4458

4559
error: excessive use of `for_each`
46-
--> $DIR/excessive_for_each.rs:28:5
60+
--> $DIR/excessive_for_each.rs:43:5
4761
|
48-
LL | hash_map.values().for_each(|v| println!("{}", v));
49-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in hash_map.values() { .. }`
62+
LL | / hash_map.values().for_each(|v| {
63+
LL | | acc += v;
64+
LL | | });
65+
| |______^ help: try: `for v in hash_map.values() { .. }`
5066

5167
error: excessive use of `for_each`
52-
--> $DIR/excessive_for_each.rs:32:5
68+
--> $DIR/excessive_for_each.rs:49:5
5369
|
54-
LL | hash_set.iter().for_each(|v| println!("{}", v));
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in hash_set.iter() { .. }`
70+
LL | / hash_set.iter().for_each(|v| {
71+
LL | | acc += v;
72+
LL | | });
73+
| |______^ help: try: `for v in hash_set.iter() { .. }`
5674

5775
error: excessive use of `for_each`
58-
--> $DIR/excessive_for_each.rs:36:5
76+
--> $DIR/excessive_for_each.rs:55:5
5977
|
60-
LL | btree_set.iter().for_each(|v| println!("{}", v));
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in btree_set.iter() { .. }`
78+
LL | / btree_set.iter().for_each(|v| {
79+
LL | | acc += v;
80+
LL | | });
81+
| |______^ help: try: `for v in btree_set.iter() { .. }`
6282

6383
error: excessive use of `for_each`
64-
--> $DIR/excessive_for_each.rs:40:5
84+
--> $DIR/excessive_for_each.rs:61:5
6585
|
66-
LL | binary_heap.iter().for_each(|v| println!("{}", v));
67-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in binary_heap.iter() { .. }`
86+
LL | / binary_heap.iter().for_each(|v| {
87+
LL | | acc += v;
88+
LL | | });
89+
| |______^ help: try: `for v in binary_heap.iter() { .. }`
6890

6991
error: excessive use of `for_each`
70-
--> $DIR/excessive_for_each.rs:44:5
92+
--> $DIR/excessive_for_each.rs:67:5
7193
|
72-
LL | s.iter().for_each(|v| println!("{}", v));
73-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in s.iter() { .. }`
94+
LL | / s.iter().for_each(|v| {
95+
LL | | acc += v;
96+
LL | | });
97+
| |______^ help: try: `for v in s.iter() { .. }`
7498

7599
error: excessive use of `for_each`
76-
--> $DIR/excessive_for_each.rs:47:5
100+
--> $DIR/excessive_for_each.rs:72:5
77101
|
78-
LL | vec.as_slice().iter().for_each(|v| println!("{}", v));
79-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for v in vec.as_slice().iter() { .. }`
102+
LL | / vec.as_slice().iter().for_each(|v| {
103+
LL | | acc += v;
104+
LL | | });
105+
| |______^ help: try: `for v in vec.as_slice().iter() { .. }`
80106

81107
error: excessive use of `for_each`
82-
--> $DIR/excessive_for_each.rs:50:5
108+
--> $DIR/excessive_for_each.rs:77:5
83109
|
84110
LL | / vec.iter().for_each(|v| {
85111
LL | | if *v == 10 {
@@ -91,13 +117,13 @@ LL | | });
91117
| |______^ help: try: `for v in vec.iter() { .. }`
92118
|
93119
note: change `return` to `continue` in the loop body
94-
--> $DIR/excessive_for_each.rs:52:13
120+
--> $DIR/excessive_for_each.rs:79:13
95121
|
96122
LL | return;
97123
| ^^^^^^
98124

99125
error: excessive use of `for_each`
100-
--> $DIR/excessive_for_each.rs:59:5
126+
--> $DIR/excessive_for_each.rs:86:5
101127
|
102128
LL | / vec.iter().for_each(|v| {
103129
LL | | for i in 0..*v {
@@ -109,12 +135,12 @@ LL | | });
109135
| |______^ help: try: `'outer: for v in vec.iter() { .. }`
110136
|
111137
note: change `return` to `continue 'outer` in the loop body
112-
--> $DIR/excessive_for_each.rs:62:17
138+
--> $DIR/excessive_for_each.rs:89:17
113139
|
114140
LL | return;
115141
| ^^^^^^
116142
note: change `return` to `continue` in the loop body
117-
--> $DIR/excessive_for_each.rs:68:13
143+
--> $DIR/excessive_for_each.rs:95:13
118144
|
119145
LL | return;
120146
| ^^^^^^

0 commit comments

Comments
 (0)