Skip to content

Commit 64b0b2b

Browse files
committed
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...
1 parent 2aeb593 commit 64b0b2b

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

src/librustc_errors/diagnostic_builder.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,22 @@ impl<'a> DiagnosticBuilder<'a> {
110110
// }
111111
}
112112

113+
/// Delay emission of this diagnostic as a bug.
114+
///
115+
/// This can be useful in contexts where an error indicates a bug but
116+
/// typically this only happens when other compilation errors have already
117+
/// happened. In those cases this can be used to defer emission of this
118+
/// diagnostic as a bug in the compiler only if no other errors have been
119+
/// emitted.
120+
///
121+
/// In the meantime, though, callsites are required to deal with the "bug"
122+
/// locally in whichever way makes the most sense.
123+
pub fn delay_as_bug(&mut self) {
124+
self.level = Level::Bug;
125+
*self.handler.delayed_span_bug.borrow_mut() = Some(self.diagnostic.clone());
126+
self.cancel();
127+
}
128+
113129
/// Add a span/label to be included in the resulting snippet.
114130
/// This is pushed onto the `MultiSpan` that was created when the
115131
/// diagnostic was first built. If you don't call this function at
@@ -182,8 +198,10 @@ impl<'a> DiagnosticBuilder<'a> {
182198
DiagnosticBuilder::new_diagnostic(handler, diagnostic)
183199
}
184200

185-
/// Creates a new `DiagnosticBuilder` with an already constructed diagnostic.
186-
pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic) -> DiagnosticBuilder<'a> {
201+
/// Creates a new `DiagnosticBuilder` with an already constructed
202+
/// diagnostic.
203+
pub fn new_diagnostic(handler: &'a Handler, diagnostic: Diagnostic)
204+
-> DiagnosticBuilder<'a> {
187205
DiagnosticBuilder { handler, diagnostic }
188206
}
189207
}

src/librustc_errors/lib.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ pub struct Handler {
275275
pub can_emit_warnings: bool,
276276
treat_err_as_bug: bool,
277277
continue_after_error: Cell<bool>,
278-
delayed_span_bug: RefCell<Option<(MultiSpan, String)>>,
278+
delayed_span_bug: RefCell<Option<Diagnostic>>,
279279
tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>,
280280
}
281281

@@ -442,8 +442,9 @@ impl Handler {
442442
if self.treat_err_as_bug {
443443
self.span_bug(sp, msg);
444444
}
445-
let mut delayed = self.delayed_span_bug.borrow_mut();
446-
*delayed = Some((sp.into(), msg.to_string()));
445+
let mut diagnostic = Diagnostic::new(Level::Bug, msg);
446+
diagnostic.set_span(sp.into());
447+
*self.delayed_span_bug.borrow_mut() = Some(diagnostic);
447448
}
448449
pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
449450
self.emit(&sp.into(), msg, Bug);
@@ -510,14 +511,9 @@ impl Handler {
510511
let s;
511512
match self.err_count.get() {
512513
0 => {
513-
let delayed_bug = self.delayed_span_bug.borrow();
514-
match *delayed_bug {
515-
Some((ref span, ref errmsg)) => {
516-
self.span_bug(span.clone(), errmsg);
517-
}
518-
_ => {}
514+
if let Some(bug) = self.delayed_span_bug.borrow_mut().take() {
515+
DiagnosticBuilder::new_diagnostic(self, bug).emit();
519516
}
520-
521517
return;
522518
}
523519
1 => s = "aborting due to previous error".to_string(),

0 commit comments

Comments
 (0)