about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2016-09-27 11:45:50 +1300
committerNick Cameron <ncameron@mozilla.com>2016-09-28 16:20:30 +1300
commite8a4db25acde9d2d23a4ebfb464d283d495b5b8d (patch)
tree5f299d1e451fbdf7377ad9e10eae6cee5e071e51 /src
parent322b5530ba8a74e0363243da5cdc3d0ac43762d7 (diff)
downloadrust-e8a4db25acde9d2d23a4ebfb464d283d495b5b8d.tar.gz
rust-e8a4db25acde9d2d23a4ebfb464d283d495b5b8d.zip
Allow supplying an error destination via the compiler driver
Allows replacing stderr with a buffer from the client.

Also, some refactoring around run_compiler.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/session/mod.rs20
-rw-r--r--src/librustc_driver/lib.rs39
-rw-r--r--src/librustc_errors/emitter.rs6
-rw-r--r--src/libsyntax/json.rs16
-rw-r--r--src/test/run-make/llvm-phase/test.rs4
-rw-r--r--src/test/run-pass-fulldeps/compiler-calls.rs2
6 files changed, 55 insertions, 32 deletions
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 268dbd70bb5..53e1dcc5533 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -42,6 +42,7 @@ use std::cell::{self, Cell, RefCell};
 use std::collections::HashMap;
 use std::env;
 use std::ffi::CString;
+use std::io::Write;
 use std::rc::Rc;
 use std::fmt;
 use std::time::Duration;
