about summary refs log tree commit diff
path: root/src/librustc_errors
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-08-12 15:37:28 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-08-24 15:18:06 -0700
commit8e95b3a939d73e1bc0bd65b136dda3e5b2a23425 (patch)
tree1e73744431d0bfce780c5d6edeede1557760511d /src/librustc_errors
parent2c0558f635861533e2fcb4298ea93250cdfc2c58 (diff)
downloadrust-8e95b3a939d73e1bc0bd65b136dda3e5b2a23425.tar.gz
rust-8e95b3a939d73e1bc0bd65b136dda3e5b2a23425.zip
rustc: Capture diagnostics from all queries
This commit alters the `rustc::ty::maps` implementation to ensure that all
output diagnostics from the compiler are tracked for the duration of each query.
These are then intended to be replayed back the first time a cached value is
loaded, and otherwise the cache should operate the same as it does today.

Closes #42513
Diffstat (limited to 'src/librustc_errors')
-rw-r--r--src/librustc_errors/diagnostic_builder.rs13
-rw-r--r--src/librustc_errors/lib.rs23
2 files changed, 30 insertions, 6 deletions
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 8d7ce4eb4f6..0a811989350 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -98,7 +98,7 @@ impl<'a> DiagnosticBuilder<'a> {
             }
         };
 
-        self.handler.emitter.borrow_mut().emit(&self);
+        self.handler.emit_db(&self);
         self.cancel();
 
         if is_error {
@@ -178,10 +178,13 @@ impl<'a> DiagnosticBuilder<'a> {
                          code: Option<String>,
                          message: &str)
                          -> DiagnosticBuilder<'a> {
-        DiagnosticBuilder {
-            handler,
-            diagnostic: Diagnostic::new_with_code(level, code, message)
-        }
+        let diagnostic = Diagnostic::new_with_code(level, code, message);
+        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> {
+        DiagnosticBuilder { handler, diagnostic }
     }
 }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 12b5ccf4837..a51e6022350 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -35,8 +35,9 @@ use emitter::{Emitter, EmitterWriter};
 
 use std::borrow::Cow;
 use std::cell::{RefCell, Cell};
-use std::{error, fmt};
+use std::mem;
 use std::rc::Rc;
+use std::{error, fmt};
 
 mod diagnostic;
 mod diagnostic_builder;
@@ -275,6 +276,7 @@ pub struct Handler {
     treat_err_as_bug: bool,
     continue_after_error: Cell<bool>,
     delayed_span_bug: RefCell<Option<(MultiSpan, String)>>,
+    tracked_diagnostics: RefCell<Option<Vec<Diagnostic>>>,
 }
 
 impl Handler {
@@ -298,6 +300,7 @@ impl Handler {
             treat_err_as_bug,
             continue_after_error: Cell::new(true),
             delayed_span_bug: RefCell::new(None),
+            tracked_diagnostics: RefCell::new(None),
         }
     }
 
@@ -547,6 +550,24 @@ impl Handler {
             self.abort_if_errors();
         }
     }
+
+    pub fn track_diagnostics<F, R>(&self, f: F) -> (R, Vec<Diagnostic>)
+        where F: FnOnce() -> R
+    {
+        let prev = mem::replace(&mut *self.tracked_diagnostics.borrow_mut(),
+                                Some(Vec::new()));
+        let ret = f();
+        let diagnostics = mem::replace(&mut *self.tracked_diagnostics.borrow_mut(), prev)
+            .unwrap();
+        (ret, diagnostics)
+    }
+
+    fn emit_db(&self, db: &DiagnosticBuilder) {
+        if let Some(ref mut list) = *self.tracked_diagnostics.borrow_mut() {
+            list.push((**db).clone());
+        }
+        self.emitter.borrow_mut().emit(db);
+    }
 }