@@ -305,6 +305,33 @@ pub fn compile(
305305 } )
306306 . collect ( ) ;
307307
308+ let mut compile_waves = AHashMap :: < String , usize > :: new ( ) ;
309+ let mut unresolved_waves = compile_universe. clone ( ) ;
310+ while !unresolved_waves. is_empty ( ) {
311+ let mut progressed = false ;
312+ for name in unresolved_waves. iter ( ) . cloned ( ) . collect :: < Vec < String > > ( ) {
313+ let module = build_state. get_module ( & name) . unwrap ( ) ;
314+ let deps = module
315+ . deps
316+ . iter ( )
317+ . filter ( |dep| compile_universe. contains ( * dep) )
318+ . collect :: < Vec < & String > > ( ) ;
319+ if deps. iter ( ) . all ( |dep| compile_waves. contains_key ( * dep) ) {
320+ let wave = deps
321+ . iter ( )
322+ . filter_map ( |dep| compile_waves. get ( * dep) )
323+ . max ( )
324+ . map_or ( 0 , |wave| wave + 1 ) ;
325+ compile_waves. insert ( name. clone ( ) , wave) ;
326+ unresolved_waves. remove ( & name) ;
327+ progressed = true ;
328+ }
329+ }
330+ if !progressed {
331+ break ;
332+ }
333+ }
334+
308335 let mut ready_heap: BinaryHeap < WorkUnit > = compile_universe
309336 . iter ( )
310337 . filter ( |name| pending_deps[ * name] == 0 )
@@ -413,6 +440,7 @@ pub fn compile(
413440 let mut compile_errors = String :: new ( ) ;
414441 let mut compile_warnings = String :: new ( ) ;
415442 let mut num_compiled_modules = 0 ;
443+ let mut first_error_wave: Option < usize > = None ;
416444
417445 // Persist propagated dirtiness back onto build_state. Modules that were
418446 // marked dirty (because a predecessor's cmi changed) but never scheduled
@@ -533,6 +561,11 @@ pub fn compile(
533561 ( compile_warning, compile_error, interface_warning, interface_error)
534562 } ;
535563
564+ if compile_error. is_some ( ) || interface_error. is_some ( ) {
565+ let wave = compile_waves. get ( & module_name) . copied ( ) . unwrap_or ( usize:: MAX ) ;
566+ first_error_wave = Some ( first_error_wave. map_or ( wave, |first_wave| first_wave. min ( wave) ) ) ;
567+ }
568+
536569 if let Some ( warning) = compile_warning {
537570 logs:: append ( package, & warning) ;
538571 compile_warnings. push_str ( & warning) ;
@@ -606,7 +639,25 @@ pub fn compile(
606639 }
607640 }
608641
609- Ok ( ( compile_errors, compile_warnings, num_compiled_modules) )
642+ let reported_num_compiled_modules = if let Some ( first_error_wave) = first_error_wave {
643+ dirty_set
644+ . iter ( )
645+ . filter ( |module_name| {
646+ compile_waves
647+ . get ( * module_name)
648+ . is_some_and ( |wave| * wave <= first_error_wave)
649+ } )
650+ . filter ( |module_name| {
651+ build_state
652+ . get_module ( module_name)
653+ . is_some_and ( |module| matches ! ( module. source_type, SourceType :: SourceFile ( _) ) )
654+ } )
655+ . count ( )
656+ } else {
657+ num_compiled_modules
658+ } ;
659+
660+ Ok ( ( compile_errors, compile_warnings, reported_num_compiled_modules) )
610661}
611662
612663static RUNTIME_PATH_MEMO : OnceLock < PathBuf > = OnceLock :: new ( ) ;
0 commit comments