Skip to content

Commit

Permalink
Rollup merge of rust-lang#121723 - nnethercote:two-diagnostic-things,…
Browse files Browse the repository at this point in the history
… r=oli-obk

Two diagnostic things

Two minor improvements to diagnostics-related things.

r? `@RalfJung`
  • Loading branch information
GuillaumeGomez committed Feb 28, 2024
2 parents fd3b535 + bac96bd commit 9704475
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 21 deletions.
19 changes: 19 additions & 0 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,25 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {

/// Trait implemented by error types. This is rarely implemented manually. Instead, use
/// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic].
///
/// When implemented manually, it should be generic over the emission
/// guarantee, i.e.:
/// ```ignore (fragment)
/// impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for Foo { ... }
/// ```
/// rather than being specific:
/// ```ignore (fragment)
/// impl<'a> IntoDiagnostic<'a> for Bar { ... } // the default type param is `ErrorGuaranteed`
/// impl<'a> IntoDiagnostic<'a, ()> for Baz { ... }
/// ```
/// There are two reasons for this.
/// - A diagnostic like `Foo` *could* be emitted at any level -- `level` is
/// passed in to `into_diagnostic` from outside. Even if in practice it is
/// always emitted at a single level, we let the diagnostic creation/emission
/// site determine the level (by using `create_err`, `emit_warn`, etc.)
/// rather than the `IntoDiagnostic` impl.
/// - Derived impls are always generic, and it's good for the hand-written
/// impls to be consistent with them.
#[rustc_diagnostic_item = "IntoDiagnostic"]
pub trait IntoDiagnostic<'a, G: EmissionGuarantee = ErrorGuaranteed> {
/// Write out as a diagnostic out of `DiagCtxt`.
Expand Down
42 changes: 21 additions & 21 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1514,14 +1514,26 @@ impl DiagCtxtInner {
let bugs: Vec<_> =
std::mem::take(&mut self.delayed_bugs).into_iter().map(|(b, _)| b).collect();

// If backtraces are enabled, also print the query stack
let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0");
for (i, bug) in bugs.into_iter().enumerate() {
if let Some(file) = self.ice_file.as_ref()
&& let Ok(mut out) = std::fs::File::options().create(true).append(true).open(file)
{
let _ = write!(
&mut out,
let decorate = backtrace || self.ice_file.is_none();
let mut out = self
.ice_file
.as_ref()
.and_then(|file| std::fs::File::options().create(true).append(true).open(file).ok());

// Put the overall explanation before the `DelayedBug`s, to frame them
// better (e.g. separate warnings from them). Also, use notes, which
// don't count as errors, to avoid possibly triggering
// `-Ztreat-err-as-bug`, which we don't want.
let note1 = "no errors encountered even though delayed bugs were created";
let note2 = "those delayed bugs will now be shown as internal compiler errors";
self.emit_diagnostic(Diagnostic::new(Note, note1));
self.emit_diagnostic(Diagnostic::new(Note, note2));

for bug in bugs {
if let Some(out) = &mut out {
_ = write!(
out,
"delayed bug: {}\n{}\n",
bug.inner
.messages
Expand All @@ -1532,21 +1544,9 @@ impl DiagCtxtInner {
);
}

if i == 0 {
// Put the overall explanation before the `DelayedBug`s, to
// frame them better (e.g. separate warnings from them). Also,
// make it a note so it doesn't count as an error, because that
// could trigger `-Ztreat-err-as-bug`, which we don't want.
let note1 = "no errors encountered even though delayed bugs were created";
let note2 = "those delayed bugs will now be shown as internal compiler errors";
self.emit_diagnostic(Diagnostic::new(Note, note1));
self.emit_diagnostic(Diagnostic::new(Note, note2));
}

let mut bug =
if backtrace || self.ice_file.is_none() { bug.decorate(self) } else { bug.inner };
let mut bug = if decorate { bug.decorate(self) } else { bug.inner };

// "Undelay" the delayed bugs (into plain `Bug`s).
// "Undelay" the delayed bugs into plain bugs.
if bug.level != DelayedBug {
// NOTE(eddyb) not panicking here because we're already producing
// an ICE, and the more information the merrier.
Expand Down

0 comments on commit 9704475

Please sign in to comment.