diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 1a07393f9fc80f3fce28a0ee88615ed1af4c1e5e..3eb6f40ba53c39250734040b1591ad9fe6b62b37 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -232,8 +232,27 @@ fn print_maybe_styled(w: &mut EmitterWriter, match w.dst { Terminal(ref mut t) => { try!(t.attr(color)); - try!(t.write_str(msg)); - try!(t.reset()); + // If `msg` ends in a newline, we need to reset the color before + // the newline. We're making the assumption that we end up writing + // to a `LineBufferedWriter`, which means that emitting the reset + // after the newline ends up buffering the reset until we print + // another line or exit. Buffering the reset is a problem if we're + // sharing the terminal with any other programs (e.g. other rustc + // instances via `make -jN`). + // + // Note that if `msg` contains any internal newlines, this will + // result in the `LineBufferedWriter` flushing twice instead of + // once, which still leaves the opportunity for interleaved output + // to be miscolored. We assume this is rare enough that we don't + // have to worry about it. + if msg.ends_with("\n") { + try!(t.write_str(msg.slice_to(msg.len()-1))); + try!(t.reset()); + try!(t.write_str("\n")); + } else { + try!(t.write_str(msg)); + try!(t.reset()); + } Ok(()) } Raw(ref mut w) => {