@@ -436,7 +436,6 @@ struct DiagCtxtInner {
436
436
lint_err_guars : Vec < ErrorGuaranteed > ,
437
437
/// The delayed bugs and their error guarantees.
438
438
delayed_bugs : Vec < ( DelayedDiagnostic , ErrorGuaranteed ) > ,
439
- good_path_delayed_bugs : Vec < DelayedDiagnostic > ,
440
439
441
440
/// The number of stashed errors. Unlike the other counts, this can go up
442
441
/// and down, so it doesn't guarantee anything.
@@ -447,13 +446,18 @@ struct DiagCtxtInner {
447
446
/// The warning count shown to the user at the end.
448
447
deduplicated_warn_count : usize ,
449
448
449
+ emitter : Box < DynEmitter > ,
450
+
451
+ /// Must we produce a diagnostic to justify the use of the expensive
452
+ /// `trimmed_def_paths` function?
453
+ must_produce_diag : bool ,
454
+
450
455
/// Has this diagnostic context printed any diagnostics? (I.e. has
451
456
/// `self.emitter.emit_diagnostic()` been called?
452
457
has_printed : bool ,
453
458
454
- emitter : Box < DynEmitter > ,
455
459
/// This flag indicates that an expected diagnostic was emitted and suppressed.
456
- /// This is used for the `good_path_delayed_bugs ` check.
460
+ /// This is used for the `must_produce_diag ` check.
457
461
suppressed_expected_diag : bool ,
458
462
459
463
/// This set contains the code of all emitted diagnostics to avoid
@@ -534,11 +538,6 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
534
538
pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
535
539
AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
536
540
537
- enum DelayedBugKind {
538
- Normal ,
539
- GoodPath ,
540
- }
541
-
542
541
#[ derive( Copy , Clone , Default ) ]
543
542
pub struct DiagCtxtFlags {
544
543
/// If false, warning-level lints are suppressed.
@@ -564,11 +563,16 @@ impl Drop for DiagCtxtInner {
564
563
self . emit_stashed_diagnostics ( ) ;
565
564
566
565
if self . err_guars . is_empty ( ) {
567
- self . flush_delayed ( DelayedBugKind :: Normal )
566
+ self . flush_delayed ( )
568
567
}
569
568
570
569
if !self . has_printed && !self . suppressed_expected_diag && !std:: thread:: panicking ( ) {
571
- self . flush_delayed ( DelayedBugKind :: GoodPath ) ;
570
+ if self . must_produce_diag {
571
+ panic ! (
572
+ "must_produce_diag: trimmed_def_paths called but no diagnostics emitted; \
573
+ use `DelayDm` for lints or `with_no_trimmed_paths` for debugging"
574
+ ) ;
575
+ }
572
576
}
573
577
574
578
if self . check_unstable_expect_diagnostics {
@@ -610,12 +614,12 @@ impl DiagCtxt {
610
614
err_guars : Vec :: new ( ) ,
611
615
lint_err_guars : Vec :: new ( ) ,
612
616
delayed_bugs : Vec :: new ( ) ,
613
- good_path_delayed_bugs : Vec :: new ( ) ,
614
617
stashed_err_count : 0 ,
615
618
deduplicated_err_count : 0 ,
616
619
deduplicated_warn_count : 0 ,
617
- has_printed : false ,
618
620
emitter,
621
+ must_produce_diag : false ,
622
+ has_printed : false ,
619
623
suppressed_expected_diag : false ,
620
624
taught_diagnostics : Default :: default ( ) ,
621
625
emitted_diagnostic_codes : Default :: default ( ) ,
@@ -667,13 +671,14 @@ impl DiagCtxt {
667
671
inner. stashed_err_count = 0 ;
668
672
inner. deduplicated_err_count = 0 ;
669
673
inner. deduplicated_warn_count = 0 ;
674
+ inner. must_produce_diag = false ;
670
675
inner. has_printed = false ;
676
+ inner. suppressed_expected_diag = false ;
671
677
672
678
// actually free the underlying memory (which `clear` would not do)
673
679
inner. err_guars = Default :: default ( ) ;
674
680
inner. lint_err_guars = Default :: default ( ) ;
675
681
inner. delayed_bugs = Default :: default ( ) ;
676
- inner. good_path_delayed_bugs = Default :: default ( ) ;
677
682
inner. taught_diagnostics = Default :: default ( ) ;
678
683
inner. emitted_diagnostic_codes = Default :: default ( ) ;
679
684
inner. emitted_diagnostics = Default :: default ( ) ;
@@ -935,7 +940,13 @@ impl DiagCtxt {
935
940
}
936
941
937
942
pub fn flush_delayed ( & self ) {
938
- self . inner . borrow_mut ( ) . flush_delayed ( DelayedBugKind :: Normal ) ;
943
+ self . inner . borrow_mut ( ) . flush_delayed ( ) ;
944
+ }
945
+
946
+ /// Used when trimmed_def_paths is called and we must produce a diagnostic
947
+ /// to justify its cost.
948
+ pub fn set_must_produce_diag ( & self ) {
949
+ self . inner . borrow_mut ( ) . must_produce_diag = true ;
939
950
}
940
951
}
941
952
@@ -1109,13 +1120,6 @@ impl DiagCtxt {
1109
1120
DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug , msg) . with_span ( sp) . emit ( )
1110
1121
}
1111
1122
1112
- /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`.
1113
- // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing.
1114
- #[ track_caller]
1115
- pub fn good_path_delayed_bug ( & self , msg : impl Into < DiagnosticMessage > ) {
1116
- DiagnosticBuilder :: < ( ) > :: new ( self , GoodPathDelayedBug , msg) . emit ( )
1117
- }
1118
-
1119
1123
#[ rustc_lint_diagnostics]
1120
1124
#[ track_caller]
1121
1125
pub fn struct_warn ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
@@ -1267,19 +1271,17 @@ impl DiagCtxtInner {
1267
1271
if diagnostic. has_future_breakage ( ) {
1268
1272
// Future breakages aren't emitted if they're Level::Allow,
1269
1273
// but they still need to be constructed and stashed below,
1270
- // so they'll trigger the good-path bug check.
1274
+ // so they'll trigger the must_produce_diag check.
1271
1275
self . suppressed_expected_diag = true ;
1272
1276
self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
1273
1277
}
1274
1278
1275
- if matches ! ( diagnostic. level, DelayedBug | GoodPathDelayedBug )
1276
- && self . flags . eagerly_emit_delayed_bugs
1277
- {
1279
+ if diagnostic. level == DelayedBug && self . flags . eagerly_emit_delayed_bugs {
1278
1280
diagnostic. level = Error ;
1279
1281
}
1280
1282
1281
1283
match diagnostic. level {
1282
- // This must come after the possible promotion of `DelayedBug`/`GoodPathDelayedBug` to
1284
+ // This must come after the possible promotion of `DelayedBug` to
1283
1285
// `Error` above.
1284
1286
Fatal | Error if self . treat_next_err_as_bug ( ) => {
1285
1287
diagnostic. level = Bug ;
@@ -1298,12 +1300,6 @@ impl DiagCtxtInner {
1298
1300
. push ( ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) , guar) ) ;
1299
1301
return Some ( guar) ;
1300
1302
}
1301
- GoodPathDelayedBug => {
1302
- let backtrace = std:: backtrace:: Backtrace :: capture ( ) ;
1303
- self . good_path_delayed_bugs
1304
- . push ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) ) ;
1305
- return None ;
1306
- }
1307
1303
Warning if !self . flags . can_emit_warnings => {
1308
1304
if diagnostic. has_future_breakage ( ) {
1309
1305
( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
@@ -1415,23 +1411,14 @@ impl DiagCtxtInner {
1415
1411
self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
1416
1412
}
1417
1413
1418
- fn flush_delayed ( & mut self , kind : DelayedBugKind ) {
1419
- let ( bugs, note1) = match kind {
1420
- DelayedBugKind :: Normal => (
1421
- std:: mem:: take ( & mut self . delayed_bugs ) . into_iter ( ) . map ( |( b, _) | b) . collect ( ) ,
1422
- "no errors encountered even though delayed bugs were created" ,
1423
- ) ,
1424
- DelayedBugKind :: GoodPath => (
1425
- std:: mem:: take ( & mut self . good_path_delayed_bugs ) ,
1426
- "no warnings or errors encountered even though good path delayed bugs were created" ,
1427
- ) ,
1428
- } ;
1429
- let note2 = "those delayed bugs will now be shown as internal compiler errors" ;
1430
-
1431
- if bugs. is_empty ( ) {
1414
+ fn flush_delayed ( & mut self ) {
1415
+ if self . delayed_bugs . is_empty ( ) {
1432
1416
return ;
1433
1417
}
1434
1418
1419
+ let bugs: Vec < _ > =
1420
+ std:: mem:: take ( & mut self . delayed_bugs ) . into_iter ( ) . map ( |( b, _) | b) . collect ( ) ;
1421
+
1435
1422
// If backtraces are enabled, also print the query stack
1436
1423
let backtrace = std:: env:: var_os ( "RUST_BACKTRACE" ) . map_or ( true , |x| & x != "0" ) ;
1437
1424
for ( i, bug) in bugs. into_iter ( ) . enumerate ( ) {
@@ -1455,6 +1442,8 @@ impl DiagCtxtInner {
1455
1442
// frame them better (e.g. separate warnings from them). Also,
1456
1443
// make it a note so it doesn't count as an error, because that
1457
1444
// could trigger `-Ztreat-err-as-bug`, which we don't want.
1445
+ let note1 = "no errors encountered even though delayed bugs were created" ;
1446
+ let note2 = "those delayed bugs will now be shown as internal compiler errors" ;
1458
1447
self . emit_diagnostic ( Diagnostic :: new ( Note , note1) ) ;
1459
1448
self . emit_diagnostic ( Diagnostic :: new ( Note , note2) ) ;
1460
1449
}
@@ -1463,7 +1452,7 @@ impl DiagCtxtInner {
1463
1452
if backtrace || self . ice_file . is_none ( ) { bug. decorate ( ) } else { bug. inner } ;
1464
1453
1465
1454
// "Undelay" the delayed bugs (into plain `Bug`s).
1466
- if ! matches ! ( bug. level, DelayedBug | GoodPathDelayedBug ) {
1455
+ if bug. level != DelayedBug {
1467
1456
// NOTE(eddyb) not panicking here because we're already producing
1468
1457
// an ICE, and the more information the merrier.
1469
1458
bug. subdiagnostic ( InvalidFlushedDelayedDiagnosticLevel {
@@ -1535,7 +1524,6 @@ impl DelayedDiagnostic {
1535
1524
/// Fatal yes FatalAbort/FatalError(*) yes - -
1536
1525
/// Error yes ErrorGuaranteed yes - yes
1537
1526
/// DelayedBug yes ErrorGuaranteed yes - -
1538
- /// GoodPathDelayedBug - () yes - -
1539
1527
/// ForceWarning - () yes - lint-only
1540
1528
/// Warning - () yes yes yes
1541
1529
/// Note - () rare yes -
@@ -1568,20 +1556,6 @@ pub enum Level {
1568
1556
/// that should only be reached when compiling erroneous code.
1569
1557
DelayedBug ,
1570
1558
1571
- /// Like `DelayedBug`, but weaker: lets you register an error without emitting it. If
1572
- /// compilation ends without any other diagnostics being emitted (and without an expected lint
1573
- /// being suppressed), this will be emitted as a bug. Otherwise, it will be silently dropped.
1574
- /// I.e. "expect other diagnostics are emitted (or suppressed)" semantics. Useful on code paths
1575
- /// that should only be reached when emitting diagnostics, e.g. for expensive one-time
1576
- /// diagnostic formatting operations.
1577
- ///
1578
- /// FIXME(nnethercote) good path delayed bugs are semantically strange: if printed they produce
1579
- /// an ICE, but they don't satisfy `is_error` and they don't guarantee an error is emitted.
1580
- /// Plus there's the extra complication with expected (suppressed) lints. They have limited
1581
- /// use, and are used in very few places, and "good path" isn't a good name. It would be good
1582
- /// to remove them.
1583
- GoodPathDelayedBug ,
1584
-
1585
1559
/// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
1586
1560
/// from finishing.
1587
1561
///
@@ -1626,7 +1600,7 @@ impl Level {
1626
1600
fn color ( self ) -> ColorSpec {
1627
1601
let mut spec = ColorSpec :: new ( ) ;
1628
1602
match self {
1629
- Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => {
1603
+ Bug | Fatal | Error | DelayedBug => {
1630
1604
spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
1631
1605
}
1632
1606
ForceWarning ( _) | Warning => {
@@ -1646,7 +1620,7 @@ impl Level {
1646
1620
1647
1621
pub fn to_str ( self ) -> & ' static str {
1648
1622
match self {
1649
- Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error" ,
1623
+ Bug | DelayedBug => "error: internal compiler error" ,
1650
1624
Fatal | Error => "error" ,
1651
1625
ForceWarning ( _) | Warning => "warning" ,
1652
1626
Note | OnceNote => "note" ,
@@ -1671,8 +1645,8 @@ impl Level {
1671
1645
// subdiagnostic message?
1672
1646
fn can_be_top_or_sub ( & self ) -> ( bool , bool ) {
1673
1647
match self {
1674
- Bug | DelayedBug | Fatal | Error | GoodPathDelayedBug | ForceWarning ( _)
1675
- | FailureNote | Allow | Expect ( _) => ( true , false ) ,
1648
+ Bug | DelayedBug | Fatal | Error | ForceWarning ( _) | FailureNote | Allow
1649
+ | Expect ( _) => ( true , false ) ,
1676
1650
1677
1651
Warning | Note | Help => ( true , true ) ,
1678
1652
0 commit comments