@@ -69,7 +69,7 @@ use super::job::{
69
69
} ;
70
70
use super :: timings:: Timings ;
71
71
use super :: { BuildContext , BuildPlan , CompileMode , Context , Unit } ;
72
- use crate :: core:: { PackageId , TargetKind } ;
72
+ use crate :: core:: { PackageId , Shell , TargetKind } ;
73
73
use crate :: util:: diagnostic_server:: { self , DiagnosticPrinter } ;
74
74
use crate :: util:: machine_message:: { self , Message as _} ;
75
75
use crate :: util:: { self , internal, profile} ;
@@ -412,7 +412,6 @@ impl<'cfg> DrainState<'cfg> {
412
412
cx : & mut Context < ' _ , ' _ > ,
413
413
jobserver_helper : & HelperThread ,
414
414
scope : & Scope < ' _ > ,
415
- has_errored : bool ,
416
415
) -> CargoResult < ( ) > {
417
416
// Dequeue as much work as we can, learning about everything
418
417
// possible that can run. Note that this is also the point where we
@@ -425,11 +424,6 @@ impl<'cfg> DrainState<'cfg> {
425
424
}
426
425
}
427
426
428
- // Do not actually spawn the new work if we've errored out
429
- if has_errored {
430
- return Ok ( ( ) ) ;
431
- }
432
-
433
427
// Now that we've learned of all possible work that we can execute
434
428
// try to spawn it so long as we've got a jobserver token which says
435
429
// we're able to perform some parallel work.
@@ -487,7 +481,7 @@ impl<'cfg> DrainState<'cfg> {
487
481
jobserver_helper : & HelperThread ,
488
482
plan : & mut BuildPlan ,
489
483
event : Message ,
490
- ) -> CargoResult < Option < anyhow :: Error > > {
484
+ ) -> CargoResult < ( ) > {
491
485
match event {
492
486
Message :: Run ( id, cmd) => {
493
487
cx. bcx
@@ -545,17 +539,7 @@ impl<'cfg> DrainState<'cfg> {
545
539
Err ( e) => {
546
540
let msg = "The following warnings were emitted during compilation:" ;
547
541
self . emit_warnings ( Some ( msg) , & unit, cx) ?;
548
-
549
- if !self . active . is_empty ( ) {
550
- crate :: display_error ( & e, & mut * cx. bcx . config . shell ( ) ) ;
551
- cx. bcx . config . shell ( ) . warn (
552
- "build failed, waiting for other \
553
- jobs to finish...",
554
- ) ?;
555
- return Ok ( Some ( anyhow:: format_err!( "build failed" ) ) ) ;
556
- } else {
557
- return Ok ( Some ( e) ) ;
558
- }
542
+ return Err ( e) ;
559
543
}
560
544
}
561
545
}
@@ -590,7 +574,7 @@ impl<'cfg> DrainState<'cfg> {
590
574
}
591
575
}
592
576
593
- Ok ( None )
577
+ Ok ( ( ) )
594
578
}
595
579
596
580
// This will also tick the progress bar as appropriate
@@ -651,25 +635,33 @@ impl<'cfg> DrainState<'cfg> {
651
635
// successful and otherwise wait for pending work to finish if it failed
652
636
// and then immediately return.
653
637
let mut error = None ;
638
+ // CAUTION! From here on out, do not use `?`. Every error must be handled
639
+ // in such a way that the loop is still allowed to drain event messages.
654
640
loop {
655
- self . spawn_work_if_possible ( cx, jobserver_helper, scope, error. is_some ( ) ) ?;
641
+ if error. is_none ( ) {
642
+ if let Err ( e) = self . spawn_work_if_possible ( cx, jobserver_helper, scope) {
643
+ self . handle_error ( & mut cx. bcx . config . shell ( ) , & mut error, e) ;
644
+ }
645
+ }
656
646
657
647
// If after all that we're not actually running anything then we're
658
648
// done!
659
649
if self . active . is_empty ( ) {
660
650
break ;
661
651
}
662
652
663
- self . grant_rustc_token_requests ( ) ?;
653
+ if let Err ( e) = self . grant_rustc_token_requests ( ) {
654
+ self . handle_error ( & mut cx. bcx . config . shell ( ) , & mut error, e) ;
655
+ }
664
656
665
657
// And finally, before we block waiting for the next event, drop any
666
658
// excess tokens we may have accidentally acquired. Due to how our
667
659
// jobserver interface is architected we may acquire a token that we
668
660
// don't actually use, and if this happens just relinquish it back
669
661
// to the jobserver itself.
670
662
for event in self . wait_for_events ( ) {
671
- if let Some ( err ) = self . handle_event ( cx, jobserver_helper, plan, event) ? {
672
- error = Some ( err ) ;
663
+ if let Err ( event_err ) = self . handle_event ( cx, jobserver_helper, plan, event) {
664
+ self . handle_error ( & mut cx . bcx . config . shell ( ) , & mut error , event_err ) ;
673
665
}
674
666
}
675
667
}
@@ -694,13 +686,25 @@ impl<'cfg> DrainState<'cfg> {
694
686
}
695
687
696
688
let time_elapsed = util:: elapsed ( cx. bcx . config . creation_time ( ) . elapsed ( ) ) ;
697
- self . timings . finished ( cx. bcx , & error) ?;
689
+ if let Err ( e) = self . timings . finished ( cx. bcx , & error) {
690
+ if error. is_some ( ) {
691
+ crate :: display_error ( & e, & mut cx. bcx . config . shell ( ) ) ;
692
+ } else {
693
+ return Err ( e) ;
694
+ }
695
+ }
698
696
if cx. bcx . build_config . emit_json ( ) {
699
697
let msg = machine_message:: BuildFinished {
700
698
success : error. is_none ( ) ,
701
699
}
702
700
. to_json_string ( ) ;
703
- writeln ! ( cx. bcx. config. shell( ) . out( ) , "{}" , msg) ?;
701
+ if let Err ( e) = writeln ! ( cx. bcx. config. shell( ) . out( ) , "{}" , msg) {
702
+ if error. is_some ( ) {
703
+ crate :: display_error ( & e. into ( ) , & mut cx. bcx . config . shell ( ) ) ;
704
+ } else {
705
+ return Err ( e. into ( ) ) ;
706
+ }
707
+ }
704
708
}
705
709
706
710
if let Some ( e) = error {
@@ -711,7 +715,8 @@ impl<'cfg> DrainState<'cfg> {
711
715
profile_name, opt_type, time_elapsed
712
716
) ;
713
717
if !cx. bcx . build_config . build_plan {
714
- cx. bcx . config . shell ( ) . status ( "Finished" , message) ?;
718
+ // It doesn't really matter if this fails.
719
+ drop ( cx. bcx . config . shell ( ) . status ( "Finished" , message) ) ;
715
720
}
716
721
Ok ( ( ) )
717
722
} else {
@@ -720,6 +725,26 @@ impl<'cfg> DrainState<'cfg> {
720
725
}
721
726
}
722
727
728
+ fn handle_error (
729
+ & self ,
730
+ shell : & mut Shell ,
731
+ err_state : & mut Option < anyhow:: Error > ,
732
+ new_err : anyhow:: Error ,
733
+ ) {
734
+ if err_state. is_some ( ) {
735
+ // Already encountered one error.
736
+ log:: warn!( "{:?}" , new_err) ;
737
+ } else {
738
+ if !self . active . is_empty ( ) {
739
+ crate :: display_error ( & new_err, shell) ;
740
+ drop ( shell. warn ( "build failed, waiting for other jobs to finish..." ) ) ;
741
+ * err_state = Some ( anyhow:: format_err!( "build failed" ) ) ;
742
+ } else {
743
+ * err_state = Some ( new_err) ;
744
+ }
745
+ }
746
+ }
747
+
723
748
// This also records CPU usage and marks concurrency; we roughly want to do
724
749
// this as often as we spin on the events receiver (at least every 500ms or
725
750
// so).
0 commit comments