@@ -420,15 +420,21 @@ pub struct DiagCtxt {
420420/// as well as inconsistent state observation.
421421struct DiagCtxtInner {
422422 flags : DiagCtxtFlags ,
423+
423424 /// The number of lint errors that have been emitted.
424425 lint_err_count : usize ,
425426 /// The number of errors that have been emitted, including duplicates.
426427 ///
427428 /// This is not necessarily the count that's reported to the user once
428429 /// compilation ends.
429430 err_count : usize ,
430- warn_count : usize ,
431431 deduplicated_err_count : usize ,
432+ /// The warning count, used for a recap upon finishing
433+ deduplicated_warn_count : usize ,
434+ /// Has this diagnostic context printed any diagnostics? (I.e. has
435+ /// `self.emitter.emit_diagnostic()` been called?
436+ has_printed : bool ,
437+
432438 emitter : Box < DynEmitter > ,
433439 span_delayed_bugs : Vec < DelayedDiagnostic > ,
434440 good_path_delayed_bugs : Vec < DelayedDiagnostic > ,
@@ -455,9 +461,6 @@ struct DiagCtxtInner {
455461 /// When `.abort_if_errors()` is called, these are also emitted.
456462 stashed_diagnostics : FxIndexMap < ( Span , StashKey ) , Diagnostic > ,
457463
458- /// The warning count, used for a recap upon finishing
459- deduplicated_warn_count : usize ,
460-
461464 future_breakage_diagnostics : Vec < Diagnostic > ,
462465
463466 /// The [`Self::unstable_expect_diagnostics`] should be empty when this struct is
@@ -513,7 +516,7 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
513516 ( * f) ( diag)
514517}
515518
516- pub static TRACK_DIAGNOSTICS : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
519+ pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
517520 AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
518521
519522#[ derive( Copy , Clone , Default ) ]
@@ -547,8 +550,7 @@ impl Drop for DiagCtxtInner {
547550 // instead of "require some error happened". Sadly that isn't ideal, as
548551 // lints can be `#[allow]`'d, potentially leading to this triggering.
549552 // Also, "good path" should be replaced with a better naming.
550- let has_any_message = self . err_count > 0 || self . lint_err_count > 0 || self . warn_count > 0 ;
551- if !has_any_message && !self . suppressed_expected_diag && !std:: thread:: panicking ( ) {
553+ if !self . has_printed && !self . suppressed_expected_diag && !std:: thread:: panicking ( ) {
552554 let bugs = std:: mem:: replace ( & mut self . good_path_delayed_bugs , Vec :: new ( ) ) ;
553555 self . flush_delayed (
554556 bugs,
@@ -594,9 +596,9 @@ impl DiagCtxt {
594596 flags : DiagCtxtFlags { can_emit_warnings : true , ..Default :: default ( ) } ,
595597 lint_err_count : 0 ,
596598 err_count : 0 ,
597- warn_count : 0 ,
598599 deduplicated_err_count : 0 ,
599600 deduplicated_warn_count : 0 ,
601+ has_printed : false ,
600602 emitter,
601603 span_delayed_bugs : Vec :: new ( ) ,
602604 good_path_delayed_bugs : Vec :: new ( ) ,
@@ -647,10 +649,11 @@ impl DiagCtxt {
647649 /// the overall count of emitted error diagnostics.
648650 pub fn reset_err_count ( & self ) {
649651 let mut inner = self . inner . borrow_mut ( ) ;
652+ inner. lint_err_count = 0 ;
650653 inner. err_count = 0 ;
651- inner. warn_count = 0 ;
652654 inner. deduplicated_err_count = 0 ;
653655 inner. deduplicated_warn_count = 0 ;
656+ inner. has_printed = false ;
654657
655658 // actually free the underlying memory (which `clear` would not do)
656659 inner. span_delayed_bugs = Default :: default ( ) ;
@@ -669,16 +672,11 @@ impl DiagCtxt {
669672 let key = ( span. with_parent ( None ) , key) ;
670673
671674 if diag. is_error ( ) {
672- if diag. level == Error && diag . is_lint {
675+ if diag. is_lint {
673676 inner. lint_err_count += 1 ;
674677 } else {
675678 inner. err_count += 1 ;
676679 }
677- } else {
678- // Warnings are only automatically flushed if they're forced.
679- if diag. is_force_warn ( ) {
680- inner. warn_count += 1 ;
681- }
682680 }
683681
684682 // FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
@@ -693,15 +691,11 @@ impl DiagCtxt {
693691 let key = ( span. with_parent ( None ) , key) ;
694692 let diag = inner. stashed_diagnostics . remove ( & key) ?;
695693 if diag. is_error ( ) {
696- if diag. level == Error && diag . is_lint {
694+ if diag. is_lint {
697695 inner. lint_err_count -= 1 ;
698696 } else {
699697 inner. err_count -= 1 ;
700698 }
701- } else {
702- if diag. is_force_warn ( ) {
703- inner. warn_count -= 1 ;
704- }
705699 }
706700 Some ( DiagnosticBuilder :: new_diagnostic ( self , diag) )
707701 }
@@ -738,7 +732,7 @@ impl DiagCtxt {
738732 #[ rustc_lint_diagnostics]
739733 #[ track_caller]
740734 pub fn struct_warn ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
741- DiagnosticBuilder :: new ( self , Warning ( None ) , msg)
735+ DiagnosticBuilder :: new ( self , Warning , msg)
742736 }
743737
744738 /// Construct a builder at the `Allow` level with the `msg`.
@@ -1005,7 +999,7 @@ impl DiagCtxt {
1005999 ( 0 , 0 ) => return ,
10061000 ( 0 , _) => inner
10071001 . emitter
1008- . emit_diagnostic ( & Diagnostic :: new ( Warning ( None ) , DiagnosticMessage :: Str ( warnings) ) ) ,
1002+ . emit_diagnostic ( & Diagnostic :: new ( Warning , DiagnosticMessage :: Str ( warnings) ) ) ,
10091003 ( _, 0 ) => {
10101004 inner. emit_diagnostic ( Diagnostic :: new ( Fatal , errors) ) ;
10111005 }
@@ -1094,7 +1088,7 @@ impl DiagCtxt {
10941088 & ' a self ,
10951089 warning : impl IntoDiagnostic < ' a , ( ) > ,
10961090 ) -> DiagnosticBuilder < ' a , ( ) > {
1097- warning. into_diagnostic ( self , Warning ( None ) )
1091+ warning. into_diagnostic ( self , Warning )
10981092 }
10991093
11001094 #[ track_caller]
@@ -1241,21 +1235,17 @@ impl DiagCtxtInner {
12411235 for diag in diags {
12421236 // Decrement the count tracking the stash; emitting will increment it.
12431237 if diag. is_error ( ) {
1244- if diag. level == Error && diag . is_lint {
1238+ if diag. is_lint {
12451239 self . lint_err_count -= 1 ;
12461240 } else {
12471241 self . err_count -= 1 ;
12481242 }
12491243 } else {
1250- if diag. is_force_warn ( ) {
1251- self . warn_count -= 1 ;
1252- } else {
1253- // Unless they're forced, don't flush stashed warnings when
1254- // there are errors, to avoid causing warning overload. The
1255- // stash would've been stolen already if it were important.
1256- if has_errors {
1257- continue ;
1258- }
1244+ // Unless they're forced, don't flush stashed warnings when
1245+ // there are errors, to avoid causing warning overload. The
1246+ // stash would've been stolen already if it were important.
1247+ if !diag. is_force_warn ( ) && has_errors {
1248+ continue ;
12591249 }
12601250 }
12611251 let reported_this = self . emit_diagnostic ( diag) ;
@@ -1304,23 +1294,20 @@ impl DiagCtxtInner {
13041294 self . fulfilled_expectations . insert ( expectation_id. normalize ( ) ) ;
13051295 }
13061296
1307- if matches ! ( diagnostic. level, Warning ( _) )
1308- && !self . flags . can_emit_warnings
1309- && !diagnostic. is_force_warn ( )
1310- {
1297+ if diagnostic. level == Warning && !self . flags . can_emit_warnings {
13111298 if diagnostic. has_future_breakage ( ) {
1312- ( * TRACK_DIAGNOSTICS ) ( diagnostic, & mut |_| { } ) ;
1299+ ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
13131300 }
13141301 return None ;
13151302 }
13161303
13171304 if matches ! ( diagnostic. level, Expect ( _) | Allow ) {
1318- ( * TRACK_DIAGNOSTICS ) ( diagnostic, & mut |_| { } ) ;
1305+ ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
13191306 return None ;
13201307 }
13211308
13221309 let mut guaranteed = None ;
1323- ( * TRACK_DIAGNOSTICS ) ( diagnostic, & mut |mut diagnostic| {
1310+ ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |mut diagnostic| {
13241311 if let Some ( ref code) = diagnostic. code {
13251312 self . emitted_diagnostic_codes . insert ( code. clone ( ) ) ;
13261313 }
@@ -1359,12 +1346,13 @@ impl DiagCtxtInner {
13591346 self . emitter . emit_diagnostic ( & diagnostic) ;
13601347 if diagnostic. is_error ( ) {
13611348 self . deduplicated_err_count += 1 ;
1362- } else if let Warning ( _) = diagnostic . level {
1349+ } else if matches ! ( diagnostic . level , ForceWarning ( _) | Warning ) {
13631350 self . deduplicated_warn_count += 1 ;
13641351 }
1352+ self . has_printed = true ;
13651353 }
13661354 if diagnostic. is_error ( ) {
1367- if diagnostic. level == Error && diagnostic . is_lint {
1355+ if diagnostic. is_lint {
13681356 self . bump_lint_err_count ( ) ;
13691357 } else {
13701358 self . bump_err_count ( ) ;
@@ -1374,8 +1362,6 @@ impl DiagCtxtInner {
13741362 {
13751363 guaranteed = Some ( ErrorGuaranteed :: unchecked_claim_error_was_emitted ( ) ) ;
13761364 }
1377- } else {
1378- self . bump_warn_count ( ) ;
13791365 }
13801366 } ) ;
13811367
@@ -1471,10 +1457,6 @@ impl DiagCtxtInner {
14711457 self . panic_if_treat_err_as_bug ( ) ;
14721458 }
14731459
1474- fn bump_warn_count ( & mut self ) {
1475- self . warn_count += 1 ;
1476- }
1477-
14781460 fn panic_if_treat_err_as_bug ( & self ) {
14791461 if self . treat_err_as_bug ( ) {
14801462 match (
@@ -1562,14 +1544,17 @@ pub enum Level {
15621544 /// Its `EmissionGuarantee` is `ErrorGuaranteed`.
15631545 Error ,
15641546
1565- /// A warning about the code being compiled. Does not prevent compilation from finishing.
1547+ /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
1548+ /// from finishing.
15661549 ///
1567- /// This [`LintExpectationId`] is used for expected lint diagnostics, which should
1568- /// also emit a warning due to the `force-warn` flag. In all other cases this should
1569- /// be `None`.
1550+ /// The [`LintExpectationId`] is used for expected lint diagnostics. In all other cases this
1551+ /// should be `None`.
1552+ ForceWarning ( Option < LintExpectationId > ) ,
1553+
1554+ /// A warning about the code being compiled. Does not prevent compilation from finishing.
15701555 ///
15711556 /// Its `EmissionGuarantee` is `()`.
1572- Warning ( Option < LintExpectationId > ) ,
1557+ Warning ,
15731558
15741559 /// A message giving additional context. Rare, because notes are more commonly attached to other
15751560 /// diagnostics such as errors.
@@ -1622,7 +1607,7 @@ impl Level {
16221607 Bug | DelayedBug | Fatal | Error => {
16231608 spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
16241609 }
1625- Warning ( _) => {
1610+ ForceWarning ( _) | Warning => {
16261611 spec. set_fg ( Some ( Color :: Yellow ) ) . set_intense ( cfg ! ( windows) ) ;
16271612 }
16281613 Note | OnceNote => {
@@ -1641,7 +1626,7 @@ impl Level {
16411626 match self {
16421627 Bug | DelayedBug => "error: internal compiler error" ,
16431628 Fatal | Error => "error" ,
1644- Warning ( _) => "warning" ,
1629+ ForceWarning ( _) | Warning => "warning" ,
16451630 Note | OnceNote => "note" ,
16461631 Help | OnceHelp => "help" ,
16471632 FailureNote => "failure-note" ,
@@ -1655,7 +1640,7 @@ impl Level {
16551640
16561641 pub fn get_expectation_id ( & self ) -> Option < LintExpectationId > {
16571642 match self {
1658- Expect ( id) | Warning ( Some ( id) ) => Some ( * id) ,
1643+ Expect ( id) | ForceWarning ( Some ( id) ) => Some ( * id) ,
16591644 _ => None ,
16601645 }
16611646 }
0 commit comments