@@ -420,15 +420,21 @@ pub struct DiagCtxt {
420
420
/// as well as inconsistent state observation.
421
421
struct DiagCtxtInner {
422
422
flags : DiagCtxtFlags ,
423
+
423
424
/// The number of lint errors that have been emitted.
424
425
lint_err_count : usize ,
425
426
/// The number of errors that have been emitted, including duplicates.
426
427
///
427
428
/// This is not necessarily the count that's reported to the user once
428
429
/// compilation ends.
429
430
err_count : usize ,
430
- warn_count : usize ,
431
431
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
+
432
438
emitter : Box < DynEmitter > ,
433
439
span_delayed_bugs : Vec < DelayedDiagnostic > ,
434
440
good_path_delayed_bugs : Vec < DelayedDiagnostic > ,
@@ -455,9 +461,6 @@ struct DiagCtxtInner {
455
461
/// When `.abort_if_errors()` is called, these are also emitted.
456
462
stashed_diagnostics : FxIndexMap < ( Span , StashKey ) , Diagnostic > ,
457
463
458
- /// The warning count, used for a recap upon finishing
459
- deduplicated_warn_count : usize ,
460
-
461
464
future_breakage_diagnostics : Vec < Diagnostic > ,
462
465
463
466
/// 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)) {
513
516
( * f) ( diag)
514
517
}
515
518
516
- pub static TRACK_DIAGNOSTICS : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
519
+ pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
517
520
AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
518
521
519
522
#[ derive( Copy , Clone , Default ) ]
@@ -547,8 +550,7 @@ impl Drop for DiagCtxtInner {
547
550
// instead of "require some error happened". Sadly that isn't ideal, as
548
551
// lints can be `#[allow]`'d, potentially leading to this triggering.
549
552
// 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 ( ) {
552
554
let bugs = std:: mem:: replace ( & mut self . good_path_delayed_bugs , Vec :: new ( ) ) ;
553
555
self . flush_delayed (
554
556
bugs,
@@ -594,9 +596,9 @@ impl DiagCtxt {
594
596
flags : DiagCtxtFlags { can_emit_warnings : true , ..Default :: default ( ) } ,
595
597
lint_err_count : 0 ,
596
598
err_count : 0 ,
597
- warn_count : 0 ,
598
599
deduplicated_err_count : 0 ,
599
600
deduplicated_warn_count : 0 ,
601
+ has_printed : false ,
600
602
emitter,
601
603
span_delayed_bugs : Vec :: new ( ) ,
602
604
good_path_delayed_bugs : Vec :: new ( ) ,
@@ -647,10 +649,11 @@ impl DiagCtxt {
647
649
/// the overall count of emitted error diagnostics.
648
650
pub fn reset_err_count ( & self ) {
649
651
let mut inner = self . inner . borrow_mut ( ) ;
652
+ inner. lint_err_count = 0 ;
650
653
inner. err_count = 0 ;
651
- inner. warn_count = 0 ;
652
654
inner. deduplicated_err_count = 0 ;
653
655
inner. deduplicated_warn_count = 0 ;
656
+ inner. has_printed = false ;
654
657
655
658
// actually free the underlying memory (which `clear` would not do)
656
659
inner. span_delayed_bugs = Default :: default ( ) ;
@@ -669,16 +672,11 @@ impl DiagCtxt {
669
672
let key = ( span. with_parent ( None ) , key) ;
670
673
671
674
if diag. is_error ( ) {
672
- if diag. level == Error && diag . is_lint {
675
+ if diag. is_lint {
673
676
inner. lint_err_count += 1 ;
674
677
} else {
675
678
inner. err_count += 1 ;
676
679
}
677
- } else {
678
- // Warnings are only automatically flushed if they're forced.
679
- if diag. is_force_warn ( ) {
680
- inner. warn_count += 1 ;
681
- }
682
680
}
683
681
684
682
// FIXME(Centril, #69537): Consider reintroducing panic on overwriting a stashed diagnostic
@@ -693,15 +691,11 @@ impl DiagCtxt {
693
691
let key = ( span. with_parent ( None ) , key) ;
694
692
let diag = inner. stashed_diagnostics . remove ( & key) ?;
695
693
if diag. is_error ( ) {
696
- if diag. level == Error && diag . is_lint {
694
+ if diag. is_lint {
697
695
inner. lint_err_count -= 1 ;
698
696
} else {
699
697
inner. err_count -= 1 ;
700
698
}
701
- } else {
702
- if diag. is_force_warn ( ) {
703
- inner. warn_count -= 1 ;
704
- }
705
699
}
706
700
Some ( DiagnosticBuilder :: new_diagnostic ( self , diag) )
707
701
}
@@ -738,7 +732,7 @@ impl DiagCtxt {
738
732
#[ rustc_lint_diagnostics]
739
733
#[ track_caller]
740
734
pub fn struct_warn ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
741
- DiagnosticBuilder :: new ( self , Warning ( None ) , msg)
735
+ DiagnosticBuilder :: new ( self , Warning , msg)
742
736
}
743
737
744
738
/// Construct a builder at the `Allow` level with the `msg`.
@@ -1005,7 +999,7 @@ impl DiagCtxt {
1005
999
( 0 , 0 ) => return ,
1006
1000
( 0 , _) => inner
1007
1001
. emitter
1008
- . emit_diagnostic ( & Diagnostic :: new ( Warning ( None ) , DiagnosticMessage :: Str ( warnings) ) ) ,
1002
+ . emit_diagnostic ( & Diagnostic :: new ( Warning , DiagnosticMessage :: Str ( warnings) ) ) ,
1009
1003
( _, 0 ) => {
1010
1004
inner. emit_diagnostic ( Diagnostic :: new ( Fatal , errors) ) ;
1011
1005
}
@@ -1094,7 +1088,7 @@ impl DiagCtxt {
1094
1088
& ' a self ,
1095
1089
warning : impl IntoDiagnostic < ' a , ( ) > ,
1096
1090
) -> DiagnosticBuilder < ' a , ( ) > {
1097
- warning. into_diagnostic ( self , Warning ( None ) )
1091
+ warning. into_diagnostic ( self , Warning )
1098
1092
}
1099
1093
1100
1094
#[ track_caller]
@@ -1241,21 +1235,17 @@ impl DiagCtxtInner {
1241
1235
for diag in diags {
1242
1236
// Decrement the count tracking the stash; emitting will increment it.
1243
1237
if diag. is_error ( ) {
1244
- if diag. level == Error && diag . is_lint {
1238
+ if diag. is_lint {
1245
1239
self . lint_err_count -= 1 ;
1246
1240
} else {
1247
1241
self . err_count -= 1 ;
1248
1242
}
1249
1243
} 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 ;
1259
1249
}
1260
1250
}
1261
1251
let reported_this = self . emit_diagnostic ( diag) ;
@@ -1304,23 +1294,20 @@ impl DiagCtxtInner {
1304
1294
self . fulfilled_expectations . insert ( expectation_id. normalize ( ) ) ;
1305
1295
}
1306
1296
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 {
1311
1298
if diagnostic. has_future_breakage ( ) {
1312
- ( * TRACK_DIAGNOSTICS ) ( diagnostic, & mut |_| { } ) ;
1299
+ ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
1313
1300
}
1314
1301
return None ;
1315
1302
}
1316
1303
1317
1304
if matches ! ( diagnostic. level, Expect ( _) | Allow ) {
1318
- ( * TRACK_DIAGNOSTICS ) ( diagnostic, & mut |_| { } ) ;
1305
+ ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
1319
1306
return None ;
1320
1307
}
1321
1308
1322
1309
let mut guaranteed = None ;
1323
- ( * TRACK_DIAGNOSTICS ) ( diagnostic, & mut |mut diagnostic| {
1310
+ ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |mut diagnostic| {
1324
1311
if let Some ( ref code) = diagnostic. code {
1325
1312
self . emitted_diagnostic_codes . insert ( code. clone ( ) ) ;
1326
1313
}
@@ -1359,12 +1346,13 @@ impl DiagCtxtInner {
1359
1346
self . emitter . emit_diagnostic ( & diagnostic) ;
1360
1347
if diagnostic. is_error ( ) {
1361
1348
self . deduplicated_err_count += 1 ;
1362
- } else if let Warning ( _) = diagnostic . level {
1349
+ } else if matches ! ( diagnostic . level , ForceWarning ( _) | Warning ) {
1363
1350
self . deduplicated_warn_count += 1 ;
1364
1351
}
1352
+ self . has_printed = true ;
1365
1353
}
1366
1354
if diagnostic. is_error ( ) {
1367
- if diagnostic. level == Error && diagnostic . is_lint {
1355
+ if diagnostic. is_lint {
1368
1356
self . bump_lint_err_count ( ) ;
1369
1357
} else {
1370
1358
self . bump_err_count ( ) ;
@@ -1374,8 +1362,6 @@ impl DiagCtxtInner {
1374
1362
{
1375
1363
guaranteed = Some ( ErrorGuaranteed :: unchecked_claim_error_was_emitted ( ) ) ;
1376
1364
}
1377
- } else {
1378
- self . bump_warn_count ( ) ;
1379
1365
}
1380
1366
} ) ;
1381
1367
@@ -1471,10 +1457,6 @@ impl DiagCtxtInner {
1471
1457
self . panic_if_treat_err_as_bug ( ) ;
1472
1458
}
1473
1459
1474
- fn bump_warn_count ( & mut self ) {
1475
- self . warn_count += 1 ;
1476
- }
1477
-
1478
1460
fn panic_if_treat_err_as_bug ( & self ) {
1479
1461
if self . treat_err_as_bug ( ) {
1480
1462
match (
@@ -1562,14 +1544,17 @@ pub enum Level {
1562
1544
/// Its `EmissionGuarantee` is `ErrorGuaranteed`.
1563
1545
Error ,
1564
1546
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.
1566
1549
///
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.
1570
1555
///
1571
1556
/// Its `EmissionGuarantee` is `()`.
1572
- Warning ( Option < LintExpectationId > ) ,
1557
+ Warning ,
1573
1558
1574
1559
/// A message giving additional context. Rare, because notes are more commonly attached to other
1575
1560
/// diagnostics such as errors.
@@ -1622,7 +1607,7 @@ impl Level {
1622
1607
Bug | DelayedBug | Fatal | Error => {
1623
1608
spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
1624
1609
}
1625
- Warning ( _) => {
1610
+ ForceWarning ( _) | Warning => {
1626
1611
spec. set_fg ( Some ( Color :: Yellow ) ) . set_intense ( cfg ! ( windows) ) ;
1627
1612
}
1628
1613
Note | OnceNote => {
@@ -1641,7 +1626,7 @@ impl Level {
1641
1626
match self {
1642
1627
Bug | DelayedBug => "error: internal compiler error" ,
1643
1628
Fatal | Error => "error" ,
1644
- Warning ( _) => "warning" ,
1629
+ ForceWarning ( _) | Warning => "warning" ,
1645
1630
Note | OnceNote => "note" ,
1646
1631
Help | OnceHelp => "help" ,
1647
1632
FailureNote => "failure-note" ,
@@ -1655,7 +1640,7 @@ impl Level {
1655
1640
1656
1641
pub fn get_expectation_id ( & self ) -> Option < LintExpectationId > {
1657
1642
match self {
1658
- Expect ( id) | Warning ( Some ( id) ) => Some ( * id) ,
1643
+ Expect ( id) | ForceWarning ( Some ( id) ) => Some ( * id) ,
1659
1644
_ => None ,
1660
1645
}
1661
1646
}
0 commit comments