Skip to content

Commit 5bffce5

Browse files
committed
par_iter can now handle multiple iterators in one_chain
1 parent d62b205 commit 5bffce5

File tree

4 files changed

+96
-1
lines changed

4 files changed

+96
-1
lines changed

lints/par_iter/src/lib.rs

+13
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,26 @@ impl<'tcx> LateLintPass<'tcx> for ParIter {
7171
allowed_methods.extend(get_methods(cx));
7272

7373
let mut top_expr = *recv;
74+
let mut found_iter_method = false;
7475

7576
while let Some(parent_expr) = get_parent_expr(cx, top_expr) {
7677
match parent_expr.kind {
7778
hir::ExprKind::MethodCall(method_name, _, _, _) => {
79+
if ["into_iter", "iter", "iter_mut"]
80+
.contains(&method_name.ident.as_str())
81+
{
82+
if found_iter_method {
83+
// Exit early on the second iteration method
84+
break;
85+
}
86+
// Mark that we've found an iteration method
87+
found_iter_method = true;
88+
}
89+
7890
if !allowed_methods.contains(method_name.ident.as_str()) {
7991
return;
8092
}
93+
8194
top_expr = parent_expr;
8295
}
8396
hir::ExprKind::Closure(_) => {

lints/par_iter/ui/main.fixed

+34
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,37 @@ fn nested_pars() {
423423
.cloned()
424424
.collect();
425425
}
426+
427+
// 1st should parallelize, 2nd no
428+
fn multiple_iter_one_chain() {
429+
let people = vec![
430+
Person {
431+
name: "Alice".to_string(),
432+
age: 25,
433+
},
434+
Person {
435+
name: "Bob".to_string(),
436+
age: 35,
437+
},
438+
Person {
439+
name: "Carol".to_string(),
440+
age: 32,
441+
},
442+
];
443+
444+
let mut counter = 0;
445+
446+
let names_over_30: Vec<String> = people
447+
.par_iter()
448+
.filter(|p| p.age > 30)
449+
.map(|p| p.name.clone())
450+
.collect::<Vec<String>>()
451+
.into_iter()
452+
.map(|name| {
453+
counter += 1;
454+
format!("{}: {}", counter, name)
455+
})
456+
.collect();
457+
458+
println!("{:?}", names_over_30);
459+
}

lints/par_iter/ui/main.rs

+34
Original file line numberDiff line numberDiff line change
@@ -423,3 +423,37 @@ fn nested_pars() {
423423
.cloned()
424424
.collect();
425425
}
426+
427+
// 1st should parallelize, 2nd no
428+
fn multiple_iter_one_chain() {
429+
let people = vec![
430+
Person {
431+
name: "Alice".to_string(),
432+
age: 25,
433+
},
434+
Person {
435+
name: "Bob".to_string(),
436+
age: 35,
437+
},
438+
Person {
439+
name: "Carol".to_string(),
440+
age: 32,
441+
},
442+
];
443+
444+
let mut counter = 0;
445+
446+
let names_over_30: Vec<String> = people
447+
.iter()
448+
.filter(|p| p.age > 30)
449+
.map(|p| p.name.clone())
450+
.collect::<Vec<String>>()
451+
.into_iter()
452+
.map(|name| {
453+
counter += 1;
454+
format!("{}: {}", counter, name)
455+
})
456+
.collect();
457+
458+
println!("{:?}", names_over_30);
459+
}

lints/par_iter/ui/main.stderr

+15-1
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,19 @@ warning: found iterator that can be parallelized
8989
LL | .chain(used_filtered.iter())
9090
| ^^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `used_filtered.par_iter()`
9191

92-
warning: 11 warnings emitted
92+
warning: found iterator that can be parallelized
93+
--> $DIR/main.rs:446:38
94+
|
95+
LL | let names_over_30: Vec<String> = people
96+
| ______________________________________^
97+
LL | | .iter()
98+
| |_______________^
99+
|
100+
help: try using a parallel iterator
101+
|
102+
LL ~ let names_over_30: Vec<String> = people
103+
LL + .par_iter()
104+
|
105+
106+
warning: 12 warnings emitted
93107

0 commit comments

Comments
 (0)