@@ -435,7 +435,6 @@ struct DiagCtxtInner {
435435 lint_err_guars : Vec < ErrorGuaranteed > ,
436436 /// The delayed bugs and their error guarantees.
437437 delayed_bugs : Vec < ( DelayedDiagnostic , ErrorGuaranteed ) > ,
438- good_path_delayed_bugs : Vec < DelayedDiagnostic > ,
439438
440439 /// The number of stashed errors. Unlike the other counts, this can go up
441440 /// and down, so it doesn't guarantee anything.
@@ -446,13 +445,18 @@ struct DiagCtxtInner {
446445 /// The warning count shown to the user at the end.
447446 deduplicated_warn_count : usize ,
448447
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+
449454 /// Has this diagnostic context printed any diagnostics? (I.e. has
450455 /// `self.emitter.emit_diagnostic()` been called?
451456 has_printed : bool ,
452457
453- emitter : Box < DynEmitter > ,
454458 /// 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.
456460 suppressed_expected_diag : bool ,
457461
458462 /// 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)) {
533537pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
534538 AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
535539
536- enum DelayedBugKind {
537- Normal ,
538- GoodPath ,
539- }
540-
541540#[ derive( Copy , Clone , Default ) ]
542541pub struct DiagCtxtFlags {
543542 /// If false, warning-level lints are suppressed.
@@ -563,11 +562,16 @@ impl Drop for DiagCtxtInner {
563562 self . emit_stashed_diagnostics ( ) ;
564563
565564 if self . err_guars . is_empty ( ) {
566- self . flush_delayed ( DelayedBugKind :: Normal )
565+ self . flush_delayed ( )
567566 }
568567
569568 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+ }
571575 }
572576
573577 if self . check_unstable_expect_diagnostics {
@@ -609,12 +613,12 @@ impl DiagCtxt {
609613 err_guars : Vec :: new ( ) ,
610614 lint_err_guars : Vec :: new ( ) ,
611615 delayed_bugs : Vec :: new ( ) ,
612- good_path_delayed_bugs : Vec :: new ( ) ,
613616 stashed_err_count : 0 ,
614617 deduplicated_err_count : 0 ,
615618 deduplicated_warn_count : 0 ,
616- has_printed : false ,
617619 emitter,
620+ must_produce_diag : false ,
621+ has_printed : false ,
618622 suppressed_expected_diag : false ,
619623 taught_diagnostics : Default :: default ( ) ,
620624 emitted_diagnostic_codes : Default :: default ( ) ,
@@ -666,13 +670,14 @@ impl DiagCtxt {
666670 inner. stashed_err_count = 0 ;
667671 inner. deduplicated_err_count = 0 ;
668672 inner. deduplicated_warn_count = 0 ;
673+ inner. must_produce_diag = false ;
669674 inner. has_printed = false ;
675+ inner. suppressed_expected_diag = false ;
670676
671677 // actually free the underlying memory (which `clear` would not do)
672678 inner. err_guars = Default :: default ( ) ;
673679 inner. lint_err_guars = Default :: default ( ) ;
674680 inner. delayed_bugs = Default :: default ( ) ;
675- inner. good_path_delayed_bugs = Default :: default ( ) ;
676681 inner. taught_diagnostics = Default :: default ( ) ;
677682 inner. emitted_diagnostic_codes = Default :: default ( ) ;
678683 inner. emitted_diagnostics = Default :: default ( ) ;
@@ -934,7 +939,13 @@ impl DiagCtxt {
934939 }
935940
936941 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 ;
938949 }
939950}
940951
@@ -1108,13 +1119,6 @@ impl DiagCtxt {
11081119 DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug , msg) . with_span ( sp) . emit ( )
11091120 }
11101121
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-
11181122 #[ rustc_lint_diagnostics]
11191123 #[ track_caller]
11201124 pub fn struct_warn ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
@@ -1266,19 +1270,17 @@ impl DiagCtxtInner {
12661270 if diagnostic. has_future_breakage ( ) {
12671271 // Future breakages aren't emitted if they're Level::Allow,
12681272 // 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.
12701274 self . suppressed_expected_diag = true ;
12711275 self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
12721276 }
12731277
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 {
12771279 diagnostic. level = Error ;
12781280 }
12791281
12801282 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
12821284 // `Error` above.
12831285 Fatal | Error if self . treat_next_err_as_bug ( ) => {
12841286 diagnostic. level = Bug ;
@@ -1297,12 +1299,6 @@ impl DiagCtxtInner {
12971299 . push ( ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) , guar) ) ;
12981300 return Some ( guar) ;
12991301 }
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- }
13061302 Warning if !self . flags . can_emit_warnings => {
13071303 if diagnostic. has_future_breakage ( ) {
13081304 ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
@@ -1414,23 +1410,14 @@ impl DiagCtxtInner {
14141410 self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
14151411 }
14161412
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 ( ) {
14311415 return ;
14321416 }
14331417
1418+ let bugs: Vec < _ > =
1419+ std:: mem:: take ( & mut self . delayed_bugs ) . into_iter ( ) . map ( |( b, _) | b) . collect ( ) ;
1420+
14341421 // If backtraces are enabled, also print the query stack
14351422 let backtrace = std:: env:: var_os ( "RUST_BACKTRACE" ) . map_or ( true , |x| & x != "0" ) ;
14361423 for ( i, bug) in bugs. into_iter ( ) . enumerate ( ) {
@@ -1454,6 +1441,8 @@ impl DiagCtxtInner {
14541441 // frame them better (e.g. separate warnings from them). Also,
14551442 // make it a note so it doesn't count as an error, because that
14561443 // 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" ;
14571446 self . emit_diagnostic ( Diagnostic :: new ( Note , note1) ) ;
14581447 self . emit_diagnostic ( Diagnostic :: new ( Note , note2) ) ;
14591448 }
@@ -1462,7 +1451,7 @@ impl DiagCtxtInner {
14621451 if backtrace || self . ice_file . is_none ( ) { bug. decorate ( ) } else { bug. inner } ;
14631452
14641453 // "Undelay" the delayed bugs (into plain `Bug`s).
1465- if ! matches ! ( bug. level, DelayedBug | GoodPathDelayedBug ) {
1454+ if bug. level != DelayedBug {
14661455 // NOTE(eddyb) not panicking here because we're already producing
14671456 // an ICE, and the more information the merrier.
14681457 bug. subdiagnostic ( InvalidFlushedDelayedDiagnosticLevel {
@@ -1534,7 +1523,6 @@ impl DelayedDiagnostic {
15341523/// Fatal yes FatalAbort/FatalError(*) yes - -
15351524/// Error yes ErrorGuaranteed yes - yes
15361525/// DelayedBug yes ErrorGuaranteed yes - -
1537- /// GoodPathDelayedBug - () yes - -
15381526/// ForceWarning - () yes - lint-only
15391527/// Warning - () yes yes yes
15401528/// Note - () rare yes -
@@ -1567,20 +1555,6 @@ pub enum Level {
15671555 /// that should only be reached when compiling erroneous code.
15681556 DelayedBug ,
15691557
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-
15841558 /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
15851559 /// from finishing.
15861560 ///
@@ -1625,7 +1599,7 @@ impl Level {
16251599 fn color ( self ) -> ColorSpec {
16261600 let mut spec = ColorSpec :: new ( ) ;
16271601 match self {
1628- Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => {
1602+ Bug | Fatal | Error | DelayedBug => {
16291603 spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
16301604 }
16311605 ForceWarning ( _) | Warning => {
@@ -1645,7 +1619,7 @@ impl Level {
16451619
16461620 pub fn to_str ( self ) -> & ' static str {
16471621 match self {
1648- Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error" ,
1622+ Bug | DelayedBug => "error: internal compiler error" ,
16491623 Fatal | Error => "error" ,
16501624 ForceWarning ( _) | Warning => "warning" ,
16511625 Note | OnceNote => "note" ,
@@ -1670,8 +1644,8 @@ impl Level {
16701644 // subdiagnostic message?
16711645 fn can_be_top_or_sub ( & self ) -> ( bool , bool ) {
16721646 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 ) ,
16751649
16761650 Warning | Note | Help => ( true , true ) ,
16771651
0 commit comments