@@ -436,7 +436,6 @@ struct DiagCtxtInner {
436436 lint_err_guars : Vec < ErrorGuaranteed > ,
437437 /// The delayed bugs and their error guarantees.
438438 delayed_bugs : Vec < ( DelayedDiagnostic , ErrorGuaranteed ) > ,
439- good_path_delayed_bugs : Vec < DelayedDiagnostic > ,
440439
441440 /// The number of stashed errors. Unlike the other counts, this can go up
442441 /// and down, so it doesn't guarantee anything.
@@ -447,13 +446,18 @@ struct DiagCtxtInner {
447446 /// The warning count shown to the user at the end.
448447 deduplicated_warn_count : usize ,
449448
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+
450455 /// Has this diagnostic context printed any diagnostics? (I.e. has
451456 /// `self.emitter.emit_diagnostic()` been called?
452457 has_printed : bool ,
453458
454- emitter : Box < DynEmitter > ,
455459 /// 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.
457461 suppressed_expected_diag : bool ,
458462
459463 /// 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)) {
534538pub static TRACK_DIAGNOSTIC : AtomicRef < fn ( Diagnostic , & mut dyn FnMut ( Diagnostic ) ) > =
535539 AtomicRef :: new ( & ( default_track_diagnostic as _ ) ) ;
536540
537- enum DelayedBugKind {
538- Normal ,
539- GoodPath ,
540- }
541-
542541#[ derive( Copy , Clone , Default ) ]
543542pub struct DiagCtxtFlags {
544543 /// If false, warning-level lints are suppressed.
@@ -564,11 +563,16 @@ impl Drop for DiagCtxtInner {
564563 self . emit_stashed_diagnostics ( ) ;
565564
566565 if self . err_guars . is_empty ( ) {
567- self . flush_delayed ( DelayedBugKind :: Normal )
566+ self . flush_delayed ( )
568567 }
569568
570569 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+ }
572576 }
573577
574578 if self . check_unstable_expect_diagnostics {
@@ -610,12 +614,12 @@ impl DiagCtxt {
610614 err_guars : Vec :: new ( ) ,
611615 lint_err_guars : Vec :: new ( ) ,
612616 delayed_bugs : Vec :: new ( ) ,
613- good_path_delayed_bugs : Vec :: new ( ) ,
614617 stashed_err_count : 0 ,
615618 deduplicated_err_count : 0 ,
616619 deduplicated_warn_count : 0 ,
617- has_printed : false ,
618620 emitter,
621+ must_produce_diag : false ,
622+ has_printed : false ,
619623 suppressed_expected_diag : false ,
620624 taught_diagnostics : Default :: default ( ) ,
621625 emitted_diagnostic_codes : Default :: default ( ) ,
@@ -667,13 +671,14 @@ impl DiagCtxt {
667671 inner. stashed_err_count = 0 ;
668672 inner. deduplicated_err_count = 0 ;
669673 inner. deduplicated_warn_count = 0 ;
674+ inner. must_produce_diag = false ;
670675 inner. has_printed = false ;
676+ inner. suppressed_expected_diag = false ;
671677
672678 // actually free the underlying memory (which `clear` would not do)
673679 inner. err_guars = Default :: default ( ) ;
674680 inner. lint_err_guars = Default :: default ( ) ;
675681 inner. delayed_bugs = Default :: default ( ) ;
676- inner. good_path_delayed_bugs = Default :: default ( ) ;
677682 inner. taught_diagnostics = Default :: default ( ) ;
678683 inner. emitted_diagnostic_codes = Default :: default ( ) ;
679684 inner. emitted_diagnostics = Default :: default ( ) ;
@@ -935,7 +940,13 @@ impl DiagCtxt {
935940 }
936941
937942 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 ;
939950 }
940951}
941952
@@ -1109,13 +1120,6 @@ impl DiagCtxt {
11091120 DiagnosticBuilder :: < ErrorGuaranteed > :: new ( self , DelayedBug , msg) . with_span ( sp) . emit ( )
11101121 }
11111122
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-
11191123 #[ rustc_lint_diagnostics]
11201124 #[ track_caller]
11211125 pub fn struct_warn ( & self , msg : impl Into < DiagnosticMessage > ) -> DiagnosticBuilder < ' _ , ( ) > {
@@ -1267,19 +1271,17 @@ impl DiagCtxtInner {
12671271 if diagnostic. has_future_breakage ( ) {
12681272 // Future breakages aren't emitted if they're Level::Allow,
12691273 // 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.
12711275 self . suppressed_expected_diag = true ;
12721276 self . future_breakage_diagnostics . push ( diagnostic. clone ( ) ) ;
12731277 }
12741278
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 {
12781280 diagnostic. level = Error ;
12791281 }
12801282
12811283 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
12831285 // `Error` above.
12841286 Fatal | Error if self . treat_next_err_as_bug ( ) => {
12851287 diagnostic. level = Bug ;
@@ -1298,12 +1300,6 @@ impl DiagCtxtInner {
12981300 . push ( ( DelayedDiagnostic :: with_backtrace ( diagnostic, backtrace) , guar) ) ;
12991301 return Some ( guar) ;
13001302 }
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- }
13071303 Warning if !self . flags . can_emit_warnings => {
13081304 if diagnostic. has_future_breakage ( ) {
13091305 ( * TRACK_DIAGNOSTIC ) ( diagnostic, & mut |_| { } ) ;
@@ -1415,23 +1411,14 @@ impl DiagCtxtInner {
14151411 self . emit_diagnostic ( Diagnostic :: new ( FailureNote , msg) ) ;
14161412 }
14171413
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 ( ) {
14321416 return ;
14331417 }
14341418
1419+ let bugs: Vec < _ > =
1420+ std:: mem:: take ( & mut self . delayed_bugs ) . into_iter ( ) . map ( |( b, _) | b) . collect ( ) ;
1421+
14351422 // If backtraces are enabled, also print the query stack
14361423 let backtrace = std:: env:: var_os ( "RUST_BACKTRACE" ) . map_or ( true , |x| & x != "0" ) ;
14371424 for ( i, bug) in bugs. into_iter ( ) . enumerate ( ) {
@@ -1455,6 +1442,8 @@ impl DiagCtxtInner {
14551442 // frame them better (e.g. separate warnings from them). Also,
14561443 // make it a note so it doesn't count as an error, because that
14571444 // 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" ;
14581447 self . emit_diagnostic ( Diagnostic :: new ( Note , note1) ) ;
14591448 self . emit_diagnostic ( Diagnostic :: new ( Note , note2) ) ;
14601449 }
@@ -1463,7 +1452,7 @@ impl DiagCtxtInner {
14631452 if backtrace || self . ice_file . is_none ( ) { bug. decorate ( ) } else { bug. inner } ;
14641453
14651454 // "Undelay" the delayed bugs (into plain `Bug`s).
1466- if ! matches ! ( bug. level, DelayedBug | GoodPathDelayedBug ) {
1455+ if bug. level != DelayedBug {
14671456 // NOTE(eddyb) not panicking here because we're already producing
14681457 // an ICE, and the more information the merrier.
14691458 bug. subdiagnostic ( InvalidFlushedDelayedDiagnosticLevel {
@@ -1535,7 +1524,6 @@ impl DelayedDiagnostic {
15351524/// Fatal yes FatalAbort/FatalError(*) yes - -
15361525/// Error yes ErrorGuaranteed yes - yes
15371526/// DelayedBug yes ErrorGuaranteed yes - -
1538- /// GoodPathDelayedBug - () yes - -
15391527/// ForceWarning - () yes - lint-only
15401528/// Warning - () yes yes yes
15411529/// Note - () rare yes -
@@ -1568,20 +1556,6 @@ pub enum Level {
15681556 /// that should only be reached when compiling erroneous code.
15691557 DelayedBug ,
15701558
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-
15851559 /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
15861560 /// from finishing.
15871561 ///
@@ -1626,7 +1600,7 @@ impl Level {
16261600 fn color ( self ) -> ColorSpec {
16271601 let mut spec = ColorSpec :: new ( ) ;
16281602 match self {
1629- Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => {
1603+ Bug | Fatal | Error | DelayedBug => {
16301604 spec. set_fg ( Some ( Color :: Red ) ) . set_intense ( true ) ;
16311605 }
16321606 ForceWarning ( _) | Warning => {
@@ -1646,7 +1620,7 @@ impl Level {
16461620
16471621 pub fn to_str ( self ) -> & ' static str {
16481622 match self {
1649- Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error" ,
1623+ Bug | DelayedBug => "error: internal compiler error" ,
16501624 Fatal | Error => "error" ,
16511625 ForceWarning ( _) | Warning => "warning" ,
16521626 Note | OnceNote => "note" ,
@@ -1671,8 +1645,8 @@ impl Level {
16711645 // subdiagnostic message?
16721646 fn can_be_top_or_sub ( & self ) -> ( bool , bool ) {
16731647 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 ) ,
16761650
16771651 Warning | Note | Help => ( true , true ) ,
16781652
0 commit comments