Skip to content

Commit 6291955

Browse files
committed
auto merge of #14296 : kballard/rust/diagnostic_color_newline, r=alexcrichton
When printing colored diagnostics, we need to reset the terminal before emitting the newline, not after. Otherwise it gets line-buffered and the color won't reset until the next line is printed or the compiler exits. Normally this isn't a problem, but when running rustc in parallel with other processes (e.g. `make -j4`) this can cause the color to leak to other lines.
2 parents ec8ec54 + b991bbe commit 6291955

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

src/libsyntax/diagnostic.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,27 @@ fn print_maybe_styled(w: &mut EmitterWriter,
232232
match w.dst {
233233
Terminal(ref mut t) => {
234234
try!(t.attr(color));
235-
try!(t.write_str(msg));
236-
try!(t.reset());
235+
// If `msg` ends in a newline, we need to reset the color before
236+
// the newline. We're making the assumption that we end up writing
237+
// to a `LineBufferedWriter`, which means that emitting the reset
238+
// after the newline ends up buffering the reset until we print
239+
// another line or exit. Buffering the reset is a problem if we're
240+
// sharing the terminal with any other programs (e.g. other rustc
241+
// instances via `make -jN`).
242+
//
243+
// Note that if `msg` contains any internal newlines, this will
244+
// result in the `LineBufferedWriter` flushing twice instead of
245+
// once, which still leaves the opportunity for interleaved output
246+
// to be miscolored. We assume this is rare enough that we don't
247+
// have to worry about it.
248+
if msg.ends_with("\n") {
249+
try!(t.write_str(msg.slice_to(msg.len()-1)));
250+
try!(t.reset());
251+
try!(t.write_str("\n"));
252+
} else {
253+
try!(t.write_str(msg));
254+
try!(t.reset());
255+
}
237256
Ok(())
238257
}
239258
Raw(ref mut w) => {

0 commit comments

Comments
 (0)