From 8dd476824d524f4dc3978d1f7d4e4449239875ee Mon Sep 17 00:00:00 2001 From: lucarlig Date: Mon, 25 Mar 2024 09:24:19 +0000 Subject: [PATCH] deal with closure in chain methods --- Cargo.lock | 4 ++-- Cargo.toml | 7 ++++-- lints/par_iter/Cargo.toml | 2 +- lints/par_iter/src/lib.rs | 20 ++++++++++------ lints/par_iter/ui/main.fixed | 37 ++++++++++++++++++++++++++++- lints/par_iter/ui/main.rs | 37 ++++++++++++++++++++++++++++- lints/par_iter/ui/main.stderr | 44 ++++++++++++++++++++++++++++------- lints/par_iter/ui/main2.fixed | 36 ---------------------------- lints/par_iter/ui/main2.rs | 36 ---------------------------- 9 files changed, 128 insertions(+), 95 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 32316fb..a1785e1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -750,7 +750,7 @@ dependencies = [ [[package]] name = "mate" -version = "0.1.0" +version = "0.1.1" dependencies = [ "dylint_linting", "dylint_testing", @@ -831,7 +831,7 @@ dependencies = [ [[package]] name = "par_iter" -version = "0.1.0" +version = "0.1.1" dependencies = [ "clippy_utils", "dylint_linting", diff --git a/Cargo.toml b/Cargo.toml index 17955ef..2ca2e2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,10 @@ [package] name = "mate" -version = "0.1.0" -authors = ["Cameron Low ", "Luca Carlig ", + "Luca Carlig LateLintPass<'tcx> for ParIter { if !par_iter_traits.is_empty() && is_type_valid(cx, ty) { // TODO: issue with into_par_iter() need to check directly with // parallel iterator - // let mut implemented_methods: Vec<&AssocItems> = Vec::new(); let mut allowed_methods: FxHashSet<&str> = ["into_iter", "iter", "iter_mut", "map_or"] @@ -74,17 +73,24 @@ impl<'tcx> LateLintPass<'tcx> for ParIter { let mut top_expr = *recv; while let Some(parent_expr) = get_parent_expr(cx, top_expr) { - if let hir::ExprKind::MethodCall(method_name, _, _, _) = parent_expr.kind { - if !allowed_methods.contains(method_name.ident.as_str()) { - return; + match parent_expr.kind { + hir::ExprKind::MethodCall(method_name, _, _, _) => { + if !allowed_methods.contains(method_name.ident.as_str()) { + return; + } + top_expr = parent_expr; + } + hir::ExprKind::Closure(_) => { + top_expr = parent_expr; + } + _ => { + break; } - top_expr = parent_expr; - } else { - break; } } let ty: Ty<'_> = cx.typeck_results().expr_ty(top_expr); + // TODO: find a way to deal with iterators returns if check_trait_impl(cx, ty, sym::Iterator) { return; diff --git a/lints/par_iter/ui/main.fixed b/lints/par_iter/ui/main.fixed index 9ba881b..3e7c05b 100644 --- a/lints/par_iter/ui/main.fixed +++ b/lints/par_iter/ui/main.fixed @@ -5,7 +5,7 @@ use core::ascii; use futures::io::{self, AsyncWrite, IoSlice}; use futures::task::{Context, Poll}; use rayon::prelude::*; -use std::collections::LinkedList; +use std::collections::{HashMap, HashSet, LinkedList}; use std::ops::Range; use std::pin::Pin; use std::rc::Rc; @@ -40,6 +40,23 @@ struct ApplicationState { struct MyWriter; +#[derive(Hash, Eq, PartialEq, Clone)] +struct Id(String); + +struct Cmd { + args: HashMap, +} + +impl Cmd { + fn find(&self, key: &Id) -> Option<&Arg> { + self.args.get(key) + } +} + +struct Arg { + requires: Vec<(String, Id)>, +} + fn main() {} // should parallelize @@ -388,3 +405,21 @@ impl AsyncWrite for MyWriter { self.poll_write(cx, buf) } } + +//should parallelize +fn nested_pars() { + let used_filtered: HashSet = HashSet::new(); + let conflicting_keys: HashSet = HashSet::new(); + let cmd = Cmd { + args: HashMap::new(), + }; + + let required: Vec = used_filtered + .par_iter() + .filter_map(|key| cmd.find(key)) + .flat_map(|arg| arg.requires.par_iter().map(|item| &item.1)) + .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key)) + .chain(used_filtered.par_iter()) + .cloned() + .collect(); +} diff --git a/lints/par_iter/ui/main.rs b/lints/par_iter/ui/main.rs index 8e906cf..a8c8ff4 100644 --- a/lints/par_iter/ui/main.rs +++ b/lints/par_iter/ui/main.rs @@ -5,7 +5,7 @@ use core::ascii; use futures::io::{self, AsyncWrite, IoSlice}; use futures::task::{Context, Poll}; use rayon::prelude::*; -use std::collections::LinkedList; +use std::collections::{HashMap, HashSet, LinkedList}; use std::ops::Range; use std::pin::Pin; use std::rc::Rc; @@ -40,6 +40,23 @@ struct ApplicationState { struct MyWriter; +#[derive(Hash, Eq, PartialEq, Clone)] +struct Id(String); + +struct Cmd { + args: HashMap, +} + +impl Cmd { + fn find(&self, key: &Id) -> Option<&Arg> { + self.args.get(key) + } +} + +struct Arg { + requires: Vec<(String, Id)>, +} + fn main() {} // should parallelize @@ -388,3 +405,21 @@ impl AsyncWrite for MyWriter { self.poll_write(cx, buf) } } + +//should parallelize +fn nested_pars() { + let used_filtered: HashSet = HashSet::new(); + let conflicting_keys: HashSet = HashSet::new(); + let cmd = Cmd { + args: HashMap::new(), + }; + + let required: Vec = used_filtered + .iter() + .filter_map(|key| cmd.find(key)) + .flat_map(|arg| arg.requires.iter().map(|item| &item.1)) + .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key)) + .chain(used_filtered.iter()) + .cloned() + .collect(); +} diff --git a/lints/par_iter/ui/main.stderr b/lints/par_iter/ui/main.stderr index 7bacf3b..e8ab282 100644 --- a/lints/par_iter/ui/main.stderr +++ b/lints/par_iter/ui/main.stderr @@ -1,5 +1,5 @@ warning: found iterator that can be parallelized - --> $DIR/main.rs:47:5 + --> $DIR/main.rs:64:5 | LL | (0..100).into_iter().for_each(|x| println!("{:?}", x)); | ^^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `(0..100).into_par_iter()` @@ -7,7 +7,7 @@ LL | (0..100).into_iter().for_each(|x| println!("{:?}", x)); = note: `#[warn(par_iter)]` on by default warning: found iterator that can be parallelized - --> $DIR/main.rs:71:5 + --> $DIR/main.rs:88:5 | LL | / (0..100) LL | | .into_iter() @@ -20,37 +20,37 @@ LL + .into_par_iter() | warning: found iterator that can be parallelized - --> $DIR/main.rs:106:5 + --> $DIR/main.rs:123:5 | LL | list.into_iter().for_each(|x| println!("{:?}", x)); | ^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `list.into_par_iter()` warning: found iterator that can be parallelized - --> $DIR/main.rs:122:5 + --> $DIR/main.rs:139:5 | LL | (0..10).into_iter().for_each(|x| { | ^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `(0..10).into_par_iter()` warning: found iterator that can be parallelized - --> $DIR/main.rs:205:5 + --> $DIR/main.rs:222:5 | LL | data.iter() | ^^^^^^^^^^^ help: try using a parallel iterator: `data.par_iter()` warning: found iterator that can be parallelized - --> $DIR/main.rs:232:5 + --> $DIR/main.rs:249:5 | LL | numbers.iter().enumerate().for_each(|t| { | ^^^^^^^^^^^^^^ help: try using a parallel iterator: `numbers.par_iter()` warning: found iterator that can be parallelized - --> $DIR/main.rs:328:30 + --> $DIR/main.rs:345:30 | LL | let names: Vec = people.iter().map(|p| p.name.clone()).collect(); | ^^^^^^^^^^^^^ help: try using a parallel iterator: `people.par_iter()` warning: found iterator that can be parallelized - --> $DIR/main.rs:384:19 + --> $DIR/main.rs:401:19 | LL | let buf = bufs | ___________________^ @@ -63,5 +63,31 @@ LL ~ let buf = bufs LL + .par_iter() | -warning: 8 warnings emitted +warning: found iterator that can be parallelized + --> $DIR/main.rs:417:29 + | +LL | let required: Vec = used_filtered + | _____________________________^ +LL | | .iter() + | |_______________^ + | +help: try using a parallel iterator + | +LL ~ let required: Vec = used_filtered +LL + .par_iter() + | + +warning: found iterator that can be parallelized + --> $DIR/main.rs:420:25 + | +LL | .flat_map(|arg| arg.requires.iter().map(|item| &item.1)) + | ^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `arg.requires.par_iter()` + +warning: found iterator that can be parallelized + --> $DIR/main.rs:422:16 + | +LL | .chain(used_filtered.iter()) + | ^^^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `used_filtered.par_iter()` + +warning: 11 warnings emitted diff --git a/lints/par_iter/ui/main2.fixed b/lints/par_iter/ui/main2.fixed index 8c83ad4..f3ea350 100644 --- a/lints/par_iter/ui/main2.fixed +++ b/lints/par_iter/ui/main2.fixed @@ -5,7 +5,6 @@ use core::ascii; use rayon::prelude::*; -use std::collections::LinkedList; use std::ops::Range; use std::rc::Rc; @@ -100,38 +99,3 @@ fn main() {} // println!("{:?}", doubled_numbers); // } // - -// #[derive(Hash, Eq, PartialEq, Clone)] -// struct Id(String); - -// struct Cmd { -// args: HashMap, -// } - -// impl Cmd { -// fn find(&self, key: &Id) -> Option<&Arg> { -// self.args.get(key) -// } -// } - -// struct Arg { -// requires: Vec<(String, Id)>, -// } - -// //should parallelize -// fn nested_pars() { -// let used_filtered: HashSet = HashSet::new(); -// let conflicting_keys: HashSet = HashSet::new(); -// let cmd = Cmd { -// args: HashMap::new(), -// }; - -// let required: Vec = used_filtered -// .iter() -// .filter_map(|key| cmd.find(key)) -// .flat_map(|arg| arg.requires.iter().map(|item| &item.1)) -// .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key)) -// .chain(used_filtered.iter()) -// .cloned() -// .collect(); -// } diff --git a/lints/par_iter/ui/main2.rs b/lints/par_iter/ui/main2.rs index 8c83ad4..f3ea350 100644 --- a/lints/par_iter/ui/main2.rs +++ b/lints/par_iter/ui/main2.rs @@ -5,7 +5,6 @@ use core::ascii; use rayon::prelude::*; -use std::collections::LinkedList; use std::ops::Range; use std::rc::Rc; @@ -100,38 +99,3 @@ fn main() {} // println!("{:?}", doubled_numbers); // } // - -// #[derive(Hash, Eq, PartialEq, Clone)] -// struct Id(String); - -// struct Cmd { -// args: HashMap, -// } - -// impl Cmd { -// fn find(&self, key: &Id) -> Option<&Arg> { -// self.args.get(key) -// } -// } - -// struct Arg { -// requires: Vec<(String, Id)>, -// } - -// //should parallelize -// fn nested_pars() { -// let used_filtered: HashSet = HashSet::new(); -// let conflicting_keys: HashSet = HashSet::new(); -// let cmd = Cmd { -// args: HashMap::new(), -// }; - -// let required: Vec = used_filtered -// .iter() -// .filter_map(|key| cmd.find(key)) -// .flat_map(|arg| arg.requires.iter().map(|item| &item.1)) -// .filter(|key| !used_filtered.contains(key) && !conflicting_keys.contains(key)) -// .chain(used_filtered.iter()) -// .cloned() -// .collect(); -// }