about summary refs log tree commit diff
path: root/src/librustc_errors
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-08-23 12:52:22 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-08-25 16:08:35 -0700
commit64b0b2bfebf857f25f826ca9ebb07630287bc4d0 (patch)
tree090e7db6d234499c51d8e2139fa46216c2b2df76 /src/librustc_errors
parent2aeb5930f32514b9f2a4b90cd8ce6362af5f3c9f (diff)
downloadrust-64b0b2bfebf857f25f826ca9ebb07630287bc4d0.tar.gz
rust-64b0b2bfebf857f25f826ca9ebb07630287bc4d0.zip
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...
Diffstat (limited to 'src/librustc_errors')
-rw-r--r--src/librustc_errors/diagnostic_builder.rs22
-rw-r--r--src/librustc_errors/lib.rs16
2 files changed, 26 insertions, 12 deletions
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 0a811989350..2c8d8b4691f 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -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 }
     }
 }
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index a51e6022350..60f9276c0ca 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -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(),