rustdoc: Capture all output from rustc by default

This helps prevent interleaving of error messages when running rustdoc tests.
This has an interesting bit of shuffling with I/O handles, but other than that
this is just using the APIs laid out in the previous commit.

Closes #12623
This commit is contained in:
Alex Crichton 2014-02-28 12:33:49 -08:00
parent 324547140e
commit 0e1a860789
4 changed files with 33 additions and 5 deletions

View File

@ -58,7 +58,7 @@ fn get_ast_and_resolve(cpath: &Path,
};
let diagnostic_handler = syntax::diagnostic::mk_handler();
let diagnostic_handler = syntax::diagnostic::default_handler();
let span_diagnostic_handler =
syntax::diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);

View File

@ -28,7 +28,7 @@
/// Highlights some source code, returning the HTML output.
pub fn highlight(src: &str) -> ~str {
let sess = parse::new_parse_sess();
let handler = diagnostic::mk_handler();
let handler = diagnostic::default_handler();
let span_handler = diagnostic::mk_span_handler(handler, sess.cm);
let fm = parse::string_to_filemap(sess, src.to_owned(), ~"<stdin>");

View File

@ -50,7 +50,7 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
let cm = @CodeMap::new();
let diagnostic_handler = diagnostic::mk_handler();
let diagnostic_handler = diagnostic::default_handler();
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, cm);
let parsesess = parse::new_parse_sess_special_handler(span_diagnostic_handler,
@ -115,7 +115,30 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool)
.. (*session::basic_options()).clone()
};
let diagnostic_handler = diagnostic::mk_handler();
// Shuffle around a few input and output handles here. We're going to pass
// an explicit handle into rustc to collect output messages, but we also
// want to catch the error message that rustc prints when it fails.
//
// We take our task-local stderr (likely set by the test runner), and move
// it into another task. This helper task then acts as a sink for both the
// stderr of this task and stderr of rustc itself, copying all the info onto
// the stderr channel we originally started with.
//
// The basic idea is to not use a default_handler() for rustc, and then also
// not print things by default to the actual stderr.
let (p, c) = Chan::new();
let w1 = io::ChanWriter::new(c);
let w2 = w1.clone();
let old = io::stdio::set_stderr(~w1);
spawn(proc() {
let mut p = io::PortReader::new(p);
let mut err = old.unwrap_or(~io::stderr() as ~Writer);
io::util::copy(&mut p, &mut err).unwrap();
});
let emitter = diagnostic::EmitterWriter::new(~w2);
// Compile the code
let diagnostic_handler = diagnostic::mk_handler(~emitter);
let span_diagnostic_handler =
diagnostic::mk_span_handler(diagnostic_handler, parsesess.cm);
@ -129,6 +152,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool)
let cfg = driver::build_configuration(sess);
driver::compile_input(sess, cfg, &input, &out, &None);
// Run the code!
let exe = outdir.path().join("rust_out");
let out = Process::output(exe.as_str().unwrap(), []);
match out {

View File

@ -1004,6 +1004,7 @@ mod test {
use diagnostic;
use parse::token;
use parse::token::{str_to_ident};
use std::io::util;
// represents a testing reader (incl. both reader and interner)
struct Env {
@ -1014,7 +1015,10 @@ struct Env {
fn setup(teststr: ~str) -> Env {
let cm = CodeMap::new();
let fm = cm.new_filemap(~"zebra.rs", teststr);
let span_handler = diagnostic::mk_span_handler(diagnostic::mk_handler(), @cm);
let writer = ~util::NullWriter;
let emitter = diagnostic::EmitterWriter::new(writer);
let handler = diagnostic::mk_handler(~emitter);
let span_handler = diagnostic::mk_span_handler(handler, @cm);
Env {
string_reader: new_string_reader(span_handler,fm)
}