4
4
5
5
#![ doc( html_root_url = "https://doc.rust-lang.org/nightly/" ) ]
6
6
#![ feature( crate_visibility_modifier) ]
7
+ #![ feature( backtrace) ]
7
8
#![ feature( nll) ]
8
9
9
10
#[ macro_use]
@@ -296,9 +297,11 @@ struct HandlerInner {
296
297
/// This is not necessarily the count that's reported to the user once
297
298
/// compilation ends.
298
299
err_count : usize ,
300
+ warn_count : usize ,
299
301
deduplicated_err_count : usize ,
300
302
emitter : Box < dyn Emitter + sync:: Send > ,
301
303
delayed_span_bugs : Vec < Diagnostic > ,
304
+ delayed_good_path_bugs : Vec < Diagnostic > ,
302
305
303
306
/// This set contains the `DiagnosticId` of all emitted diagnostics to avoid
304
307
/// emitting the same diagnostic with extended help (`--teach`) twice, which
@@ -361,13 +364,15 @@ impl Drop for HandlerInner {
361
364
362
365
if !self . has_errors ( ) {
363
366
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
+ ) ;
371
376
}
372
377
}
373
378
}
@@ -422,10 +427,12 @@ impl Handler {
422
427
inner : Lock :: new ( HandlerInner {
423
428
flags,
424
429
err_count : 0 ,
430
+ warn_count : 0 ,
425
431
deduplicated_err_count : 0 ,
426
432
deduplicated_warn_count : 0 ,
427
433
emitter,
428
434
delayed_span_bugs : Vec :: new ( ) ,
435
+ delayed_good_path_bugs : Vec :: new ( ) ,
429
436
taught_diagnostics : Default :: default ( ) ,
430
437
emitted_diagnostic_codes : Default :: default ( ) ,
431
438
emitted_diagnostics : Default :: default ( ) ,
@@ -448,11 +455,13 @@ impl Handler {
448
455
pub fn reset_err_count ( & self ) {
449
456
let mut inner = self . inner . borrow_mut ( ) ;
450
457
inner. err_count = 0 ;
458
+ inner. warn_count = 0 ;
451
459
inner. deduplicated_err_count = 0 ;
452
460
inner. deduplicated_warn_count = 0 ;
453
461
454
462
// actually free the underlying memory (which `clear` would not do)
455
463
inner. delayed_span_bugs = Default :: default ( ) ;
464
+ inner. delayed_good_path_bugs = Default :: default ( ) ;
456
465
inner. taught_diagnostics = Default :: default ( ) ;
457
466
inner. emitted_diagnostic_codes = Default :: default ( ) ;
458
467
inner. emitted_diagnostics = Default :: default ( ) ;
@@ -629,6 +638,10 @@ impl Handler {
629
638
self . inner . borrow_mut ( ) . delay_span_bug ( span, msg)
630
639
}
631
640
641
+ pub fn delay_good_path_bug ( & self , msg : & str ) {
642
+ self . inner . borrow_mut ( ) . delay_good_path_bug ( msg)
643
+ }
644
+
632
645
pub fn span_bug_no_panic ( & self , span : impl Into < MultiSpan > , msg : & str ) {
633
646
self . emit_diag_at_span ( Diagnostic :: new ( Bug , msg) , span) ;
634
647
}
@@ -768,6 +781,8 @@ impl HandlerInner {
768
781
}
769
782
if diagnostic. is_error ( ) {
770
783
self . bump_err_count ( ) ;
784
+ } else {
785
+ self . bump_warn_count ( ) ;
771
786
}
772
787
}
773
788
@@ -859,6 +874,9 @@ impl HandlerInner {
859
874
fn has_errors_or_delayed_span_bugs ( & self ) -> bool {
860
875
self . has_errors ( ) || !self . delayed_span_bugs . is_empty ( )
861
876
}
877
+ fn has_any_message ( & self ) -> bool {
878
+ self . err_count ( ) > 0 || self . warn_count > 0
879
+ }
862
880
863
881
fn abort_if_errors ( & mut self ) {
864
882
self . emit_stashed_diagnostics ( ) ;
@@ -892,6 +910,15 @@ impl HandlerInner {
892
910
self . delay_as_bug ( diagnostic)
893
911
}
894
912
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
+
895
922
fn failure ( & mut self , msg : & str ) {
896
923
self . emit_diagnostic ( & Diagnostic :: new ( FailureNote , msg) ) ;
897
924
}
@@ -925,11 +952,25 @@ impl HandlerInner {
925
952
self . delayed_span_bugs . push ( diagnostic) ;
926
953
}
927
954
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
+
928
965
fn bump_err_count ( & mut self ) {
929
966
self . err_count += 1 ;
930
967
self . panic_if_treat_err_as_bug ( ) ;
931
968
}
932
969
970
+ fn bump_warn_count ( & mut self ) {
971
+ self . warn_count += 1 ;
972
+ }
973
+
933
974
fn panic_if_treat_err_as_bug ( & self ) {
934
975
if self . treat_err_as_bug ( ) {
935
976
let s = match ( self . err_count ( ) , self . flags . treat_err_as_bug . unwrap_or ( 0 ) ) {
0 commit comments