Skip to content

Commit 57098c1

Browse files
Auto merge of #147207 - Muscraft:anstyle-anstream, r=<try>
refactor: Move to anstream + anstyle for styling
2 parents 1e1a394 + 1f92a2f commit 57098c1

27 files changed

+1225
-1217
lines changed

Cargo.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ dependencies = [
9595

9696
[[package]]
9797
name = "anstyle"
98-
version = "1.0.11"
98+
version = "1.0.13"
9999
source = "registry+https://github.com/rust-lang/crates.io-index"
100-
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
100+
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
101101

102102
[[package]]
103103
name = "anstyle-lossy"
@@ -3754,6 +3754,8 @@ name = "rustc_errors"
37543754
version = "0.0.0"
37553755
dependencies = [
37563756
"annotate-snippets 0.11.5",
3757+
"anstream",
3758+
"anstyle",
37573759
"derive_setters",
37583760
"rustc_abi",
37593761
"rustc_ast",
@@ -3770,7 +3772,6 @@ dependencies = [
37703772
"rustc_span",
37713773
"serde",
37723774
"serde_json",
3773-
"termcolor",
37743775
"termize",
37753776
"tracing",
37763777
"windows 0.61.3",
@@ -4323,7 +4324,6 @@ dependencies = [
43234324
"rustc_macros",
43244325
"rustc_session",
43254326
"rustc_span",
4326-
"termcolor",
43274327
"thin-vec",
43284328
"tracing",
43294329
"unicode-normalization",

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -521,11 +521,11 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
521521
};
522522

523523
// Try to prettify the raw markdown text. The result can be used by the pager or on stdout.
524-
let pretty_data = {
524+
let mut pretty_data = {
525525
let mdstream = markdown::MdStream::parse_str(content);
526526
let bufwtr = markdown::create_stdout_bufwtr();
527-
let mut mdbuf = bufwtr.buffer();
528-
if mdstream.write_termcolor_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None }
527+
let mut mdbuf = Vec::new();
528+
if mdstream.write_anstream_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None }
529529
};
530530

531531
// Try to print via the pager, pretty output if possible.
@@ -546,8 +546,8 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
546546
}
547547

548548
// The pager failed. Try to print pretty output to stdout.
549-
if let Some((bufwtr, mdbuf)) = &pretty_data
550-
&& bufwtr.print(mdbuf).is_ok()
549+
if let Some((bufwtr, mdbuf)) = &mut pretty_data
550+
&& bufwtr.write_all(&mdbuf).is_ok()
551551
{
552552
return;
553553
}

compiler/rustc_errors/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ edition = "2024"
66
[dependencies]
77
# tidy-alphabetical-start
88
annotate-snippets = "0.11"
9+
anstream = "0.6.20"
10+
anstyle = "1.0.13"
911
derive_setters = "0.1.6"
1012
rustc_abi = { path = "../rustc_abi" }
1113
rustc_ast = { path = "../rustc_ast" }
@@ -22,7 +24,6 @@ rustc_serialize = { path = "../rustc_serialize" }
2224
rustc_span = { path = "../rustc_span" }
2325
serde = { version = "1.0.125", features = ["derive"] }
2426
serde_json = "1.0.59"
25-
termcolor = "1.2.0"
2627
termize = "0.2"
2728
tracing = "0.1"
2829
# tidy-alphabetical-end

compiler/rustc_errors/src/emitter.rs

Lines changed: 58 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use std::iter;
1616
use std::path::Path;
1717
use std::sync::Arc;
1818

19+
use anstream::ColorChoice;
20+
use anstream::stream::{AsLockedWrite, RawStream};
21+
use anstyle::{AnsiColor, Effects};
1922
use derive_setters::Setters;
2023
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
2124
use rustc_data_structures::sync::{DynSend, IntoDynSyncSend};
@@ -25,7 +28,6 @@ use rustc_lint_defs::pluralize;
2528
use rustc_span::hygiene::{ExpnKind, MacroKind};
2629
use rustc_span::source_map::SourceMap;
2730
use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width};
28-
use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
2931
use tracing::{debug, instrument, trace, warn};
3032