@@ -449,7 +450,8 @@ pub fn build_session(sopts: config::Options,
                                local_crate_source_file,
                                registry,
                                cstore,
-                               Rc::new(codemap::CodeMap::new()))
+                               Rc::new(codemap::CodeMap::new()),
+                               None)
 }
 
 pub fn build_session_with_codemap(sopts: config::Options,
@@ -457,7 +459,8 @@ pub fn build_session_with_codemap(sopts: config::Options,
                                   local_crate_source_file: Option<PathBuf>,
                                   registry: errors::registry::Registry,
                                   cstore: Rc<for<'a> CrateStore<'a>>,
-                                  codemap: Rc<codemap::CodeMap>)
+                                  codemap: Rc<codemap::CodeMap>,
+                                  emitter_dest: Option<Box<Write + Send>>)
                                   -> Session {
     // FIXME: This is not general enough to make the warning lint completely override
     // normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -470,14 +473,21 @@ pub fn build_session_with_codemap(sopts: config::Options,
         .unwrap_or(true);
     let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug;
 
-    let emitter: Box<Emitter> = match sopts.error_format {
-        config::ErrorOutputType::HumanReadable(color_config) => {
+    let emitter: Box<Emitter> = match (sopts.error_format, emitter_dest) {
+        (config::ErrorOutputType::HumanReadable(color_config), None) => {
             Box::new(EmitterWriter::stderr(color_config,
                                            Some(codemap.clone())))
         }
-        config::ErrorOutputType::Json => {
+        (config::ErrorOutputType::HumanReadable(_), Some(dst)) => {
+            Box::new(EmitterWriter::new(dst,
+                                        Some(codemap.clone())))
+        }
+        (config::ErrorOutputType::Json, None) => {
             Box::new(JsonEmitter::stderr(Some(registry), codemap.clone()))
         }
+        (config::ErrorOutputType::Json, Some(dst)) => {
+            Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone()))
+        }
     };
 
     let diagnostic_handler =
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 5089af89285..5ac4512fe39 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -74,6 +74,7 @@ use rustc::dep_graph::DepGraph;
 use rustc::session::{self, config, Session, build_session, CompileResult};
 use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
 use rustc::session::config::nightly_options;
+use rustc::session::early_error;
 use rustc::lint::Lint;
 use rustc::lint;
 use rustc_metadata::loader;
@@ -93,8 +94,6 @@ use std::str;
 use std::sync::{Arc, Mutex};
 use std::thread;
 
-use rustc::session::early_error;
-
 use syntax::{ast, json};
 use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
 use syntax::feature_gate::{GatedCfg, UnstableFeatures};
@@ -131,17 +130,18 @@ pub fn abort_on_err<T>(result: Result<T, usize>, sess: &Session) -> T {
     }
 }
 
-pub fn run(args: Vec<String>) -> isize {
+pub fn run<F>(run_compiler: F) -> isize
+    where F: FnOnce() -> (CompileResult, Option<Session>) + Send + 'static
+{
     monitor(move || {
-        let (result, session) = run_compiler(&args, &mut RustcDefaultCalls);
+        let (result, session) = run_compiler();
         if let Err(err_count) = result {
             if err_count > 0 {
                 match session {
                     Some(sess) => sess.fatal(&abort_msg(err_count)),
                     None => {
                         let emitter =
-                            errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
-                                                                   None);
+                            errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
                         let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
                         handler.emit(&MultiSpan::new(),
                                      &abort_msg(err_count),
@@ -155,20 +155,15 @@ pub fn run(args: Vec<String>) -> isize {
     0
 }
 
-pub fn run_compiler<'a>(args: &[String],
-                        callbacks: &mut CompilerCalls<'a>)
-                        -> (CompileResult, Option<Session>) {
-    run_compiler_with_file_loader(args, callbacks, box RealFileLoader)
-}
-
 // Parse args and run the compiler. This is the primary entry point for rustc.
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
-pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
-                                            callbacks: &mut CompilerCalls<'a>,
-                                            loader: Box<L>)
-                                            -> (CompileResult, Option<Session>)
-    where L: FileLoader + 'static {
+pub fn run_compiler<'a>(args: &[String],
+                        callbacks: &mut CompilerCalls<'a>,
+                        file_loader: Option<Box<FileLoader + 'static>>,
+                        emitter_dest: Option<Box<Write + Send>>)
+                        -> (CompileResult, Option<Session>)
+{
     macro_rules! do_or_return {($expr: expr, $sess: expr) => {
         match $expr {
             Compilation::Stop => return (Ok(()), $sess),
@@ -207,13 +202,16 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
 
     let dep_graph = DepGraph::new(sopts.build_dep_graph());
     let cstore = Rc::new(CStore::new(&dep_graph));
+
+    let loader = file_loader.unwrap_or(box RealFileLoader);
     let codemap = Rc::new(CodeMap::with_file_loader(loader));
     let sess = session::build_session_with_codemap(sopts,
                                                    &dep_graph,
                                                    input_file_path,
                                                    descriptions,
                                                    cstore.clone(),
-                                                   codemap);
+                                                   codemap,
+                                                   emitter_dest);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let mut cfg = config::build_configuration(&sess, cfg);
     target_features::add_configuration(&mut cfg, &sess);
@@ -1144,6 +1142,9 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
 }
 
 pub fn main() {
-    let result = run(env::args().collect());
+    let result = run(|| run_compiler(&env::args().collect::<Vec<_>>(),
+                                     &mut RustcDefaultCalls,
+                                     None,
+                                     None));
     process::exit(result as i32);
 }
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 6456b72dfb5..1d7ff45b3b8 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -99,8 +99,10 @@ impl EmitterWriter {
     pub fn new(dst: Box<Write + Send>,
                code_map: Option<Rc<CodeMapper>>)
                -> EmitterWriter {
-        EmitterWriter { dst: Raw(dst),
-                        cm: code_map}
+        EmitterWriter {
+            dst: Raw(dst),
+            cm: code_map,
+        }
     }
 
     fn preprocess_annotations(&self, msp: &MultiSpan) -> Vec<FileWithAnnotatedLines> {
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index a40c30b3e33..a1c273baeea 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -38,14 +38,24 @@ pub struct JsonEmitter {
 }
 
 impl JsonEmitter {
+    pub fn stderr(registry: Option<Registry>,
+                  code_map: Rc<CodeMap>) -> JsonEmitter {
+        JsonEmitter {
+            dst: Box::new(io::stderr()),
+            registry: registry,
+            cm: code_map,
+        }
+    }
+
     pub fn basic() -> JsonEmitter {
         JsonEmitter::stderr(None, Rc::new(CodeMap::new()))
     }
 
-    pub fn stderr(registry: Option<Registry>,
-                  code_map: Rc<CodeMap>) -> JsonEmitter {
+    pub fn new(dst: Box<Write + Send>,
+               registry: Option<Registry>,
+               code_map: Rc<CodeMap>) -> JsonEmitter {
         JsonEmitter {
-            dst: Box::new(io::stderr()),
+            dst: dst,
             registry: registry,
             cm: code_map,
         }
diff --git a/src/test/run-make/llvm-phase/test.rs b/src/test/run-make/llvm-phase/test.rs
index 19e410fef53..05c1713561a 100644
--- a/src/test/run-make/llvm-phase/test.rs
+++ b/src/test/run-make/llvm-phase/test.rs
@@ -79,8 +79,8 @@ fn main() {
         format!("_ _ --sysroot {} --crate-type dylib", path.to_str().unwrap())
         .split(' ').map(|s| s.to_string()).collect();
 
-    let (result, _) = rustc_driver::run_compiler_with_file_loader(
-        &args, &mut JitCalls, box JitLoader);
+    let (result, _) = rustc_driver::run_compiler(
+        &args, &mut JitCalls, Some(box JitLoader), None);
     if let Err(n) = result {
         panic!("Error {}", n);
     }
diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs
index 775ba38004e..35e9f3f5c8d 100644
--- a/src/test/run-pass-fulldeps/compiler-calls.rs
+++ b/src/test/run-pass-fulldeps/compiler-calls.rs
@@ -86,6 +86,6 @@ fn main() {
     let mut tc = TestCalls { count: 1 };
     // we should never get use this filename, but lets make sure they are valid args.
     let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
-    rustc_driver::run_compiler(&args, &mut tc);
+    rustc_driver::run_compiler(&args, &mut tc, None, None);
     assert_eq!(tc.count, 30);
 }