diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index bedb677c1e93d..d4f884d49ea56 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -442,8 +442,8 @@ struct DiagCtxtInner { emitter: Box, /// Must we produce a diagnostic to justify the use of the expensive - /// `trimmed_def_paths` function? - must_produce_diag: bool, + /// `trimmed_def_paths` function? Backtrace is the location of the call. + must_produce_diag: Option, /// Has this diagnostic context printed any diagnostics? (I.e. has /// `self.emitter.emit_diagnostic()` been called? @@ -572,10 +572,11 @@ impl Drop for DiagCtxtInner { } if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() { - if self.must_produce_diag { + if let Some(backtrace) = &self.must_produce_diag { panic!( - "must_produce_diag: trimmed_def_paths called but no diagnostics emitted; \ - use `DelayDm` for lints or `with_no_trimmed_paths` for debugging" + "must_produce_diag: `trimmed_def_paths` called but no diagnostics emitted; \ + use `DelayDm` for lints or `with_no_trimmed_paths` for debugging. \ + called at: {backtrace}" ); } } @@ -721,7 +722,7 @@ impl DiagCtxt { *delayed_bugs = Default::default(); *deduplicated_err_count = 0; *deduplicated_warn_count = 0; - *must_produce_diag = false; + *must_produce_diag = None; *has_printed = false; *suppressed_expected_diag = false; *taught_diagnostics = Default::default(); @@ -1091,8 +1092,13 @@ impl DiagCtxt { /// Used when trimmed_def_paths is called and we must produce a diagnostic /// to justify its cost. + #[track_caller] pub fn set_must_produce_diag(&self) { - self.inner.borrow_mut().must_produce_diag = true; + assert!( + self.inner.borrow().must_produce_diag.is_none(), + "should only need to collect a backtrace once" + ); + self.inner.borrow_mut().must_produce_diag = Some(Backtrace::capture()); } } @@ -1384,7 +1390,7 @@ impl DiagCtxtInner { deduplicated_err_count: 0, deduplicated_warn_count: 0, emitter, - must_produce_diag: false, + must_produce_diag: None, has_printed: false, suppressed_expected_diag: false, taught_diagnostics: Default::default(),