@@ -128,12 +128,30 @@ fn par_slice<I: DynSend>(
128128 guard : & ParallelGuard ,
129129 for_each : impl Fn ( & mut I ) + DynSync + DynSend ,
130130) {
131+ match items {
132+ [ ] => return ,
133+ [ item] => {
134+ guard. run ( || for_each ( item) ) ;
135+ return ;
136+ }
137+ _ => ( ) ,
138+ }
139+
131140 let for_each = FromDyn :: from ( for_each) ;
132141 let mut items = for_each. derive ( items) ;
133142 rustc_thread_pool:: scope ( |s| {
134143 let proof = items. derive ( ( ) ) ;
135- let group_size = std:: cmp:: max ( items. len ( ) / 128 , 1 ) ;
136- for group in items. chunks_mut ( group_size) {
144+
145+ const MAX_GROUP_COUNT : usize = 128 ;
146+ let group_size = items. len ( ) . div_ceil ( MAX_GROUP_COUNT ) ;
147+ let mut groups = items. chunks_mut ( group_size) ;
148+
149+ let Some ( first_group) = groups. next ( ) else { return } ;
150+
151+ // Reverse the order of the later functions since Rayon executes them in reverse
152+ // order when using a single thread. This ensures the execution order matches
153+ // that of a single threaded rustc.
154+ for group in groups. rev ( ) {
137155 let group = proof. derive ( group) ;
138156 s. spawn ( |_| {
139157 let mut group = group;
@@ -142,6 +160,12 @@ fn par_slice<I: DynSend>(
142160 }
143161 } ) ;
144162 }
163+
164+ // Run the first function without spawning to
165+ // ensure it executes immediately on this thread.
166+ for i in first_group. iter_mut ( ) {
167+ guard. run ( || for_each ( i) ) ;
168+ }
145169 } ) ;
146170}
147171
0 commit comments