Skip to content

Commit 4ad8eb2

Browse files
committed
par_iter able to handle biding inside main closure
1 parent b4161b2 commit 4ad8eb2

10 files changed

+61
-40
lines changed

Cargo.lock

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

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "mate"
3-
version = "0.1.3"
3+
version = "0.1.4"
44
authors = [
55
"Cameron Low <cameron.low.2018@bristol.ac.uk>",
66
"Luca Carlig <luca.carlig@huawei.com",

lints/par_iter/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ utils = { workspace = true }
1818
[dev-dependencies]
1919
dylint_testing = "3.0.0"
2020
rayon = "1.9.0"
21-
futures = "*"
21+
futures = "0.3.30"
2222

2323
[package.metadata.rust-analyzer]
2424
rustc_private = true

lints/par_iter/src/lib.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,22 @@ impl<'a, 'tcx> hir::intravisit::Visitor<'_> for Validator<'a, 'tcx> {
157157

158158
for arg in args {
159159
if let hir::ExprKind::Closure(closure) = arg.kind {
160+
let mut params = hir::HirIdSet::default();
160161
let mut mut_params = hir::HirIdSet::default();
161162
let body = self.cx.tcx.hir().body(closure.body);
162163

163-
if self.is_mut {
164-
for param in body.params {
165-
if let hir::PatKind::Binding(_, hir_id, _, _) = param.pat.kind {
164+
for param in body.params {
165+
if let hir::PatKind::Binding(_, hir_id, _, _) = param.pat.kind {
166+
if self.is_mut {
166167
mut_params.insert(hir_id);
168+
} else {
169+
params.insert(hir_id);
167170
}
168171
}
169172
}
170173

171-
self.is_valid &= check_variables(self.cx, closure.def_id, body, &mut_params);
174+
self.is_valid &=
175+
check_variables(self.cx, closure.def_id, body, &mut_params, &params);
172176
}
173177
}
174178
}

lints/par_iter/src/variable_check.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::constants::TRAIT_PATHS;
1717

1818
pub(crate) struct MutablyUsedVariablesCtxt<'tcx> {
1919
mutably_used_vars: hir::HirIdSet,
20+
locally_bind_vars: hir::HirIdSet,
2021
all_vars: FxHashSet<Ty<'tcx>>,
2122
prev_bind: Option<hir::HirId>,
2223
/// In async functions, the inner AST is composed of multiple layers until we reach the code
@@ -34,14 +35,17 @@ pub(crate) fn check_variables<'tcx>(
3435
body_owner: hir::def_id::LocalDefId,
3536
body: &hir::Body<'tcx>,
3637
mut_params: &hir::HirIdSet,
38+
params: &hir::HirIdSet,
3739
) -> bool {
3840
let MutablyUsedVariablesCtxt {
3941
mut mutably_used_vars,
4042
all_vars,
43+
mut locally_bind_vars,
4144
..
4245
} = {
4346
let mut ctx = MutablyUsedVariablesCtxt {
4447
mutably_used_vars: hir::HirIdSet::default(),
48+
locally_bind_vars: hir::HirIdSet::default(),
4549
all_vars: FxHashSet::default(),
4650
prev_bind: None,
4751
prev_move_to_closure: hir::HirIdSet::default(),
@@ -78,7 +82,9 @@ pub(crate) fn check_variables<'tcx>(
7882
for ty in all_vars {
7983
res &= is_type_valid(cx, ty);
8084
}
85+
locally_bind_vars.retain(|&item| !params.contains(&item));
8186
mutably_used_vars.retain(|&item| !mut_params.contains(&item));
87+
mutably_used_vars.retain(|&item| !locally_bind_vars.contains(&item));
8288

8389
res &= mutably_used_vars.is_empty();
8490

@@ -315,11 +321,10 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
315321
var_path: UpvarPath { hir_id: vid },
316322
..
317323
}),
318-
base_ty,
319324
..
320325
} = &cmt.place
321326
{
322-
self.all_vars.insert(*base_ty);
327+
self.locally_bind_vars.insert(*vid);
323328
if self.is_in_unsafe_block(id) {
324329
self.add_mutably_used_var(*vid);
325330
}

lints/par_iter/ui/main.fixed

+14
Original file line numberDiff line numberDiff line change
@@ -464,3 +464,17 @@ fn simple_iter_mut() {
464464
numbers.par_iter_mut().for_each(|num| *num *= 2); // Double each number
465465
println!("{:?}", numbers);
466466
}
467+
468+
// should parallelize
469+
fn mut_var_declared_in_closure() {
470+
let numbers = vec![1, 2, 3, 4, 5];
471+
let doubled_numbers: Vec<i32> = numbers
472+
.into_par_iter()
473+
.map(|num| {
474+
let mut doubled = num * 2; // Mutable variable inside the closure
475+
doubled += 1; // Modify the mutable variable
476+
doubled // Return the modified value
477+
})
478+
.collect();
479+
println!("{:?}", doubled_numbers);
480+
}

lints/par_iter/ui/main.rs

+14
Original file line numberDiff line numberDiff line change
@@ -464,3 +464,17 @@ fn simple_iter_mut() {
464464
numbers.iter_mut().for_each(|num| *num *= 2); // Double each number
465465
println!("{:?}", numbers);
466466
}
467+
468+
// should parallelize
469+
fn mut_var_declared_in_closure() {
470+
let numbers = vec![1, 2, 3, 4, 5];
471+
let doubled_numbers: Vec<i32> = numbers
472+
.into_iter()
473+
.map(|num| {
474+
let mut doubled = num * 2; // Mutable variable inside the closure
475+
doubled += 1; // Modify the mutable variable
476+
doubled // Return the modified value
477+
})
478+
.collect();
479+
println!("{:?}", doubled_numbers);
480+
}

lints/par_iter/ui/main.stderr

+15-1
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,19 @@ warning: found iterator that can be parallelized
109109
LL | numbers.iter_mut().for_each(|num| *num *= 2); // Double each number
110110
| ^^^^^^^^^^^^^^^^^^ help: try using a parallel iterator: `numbers.par_iter_mut()`
111111

112-
warning: 13 warnings emitted
112+
warning: found iterator that can be parallelized
113+
--> $DIR/main.rs:471:37
114+
|
115+
LL | let doubled_numbers: Vec<i32> = numbers
116+
| _____________________________________^
117+
LL | | .into_iter()
118+
| |____________________^
119+
|
120+
help: try using a parallel iterator
121+
|
122+
LL ~ let doubled_numbers: Vec<i32> = numbers
123+
LL + .into_par_iter()
124+
|
125+
126+
warning: 14 warnings emitted
113127

lints/par_iter/ui/main2.fixed

-15
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,3 @@ fn main() {}
4343
// pub fn iter_returned_in_variable() {
4444
// let _: Range<i32> = (0..100).into_iter();
4545
// }
46-
47-
// // should parallelize
48-
// fn mut_var_declared_in_closure() {
49-
// let numbers = vec![1, 2, 3, 4, 5];
50-
// let doubled_numbers: Vec<i32> = numbers
51-
// .into_iter()
52-
// .map(|num| {
53-
// let mut doubled = num * 2; // Mutable variable inside the closure
54-
// doubled += 1; // Modify the mutable variable
55-
// doubled // Return the modified value
56-
// })
57-
// .collect();
58-
// println!("{:?}", doubled_numbers);
59-
// }
60-
//

lints/par_iter/ui/main2.rs

-15
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,3 @@ fn main() {}
4343
// pub fn iter_returned_in_variable() {
4444
// let _: Range<i32> = (0..100).into_iter();
4545
// }
46-
47-
// // should parallelize
48-
// fn mut_var_declared_in_closure() {
49-
// let numbers = vec![1, 2, 3, 4, 5];
50-
// let doubled_numbers: Vec<i32> = numbers
51-
// .into_iter()
52-
// .map(|num| {
53-
// let mut doubled = num * 2; // Mutable variable inside the closure
54-
// doubled += 1; // Modify the mutable variable
55-
// doubled // Return the modified value
56-
// })
57-
// .collect();
58-
// println!("{:?}", doubled_numbers);
59-
// }
60-
//

0 commit comments

Comments
 (0)