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