@@ -448,9 +448,13 @@ struct DiagCtxtInner {
448
448
449
449
emitter : Box < DynEmitter > ,
450
450
delayed_bugs : Vec < DelayedDiagnostic > ,
451
- good_path_delayed_bugs : Vec < DelayedDiagnostic > ,
451
+
452
+ /// Must we produce a diagnostic to justify the use of the expensive
453
+ /// `trimmed_def_paths` function?
454
+ must_produce_diag : bool ,
455
+
452
456
/// This flag indicates that an expected diagnostic was emitted and suppressed.
453
- /// This is used for the `good_path_delayed_bugs ` check.
457
+ /// This is used for the `must_produce_diag ` check.
454
458
suppressed_expected_diag : bool ,
455
459
456
460
/// This set contains the code of all emitted diagnostics to avoid
@@ -531,11 +535,6 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
531
535
pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
532
536
AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
533
537
534
- enum DelayedBugKind {
535
- Normal ,
536
- GoodPath ,
537
- }
538
-
539
538
#[ derive( Copy , Clone , Default ) ]
540
539
pub struct DiagCtxtFlags {
541
540
/// If false, warning-level lints are suppressed.
@@ -561,11 +560,16 @@ impl Drop for DiagCtxtInner {
561
560
self . emit_stashed_diagnostics ( ) ;
562
561
563
562
if !self . has_errors ( ) {
564
- self . flush_delayed ( DelayedBugKind :: Normal )
563
+ self . flush_delayed ( )
565
564
}
566
565
567
566
if !self . has_printed && !self . suppressed_expected_diag && !std:: thread:: panicking ( ) {
568
- self . flush_delayed ( DelayedBugKind :: GoodPath ) ;
567
+ if self . must_produce_diag {
568
+ panic ! (
569
+ "must_produce_diag: trimmed_def_paths called but no diagnostics emitted; \
570
+ use `DelayDm` for lints or `with_no_trimmed_paths` for debugging"
571
+ ) ;
572
+ }
569
573
}
570
574
571
575
if self . check_unstable_expect_diagnostics {
@@ -612,7 +616,7 @@ impl DiagCtxt {
612
616
has_printed : false ,
613
617
emitter,
614
618
delayed_bugs : Vec :: new ( ) ,
615
- good_path_delayed_bugs : Vec :: new ( ) ,
619
+ must_produce_diag : false ,
616
620
suppressed_expected_diag : false ,
617
621
taught_diagnostics : Default :: default ( ) ,
618
622
emitted_diagnostic_codes : Default :: default ( ) ,
@@ -670,7 +674,7 @@ impl DiagCtxt {
670
674
671
675
// actually free the underlying memory (which `clear` would not do)
672
676
inner. delayed_bugs = Default :: default ( ) ;
673
- inner. good_path_delayed_bugs = Default :: default ( ) ;
677
+ inner. must_produce_diag = false ;
674
678
inner. taught_diagnostics = Default :: default ( ) ;
675
679
inner. emitted_diagnostic_codes = Default :: default ( ) ;
676
680
inner. emitted_diagnostics = Default :: default ( ) ;
@@ -883,9 +887,10 @@ impl DiagCtxt {
883
887
DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug , msg) . with_span ( sp) . emit ( )
884
888
}
885
889
886
- /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`.
887
- pub fn good_path_delayed_bug ( & self , msg : impl Into < DiagnosticMessage > ) {
888
- DiagnosticBuilder :: < ( ) > :: new ( self , GoodPathDelayedBug , msg) . emit ( )
890
+ /// Used when trimmed_def_paths is called and we must produce a diagnostic
891
+ /// to justify its cost.
892
+ pub fn set_must_produce_diag ( & self ) {
893
+ self . inner . borrow_mut ( ) . must_produce_diag = true ;
889
894
}
890
895
891
896
#[ track_caller]
@@ -1225,7 +1230,7 @@ impl DiagCtxt {
1225
1230
}
1226
1231
1227
1232
pub fn flush_delayed ( & self ) {
1228
- self . inner . borrow_mut ( ) . flush_delayed ( DelayedBugKind :: Normal ) ;
1233
+ self . inner . borrow_mut ( ) . flush_delayed ( ) ;
1229
1234
}
1230
1235
}
1231
1236
@@ -1275,14 +1280,12 @@ impl DiagCtxtInner {
1275
1280
if diagnostic. has_future_breakage ( ) {
1276
1281
// Future breakages aren't emitted if they're Level::Allow,
1277
1282
// but they still need to be constructed and stashed below,
1278
- // so they'll trigger the good-path bug check.
1283
+ // so they'll trigger the must_produce_diag check.
1279
1284
self . suppressed_expected_diag = true ;
1280
1285
self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
1281
1286
}
1282
1287
1283
- if matches ! ( diagnostic. level, DelayedBug | GoodPathDelayedBug )
1284
- && self . flags . eagerly_emit_delayed_bugs
1285
- {
1288
+ if diagnostic. level == DelayedBug && self . flags . eagerly_emit_delayed_bugs {
1286
1289
diagnostic. level = Error ;
1287
1290
}
1288
1291
@@ -1302,12 +1305,6 @@ impl DiagCtxtInner {
1302
1305
#[ allow( deprecated) ]
1303
1306
return Some ( ErrorGuaranteed :: unchecked_error_guaranteed ( ) ) ;
1304
1307
}
1305
- GoodPathDelayedBug => {
1306
- let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
1307
- self . good_path_delayed_bugs
1308
- . push ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) ) ;
1309
- return None ;
1310
- }
1311
1308
Warning if !self . flags . can_emit_warnings => {
1312
1309
if diagnostic. has_future_breakage ( ) {
1313
1310
( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
@@ -1409,19 +1406,8 @@ impl DiagCtxtInner {
1409
1406
self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
1410
1407
}
1411
1408
1412
- fn flush_delayed ( & mut self , kind : DelayedBugKind ) {
1413
- let ( bugs, note1) = match kind {
1414
- DelayedBugKind :: Normal => (
1415
- std:: mem:: take ( & mut self . delayed_bugs ) ,
1416
- "no errors encountered even though delayed bugs were created" ,
1417
- ) ,
1418
- DelayedBugKind :: GoodPath => (
1419
- std:: mem:: take ( & mut self . good_path_delayed_bugs ) ,
1420
- "no warnings or errors encountered even though good path delayed bugs were created" ,
1421
- ) ,
1422
- } ;
1423
- let note2 = "those delayed bugs will now be shown as internal compiler errors" ;
1424
-
1409
+ fn flush_delayed ( & mut self ) {
1410
+ let bugs = std:: mem:: take ( & mut self . delayed_bugs ) ;
1425
1411
if bugs. is_empty ( ) {
1426
1412
return ;
1427
1413
}
@@ -1449,6 +1435,8 @@ impl DiagCtxtInner {
1449
1435
// frame them better (e.g. separate warnings from them). Also,
1450
1436
// make it a note so it doesn't count as an error, because that
1451
1437
// could trigger `-Ztreat-err-as-bug`, which we don't want.
1438
+ let note1 = "no errors encountered even though delayed bugs were created" ;
1439
+ let note2 = "those delayed bugs will now be shown as internal compiler errors" ;
1452
1440
self . emit_diagnostic ( Diagnostic :: new ( Note , note1) ) ;
1453
1441
self . emit_diagnostic ( Diagnostic :: new ( Note , note2) ) ;
1454
1442
}
@@ -1457,7 +1445,7 @@ impl DiagCtxtInner {
1457
1445
if backtrace || self . ice_file . is_none ( ) { bug. decorate ( ) } else { bug. inner } ;
1458
1446
1459
1447
// "Undelay" the delayed bugs (into plain `Bug`s).
1460
- if ! matches ! ( bug. level, DelayedBug | GoodPathDelayedBug ) {
1448
+ if bug. level != DelayedBug {
1461
1449
// NOTE(eddyb) not panicking here because we're already producing
1462
1450
// an ICE, and the more information the merrier.
1463
1451
bug. subdiagnostic ( InvalidFlushedDelayedDiagnosticLevel {
@@ -1529,7 +1517,6 @@ impl DelayedDiagnostic {
1529
1517
/// Fatal yes FatalAbort/FatalError(*) yes - -
1530
1518
/// Error yes ErrorGuaranteed yes - yes
1531
1519
/// DelayedBug yes ErrorGuaranteed yes - -
1532
- /// GoodPathDelayedBug - () yes - -
1533
1520
/// ForceWarning - () yes - lint-only
1534
1521
/// Warning - () yes yes yes
1535
1522
/// Note - () rare yes -
@@ -1562,20 +1549,6 @@ pub enum Level {
1562
1549
/// that should only be reached when compiling erroneous code.
1563
1550
DelayedBug ,
1564
1551
1565
- /// Like `DelayedBug`, but weaker: lets you register an error without emitting it. If
1566
- /// compilation ends without any other diagnostics being emitted (and without an expected lint
1567
- /// being suppressed), this will be emitted as a bug. Otherwise, it will be silently dropped.
1568
- /// I.e. "expect other diagnostics are emitted (or suppressed)" semantics. Useful on code paths
1569
- /// that should only be reached when emitting diagnostics, e.g. for expensive one-time
1570
- /// diagnostic formatting operations.
1571
- ///
1572
- /// FIXME(nnethercote) good path delayed bugs are semantically strange: if printed they produce
1573
- /// an ICE, but they don't satisfy `is_error` and they don't guarantee an error is emitted.
1574
- /// Plus there's the extra complication with expected (suppressed) lints. They have limited
1575
- /// use, and are used in very few places, and "good path" isn't a good name. It would be good
1576
- /// to remove them.
1577
- GoodPathDelayedBug ,
1578
-
1579
1552
/// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
1580
1553
/// from finishing.
1581
1554
///
@@ -1619,7 +1592,7 @@ impl Level {
1619
1592
fn color ( self ) -> ColorSpec {
1620
1593
let mut spec = ColorSpec :: new ( ) ;
1621
1594
match self {
1622
- Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => {
1595
+ Bug | Fatal | Error | DelayedBug => {
1623
1596
spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
1624
1597
}
1625
1598
ForceWarning ( _) | Warning => {
@@ -1639,7 +1612,7 @@ impl Level {
1639
1612
1640
1613
pub fn to_str ( self ) -> & ' static str {
1641
1614
match self {
1642
- Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error" ,
1615
+ Bug | DelayedBug => "error: internal compiler error" ,
1643
1616
Fatal | Error => "error" ,
1644
1617
ForceWarning ( _) | Warning => "warning" ,
1645
1618
Note | OnceNote => "note" ,
@@ -1664,8 +1637,8 @@ impl Level {
1664
1637
// subdiagnostic message?
1665
1638
fn can_be_top_or_sub ( & self ) -> ( bool , bool ) {
1666
1639
match self {
1667
- Bug | DelayedBug | Fatal | Error | GoodPathDelayedBug | ForceWarning ( _)
1668
- | FailureNote | Allow | Expect ( _) => ( true , false ) ,
1640
+ Bug | DelayedBug | Fatal | Error | ForceWarning ( _) | FailureNote | Allow
1641
+ | Expect ( _) => ( true , false ) ,
1669
1642
1670
1643
Warning | Note | Help => ( true , true ) ,
1671
1644
0 commit comments