Skip to content

Commit b991bbe

Browse files
committed
Reset the terminal color before the newline for diagnostics
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.
1 parent e8c579e commit b991bbe

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

src/libsyntax/diagnostic.rs

Lines changed: 21 additions & 2 deletions
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)