@@ -25,6 +25,7 @@ use rustc::metadata::creader::Loader;
25
25
use getopts;
26
26
use syntax:: diagnostic;
27
27
use syntax:: parse;
28
+ use syntax:: codemap:: CodeMap ;
28
29
29
30
use core;
30
31
use clean;
@@ -35,7 +36,6 @@ use passes;
35
36
use visit_ast:: RustdocVisitor ;
36
37
37
38
pub fn run ( input : & str , matches : & getopts:: Matches ) -> int {
38
- let parsesess = parse:: new_parse_sess ( ) ;
39
39
let input_path = Path :: new ( input) ;
40
40
let input = driver:: FileInput ( input_path. clone ( ) ) ;
41
41
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 {
49
49
} ;
50
50
51
51
52
- let diagnostic_handler = diagnostic:: mk_handler ( ) ;
52
+ let cm = @CodeMap :: new ( ) ;
53
+ let diagnostic_handler = diagnostic:: default_handler ( ) ;
53
54
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) ;
55
58
56
59
let sess = driver:: build_session_ ( sessopts,
57
60
Some ( input_path) ,
@@ -112,7 +115,30 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool)
112
115
.. ( * session:: basic_options ( ) ) . clone ( )
113
116
} ;
114
117
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) ;
116
142
let span_diagnostic_handler =
117
143
diagnostic:: mk_span_handler ( diagnostic_handler, parsesess. cm ) ;
118
144
@@ -126,6 +152,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool)
126
152
let cfg = driver:: build_configuration ( sess) ;
127
153
driver:: compile_input ( sess, cfg, & input, & out, & None ) ;
128
154
155
+ // Run the code!
129
156
let exe = outdir. path ( ) . join ( "rust_out" ) ;
130
157
let out = Process :: output ( exe. as_str ( ) . unwrap ( ) , [ ] ) ;
131
158
match out {
0 commit comments