44
55#![ doc( html_root_url = "https://doc.rust-lang.org/nightly/" ) ]
66#![ feature( crate_visibility_modifier) ]
7+ #![ feature( backtrace) ]
78#![ feature( nll) ]
89
910#[ macro_use]
@@ -296,9 +297,11 @@ struct HandlerInner {
296297 /// This is not necessarily the count that's reported to the user once
297298 /// compilation ends.
298299 err_count : usize ,
300+ warn_count : usize ,
299301 deduplicated_err_count : usize ,
300302 emitter : Box < dyn Emitter + sync:: Send > ,
301303 delayed_span_bugs : Vec < Diagnostic > ,
304+ delayed_good_path_bugs : Vec < Diagnostic > ,
302305
303306 /// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
304307 /// emitting the same diagnostic with extended help (`--teach`) twice, which
@@ -361,13 +364,15 @@ impl Drop for HandlerInner {
361364
362365 if !self . has_errors ( ) {
363366 let bugs = std:: mem:: replace ( & mut self . delayed_span_bugs , Vec :: new ( ) ) ;
364- let has_bugs = !bugs. is_empty ( ) ;
365- for bug in bugs {
366- self . emit_diagnostic ( & bug) ;
367- }
368- if has_bugs {
369- panic ! ( "no errors encountered even though `delay_span_bug` issued" ) ;
370- }
367+ self . flush_delayed ( bugs, "no errors encountered even though `delay_span_bug` issued" ) ;
368+ }
369+
370+ if !self . has_any_message ( ) {
371+ let bugs = std:: mem:: replace ( & mut self . delayed_good_path_bugs , Vec :: new ( ) ) ;
372+ self . flush_delayed (
373+ bugs,
374+ "no warnings or errors encountered even though `delayed_good_path_bugs` issued" ,
375+ ) ;
371376 }
372377 }
373378}
@@ -422,10 +427,12 @@ impl Handler {
422427 inner : Lock :: new ( HandlerInner {
423428 flags,
424429 err_count : 0 ,
430+ warn_count : 0 ,
425431 deduplicated_err_count : 0 ,
426432 deduplicated_warn_count : 0 ,
427433 emitter,
428434 delayed_span_bugs : Vec :: new ( ) ,
435+ delayed_good_path_bugs : Vec :: new ( ) ,
429436 taught_diagnostics : Default :: default ( ) ,
430437 emitted_diagnostic_codes : Default :: default ( ) ,
431438 emitted_diagnostics : Default :: default ( ) ,
@@ -448,11 +455,13 @@ impl Handler {
448455 pub fn reset_err_count ( & self ) {
449456 let mut inner = self . inner . borrow_mut ( ) ;
450457 inner. err_count = 0 ;
458+ inner. warn_count = 0 ;
451459 inner. deduplicated_err_count = 0 ;
452460 inner. deduplicated_warn_count = 0 ;
453461
454462 // actually free the underlying memory (which `clear` would not do)
455463 inner. delayed_span_bugs = Default :: default ( ) ;
464+ inner. delayed_good_path_bugs = Default :: default ( ) ;
456465 inner. taught_diagnostics = Default :: default ( ) ;
457466 inner. emitted_diagnostic_codes = Default :: default ( ) ;
458467 inner. emitted_diagnostics = Default :: default ( ) ;
@@ -629,6 +638,10 @@ impl Handler {
629638 self . inner . borrow_mut ( ) . delay_span_bug ( span, msg)
630639 }
631640
641+ pub fn delay_good_path_bug ( & self , msg : & str ) {
642+ self . inner . borrow_mut ( ) . delay_good_path_bug ( msg)
643+ }
644+
632645 pub fn span_bug_no_panic ( & self , span : impl Into < MultiSpan > , msg : & str ) {
633646 self . emit_diag_at_span ( Diagnostic :: new ( Bug , msg) , span) ;
634647 }
@@ -768,6 +781,8 @@ impl HandlerInner {
768781 }
769782 if diagnostic. is_error ( ) {
770783 self . bump_err_count ( ) ;
784+ } else {
785+ self . bump_warn_count ( ) ;
771786 }
772787 }
773788
@@ -859,6 +874,9 @@ impl HandlerInner {
859874 fn has_errors_or_delayed_span_bugs ( & self ) -> bool {
860875 self . has_errors ( ) || !self . delayed_span_bugs . is_empty ( )
861876 }
877+ fn has_any_message ( & self ) -> bool {
878+ self . err_count ( ) > 0 || self . warn_count > 0
879+ }
862880
863881 fn abort_if_errors ( & mut self ) {
864882 self . emit_stashed_diagnostics ( ) ;
@@ -892,6 +910,15 @@ impl HandlerInner {
892910 self . delay_as_bug ( diagnostic)
893911 }
894912
913+ fn delay_good_path_bug ( & mut self , msg : & str ) {
914+ let mut diagnostic = Diagnostic :: new ( Level :: Bug , msg) ;
915+ if self . flags . report_delayed_bugs {
916+ self . emit_diagnostic ( & diagnostic) ;
917+ }
918+ diagnostic. note ( & format ! ( "delayed at {}" , std:: backtrace:: Backtrace :: force_capture( ) ) ) ;
919+ self . delayed_good_path_bugs . push ( diagnostic) ;
920+ }
921+
895922 fn failure ( & mut self , msg : & str ) {
896923 self . emit_diagnostic ( & Diagnostic :: new ( FailureNote , msg) ) ;
897924 }
@@ -925,11 +952,25 @@ impl HandlerInner {
925952 self . delayed_span_bugs . push ( diagnostic) ;
926953 }
927954
955+ fn flush_delayed ( & mut self , bugs : Vec < Diagnostic > , explanation : & str ) {
956+ let has_bugs = !bugs. is_empty ( ) ;
957+ for bug in bugs {
958+ self . emit_diagnostic ( & bug) ;
959+ }
960+ if has_bugs {
961+ panic ! ( "{}" , explanation) ;
962+ }
963+ }
964+
928965 fn bump_err_count ( & mut self ) {
929966 self . err_count += 1 ;
930967 self . panic_if_treat_err_as_bug ( ) ;
931968 }
932969
970+ fn bump_warn_count ( & mut self ) {
971+ self . warn_count += 1 ;
972+ }
973+
933974 fn panic_if_treat_err_as_bug ( & self ) {
934975 if self . treat_err_as_bug ( ) {
935976 let s = match ( self . err_count ( ) , self . flags . treat_err_as_bug . unwrap_or ( 0 ) ) {
0 commit comments