From 50c564e6790e0b8ec271e2354a3f74a60a7dfc58 Mon Sep 17 00:00:00 2001 From: Daria Sukhonina Date: Thu, 12 Mar 2026 13:25:40 +0300 Subject: [PATCH] Make par_slice consistent with single-threaded execution --- .../src/sync/parallel.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync/parallel.rs b/compiler/rustc_data_structures/src/sync/parallel.rs index cbf88efea18d1..b112ecc2fbad1 100644 --- a/compiler/rustc_data_structures/src/sync/parallel.rs +++ b/compiler/rustc_data_structures/src/sync/parallel.rs @@ -129,12 +129,28 @@ fn par_slice( for_each: impl Fn(&mut I) + DynSync + DynSend, proof: FromDyn<()>, ) { + match items { + [] => return, + [item] => { + guard.run(|| for_each(item)); + return; + } + _ => (), + } + let for_each = proof.derive(for_each); let mut items = for_each.derive(items); rustc_thread_pool::scope(|s| { let proof = items.derive(()); - let group_size = std::cmp::max(items.len() / 128, 1); - for group in items.chunks_mut(group_size) { + + const MAX_GROUP_COUNT: usize = 128; + let group_size = items.len().div_ceil(MAX_GROUP_COUNT); + let groups = items.chunks_mut(group_size); + + // Reverse the order of the later functions since Rayon executes them in reverse + // order when using a single thread. This ensures the execution order matches + // that of a single threaded rustc. + for group in groups.rev() { let group = proof.derive(group); s.spawn(|_| { let mut group = group;