3133
use crate::registry::Registry;
@@ -1701,7 +1703,6 @@ impl HumanEmitter {
17011703
} else {
17021704
col_sep_before_no_show_source = true;
17031705
}
1704-
17051706
// print out the span location and spacer before we print the annotated source
17061707
// to do this, we need to know if this span will be primary
17071708
let is_primary = primary_lo.file.name == annotated_file.file.name;
@@ -3127,7 +3128,6 @@ impl FileWithAnnotatedLines {
31273128
multiline_depth: 0,
31283129
});
31293130
}
3130-
31313131
let mut output = vec![];
31323132
let mut multiline_annotations = vec![];
31333133

@@ -3361,7 +3361,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
33613361
('\u{2069}', "�"),
33623362
];
33633363

3364-
fn normalize_whitespace(s: &str) -> String {
3364+
pub(crate) fn normalize_whitespace(s: &str) -> String {
33653365
const {
33663366
let mut i = 1;
33673367
while i < OUTPUT_REPLACEMENTS.len() {
@@ -3406,7 +3406,26 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
34063406
)
34073407
}
34083408

3409-
fn emit_to_destination(
3409+
pub trait WriteColor: io::Write {
3410+
fn supports_color(&self) -> bool;
3411+
}
3412+
3413+
impl<S: RawStream + AsLockedWrite> WriteColor for anstream::AutoStream<S> {
3414+
fn supports_color(&self) -> bool {
3415+
match self.current_choice() {
3416+
ColorChoice::Always | ColorChoice::AlwaysAnsi | ColorChoice::Auto => true,
3417+
ColorChoice::Never => false,
3418+
}
3419+
}
3420+
}
3421+
3422+
impl WriteColor for std::io::Sink {
3423+
fn supports_color(&self) -> bool {
3424+
false
3425+
}
3426+
}
3427+
3428+
pub(crate) fn emit_to_destination(
34103429
rendered_buffer: &[Vec<StyledString>],
34113430
lvl: &Level,
34123431
dst: &mut Destination,
@@ -3429,10 +3448,8 @@ fn emit_to_destination(
34293448
let _buffer_lock = lock::acquire_global_lock("rustc_errors");
34303449
for (pos, line) in rendered_buffer.iter().enumerate() {
34313450
for part in line {
3432-
let style = part.style.color_spec(*lvl);
3433-
dst.set_color(&style)?;
3434-
write!(dst, "{}", part.text)?;
3435-
dst.reset()?;
3451+
let style = part.style.anstyle(*lvl);
3452+
write!(dst, "{style}{}{style:#}", part.text)?;
34363453
}
34373454
if !short_message && (!lvl.is_failure_note() || pos != rendered_buffer.len() - 1) {
34383455
writeln!(dst)?;
@@ -3445,8 +3462,8 @@ fn emit_to_destination(
34453462
pub type Destination = Box<dyn WriteColor + Send>;
34463463

34473464
struct Buffy {
3448-
buffer_writer: BufferWriter,
3449-
buffer: Buffer,
3465+
buffer_writer: anstream::Stderr,
3466+
buffer: Vec<u8>,
34503467
}
34513468

34523469
impl Write for Buffy {
@@ -3455,7 +3472,7 @@ impl Write for Buffy {
34553472
}
34563473

34573474
fn flush(&mut self) -> io::Result<()> {
3458-
self.buffer_writer.print(&self.buffer)?;
3475+
self.buffer_writer.write_all(&self.buffer)?;
34593476
self.buffer.clear();
34603477
Ok(())
34613478
}
@@ -3472,15 +3489,11 @@ impl Drop for Buffy {
34723489

34733490
impl WriteColor for Buffy {
34743491
fn supports_color(&self) -> bool {
3475-
self.buffer.supports_color()
3476-
}
3477-
3478-
fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
3479-
self.buffer.set_color(spec)
3480-
}
3481-
3482-
fn reset(&mut self) -> io::Result<()> {
3483-
self.buffer.reset()
3492+
self.buffer_writer.current_choice();
3493+
match self.buffer_writer.current_choice() {
3494+
ColorChoice::Always | ColorChoice::AlwaysAnsi | ColorChoice::Auto => true,
3495+
ColorChoice::Never => false,
3496+
}
34843497
}
34853498
}
34863499

@@ -3492,61 +3505,44 @@ pub fn stderr_destination(color: ColorConfig) -> Destination {
34923505
//
34933506
// On non-Windows we rely on the atomicity of `write` to ensure errors
34943507
// don't get all jumbled up.
3508+
let buffer_writer = anstream::Stderr::new(std::io::stderr(), choice);
34953509
if cfg!(windows) {
3496-
Box::new(StandardStream::stderr(choice))
3510+
Box::new(buffer_writer)
34973511
} else {
3498-
let buffer_writer = BufferWriter::stderr(choice);
3499-
let buffer = buffer_writer.buffer();
3512+
let buffer = Vec::new();
35003513
Box::new(Buffy { buffer_writer, buffer })
35013514
}
35023515
}
35033516

35043517
/// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead.
35053518
///
35063519
/// See #36178.
3507-
const BRIGHT_BLUE: Color = if cfg!(windows) { Color::Cyan } else { Color::Blue };
3520+
const BRIGHT_BLUE: anstyle::Style = if cfg!(windows) {
3521+
AnsiColor::BrightCyan.on_default()
3522+
} else {
3523+
AnsiColor::BrightBlue.on_default()
3524+
};
35083525

35093526
impl Style {
3510-
fn color_spec(&self, lvl: Level) -> ColorSpec {
3511-
let mut spec = ColorSpec::new();
3527+
pub(crate) fn anstyle(&self, lvl: Level) -> anstyle::Style {
35123528
match self {
3513-
Style::Addition => {
3514-
spec.set_fg(Some(Color::Green)).set_intense(true);
3515-
}
3516-
Style::Removal => {
3517-
spec.set_fg(Some(Color::Red)).set_intense(true);
3518-
}
3519-
Style::LineAndColumn => {}
3520-
Style::LineNumber => {
3521-
spec.set_bold(true);
3522-
spec.set_intense(true);
3523-
spec.set_fg(Some(BRIGHT_BLUE));
3524-
}
3525-
Style::Quotation => {}
3526-
Style::MainHeaderMsg => {
3527-
spec.set_bold(true);
3528-
if cfg!(windows) {
3529-
spec.set_intense(true).set_fg(Some(Color::White));
3530-
}
3531-
}
3532-
Style::UnderlinePrimary | Style::LabelPrimary => {
3533-
spec = lvl.color();
3534-
spec.set_bold(true);
3535-
}
3536-
Style::UnderlineSecondary | Style::LabelSecondary => {
3537-
spec.set_bold(true).set_intense(true);
3538-
spec.set_fg(Some(BRIGHT_BLUE));
3539-
}
3540-
Style::HeaderMsg | Style::NoStyle => {}
3541-
Style::Level(lvl) => {
3542-
spec = lvl.color();
3543-
spec.set_bold(true);
3544-
}
3545-
Style::Highlight => {
3546-
spec.set_bold(true).set_fg(Some(Color::Magenta));
3529+
Style::Addition => AnsiColor::BrightGreen.on_default(),
3530+
Style::Removal => AnsiColor::BrightRed.on_default(),
3531+
Style::LineAndColumn => anstyle::Style::new(),
3532+
Style::LineNumber => BRIGHT_BLUE.effects(Effects::BOLD),
3533+
Style::Quotation => anstyle::Style::new(),
3534+
Style::MainHeaderMsg => if cfg!(windows) {
3535+
AnsiColor::BrightWhite.on_default()
3536+
} else {
3537+
anstyle::Style::new()
35473538
}
3539+
.effects(Effects::BOLD),
3540+
Style::UnderlinePrimary | Style::LabelPrimary => lvl.color().effects(Effects::BOLD),
3541+
Style::UnderlineSecondary | Style::LabelSecondary => BRIGHT_BLUE.effects(Effects::BOLD),
3542+
Style::HeaderMsg | Style::NoStyle => anstyle::Style::new(),
3543+
Style::Level(lvl) => lvl.color().effects(Effects::BOLD),
3544+
Style::Highlight => AnsiColor::Magenta.on_default().effects(Effects::BOLD),
35483545
}
3549-
spec
35503546
}
35513547
}
35523548

compiler/rustc_errors/src/json.rs

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use std::path::Path;
1515
use std::sync::{Arc, Mutex};
1616
use std::vec;
1717

18+
use anstream::AutoStream;
1819
use derive_setters::Setters;
1920
use rustc_data_structures::sync::IntoDynSyncSend;
2021
use rustc_error_messages::FluentArgs;
@@ -23,12 +24,11 @@ use rustc_span::Span;
2324
use rustc_span::hygiene::ExpnData;
2425
use rustc_span::source_map::{FilePathMapping, SourceMap};
2526
use serde::Serialize;
26-
use termcolor::{ColorSpec, WriteColor};
2727

2828
use crate::diagnostic::IsLint;
2929
use crate::emitter::{
3030
ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, OutputTheme,
31-
TimingEvent, should_show_source_code,
31+
TimingEvent, WriteColor, should_show_source_code,
3232
};
3333
use crate::registry::Registry;
3434
use crate::timings::{TimingRecord, TimingSection};
@@ -333,8 +333,8 @@ impl Diagnostic {
333333
// generate regular command line output and store it in the json
334334

335335
// A threadsafe buffer for writing.
336-
#[derive(Default, Clone)]
337-
struct BufWriter(Arc<Mutex<Vec<u8>>>);
336+
#[derive(Clone)]
337+
struct BufWriter(Arc<Mutex<AutoStream<Vec<u8>>>>);
338338

339339
impl Write for BufWriter {
340340
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
@@ -344,17 +344,15 @@ impl Diagnostic {
344344
self.0.lock().unwrap().flush()
345345
}
346346
}
347+
347348
impl WriteColor for BufWriter {
348349
fn supports_color(&self) -> bool {
349-
false
350-
}
351-
352-
fn set_color(&mut self, _spec: &ColorSpec) -> io::Result<()> {
353-
Ok(())
354-
}
355-
356-
fn reset(&mut self) -> io::Result<()> {
357-
Ok(())
350+
match self.0.lock().unwrap().current_choice() {
351+
anstream::ColorChoice::Always
352+
| anstream::ColorChoice::AlwaysAnsi
353+
| anstream::ColorChoice::Auto => true,
354+
anstream::ColorChoice::Never => false,
355+
}
358356
}
359357
}
360358

@@ -382,13 +380,12 @@ impl Diagnostic {
382380
children
383381
.insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je));
384382
}
385-
let buf = BufWriter::default();
386-
let mut dst: Destination = Box::new(buf.clone());
383+
let buf = BufWriter(Arc::new(Mutex::new(AutoStream::new(
384+
Vec::new(),
385+
je.color_config.to_color_choice(),
386+
))));
387387
let short = je.json_rendered.short();
388-
match je.color_config {
389-
ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)),
390-
ColorConfig::Never => {}
391-
}
388+
let dst: Destination = Box::new(buf.clone());
392389
HumanEmitter::new(dst, je.translator.clone())
393390
.short_message(short)
394391
.sm(je.sm.clone())
@@ -405,7 +402,7 @@ impl Diagnostic {
405402
})
406403
.emit_diagnostic(diag, registry);
407404
let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap();
408-
let buf = String::from_utf8(buf).unwrap();
405+
let buf = String::from_utf8(buf.into_inner()).unwrap();
409406

410407
Diagnostic {
411408
message: translated_message.to_string(),

0 commit comments

Comments
 (0)