@@ -274,7 +274,7 @@ pub struct Handler {
274274 err_count : AtomicUsize ,
275275 emitter : Lock < Box < dyn Emitter + sync:: Send > > ,
276276 continue_after_error : LockCell < bool > ,
277- delayed_span_bug : Lock < Option < Diagnostic > > ,
277+ delayed_span_bugs : Lock < Vec < Diagnostic > > ,
278278
279279 // This set contains the `DiagnosticId` of all emitted diagnostics to avoid
280280 // emitting the same diagnostic with extended help (`--teach`) twice, which
@@ -299,9 +299,25 @@ thread_local!(pub static TRACK_DIAGNOSTICS: Cell<fn(&Diagnostic)> =
299299pub struct HandlerFlags {
300300 pub can_emit_warnings : bool ,
301301 pub treat_err_as_bug : bool ,
302+ pub report_delayed_bugs : bool ,
302303 pub external_macro_backtrace : bool ,
303304}
304305
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+
305321impl Handler {
306322 pub fn with_tty_emitter ( color_config : ColorConfig ,
307323 can_emit_warnings : bool ,
@@ -346,7 +362,7 @@ impl Handler {
346362 err_count : AtomicUsize :: new ( 0 ) ,
347363 emitter : Lock :: new ( e) ,
348364 continue_after_error : LockCell :: new ( true ) ,
349- delayed_span_bug : Lock :: new ( None ) ,
365+ delayed_span_bugs : Lock :: new ( Vec :: new ( ) ) ,
350366 taught_diagnostics : Lock :: new ( FxHashSet ( ) ) ,
351367 emitted_diagnostic_codes : Lock :: new ( FxHashSet ( ) ) ,
352368 emitted_diagnostics : Lock :: new ( FxHashSet ( ) ) ,
@@ -503,11 +519,18 @@ impl Handler {
503519 }
504520 pub fn delay_span_bug < S : Into < MultiSpan > > ( & self , sp : S , msg : & str ) {
505521 if self . flags . treat_err_as_bug {
522+ // FIXME: don't abort here if report_delayed_bugs is off
506523 self . span_bug ( sp, msg) ;
507524 }
508525 let mut diagnostic = Diagnostic :: new ( Level :: Bug , msg) ;
509526 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) ;
511534 }
512535 pub fn span_bug_no_panic < S : Into < MultiSpan > > ( & self , sp : S , msg : & str ) {
513536 self . emit ( & sp. into ( ) , msg, Bug ) ;
@@ -615,9 +638,6 @@ impl Handler {
615638
616639 pub fn abort_if_errors ( & self ) {
617640 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- }
621641 return ;
622642 }
623643 FatalError . raise ( ) ;
0 commit comments