@@ -5,9 +5,9 @@ use std::sync::Arc;
5
5
use rustc_ast:: { LitKind , MetaItemKind , token} ;
6
6
use rustc_codegen_ssa:: traits:: CodegenBackend ;
7
7
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
8
+ use rustc_data_structures:: jobserver;
8
9
use rustc_data_structures:: stable_hasher:: StableHasher ;
9
10
use rustc_data_structures:: sync:: Lrc ;
10
- use rustc_data_structures:: { defer, jobserver} ;
11
11
use rustc_errors:: registry:: Registry ;
12
12
use rustc_errors:: { DiagCtxtHandle , ErrorGuaranteed } ;
13
13
use rustc_lint:: LintStore ;
@@ -492,21 +492,13 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
492
492
493
493
// There are two paths out of `f`.
494
494
// - Normal exit.
495
- // - Panic, e.g. triggered by `abort_if_errors`.
495
+ // - Panic, e.g. triggered by `abort_if_errors` or a fatal error .
496
496
//
497
497
// We must run `finish_diagnostics` in both cases.
498
498
let res = {
499
- // If `f` panics, `finish_diagnostics` will run during
500
- // unwinding because of the `defer`.
501
- let sess_abort_guard = defer ( || {
502
- compiler. sess . finish_diagnostics ( ) ;
503
- } ) ;
499
+ let res = std:: panic:: catch_unwind ( std:: panic:: AssertUnwindSafe ( || f ( & compiler) ) ) ;
504
500
505
- let res = f ( & compiler) ;
506
-
507
- // If `f` doesn't panic, `finish_diagnostics` will run
508
- // normally when `sess_abort_guard` is dropped.
509
- drop ( sess_abort_guard) ;
501
+ compiler. sess . finish_diagnostics ( ) ;
510
502
511
503
// If error diagnostics have been emitted, we can't return an
512
504
// error directly, because the return type of this function
@@ -515,9 +507,20 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
515
507
// mistakenly think that no errors occurred and return a zero
516
508
// exit code. So we abort (panic) instead, similar to if `f`
517
509
// had panicked.
518
- compiler. sess . dcx ( ) . abort_if_errors ( ) ;
510
+ if res. is_ok ( ) {
511
+ compiler. sess . dcx ( ) . abort_if_errors ( ) ;
512
+ }
519
513
520
- res
514
+ // Also make sure to flush delayed bugs as if we panicked, the
515
+ // bugs would be flushed by the Drop impl of DiagCtxt while
516
+ // unwinding, which would result in an abort with
517
+ // "panic in a destructor during cleanup".
518
+ compiler. sess . dcx ( ) . flush_delayed ( ) ;
519
+
520
+ match res {
521
+ Ok ( res) => res,
522
+ Err ( err) => std:: panic:: resume_unwind ( err) ,
523
+ }
521
524
} ;
522
525
523
526
let prof = compiler. sess . prof . clone ( ) ;
0 commit comments