@@ -78,6 +78,7 @@ use std::fmt;
78
78
use std:: hash:: Hash ;
79
79
use std:: io:: Write ;
80
80
use std:: num:: NonZeroUsize ;
81
+ use std:: ops:: DerefMut ;
81
82
use std:: panic;
82
83
use std:: path:: { Path , PathBuf } ;
83
84
@@ -666,22 +667,51 @@ impl DiagCtxt {
666
667
/// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
667
668
/// the overall count of emitted error diagnostics.
668
669
pub fn reset_err_count ( & self ) {
670
+ // Use destructuring so that if a field gets added to `DiagCtxtInner`, it's impossible to
671
+ // fail to update this method as well.
669
672
let mut inner = self . inner . borrow_mut ( ) ;
670
- inner. stashed_err_count = 0 ;
671
- inner. deduplicated_err_count = 0 ;
672
- inner. deduplicated_warn_count = 0 ;
673
- inner. must_produce_diag = false ;
674
- inner. has_printed = false ;
675
- inner. suppressed_expected_diag = false ;
676
-
677
- // actually free the underlying memory (which `clear` would not do)
678
- inner. err_guars = Default :: default ( ) ;
679
- inner. lint_err_guars = Default :: default ( ) ;
680
- inner. delayed_bugs = Default :: default ( ) ;
681
- inner. taught_diagnostics = Default :: default ( ) ;
682
- inner. emitted_diagnostic_codes = Default :: default ( ) ;
683
- inner. emitted_diagnostics = Default :: default ( ) ;
684
- inner. stashed_diagnostics = Default :: default ( ) ;
673
+ let DiagCtxtInner {
674
+ flags : _,
675
+ err_guars,
676
+ lint_err_guars,
677
+ delayed_bugs,
678
+ stashed_err_count,
679
+ deduplicated_err_count,
680
+ deduplicated_warn_count,
681
+ emitter : _,
682
+ must_produce_diag,
683
+ has_printed,
684
+ suppressed_expected_diag,
685
+ taught_diagnostics,
686
+ emitted_diagnostic_codes,
687
+ emitted_diagnostics,
688
+ stashed_diagnostics,
689
+ future_breakage_diagnostics,
690
+ check_unstable_expect_diagnostics,
691
+ unstable_expect_diagnostics,
692
+ fulfilled_expectations,
693
+ ice_file : _,
694
+ } = inner. deref_mut ( ) ;
695
+
696
+ // For the `Vec`s and `HashMap`s, we overwrite with an empty container to free the
697
+ // underlying memory (which `clear` would not do).
698
+ * err_guars = Default :: default ( ) ;
699
+ * lint_err_guars = Default :: default ( ) ;
700
+ * delayed_bugs = Default :: default ( ) ;
701
+ * stashed_err_count = 0 ;
702
+ * deduplicated_err_count = 0 ;
703
+ * deduplicated_warn_count = 0 ;
704
+ * must_produce_diag = false ;
705
+ * has_printed = false ;
706
+ * suppressed_expected_diag = false ;
707
+ * taught_diagnostics = Default :: default ( ) ;
708
+ * emitted_diagnostic_codes = Default :: default ( ) ;
709
+ * emitted_diagnostics = Default :: default ( ) ;
710
+ * stashed_diagnostics = Default :: default ( ) ;
711
+ * future_breakage_diagnostics = Default :: default ( ) ;
712
+ * check_unstable_expect_diagnostics = false ;
713
+ * unstable_expect_diagnostics = Default :: default ( ) ;
714
+ * fulfilled_expectations = Default :: default ( ) ;
685
715
}
686
716
687
717
/// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key.
@@ -780,11 +810,12 @@ impl DiagCtxt {
780
810
match ( errors. len ( ) , warnings. len ( ) ) {
781
811
( 0 , 0 ) => return ,
782
812
( 0 , _) => {
783
- // Use `inner.emitter` directly, otherwise the warning might not be emitted, e.g.
784
- // with a configuration like `--cap-lints allow --force-warn bare_trait_objects`.
785
- inner
786
- . emitter
787
- . emit_diagnostic ( Diagnostic :: new ( Warning , DiagnosticMessage :: Str ( warnings) ) ) ;
813
+ // Use `ForceWarning` rather than `Warning` to guarantee emission, e.g. with a
814
+ // configuration like `--cap-lints allow --force-warn bare_trait_objects`.
815
+ inner. emit_diagnostic ( Diagnostic :: new (
816
+ ForceWarning ( None ) ,
817
+ DiagnosticMessage :: Str ( warnings) ,
818
+ ) ) ;
788
819
}
789
820
( _, 0 ) => {
790
821
inner. emit_diagnostic ( Diagnostic :: new ( Error , errors) ) ;
@@ -812,20 +843,23 @@ impl DiagCtxt {
812
843
error_codes. sort ( ) ;
813
844
if error_codes. len ( ) > 1 {
814
845
let limit = if error_codes. len ( ) > 9 { 9 } else { error_codes. len ( ) } ;
815
- inner . failure_note ( format ! (
846
+ let msg1 = format ! (
816
847
"Some errors have detailed explanations: {}{}" ,
817
848
error_codes[ ..limit] . join( ", " ) ,
818
849
if error_codes. len( ) > 9 { "..." } else { "." }
819
- ) ) ;
820
- inner . failure_note ( format ! (
850
+ ) ;
851
+ let msg2 = format ! (
821
852
"For more information about an error, try `rustc --explain {}`." ,
822
853
& error_codes[ 0 ]
823
- ) ) ;
854
+ ) ;
855
+ inner. emit_diagnostic ( Diagnostic :: new ( FailureNote , msg1) ) ;
856
+ inner. emit_diagnostic ( Diagnostic :: new ( FailureNote , msg2) ) ;
824
857
} else {
825
- inner . failure_note ( format ! (
858
+ let msg = format ! (
826
859
"For more information about this error, try `rustc --explain {}`." ,
827
860
& error_codes[ 0 ]
828
- ) ) ;
861
+ ) ;
862
+ inner. emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
829
863
}
830
864
}
831
865
}
@@ -848,10 +882,6 @@ impl DiagCtxt {
848
882
self . inner . borrow_mut ( ) . taught_diagnostics . insert ( code)
849
883
}
850
884
851
- pub fn force_print_diagnostic ( & self , db : Diagnostic ) {
852
- self . inner . borrow_mut ( ) . emitter . emit_diagnostic ( db) ;
853
- }
854
-
855
885
pub fn emit_diagnostic ( & self , diagnostic : Diagnostic ) -> Option < ErrorGuaranteed > {
856
886
self . inner . borrow_mut ( ) . emit_diagnostic ( diagnostic)
857
887
}
@@ -1179,7 +1209,7 @@ impl DiagCtxt {
1179
1209
span : impl Into < MultiSpan > ,
1180
1210
msg : impl Into < DiagnosticMessage > ,
1181
1211
) -> DiagnosticBuilder < ' _ , ( ) > {
1182
- DiagnosticBuilder :: new ( self , Note , msg) . with_span ( span)
1212
+ self . struct_note ( msg) . with_span ( span)
1183
1213
}
1184
1214
1185
1215
#[ rustc_lint_diagnostics]
@@ -1207,6 +1237,15 @@ impl DiagCtxt {
1207
1237
DiagnosticBuilder :: new ( self , Help , msg)
1208
1238
}
1209
1239
1240
+ #[ rustc_lint_diagnostics]
1241
+ #[ track_caller]
1242
+ pub fn struct_failure_note (
1243
+ & self ,
1244
+ msg : impl Into < DiagnosticMessage > ,
1245
+ ) -> DiagnosticBuilder < ' _ , ( ) > {
1246
+ DiagnosticBuilder :: new ( self , FailureNote , msg)
1247
+ }
1248
+
1210
1249
#[ rustc_lint_diagnostics]
1211
1250
#[ track_caller]
1212
1251
pub fn struct_allow ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
@@ -1406,10 +1445,6 @@ impl DiagCtxtInner {
1406
1445
. or_else ( || self . delayed_bugs . get ( 0 ) . map ( |( _, guar) | guar) . copied ( ) )
1407
1446
}
1408
1447
1409
- fn failure_note ( & mut self , msg : impl Into < DiagnosticMessage > ) {
1410
- self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
1411
- }
1412
-
1413
1448
fn flush_delayed ( & mut self ) {
1414
1449
if self . delayed_bugs . is_empty ( ) {
1415
1450
return ;
0 commit comments