@@ -519,7 +519,8 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
519
519
pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
520
520
AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
521
521
522
- enum DelayedBugKind {
522
+ #[ derive( Copy , PartialEq , Eq , Clone , Hash , Debug , Encodable , Decodable ) ]
523
+ pub enum DelayedBugKind {
523
524
Normal ,
524
525
GoodPath ,
525
526
}
@@ -865,7 +866,8 @@ impl DiagCtxt {
865
866
if treat_next_err_as_bug {
866
867
self . bug ( msg) ;
867
868
}
868
- DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug , msg) . emit ( )
869
+ DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug ( DelayedBugKind :: Normal ) , msg)
870
+ . emit ( )
869
871
}
870
872
871
873
/// Like `delayed_bug`, but takes an additional span.
@@ -882,16 +884,15 @@ impl DiagCtxt {
882
884
if treat_next_err_as_bug {
883
885
self . span_bug ( sp, msg) ;
884
886
}
885
- DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug , msg) . with_span ( sp) . emit ( )
887
+ DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug ( DelayedBugKind :: Normal ) , msg)
888
+ . with_span ( sp)
889
+ . emit ( )
886
890
}
887
891
888
892
// FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's
889
893
// where the explanation of what "good path" is (also, it should be renamed).
890
894
pub fn good_path_delayed_bug ( & self , msg : impl Into < DiagnosticMessage > ) {
891
- let mut inner = self . inner . borrow_mut ( ) ;
892
- let diagnostic = Diagnostic :: new ( DelayedBug , msg) ;
893
- let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
894
- inner. good_path_delayed_bugs . push ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) ) ;
895
+ DiagnosticBuilder :: < ( ) > :: new ( self , DelayedBug ( DelayedBugKind :: GoodPath ) , msg) . emit ( )
895
896
}
896
897
897
898
#[ track_caller]
@@ -1268,17 +1269,27 @@ impl DiagCtxtInner {
1268
1269
return None ;
1269
1270
}
1270
1271
1271
- if diagnostic. level == DelayedBug {
1272
- // FIXME(eddyb) this should check for `has_errors` and stop pushing
1273
- // once *any* errors were emitted (and truncate `span_delayed_bugs`
1274
- // when an error is first emitted, also), but maybe there's a case
1275
- // in which that's not sound? otherwise this is really inefficient.
1276
- let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
1277
- self . span_delayed_bugs
1278
- . push ( DelayedDiagnostic :: with_backtrace ( diagnostic. clone ( ) , backtrace) ) ;
1272
+ // FIXME(eddyb) this should check for `has_errors` and stop pushing
1273
+ // once *any* errors were emitted (and truncate `span_delayed_bugs`
1274
+ // when an error is first emitted, also), but maybe there's a case
1275
+ // in which that's not sound? otherwise this is really inefficient.
1276
+ match diagnostic. level {
1277
+ DelayedBug ( DelayedBugKind :: Normal ) => {
1278
+ let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
1279
+ self . span_delayed_bugs
1280
+ . push ( DelayedDiagnostic :: with_backtrace ( diagnostic. clone ( ) , backtrace) ) ;
1279
1281
1280
- #[ allow( deprecated) ]
1281
- return Some ( ErrorGuaranteed :: unchecked_claim_error_was_emitted ( ) ) ;
1282
+ #[ allow( deprecated) ]
1283
+ return Some ( ErrorGuaranteed :: unchecked_claim_error_was_emitted ( ) ) ;
1284
+ }
1285
+ DelayedBug ( DelayedBugKind :: GoodPath ) => {
1286
+ let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
1287
+ self . good_path_delayed_bugs
1288
+ . push ( DelayedDiagnostic :: with_backtrace ( diagnostic. clone ( ) , backtrace) ) ;
1289
+
1290
+ return None ;
1291
+ }
1292
+ _ => { }
1282
1293
}
1283
1294
1284
1295
if diagnostic. has_future_breakage ( ) {
@@ -1438,7 +1449,7 @@ impl DiagCtxtInner {
1438
1449
if backtrace || self . ice_file . is_none ( ) { bug. decorate ( ) } else { bug. inner } ;
1439
1450
1440
1451
// "Undelay" the `DelayedBug`s (into plain `Bug`s).
1441
- if bug. level != DelayedBug {
1452
+ if ! matches ! ( bug. level, DelayedBug ( _ ) ) {
1442
1453
// NOTE(eddyb) not panicking here because we're already producing
1443
1454
// an ICE, and the more information the merrier.
1444
1455
bug. subdiagnostic ( InvalidFlushedDelayedDiagnosticLevel {
@@ -1526,8 +1537,9 @@ pub enum Level {
1526
1537
/// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
1527
1538
/// that should only be reached when compiling erroneous code.
1528
1539
///
1529
- /// Its `EmissionGuarantee` is `ErrorGuaranteed`.
1530
- DelayedBug ,
1540
+ /// Its `EmissionGuarantee` is `ErrorGuaranteed` for `Normal` delayed bugs, and `()` for
1541
+ /// `GoodPath` delayed bugs.
1542
+ DelayedBug ( DelayedBugKind ) ,
1531
1543
1532
1544
/// An error that causes an immediate abort. Used for things like configuration errors,
1533
1545
/// internal overflows, some file operation errors.
@@ -1602,7 +1614,7 @@ impl Level {
1602
1614
fn color ( self ) -> ColorSpec {
1603
1615
let mut spec = ColorSpec :: new ( ) ;
1604
1616
match self {
1605
- Bug | DelayedBug | Fatal | Error => {
1617
+ Bug | DelayedBug ( _ ) | Fatal | Error => {
1606
1618
spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
1607
1619
}
1608
1620
ForceWarning ( _) | Warning => {
@@ -1622,7 +1634,7 @@ impl Level {
1622
1634
1623
1635
pub fn to_str ( self ) -> & ' static str {
1624
1636
match self {
1625
- Bug | DelayedBug => "error: internal compiler error" ,
1637
+ Bug | DelayedBug ( _ ) => "error: internal compiler error" ,
1626
1638
Fatal | Error => "error" ,
1627
1639
ForceWarning ( _) | Warning => "warning" ,
1628
1640
Note | OnceNote => "note" ,
0 commit comments