Skip to content

Commit

Permalink
par_iter able to handle biding inside main closure
Browse files Browse the repository at this point in the history
  • Loading branch information
lucarlig committed Mar 25, 2024
1 parent b4161b2 commit 4ad8eb2
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 40 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mate"
version = "0.1.3"
version = "0.1.4"
authors = [
"Cameron Low <[email protected]>",
"Luca Carlig <[email protected]",
Expand Down
2 changes: 1 addition & 1 deletion lints/par_iter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ utils = { workspace = true }
[dev-dependencies]
dylint_testing = "3.0.0"
rayon = "1.9.0"
futures = "*"
futures = "0.3.30"

[package.metadata.rust-analyzer]
rustc_private = true
Expand Down
12 changes: 8 additions & 4 deletions lints/par_iter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,18 +157,22 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'_> for Validator<'a, 'tcx> {

for arg in args {
if let hir::ExprKind::Closure(closure) = arg.kind {
let mut params = hir::HirIdSet::default();
let mut mut_params = hir::HirIdSet::default();
let body = self.cx.tcx.hir().body(closure.body);

if self.is_mut {
for param in body.params {
if let hir::PatKind::Binding(_, hir_id, _, _) = param.pat.kind {
for param in body.params {
if let hir::PatKind::Binding(_, hir_id, _, _) = param.pat.kind {
if self.is_mut {
mut_params.insert(hir_id);
} else {
params.insert(hir_id);
}
}
}

self.is_valid &= check_variables(self.cx, closure.def_id, body, &mut_params);
self.is_valid &=
check_variables(self.cx, closure.def_id, body, &mut_params, &params);
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions lints/par_iter/src/variable_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::constants::TRAIT_PATHS;

pub(crate) struct MutablyUsedVariablesCtxt<'tcx> {
mutably_used_vars: hir::HirIdSet,
locally_bind_vars: hir::HirIdSet,
all_vars: FxHashSet<Ty<'tcx>>,
prev_bind: Option<hir::HirId>,
/// In async functions, the inner AST is composed of multiple layers until we reach the code
Expand All @@ -34,14 +35,17 @@ pub(crate) fn check_variables<'tcx>(
body_owner: hir::def_id::LocalDefId,
body: &hir::Body<'tcx>,
mut_params: &hir::HirIdSet,
params: &hir::HirIdSet,
) -> bool {
let MutablyUsedVariablesCtxt {
mut mutably_used_vars,
all_vars,
mut locally_bind_vars,
..
} = {
let mut ctx = MutablyUsedVariablesCtxt {
mutably_used_vars: hir::HirIdSet::default(),
locally_bind_vars: hir::HirIdSet::default(),
all_vars: FxHashSet::default(),
prev_bind: None,
prev_move_to_closure: hir::HirIdSet::default(),
Expand Down Expand Up @@ -78,7 +82,9 @@ pub(crate) fn check_variables<'tcx>(
for ty in all_vars {
res &= is_type_valid(cx, ty);
}
locally_bind_vars.retain(|&item| !params.contains(&item));
mutably_used_vars.retain(|&item| !mut_params.contains(&item));
mutably_used_vars.retain(|&item| !locally_bind_vars.contains(&item));

res &= mutably_used_vars.is_empty();

Expand Down Expand Up @@ -315,11 +321,10 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
var_path: UpvarPath { hir_id: vid },
..
}),
base_ty,
..
} = &cmt.place
{
self.all_vars.insert(*base_ty);
self.locally_bind_vars.insert(*vid);
if self.is_in_unsafe_block(id) {
self.add_mutably_used_var(*vid);
}
Expand Down
14 changes: 14 additions & 0 deletions lints/par_iter/ui/main.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,17 @@ fn simple_iter_mut() {
numbers.par_iter_mut().for_each(|num| *num *= 2); // Double each number
println!("{:?}", numbers);
}

// should parallelize
fn mut_var_declared_in_closure() {
let numbers = vec![1, 2, 3, 4, 5];
let doubled_numbers: Vec<i32> = numbers
.into_par_iter()
.map(|num| {
let mut doubled = num * 2; // Mutable variable inside the closure
doubled += 1; // Modify the mutable variable
doubled // Return the modified value
})
.collect();
println!("{:?}", doubled_numbers);
}
14 changes: 14 additions & 0 deletions lints/par_iter/ui/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,3 +464,17 @@ fn simple_iter_mut() {
numbers.iter_mut().for_each(|num| *num *= 2); // Double each number
println!("{:?}", numbers);
}

// should parallelize
fn mut_var_declared_in_closure() {
let numbers = vec![1, 2, 3, 4, 5];
let doubled_numbers: Vec<i32> = numbers
.into_iter()
.map(|num| {
let mut doubled = num * 2; // Mutable variable inside the closure
doubled += 1; // Modify the mutable variable
doubled // Return the modified value
})
.collect();
println!("{:?}", doubled_numbers);
}
16 changes: 15 additions & 1 deletion lints/par_iter/ui/main.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,19 @@ warning: found iterator that can be parallelized
LL | numbers.iter_mut().for_each(|num| *num *= 2); // Double each number
| ^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `numbers.par_iter_mut()`

warning: 13 warnings emitted
warning: found iterator that can be parallelized
--> $DIR/main.rs:471:37
|
LL | let doubled_numbers: Vec<i32> = numbers
| _____________________________________^
LL | | .into_iter()
| |____________________^
|
help: try using a parallel iterator
|
LL ~ let doubled_numbers: Vec<i32> = numbers
LL + .into_par_iter()
|

warning: 14 warnings emitted

15 changes: 0 additions & 15 deletions lints/par_iter/ui/main2.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,3 @@ fn main() {}
// pub fn iter_returned_in_variable() {
// let _: Range<i32> = (0..100).into_iter();
// }

// // should parallelize
// fn mut_var_declared_in_closure() {
// let numbers = vec![1, 2, 3, 4, 5];
// let doubled_numbers: Vec<i32> = numbers
// .into_iter()
// .map(|num| {
// let mut doubled = num * 2; // Mutable variable inside the closure
// doubled += 1; // Modify the mutable variable
// doubled // Return the modified value
// })
// .collect();
// println!("{:?}", doubled_numbers);
// }
//
15 changes: 0 additions & 15 deletions lints/par_iter/ui/main2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,3 @@ fn main() {}
// pub fn iter_returned_in_variable() {
// let _: Range<i32> = (0..100).into_iter();
// }

// // should parallelize
// fn mut_var_declared_in_closure() {
// let numbers = vec![1, 2, 3, 4, 5];
// let doubled_numbers: Vec<i32> = numbers
// .into_iter()
// .map(|num| {
// let mut doubled = num * 2; // Mutable variable inside the closure
// doubled += 1; // Modify the mutable variable
// doubled // Return the modified value
// })
// .collect();
// println!("{:?}", doubled_numbers);
// }
//

0 comments on commit 4ad8eb2

Please sign in to comment.