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:
commit
45fd0626a4
@ -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 =
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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> {
|
||||
|
@ -38,10 +38,6 @@ pub struct JsonEmitter {
|
||||
}
|
||||
|
||||
impl JsonEmitter {
|
||||
pub fn basic() -> JsonEmitter {
|
||||
JsonEmitter::stderr(None, Rc::new(CodeMap::new()))
|
||||
}
|
||||
|
||||
pub fn stderr(registry: Option<Registry>,
|
||||
code_map: Rc<CodeMap>) -> JsonEmitter {
|
||||
JsonEmitter {
|
||||
@ -50,6 +46,20 @@ impl JsonEmitter {
|
||||
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 {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user