Skip to content

Commit 8dd4768

Browse files
committed
deal with closure in chain methods
1 parent 53ab0e4 commit 8dd4768

File tree

9 files changed

+128
-95
lines changed

9 files changed

+128
-95
lines changed

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[package]
22
name = "mate"
3-
version = "0.1.0"
4-
authors = ["Cameron Low <cameron.low.2018@bristol.ac.uk>", "Luca Carlig <luca.carlig@huawei.com"]
3+
version = "0.1.1"
4+
authors = [
5+
"Cameron Low <cameron.low.2018@bristol.ac.uk>",
6+
"Luca Carlig <luca.carlig@huawei.com",
7+
]
58
description = "library of lints for automatic parallelization"
69
edition = "2021"
710
publish = false

lints/par_iter/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "par_iter"
3-
version = "0.1.0"
3+
version = "0.1.1"
44
authors = ["authors go here"]
55
description = "description goes here"
66
edition = "2021"

lints/par_iter/src/lib.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ impl<'tcx> LateLintPass<'tcx> for ParIter {
6363
if !par_iter_traits.is_empty() && is_type_valid(cx, ty) {
6464
// TODO: issue with into_par_iter() need to check directly with
6565
// parallel iterator
66-
// let mut implemented_methods: Vec<&AssocItems> = Vec::new();
6766

6867
let mut allowed_methods: FxHashSet<&str> =
6968
["into_iter", "iter", "iter_mut", "map_or"]
@@ -74,17 +73,24 @@ impl<'tcx> LateLintPass<'tcx> for ParIter {
7473
let mut top_expr = *recv;
7574

7675
while let Some(parent_expr) = get_parent_expr(cx, top_expr) {
77-
if let hir::ExprKind::MethodCall(method_name, _, _, _) = parent_expr.kind {
78-
if !allowed_methods.contains(method_name.ident.as_str()) {
79-
return;
76+
match parent_expr.kind {
77+
hir::ExprKind::MethodCall(method_name, _, _, _) => {
78+
if !allowed_methods.contains(method_name.ident.as_str()) {
79+
return;
80+
}
81+
top_expr = parent_expr;
82+
}
83+
hir::ExprKind::Closure(_) => {
84+
top_expr = parent_expr;
85+
}
86+
_ => {
87+
break;
8088
}
81-
top_expr = parent_expr;
82-
} else {
83-
break;
8489
}
8590
}
8691

8792
let ty: Ty<'_> = cx.typeck_results().expr_ty(top_expr);
93+
8894
// TODO: find a way to deal with iterators returns
8995
if check_trait_impl(cx, ty, sym::Iterator) {
9096
return;

lints/par_iter/ui/main.fixed

+36-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use core::ascii;
55
use futures::io::{self, AsyncWrite, IoSlice};
66
use futures::task::{Context, Poll};
77
use rayon::prelude::*;
8-
use std::collections::LinkedList;
8+
use std::collections::{HashMap, HashSet, LinkedList};
99
use std::ops::Range;
1010
use std::pin::Pin;
1111
use std::rc::Rc;
@@ -40,6 +40,23 @@ struct ApplicationState {
4040

4141
struct MyWriter;
4242

43+
#[derive(Hash, Eq, PartialEq, Clone)]
44+
struct Id(String);
45+
46+
struct Cmd {
47+
args: HashMap<Id, Arg>,
48+
}
49+
50+
impl Cmd {
51+
fn find(&self, key: &Id) -> Option<&Arg> {
52+
self.args.get(key)
53+
}
54+
}
55+
56+
struct Arg {
57+
requires: Vec<(String, Id)>,
58+
}
59+
4360
fn main() {}
4461

4562
// should parallelize
@@ -388,3 +405,21 @@ impl AsyncWrite for MyWriter {
388405
self.poll_write(cx, buf)
389406
}
390407
}
408+
409+
//should parallelize
410+
fn nested_pars() {
411+
let used_filtered: HashSet<Id> = HashSet::new();
412+
let conflicting_keys: HashSet<Id> = HashSet::new();
413+
let cmd = Cmd {
414+
args: HashMap::new(),
415+
};
416+
417+
let required: Vec<Id> = used_filtered
418+
.par_iter()
419+
.filter_map(|key| cmd.find(key))
420+
.flat_map(|arg| arg.requires.par_iter().map(|item| &item.1))
421+
.filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key))
422+
.chain(used_filtered.par_iter())
423+
.cloned()
424+
.collect();
425+
}

lints/par_iter/ui/main.rs

+36-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use core::ascii;
55
use futures::io::{self, AsyncWrite, IoSlice};
66
use futures::task::{Context, Poll};
77
use rayon::prelude::*;
8-
use std::collections::LinkedList;
8+
use std::collections::{HashMap, HashSet, LinkedList};
99
use std::ops::Range;
1010
use std::pin::Pin;
1111
use std::rc::Rc;
@@ -40,6 +40,23 @@ struct ApplicationState {
4040

4141
struct MyWriter;
4242

43+
#[derive(Hash, Eq, PartialEq, Clone)]
44+
struct Id(String);
45+
46+
struct Cmd {
47+
args: HashMap<Id, Arg>,
48+
}
49+
50+
impl Cmd {
51+
fn find(&self, key: &Id) -> Option<&Arg> {
52+
self.args.get(key)
53+
}
54+
}
55+
56+
struct Arg {
57+
requires: Vec<(String, Id)>,
58+
}
59+
4360
fn main() {}
4461

4562
// should parallelize
@@ -388,3 +405,21 @@ impl AsyncWrite for MyWriter {
388405
self.poll_write(cx, buf)
389406
}
390407
}
408+
409+
//should parallelize
410+
fn nested_pars() {
411+
let used_filtered: HashSet<Id> = HashSet::new();
412+
let conflicting_keys: HashSet<Id> = HashSet::new();
413+
let cmd = Cmd {
414+
args: HashMap::new(),
415+
};
416+
417+
let required: Vec<Id> = used_filtered
418+
.iter()
419+
.filter_map(|key| cmd.find(key))
420+
.flat_map(|arg| arg.requires.iter().map(|item| &item.1))
421+
.filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key))
422+
.chain(used_filtered.iter())
423+
.cloned()
424+
.collect();
425+
}

lints/par_iter/ui/main.stderr

+35-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
warning: found iterator that can be parallelized
2-
--> $DIR/main.rs:47:5
2+
--> $DIR/main.rs:64:5
33
|
44
LL | (0..100).into_iter().for_each(|x| println!("{:?}", x));
55
| ^^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `(0..100).into_par_iter()`
66
|
77
= note: `#[warn(par_iter)]` on by default
88

99
warning: found iterator that can be parallelized
10-
--> $DIR/main.rs:71:5
10+
--> $DIR/main.rs:88:5
1111
|
1212
LL | / (0..100)
1313
LL | | .into_iter()
@@ -20,37 +20,37 @@ LL + .into_par_iter()
2020
|
2121

2222
warning: found iterator that can be parallelized
23-
--> $DIR/main.rs:106:5
23+
--> $DIR/main.rs:123:5
2424
|
2525
LL | list.into_iter().for_each(|x| println!("{:?}", x));
2626
| ^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `list.into_par_iter()`
2727

2828
warning: found iterator that can be parallelized
29-
--> $DIR/main.rs:122:5
29+
--> $DIR/main.rs:139:5
3030
|
3131
LL | (0..10).into_iter().for_each(|x| {
3232
| ^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `(0..10).into_par_iter()`
3333

3434
warning: found iterator that can be parallelized
35-
--> $DIR/main.rs:205:5
35+
--> $DIR/main.rs:222:5
3636
|
3737
LL | data.iter()
3838
| ^^^^^^^^^^^ help: try using a parallel iterator: `data.par_iter()`
3939

4040
warning: found iterator that can be parallelized
41-
--> $DIR/main.rs:232:5
41+
--> $DIR/main.rs:249:5
4242
|
4343
LL | numbers.iter().enumerate().for_each(|t| {
4444
| ^^^^^^^^^^^^^^ help: try using a parallel iterator: `numbers.par_iter()`
4545

4646
warning: found iterator that can be parallelized
47-
--> $DIR/main.rs:328:30
47+
--> $DIR/main.rs:345:30
4848
|
4949
LL | let names: Vec<String> = people.iter().map(|p| p.name.clone()).collect();
5050
| ^^^^^^^^^^^^^ help: try using a parallel iterator: `people.par_iter()`
5151

5252
warning: found iterator that can be parallelized
53-
--> $DIR/main.rs:384:19
53+
--> $DIR/main.rs:401:19
5454
|
5555
LL | let buf = bufs
5656
| ___________________^
@@ -63,5 +63,31 @@ LL ~ let buf = bufs
6363
LL + .par_iter()
6464
|
6565

66-
warning: 8 warnings emitted
66+
warning: found iterator that can be parallelized
67+
--> $DIR/main.rs:417:29
68+
|
69+
LL | let required: Vec<Id> = used_filtered
70+
| _____________________________^
71+
LL | | .iter()
72+
| |_______________^
73+
|
74+
help: try using a parallel iterator
75+
|
76+
LL ~ let required: Vec<Id> = used_filtered
77+
LL + .par_iter()
78+
|
79+
80+
warning: found iterator that can be parallelized
81+
--> $DIR/main.rs:420:25
82+
|
83+
LL | .flat_map(|arg| arg.requires.iter().map(|item| &item.1))
84+
| ^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `arg.requires.par_iter()`
85+
86+
warning: found iterator that can be parallelized
87+
--> $DIR/main.rs:422:16
88+
|
89+
LL | .chain(used_filtered.iter())
90+
| ^^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `used_filtered.par_iter()`
91+
92+
warning: 11 warnings emitted
6793

lints/par_iter/ui/main2.fixed

-36
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
use core::ascii;
77
use rayon::prelude::*;
8-
use std::collections::LinkedList;
98
use std::ops::Range;
109
use std::rc::Rc;
1110

@@ -100,38 +99,3 @@ fn main() {}
10099
// println!("{:?}", doubled_numbers);
101100
// }
102101
//
103-
104-
// #[derive(Hash, Eq, PartialEq, Clone)]
105-
// struct Id(String);
106-
107-
// struct Cmd {
108-
// args: HashMap<Id, Arg>,
109-
// }
110-
111-
// impl Cmd {
112-
// fn find(&self, key: &Id) -> Option<&Arg> {
113-
// self.args.get(key)
114-
// }
115-
// }
116-
117-
// struct Arg {
118-
// requires: Vec<(String, Id)>,
119-
// }
120-
121-
// //should parallelize
122-
// fn nested_pars() {
123-
// let used_filtered: HashSet<Id> = HashSet::new();
124-
// let conflicting_keys: HashSet<Id> = HashSet::new();
125-
// let cmd = Cmd {
126-
// args: HashMap::new(),
127-
// };
128-
129-
// let required: Vec<Id> = used_filtered
130-
// .iter()
131-
// .filter_map(|key| cmd.find(key))
132-
// .flat_map(|arg| arg.requires.iter().map(|item| &item.1))
133-
// .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key))
134-
// .chain(used_filtered.iter())
135-
// .cloned()
136-
// .collect();
137-
// }

lints/par_iter/ui/main2.rs

-36
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
use core::ascii;
77
use rayon::prelude::*;
8-
use std::collections::LinkedList;
98
use std::ops::Range;
109
use std::rc::Rc;
1110

@@ -100,38 +99,3 @@ fn main() {}
10099
// println!("{:?}", doubled_numbers);
101100
// }
102101
//
103-
104-
// #[derive(Hash, Eq, PartialEq, Clone)]
105-
// struct Id(String);
106-
107-
// struct Cmd {
108-
// args: HashMap<Id, Arg>,
109-
// }
110-
111-
// impl Cmd {
112-
// fn find(&self, key: &Id) -> Option<&Arg> {
113-
// self.args.get(key)
114-
// }
115-
// }
116-
117-
// struct Arg {
118-
// requires: Vec<(String, Id)>,
119-
// }
120-
121-
// //should parallelize
122-
// fn nested_pars() {
123-
// let used_filtered: HashSet<Id> = HashSet::new();
124-
// let conflicting_keys: HashSet<Id> = HashSet::new();
125-
// let cmd = Cmd {
126-
// args: HashMap::new(),
127-
// };
128-
129-
// let required: Vec<Id> = used_filtered
130-
// .iter()
131-
// .filter_map(|key| cmd.find(key))
132-
// .flat_map(|arg| arg.requires.iter().map(|item| &item.1))
133-
// .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key))
134-
// .chain(used_filtered.iter())
135-
// .cloned()
136-
// .collect();
137-
// }

0 commit comments

Comments
 (0)