@@ -78,6 +78,7 @@ use std::fmt;
7878use std:: hash:: Hash ;
7979use std:: io:: Write ;
8080use std:: num:: NonZeroUsize ;
81+ use std:: ops:: DerefMut ;
8182use std:: panic;
8283use std:: path:: { Path , PathBuf } ;
8384
@@ -666,22 +667,51 @@ impl DiagCtxt {
666667 /// tools that want to reuse a `Parser` cleaning the previously emitted diagnostics as well as
667668 /// the overall count of emitted error diagnostics.
668669 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.
669672 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 ( ) ;
685715 }
686716
687717 /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key.
@@ -780,11 +810,12 @@ impl DiagCtxt {
780810 match ( errors. len ( ) , warnings. len ( ) ) {
781811 ( 0 , 0 ) => return ,
782812 ( 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+ ) ) ;
788819 }
789820 ( _, 0 ) => {
790821 inner. emit_diagnostic ( Diagnostic :: new ( Error , errors) ) ;
@@ -812,20 +843,23 @@ impl DiagCtxt {
812843 error_codes. sort ( ) ;
813844 if error_codes. len ( ) > 1 {
814845 let limit = if error_codes. len ( ) > 9 { 9 } else { error_codes. len ( ) } ;
815- inner . failure_note ( format ! (
846+ let msg1 = format ! (
816847 "Some errors have detailed explanations: {}{}" ,
817848 error_codes[ ..limit] . join( ", " ) ,
818849 if error_codes. len( ) > 9 { "..." } else { "." }
819- ) ) ;
820- inner . failure_note ( format ! (
850+ ) ;
851+ let msg2 = format ! (
821852 "For more information about an error, try `rustc --explain {}`." ,
822853 & error_codes[ 0 ]
823- ) ) ;
854+ ) ;
855+ inner. emit_diagnostic ( Diagnostic :: new ( FailureNote , msg1) ) ;
856+ inner. emit_diagnostic ( Diagnostic :: new ( FailureNote , msg2) ) ;
824857 } else {
825- inner . failure_note ( format ! (
858+ let msg = format ! (
826859 "For more information about this error, try `rustc --explain {}`." ,
827860 & error_codes[ 0 ]
828- ) ) ;
861+ ) ;
862+ inner. emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
829863 }
830864 }
831865 }
@@ -848,10 +882,6 @@ impl DiagCtxt {
848882 self . inner . borrow_mut ( ) . taught_diagnostics . insert ( code)
849883 }
850884
851- pub fn force_print_diagnostic ( & self , db : Diagnostic ) {
852- self . inner . borrow_mut ( ) . emitter . emit_diagnostic ( db) ;
853- }
854-
855885 pub fn emit_diagnostic ( & self , diagnostic : Diagnostic ) -> Option < ErrorGuaranteed > {
856886 self . inner . borrow_mut ( ) . emit_diagnostic ( diagnostic)
857887 }
@@ -1179,7 +1209,7 @@ impl DiagCtxt {
11791209 span : impl Into < MultiSpan > ,
11801210 msg : impl Into < DiagnosticMessage > ,
11811211 ) -> DiagnosticBuilder < ' _ , ( ) > {
1182- DiagnosticBuilder :: new ( self , Note , msg) . with_span ( span)
1212+ self . struct_note ( msg) . with_span ( span)
11831213 }
11841214
11851215 #[ rustc_lint_diagnostics]
@@ -1207,6 +1237,15 @@ impl DiagCtxt {
12071237 DiagnosticBuilder :: new ( self , Help , msg)
12081238 }
12091239
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+
12101249 #[ rustc_lint_diagnostics]
12111250 #[ track_caller]
12121251 pub fn struct_allow ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
@@ -1406,10 +1445,6 @@ impl DiagCtxtInner {
14061445 . or_else ( || self . delayed_bugs . get ( 0 ) . map ( |( _, guar) | guar) . copied ( ) )
14071446 }
14081447
1409- fn failure_note ( & mut self , msg : impl Into < DiagnosticMessage > ) {
1410- self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
1411- }
1412-
14131448 fn flush_delayed ( & mut self ) {
14141449 if self . delayed_bugs . is_empty ( ) {
14151450 return ;
0 commit comments