@@ -448,9 +448,13 @@ struct DiagCtxtInner {
448448
449449 emitter : Box < DynEmitter > ,
450450 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+
452456 /// 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.
454458 suppressed_expected_diag : bool ,
455459
456460 /// 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)) {
531535pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
532536 AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
533537
534- enum DelayedBugKind {
535- Normal ,
536- GoodPath ,
537- }
538-
539538#[ derive( Copy , Clone , Default ) ]
540539pub struct DiagCtxtFlags {
541540 /// If false, warning-level lints are suppressed.
@@ -561,11 +560,16 @@ impl Drop for DiagCtxtInner {
561560 self . emit_stashed_diagnostics ( ) ;
562561
563562 if !self . has_errors ( ) {
564- self . flush_delayed ( DelayedBugKind :: Normal )
563+ self . flush_delayed ( )
565564 }
566565
567566 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+ }
569573 }
570574
571575 if self . check_unstable_expect_diagnostics {
@@ -612,7 +616,7 @@ impl DiagCtxt {
612616 has_printed : false ,
613617 emitter,
614618 delayed_bugs : Vec :: new ( ) ,
615- good_path_delayed_bugs : Vec :: new ( ) ,
619+ must_produce_diag : false ,
616620 suppressed_expected_diag : false ,
617621 taught_diagnostics : Default :: default ( ) ,
618622 emitted_diagnostic_codes : Default :: default ( ) ,
@@ -670,7 +674,7 @@ impl DiagCtxt {
670674
671675 // actually free the underlying memory (which `clear` would not do)
672676 inner. delayed_bugs = Default :: default ( ) ;
673- inner. good_path_delayed_bugs = Default :: default ( ) ;
677+ inner. must_produce_diag = false ;
674678 inner. taught_diagnostics = Default :: default ( ) ;
675679 inner. emitted_diagnostic_codes = Default :: default ( ) ;
676680 inner. emitted_diagnostics = Default :: default ( ) ;
@@ -883,9 +887,10 @@ impl DiagCtxt {
883887 DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug , msg) . with_span ( sp) . emit ( )
884888 }
885889
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 ;
889894 }
890895
891896 #[ track_caller]
@@ -1225,7 +1230,7 @@ impl DiagCtxt {
12251230 }
12261231
12271232 pub fn flush_delayed ( & self ) {
1228- self . inner . borrow_mut ( ) . flush_delayed ( DelayedBugKind :: Normal ) ;
1233+ self . inner . borrow_mut ( ) . flush_delayed ( ) ;
12291234 }
12301235}
12311236
@@ -1275,14 +1280,12 @@ impl DiagCtxtInner {
12751280 if diagnostic. has_future_breakage ( ) {
12761281 // Future breakages aren't emitted if they're Level::Allow,
12771282 // 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.
12791284 self . suppressed_expected_diag = true ;
12801285 self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
12811286 }
12821287
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 {
12861289 diagnostic. level = Error ;
12871290 }
12881291
@@ -1302,12 +1305,6 @@ impl DiagCtxtInner {
13021305 #[ allow( deprecated) ]
13031306 return Some ( ErrorGuaranteed :: unchecked_error_guaranteed ( ) ) ;
13041307 }
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- }
13111308 Warning if !self . flags . can_emit_warnings => {
13121309 if diagnostic. has_future_breakage ( ) {
13131310 ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
@@ -1409,19 +1406,8 @@ impl DiagCtxtInner {
14091406 self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
14101407 }
14111408
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 ) ;
14251411 if bugs. is_empty ( ) {
14261412 return ;
14271413 }
@@ -1449,6 +1435,8 @@ impl DiagCtxtInner {
14491435 // frame them better (e.g. separate warnings from them). Also,
14501436 // make it a note so it doesn't count as an error, because that
14511437 // 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" ;
14521440 self . emit_diagnostic ( Diagnostic :: new ( Note , note1) ) ;
14531441 self . emit_diagnostic ( Diagnostic :: new ( Note , note2) ) ;
14541442 }
@@ -1457,7 +1445,7 @@ impl DiagCtxtInner {
14571445 if backtrace || self . ice_file . is_none ( ) { bug. decorate ( ) } else { bug. inner } ;
14581446
14591447 // "Undelay" the delayed bugs (into plain `Bug`s).
1460- if ! matches ! ( bug. level, DelayedBug | GoodPathDelayedBug ) {
1448+ if bug. level != DelayedBug {
14611449 // NOTE(eddyb) not panicking here because we're already producing
14621450 // an ICE, and the more information the merrier.
14631451 bug. subdiagnostic ( InvalidFlushedDelayedDiagnosticLevel {
@@ -1529,7 +1517,6 @@ impl DelayedDiagnostic {
15291517/// Fatal yes FatalAbort/FatalError(*) yes - -
15301518/// Error yes ErrorGuaranteed yes - yes
15311519/// DelayedBug yes ErrorGuaranteed yes - -
1532- /// GoodPathDelayedBug - () yes - -
15331520/// ForceWarning - () yes - lint-only
15341521/// Warning - () yes yes yes
15351522/// Note - () rare yes -
@@ -1562,20 +1549,6 @@ pub enum Level {
15621549 /// that should only be reached when compiling erroneous code.
15631550 DelayedBug ,
15641551
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-
15791552 /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
15801553 /// from finishing.
15811554 ///
@@ -1619,7 +1592,7 @@ impl Level {
16191592 fn color ( self ) -> ColorSpec {
16201593 let mut spec = ColorSpec :: new ( ) ;
16211594 match self {
1622- Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => {
1595+ Bug | Fatal | Error | DelayedBug => {
16231596 spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
16241597 }
16251598 ForceWarning ( _) | Warning => {
@@ -1639,7 +1612,7 @@ impl Level {
16391612
16401613 pub fn to_str ( self ) -> & ' static str {
16411614 match self {
1642- Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error" ,
1615+ Bug | DelayedBug => "error: internal compiler error" ,
16431616 Fatal | Error => "error" ,
16441617 ForceWarning ( _) | Warning => "warning" ,
16451618 Note | OnceNote => "note" ,
@@ -1664,8 +1637,8 @@ impl Level {
16641637 // subdiagnostic message?
16651638 fn can_be_top_or_sub ( & self ) -> ( bool , bool ) {
16661639 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 ) ,
16691642
16701643 Warning | Note | Help => ( true , true ) ,
16711644
0 commit comments