@@ -25,6 +25,7 @@ use rustc::metadata::creader::Loader;
2525use getopts;
2626use syntax:: diagnostic;
2727use syntax:: parse;
28+ use syntax:: codemap:: CodeMap ;
2829
2930use core;
3031use clean;
@@ -35,7 +36,6 @@ use passes;
3536use visit_ast:: RustdocVisitor ;
3637
3738pub fn run ( input : & str , matches : & getopts:: Matches ) -> int {
38- let parsesess = parse:: new_parse_sess ( ) ;
3939 let input_path = Path :: new ( input) ;
4040 let input = driver:: FileInput ( input_path. clone ( ) ) ;
4141 let libs = matches. opt_strs ( "L" ) . map ( |s| Path :: new ( s. as_slice ( ) ) ) ;
@@ -49,9 +49,12 @@ pub fn run(input: &str, matches: &getopts::Matches) -> int {
4949 } ;
5050
5151
52- let diagnostic_handler = diagnostic:: mk_handler ( ) ;
52+ let cm = @CodeMap :: new ( ) ;
53+ let diagnostic_handler = diagnostic:: default_handler ( ) ;
5354 let span_diagnostic_handler =
54- diagnostic:: mk_span_handler ( diagnostic_handler, parsesess. cm ) ;
55+ diagnostic:: mk_span_handler ( diagnostic_handler, cm) ;
56+ let parsesess = parse:: new_parse_sess_special_handler ( span_diagnostic_handler,
57+ cm) ;
5558
5659 let sess = driver:: build_session_ ( sessopts,
5760 Some ( input_path) ,
@@ -112,7 +115,30 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool)
112115 .. ( * session:: basic_options ( ) ) . clone ( )
113116 } ;
114117
115- let diagnostic_handler = diagnostic:: mk_handler ( ) ;
118+ // Shuffle around a few input and output handles here. We're going to pass
119+ // an explicit handle into rustc to collect output messages, but we also
120+ // want to catch the error message that rustc prints when it fails.
121+ //
122+ // We take our task-local stderr (likely set by the test runner), and move
123+ // it into another task. This helper task then acts as a sink for both the
124+ // stderr of this task and stderr of rustc itself, copying all the info onto
125+ // the stderr channel we originally started with.
126+ //
127+ // The basic idea is to not use a default_handler() for rustc, and then also
128+ // not print things by default to the actual stderr.
129+ let ( p, c) = Chan :: new ( ) ;
130+ let w1 = io:: ChanWriter :: new ( c) ;
131+ let w2 = w1. clone ( ) ;
132+ let old = io:: stdio:: set_stderr ( ~w1) ;
133+ spawn ( proc ( ) {
134+ let mut p = io:: PortReader :: new ( p) ;
135+ let mut err = old. unwrap_or ( ~io:: stderr ( ) as ~Writer ) ;
136+ io:: util:: copy ( & mut p, & mut err) . unwrap ( ) ;
137+ } ) ;
138+ let emitter = diagnostic:: EmitterWriter :: new ( ~w2) ;
139+
140+ // Compile the code
141+ let diagnostic_handler = diagnostic:: mk_handler ( ~emitter) ;
116142 let span_diagnostic_handler =
117143 diagnostic:: mk_span_handler ( diagnostic_handler, parsesess. cm ) ;
118144
@@ -126,6 +152,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool)
126152 let cfg = driver:: build_configuration ( sess) ;
127153 driver:: compile_input ( sess, cfg, & input, & out, & None ) ;
128154
155+ // Run the code!
129156 let exe = outdir. path ( ) . join ( "rust_out" ) ;
130157 let out = Process :: output ( exe. as_str ( ) . unwrap ( ) , [ ] ) ;
131158 match out {
0 commit comments