@@ -274,7 +274,7 @@ pub struct Handler {
274
274
err_count : AtomicUsize ,
275
275
emitter : Lock < Box < dyn Emitter + sync:: Send > > ,
276
276
continue_after_error : LockCell < bool > ,
277
- delayed_span_bug : Lock < Option < Diagnostic > > ,
277
+ delayed_span_bugs : Lock < Vec < Diagnostic > > ,
278
278
279
279
// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
280
280
// emitting the same diagnostic with extended help (`--teach`) twice, which
@@ -299,9 +299,25 @@ thread_local!(pub static TRACK_DIAGNOSTICS: Cell<fn(&Diagnostic)> =
299
299
pub struct HandlerFlags {
300
300
pub can_emit_warnings : bool ,
301
301
pub treat_err_as_bug : bool ,
302
+ pub report_delayed_bugs : bool ,
302
303
pub external_macro_backtrace : bool ,
303
304
}
304
305
306
+ impl Drop for Handler {
307
+ fn drop ( & mut self ) {
308
+ if self . err_count ( ) == 0 {
309
+ let mut bugs = self . delayed_span_bugs . borrow_mut ( ) ;
310
+ let has_bugs = !bugs. is_empty ( ) ;
311
+ for bug in bugs. drain ( ..) {
312
+ DiagnosticBuilder :: new_diagnostic ( self , bug) . emit ( ) ;
313
+ }
314
+ if has_bugs {
315
+ panic ! ( "no errors encountered even though `delay_span_bug` issued" ) ;
316
+ }
317
+ }
318
+ }
319
+ }
320
+
305
321
impl Handler {
306
322
pub fn with_tty_emitter ( color_config : ColorConfig ,
307
323
can_emit_warnings : bool ,
@@ -346,7 +362,7 @@ impl Handler {
346
362
err_count : AtomicUsize :: new ( 0 ) ,
347
363
emitter : Lock :: new ( e) ,
348
364
continue_after_error : LockCell :: new ( true ) ,
349
- delayed_span_bug : Lock :: new ( None ) ,
365
+ delayed_span_bugs : Lock :: new ( Vec :: new ( ) ) ,
350
366
taught_diagnostics : Lock :: new ( FxHashSet ( ) ) ,
351
367
emitted_diagnostic_codes : Lock :: new ( FxHashSet ( ) ) ,
352
368
emitted_diagnostics : Lock :: new ( FxHashSet ( ) ) ,
@@ -503,11 +519,18 @@ impl Handler {
503
519
}
504
520
pub fn delay_span_bug < S : Into < MultiSpan > > ( & self , sp : S , msg : & str ) {
505
521
if self . flags . treat_err_as_bug {
522
+ // FIXME: don't abort here if report_delayed_bugs is off
506
523
self . span_bug ( sp, msg) ;
507
524
}
508
525
let mut diagnostic = Diagnostic :: new ( Level :: Bug , msg) ;
509
526
diagnostic. set_span ( sp. into ( ) ) ;
510
- * self . delayed_span_bug . borrow_mut ( ) = Some ( diagnostic) ;
527
+ self . delay_as_bug ( diagnostic) ;
528
+ }
529
+ fn delay_as_bug ( & self , diagnostic : Diagnostic ) {
530
+ if self . flags . report_delayed_bugs {
531
+ DiagnosticBuilder :: new_diagnostic ( self , diagnostic. clone ( ) ) . emit ( ) ;
532
+ }
533
+ self . delayed_span_bugs . borrow_mut ( ) . push ( diagnostic) ;
511
534
}
512
535
pub fn span_bug_no_panic < S : Into < MultiSpan > > ( & self , sp : S , msg : & str ) {
513
536
self . emit ( & sp. into ( ) , msg, Bug ) ;
@@ -615,9 +638,6 @@ impl Handler {
615
638
616
639
pub fn abort_if_errors ( & self ) {
617
640
if self . err_count ( ) == 0 {
618
- if let Some ( bug) = self . delayed_span_bug . borrow_mut ( ) . take ( ) {
619
- DiagnosticBuilder :: new_diagnostic ( self , bug) . emit ( ) ;
620
- }
621
641
return ;
622
642
}
623
643
FatalError . raise ( ) ;
0 commit comments