1
Fork 0

Rollup merge of #36760 - nrc:input2, r=alexcrichton

Allow supplying an error destination via the compiler driver

Allows replacing stderr with a buffer from the client.

Also, some refactoring around run_compiler.
This commit is contained in:
Jonathan Turner 2016-09-28 20:21:51 -07:00 committed by GitHub
commit 45fd0626a4
6 changed files with 56 additions and 33 deletions

View file

@ -42,6 +42,7 @@ use std::cell::{self, Cell, RefCell};
use std::collections::HashMap; use std::collections::HashMap;
use std::env; use std::env;
use std::ffi::CString; use std::ffi::CString;
use std::io::Write;
use std::rc::Rc; use std::rc::Rc;
use std::fmt; use std::fmt;
use std::time::Duration; use std::time::Duration;
@ -449,7 +450,8 @@ pub fn build_session(sopts: config::Options,
local_crate_source_file, local_crate_source_file,
registry, registry,
cstore, cstore,
Rc::new(codemap::CodeMap::new())) Rc::new(codemap::CodeMap::new()),
None)
} }
pub fn build_session_with_codemap(sopts: config::Options, 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>, local_crate_source_file: Option<PathBuf>,
registry: errors::registry::Registry, registry: errors::registry::Registry,
cstore: Rc<for<'a> CrateStore<'a>>, cstore: Rc<for<'a> CrateStore<'a>>,
codemap: Rc<codemap::CodeMap>) codemap: Rc<codemap::CodeMap>,
emitter_dest: Option<Box<Write + Send>>)
-> Session { -> Session {
// FIXME: This is not general enough to make the warning lint completely override // 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 // 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); .unwrap_or(true);
let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug; let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug;
let emitter: Box<Emitter> = match sopts.error_format { let emitter: Box<Emitter> = match (sopts.error_format, emitter_dest) {
config::ErrorOutputType::HumanReadable(color_config) => { (config::ErrorOutputType::HumanReadable(color_config), None) => {
Box::new(EmitterWriter::stderr(color_config, Box::new(EmitterWriter::stderr(color_config,
Some(codemap.clone()))) 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())) 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 = let diagnostic_handler =

View file

@ -74,6 +74,7 @@ use rustc::dep_graph::DepGraph;
use rustc::session::{self, config, Session, build_session, CompileResult}; use rustc::session::{self, config, Session, build_session, CompileResult};
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType}; use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
use rustc::session::config::nightly_options; use rustc::session::config::nightly_options;
use rustc::session::early_error;
use rustc::lint::Lint; use rustc::lint::Lint;
use rustc::lint; use rustc::lint;
use rustc_metadata::loader; use rustc_metadata::loader;
@ -93,8 +94,6 @@ use std::str;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::thread; use std::thread;
use rustc::session::early_error;
use syntax::{ast, json}; use syntax::{ast, json};
use syntax::codemap::{CodeMap, FileLoader, RealFileLoader}; use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
use syntax::feature_gate::{GatedCfg, UnstableFeatures}; 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 || { monitor(move || {
let (result, session) = run_compiler(&args, &mut RustcDefaultCalls); let (result, session) = run_compiler();
if let Err(err_count) = result { if let Err(err_count) = result {
if err_count > 0 { if err_count > 0 {
match session { match session {
Some(sess) => sess.fatal(&abort_msg(err_count)), Some(sess) => sess.fatal(&abort_msg(err_count)),
None => { None => {
let emitter = let emitter =
errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
None);
let handler = errors::Handler::with_emitter(true, false, Box::new(emitter)); let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
handler.emit(&MultiSpan::new(), handler.emit(&MultiSpan::new(),
&abort_msg(err_count), &abort_msg(err_count),
@ -155,20 +155,15 @@ pub fn run(args: Vec<String>) -> isize {
0 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. // 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. // 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. // 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], pub fn run_compiler<'a>(args: &[String],
callbacks: &mut CompilerCalls<'a>, callbacks: &mut CompilerCalls<'a>,
loader: Box<L>) file_loader: Option<Box<FileLoader + 'static>>,
emitter_dest: Option<Box<Write + Send>>)
-> (CompileResult, Option<Session>) -> (CompileResult, Option<Session>)
where L: FileLoader + 'static { {
macro_rules! do_or_return {($expr: expr, $sess: expr) => { macro_rules! do_or_return {($expr: expr, $sess: expr) => {
match $expr { match $expr {
Compilation::Stop => return (Ok(()), $sess), 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 dep_graph = DepGraph::new(sopts.build_dep_graph());
let cstore = Rc::new(CStore::new(&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 codemap = Rc::new(CodeMap::with_file_loader(loader));
let sess = session::build_session_with_codemap(sopts, let sess = session::build_session_with_codemap(sopts,
&dep_graph, &dep_graph,
input_file_path, input_file_path,
descriptions, descriptions,
cstore.clone(), cstore.clone(),
codemap); codemap,
emitter_dest);
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess)); rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
let mut cfg = config::build_configuration(&sess, cfg); let mut cfg = config::build_configuration(&sess, cfg);
target_features::add_configuration(&mut cfg, &sess); target_features::add_configuration(&mut cfg, &sess);
@ -1144,6 +1142,9 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
} }
pub fn main() { 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); process::exit(result as i32);
} }

View file

@ -99,8 +99,10 @@ impl EmitterWriter {
pub fn new(dst: Box<Write + Send>, pub fn new(dst: Box<Write + Send>,
code_map: Option<Rc<CodeMapper>>) code_map: Option<Rc<CodeMapper>>)
-> EmitterWriter { -> EmitterWriter {
EmitterWriter { dst: Raw(dst), EmitterWriter {
cm: code_map} dst: Raw(dst),
cm: code_map,
}
} }
fn preprocess_annotations(&self, msp: &MultiSpan) -> Vec<FileWithAnnotatedLines> { fn preprocess_annotations(&self, msp: &MultiSpan) -> Vec<FileWithAnnotatedLines> {

View file

@ -38,10 +38,6 @@ pub struct JsonEmitter {
} }
impl JsonEmitter { impl JsonEmitter {
pub fn basic() -> JsonEmitter {
JsonEmitter::stderr(None, Rc::new(CodeMap::new()))
}
pub fn stderr(registry: Option<Registry>, pub fn stderr(registry: Option<Registry>,
code_map: Rc<CodeMap>) -> JsonEmitter { code_map: Rc<CodeMap>) -> JsonEmitter {
JsonEmitter { JsonEmitter {
@ -50,6 +46,20 @@ impl JsonEmitter {
cm: code_map, cm: code_map,
} }
} }
pub fn basic() -> JsonEmitter {
JsonEmitter::stderr(None, Rc::new(CodeMap::new()))
}
pub fn new(dst: Box<Write + Send>,
registry: Option<Registry>,
code_map: Rc<CodeMap>) -> JsonEmitter {
JsonEmitter {
dst: dst,
registry: registry,
cm: code_map,
}
}
} }
impl Emitter for JsonEmitter { impl Emitter for JsonEmitter {

View file

@ -79,8 +79,8 @@ fn main() {
format!("_ _ --sysroot {} --crate-type dylib", path.to_str().unwrap()) format!("_ _ --sysroot {} --crate-type dylib", path.to_str().unwrap())
.split(' ').map(|s| s.to_string()).collect(); .split(' ').map(|s| s.to_string()).collect();
let (result, _) = rustc_driver::run_compiler_with_file_loader( let (result, _) = rustc_driver::run_compiler(
&args, &mut JitCalls, box JitLoader); &args, &mut JitCalls, Some(box JitLoader), None);
if let Err(n) = result { if let Err(n) = result {
panic!("Error {}", n); panic!("Error {}", n);
} }

View file

@ -86,6 +86,6 @@ fn main() {
let mut tc = TestCalls { count: 1 }; let mut tc = TestCalls { count: 1 };
// we should never get use this filename, but lets make sure they are valid args. // 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()]; 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); assert_eq!(tc.count, 30);
} }