Rollup merge of #121723 - nnethercote:two-diagnostic-things, r=oli-obk
Two diagnostic things Two minor improvements to diagnostics-related things. r? ``@RalfJung``
This commit is contained in:
commit
b098b17b47
2 changed files with 40 additions and 21 deletions
|
@ -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`.
|
||||
|
|
|
@ -1498,14 +1498,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(DiagInner::new(Note, note1));
|
||||
self.emit_diagnostic(DiagInner::new(Note, note2));
|
||||
|
||||
for bug in bugs {
|
||||
if let Some(out) = &mut out {
|
||||
_ = write!(
|
||||
out,
|
||||
"delayed bug: {}\n{}\n",
|
||||
bug.inner
|
||||
.messages
|
||||
|
@ -1516,21 +1528,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(DiagInner::new(Note, note1));
|
||||
self.emit_diagnostic(DiagInner::new(Note, note2));
|
||||
}
|
||||
let mut bug = if decorate { bug.decorate(self) } else { bug.inner };
|
||||
|
||||
let mut bug =
|
||||
if backtrace || self.ice_file.is_none() { 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.
|
||||
|
|
Loading…
Add table
Reference in a new issue