rustc_errors: Add the ability to delay as bugs
This adds a function to `DiagnosticBuilder` to delay the entire diagnostic as a bug to be emitted at a later time. This'll end up getting used in the compiler in the subsequent commits...
This commit is contained in:
parent
2aeb5930f3
commit
64b0b2bfeb
2 changed files with 26 additions and 12 deletions
|
|
@ -110,6 +110,22 @@ impl<'a> DiagnosticBuilder<'a> {
|
|||
// }
|
||||
}
|
||||
|
||||
/// Delay emission of this diagnostic as a bug.
|
||||
///
|
||||
/// This can be useful in contexts where an error indicates a bug but
|
||||
/// typically this only happens when other compilation errors have already
|
||||
/// happened. In those cases this can be used to defer emission of this
|
||||
/// diagnostic as a bug in the compiler only if no other errors have been
|
||||
/// emitted.
|
||||
///
|
||||
/// In the meantime, though, callsites are required to deal with the "bug"
|
||||
/// locally in whichever way makes the most sense.
|
||||
pub fn delay_as_bug(&mut self) {
|
||||
self.level = Level::Bug;
|
||||
*self.handler.delayed_span_bug.borrow_mut() = Some(self.diagnostic.clone());
|
||||
self.cancel();
|
||||
}
|
||||
|
||||
/// Add a span/label to be included in the resulting snippet.
|
||||
/// This is pushed onto the `MultiSpan` that was created when the
|
||||
/// diagnostic was first built. If you don't call this function at
|
||||
|
|
@ -182,8 +198,10 @@ impl<'a> DiagnosticBuilder<'a> {
|
|||
DiagnosticBuilder::new_diagnostic(handler, diagnostic)
|
||||
}
|
||||
|
||||
/// Creates a new `DiagnosticBuilder` with an already constructed diagnostic.
|
||||
pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> {
|
||||
/// Creates a new `DiagnosticBuilder` with an already constructed
|
||||
/// diagnostic.
|
||||
pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic)
|
||||
-> DiagnosticBuilder<'a> {
|
||||
DiagnosticBuilder { handler, diagnostic }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ pub struct Handler {
|
|||
pub can_emit_warnings: bool,
|
||||
treat_err_as_bug: bool,
|
||||
continue_after_error: Cell<bool>,
|
||||
delayed_span_bug: RefCell<Option<(MultiSpan, String)>>,
|
||||
delayed_span_bug: RefCell<Option<Diagnostic>>,
|
||||
tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>,
|
||||
}
|
||||
|
||||
|
|
@ -442,8 +442,9 @@ impl Handler {
|
|||
if self.treat_err_as_bug {
|
||||
self.span_bug(sp, msg);
|
||||
}
|
||||
let mut delayed = self.delayed_span_bug.borrow_mut();
|
||||
*delayed = Some((sp.into(), msg.to_string()));
|
||||
let mut diagnostic = Diagnostic::new(Level::Bug, msg);
|
||||
diagnostic.set_span(sp.into());
|
||||
*self.delayed_span_bug.borrow_mut() = Some(diagnostic);
|
||||
}
|
||||
pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
|
||||
self.emit(&sp.into(), msg, Bug);
|
||||
|
|
@ -510,14 +511,9 @@ impl Handler {
|
|||
let s;
|
||||
match self.err_count.get() {
|
||||
0 => {
|
||||
let delayed_bug = self.delayed_span_bug.borrow();
|
||||
match *delayed_bug {
|
||||
Some((ref span, ref errmsg)) => {
|
||||
self.span_bug(span.clone(), errmsg);
|
||||
}
|
||||
_ => {}
|
||||
if let Some(bug) = self.delayed_span_bug.borrow_mut().take() {
|
||||
DiagnosticBuilder::new_diagnostic(self, bug).emit();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
1 => s = "aborting due to previous error".to_string(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue