about summary refs log tree commit diff
path: root/src/librustc_errors
diff options
context:
space:
mode:
authorOliver Schneider <github35764891676564198441@oli-obk.de>2018-07-19 17:53:44 +0200
committerOliver Schneider <github35764891676564198441@oli-obk.de>2018-07-20 15:59:21 +0200
commit56c90774a94e521283030caa12c1bf8d9bc16be4 (patch)
tree6529d607de141531beded66bce8eadc44c52a204 /src/librustc_errors
parent0fc4501256b002aef627880a9f6d18065b0ca931 (diff)
downloadrust-56c90774a94e521283030caa12c1bf8d9bc16be4.tar.gz
rust-56c90774a94e521283030caa12c1bf8d9bc16be4.zip
Make sure the compiler actually panics on `delay_span_bug`
Even if that is just happening because of `abort_if_errors`
Diffstat (limited to 'src/librustc_errors')
-rw-r--r--src/librustc_errors/diagnostic_builder.rs2
-rw-r--r--src/librustc_errors/lib.rs32
2 files changed, 27 insertions, 7 deletions
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 9c7b7ea3395..24ece514a47 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -132,7 +132,7 @@ impl<'a> DiagnosticBuilder<'a> {
     /// 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.handler.delay_as_bug(self.diagnostic.clone());
         self.cancel();
     }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index f18a7bd9136..06c49b3a103 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -274,7 +274,7 @@ pub struct Handler {
     err_count: AtomicUsize,
     emitter: Lock<Box<dyn Emitter + sync::Send>>,
     continue_after_error: LockCell<bool>,
-    delayed_span_bug: Lock<Option<Diagnostic>>,
+    delayed_span_bug: Lock<Vec<Diagnostic>>,
 
     // This set contains the `DiagnosticId` of all emitted diagnostics to avoid
     // emitting the same diagnostic with extended help (`--teach`) twice, which
@@ -299,9 +299,25 @@ thread_local!(pub static TRACK_DIAGNOSTICS: Cell<fn(&Diagnostic)> =
 pub struct HandlerFlags {
     pub can_emit_warnings: bool,
     pub treat_err_as_bug: bool,
+    pub report_delayed_bugs: bool,
     pub external_macro_backtrace: bool,
 }
 
+impl Drop for Handler {
+    fn drop(&mut self) {
+        if self.err_count() == 0 {
+            let mut bugs = self.delayed_span_bug.borrow_mut();
+            let has_bugs = !bugs.is_empty();
+            for bug in bugs.drain(..) {
+                DiagnosticBuilder::new_diagnostic(self, bug).emit();
+            }
+            if has_bugs {
+                panic!("no errors encountered even though `delay_span_bug` issued");
+            }
+        }
+    }
+}
+
 impl Handler {
     pub fn with_tty_emitter(color_config: ColorConfig,
                             can_emit_warnings: bool,
@@ -346,7 +362,7 @@ impl Handler {
             err_count: AtomicUsize::new(0),
             emitter: Lock::new(e),
             continue_after_error: LockCell::new(true),
-            delayed_span_bug: Lock::new(None),
+            delayed_span_bug: Lock::new(Vec::new()),
             taught_diagnostics: Lock::new(FxHashSet()),
             emitted_diagnostic_codes: Lock::new(FxHashSet()),
             emitted_diagnostics: Lock::new(FxHashSet()),
@@ -503,11 +519,18 @@ impl Handler {
     }
     pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         if self.flags.treat_err_as_bug {
+            // FIXME: don't abort here if report_delayed_bugs is off
             self.span_bug(sp, msg);
         }
         let mut diagnostic = Diagnostic::new(Level::Bug, msg);
         diagnostic.set_span(sp.into());
-        *self.delayed_span_bug.borrow_mut() = Some(diagnostic);
+        self.delay_as_bug(diagnostic);
+    }
+    fn delay_as_bug(&self, diagnostic: Diagnostic) {
+        if self.flags.report_delayed_bugs {
+            DiagnosticBuilder::new_diagnostic(self, diagnostic.clone()).emit();
+        }
+        self.delayed_span_bug.borrow_mut().push(diagnostic);
     }
     pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
         self.emit(&sp.into(), msg, Bug);
@@ -615,9 +638,6 @@ impl Handler {
 
     pub fn abort_if_errors(&self) {
         if self.err_count() == 0 {
-            if let Some(bug) = self.delayed_span_bug.borrow_mut().take() {
-                DiagnosticBuilder::new_diagnostic(self, bug).emit();
-            }
             return;
         }
         FatalError.raise();