Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ dependencies = [

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

[[package]]
name = "anstyle-lossy"
Expand Down Expand Up @@ -3756,6 +3756,8 @@ name = "rustc_errors"
version = "0.0.0"
dependencies = [
"annotate-snippets 0.11.5",
"anstream",
"anstyle",
"derive_setters",
"rustc_abi",
"rustc_ast",
Expand All @@ -3772,7 +3774,6 @@ dependencies = [
"rustc_span",
"serde",
"serde_json",
"termcolor",
"termize",
"tracing",
"windows 0.61.3",
Expand Down Expand Up @@ -4326,7 +4327,6 @@ dependencies = [
"rustc_macros",
"rustc_session",
"rustc_span",
"termcolor",
"thin-vec",
"tracing",
"unicode-normalization",
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,11 +521,11 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
};

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

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

// The pager failed. Try to print pretty output to stdout.
if let Some((bufwtr, mdbuf)) = &pretty_data
&& bufwtr.print(mdbuf).is_ok()
if let Some((bufwtr, mdbuf)) = &mut pretty_data
&& bufwtr.write_all(&mdbuf).is_ok()
{
return;
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ edition = "2024"
[dependencies]
# tidy-alphabetical-start
annotate-snippets = "0.11"
anstream = "0.6.20"
anstyle = "1.0.13"
derive_setters = "0.1.6"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
Expand All @@ -22,7 +24,6 @@ rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0.59"
termcolor = "1.2.0"
termize = "0.2"
tracing = "0.1"
# tidy-alphabetical-end
Expand Down
115 changes: 42 additions & 73 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use std::iter;
use std::path::Path;
use std::sync::Arc;

use anstream::{AutoStream, ColorChoice};
use anstyle::{AnsiColor, Effects};
use derive_setters::Setters;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sync::{DynSend, IntoDynSyncSend};
Expand All @@ -25,7 +27,6 @@ use rustc_lint_defs::pluralize;
use rustc_span::hygiene::{ExpnKind, MacroKind};
use rustc_span::source_map::SourceMap;
use rustc_span::{FileLines, FileName, SourceFile, Span, char_width, str_width};
use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
use tracing::{debug, instrument, trace, warn};

use crate::registry::Registry;
Expand Down Expand Up @@ -525,10 +526,6 @@ impl Emitter for HumanEmitter {
!self.short_message
}

fn supports_color(&self) -> bool {
self.dst.supports_color()
}

fn translator(&self) -> &Translator {
&self.translator
}
Expand Down Expand Up @@ -1701,7 +1698,6 @@ impl HumanEmitter {
} else {
col_sep_before_no_show_source = true;
}

// print out the span location and spacer before we print the annotated source
// to do this, we need to know if this span will be primary
let is_primary = primary_lo.file.name == annotated_file.file.name;
Expand Down Expand Up @@ -3127,7 +3123,6 @@ impl FileWithAnnotatedLines {
multiline_depth: 0,
});
}

let mut output = vec![];
let mut multiline_annotations = vec![];

Expand Down Expand Up @@ -3361,7 +3356,7 @@ const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
('\u{2069}', "�"),
];

fn normalize_whitespace(s: &str) -> String {
pub(crate) fn normalize_whitespace(s: &str) -> String {
const {
let mut i = 1;
while i < OUTPUT_REPLACEMENTS.len() {
Expand Down Expand Up @@ -3406,7 +3401,7 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
)
}

fn emit_to_destination(
pub(crate) fn emit_to_destination(
rendered_buffer: &[Vec<StyledString>],
lvl: &Level,
dst: &mut Destination,
Expand All @@ -3429,10 +3424,8 @@ fn emit_to_destination(
let _buffer_lock = lock::acquire_global_lock("rustc_errors");
for (pos, line) in rendered_buffer.iter().enumerate() {
for part in line {
let style = part.style.color_spec(*lvl);
dst.set_color(&style)?;
write!(dst, "{}", part.text)?;
dst.reset()?;
let style = part.style.anstyle(*lvl);
write!(dst, "{style}{}{style:#}", part.text)?;
}
if !short_message && (!lvl.is_failure_note() || pos != rendered_buffer.len() - 1) {
writeln!(dst)?;
Expand All @@ -3442,11 +3435,11 @@ fn emit_to_destination(
Ok(())
}

pub type Destination = Box<dyn WriteColor + Send>;
pub type Destination = AutoStream<Box<dyn Write + Send>>;

struct Buffy {
buffer_writer: BufferWriter,
buffer: Buffer,
buffer_writer: std::io::Stderr,
buffer: Vec<u8>,
}

impl Write for Buffy {
Expand All @@ -3455,7 +3448,7 @@ impl Write for Buffy {
}

fn flush(&mut self) -> io::Result<()> {
self.buffer_writer.print(&self.buffer)?;
self.buffer_writer.write_all(&self.buffer)?;
self.buffer.clear();
Ok(())
}
Expand All @@ -3470,83 +3463,59 @@ impl Drop for Buffy {
}
}

impl WriteColor for Buffy {
fn supports_color(&self) -> bool {
self.buffer.supports_color()
}

fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
self.buffer.set_color(spec)
}

fn reset(&mut self) -> io::Result<()> {
self.buffer.reset()
}
}

pub fn stderr_destination(color: ColorConfig) -> Destination {
let buffer_writer = std::io::stderr();
let choice = color.to_color_choice();
// We need to resolve `ColorChoice::Auto` before `Box`ing since
// `ColorChoice::Auto` on `dyn Write` will always resolve to `Never`
let choice = if matches!(choice, ColorChoice::Auto) {
AutoStream::choice(&buffer_writer)
} else {
choice
};
// On Windows we'll be performing global synchronization on the entire
// system for emitting rustc errors, so there's no need to buffer
// anything.
//
// On non-Windows we rely on the atomicity of `write` to ensure errors
// don't get all jumbled up.
if cfg!(windows) {
Box::new(StandardStream::stderr(choice))
AutoStream::new(Box::new(buffer_writer), choice)
} else {
let buffer_writer = BufferWriter::stderr(choice);
let buffer = buffer_writer.buffer();
Box::new(Buffy { buffer_writer, buffer })
let buffer = Vec::new();
AutoStream::new(Box::new(Buffy { buffer_writer, buffer }), choice)
}
}

/// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead.
///
/// See #36178.
const BRIGHT_BLUE: Color = if cfg!(windows) { Color::Cyan } else { Color::Blue };
const BRIGHT_BLUE: anstyle::Style = if cfg!(windows) {
AnsiColor::BrightCyan.on_default()
} else {
AnsiColor::BrightBlue.on_default()
};

impl Style {
fn color_spec(&self, lvl: Level) -> ColorSpec {
let mut spec = ColorSpec::new();
pub(crate) fn anstyle(&self, lvl: Level) -> anstyle::Style {
match self {
Style::Addition => {
spec.set_fg(Some(Color::Green)).set_intense(true);
}
Style::Removal => {
spec.set_fg(Some(Color::Red)).set_intense(true);
}
Style::LineAndColumn => {}
Style::LineNumber => {
spec.set_bold(true);
spec.set_intense(true);
spec.set_fg(Some(BRIGHT_BLUE));
}
Style::Quotation => {}
Style::MainHeaderMsg => {
spec.set_bold(true);
if cfg!(windows) {
spec.set_intense(true).set_fg(Some(Color::White));
}
}
Style::UnderlinePrimary | Style::LabelPrimary => {
spec = lvl.color();
spec.set_bold(true);
}
Style::UnderlineSecondary | Style::LabelSecondary => {
spec.set_bold(true).set_intense(true);
spec.set_fg(Some(BRIGHT_BLUE));
}
Style::HeaderMsg | Style::NoStyle => {}
Style::Level(lvl) => {
spec = lvl.color();
spec.set_bold(true);
}
Style::Highlight => {
spec.set_bold(true).set_fg(Some(Color::Magenta));
Style::Addition => AnsiColor::BrightGreen.on_default(),
Style::Removal => AnsiColor::BrightRed.on_default(),
Style::LineAndColumn => anstyle::Style::new(),
Style::LineNumber => BRIGHT_BLUE.effects(Effects::BOLD),
Style::Quotation => anstyle::Style::new(),
Style::MainHeaderMsg => if cfg!(windows) {
AnsiColor::BrightWhite.on_default()
} else {
anstyle::Style::new()
}
.effects(Effects::BOLD),
Style::UnderlinePrimary | Style::LabelPrimary => lvl.color().effects(Effects::BOLD),
Style::UnderlineSecondary | Style::LabelSecondary => BRIGHT_BLUE.effects(Effects::BOLD),
Style::HeaderMsg | Style::NoStyle => anstyle::Style::new(),
Style::Level(lvl) => lvl.color().effects(Effects::BOLD),
Style::Highlight => AnsiColor::Magenta.on_default().effects(Effects::BOLD),
}
spec
}
}

Expand Down
31 changes: 10 additions & 21 deletions compiler/rustc_errors/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use std::path::Path;
use std::sync::{Arc, Mutex};
use std::vec;

use anstream::{AutoStream, ColorChoice};
use derive_setters::Setters;
use rustc_data_structures::sync::IntoDynSyncSend;
use rustc_error_messages::FluentArgs;
Expand All @@ -23,7 +24,6 @@ use rustc_span::Span;
use rustc_span::hygiene::ExpnData;
use rustc_span::source_map::{FilePathMapping, SourceMap};
use serde::Serialize;
use termcolor::{ColorSpec, WriteColor};

use crate::diagnostic::IsLint;
use crate::emitter::{
Expand Down Expand Up @@ -333,7 +333,7 @@ impl Diagnostic {
// generate regular command line output and store it in the json

// A threadsafe buffer for writing.
#[derive(Default, Clone)]
#[derive(Clone)]
struct BufWriter(Arc<Mutex<Vec<u8>>>);

impl Write for BufWriter {
Expand All @@ -344,19 +344,6 @@ impl Diagnostic {
self.0.lock().unwrap().flush()
}
}
impl WriteColor for BufWriter {
fn supports_color(&self) -> bool {
false
}

fn set_color(&mut self, _spec: &ColorSpec) -> io::Result<()> {
Ok(())
}

fn reset(&mut self) -> io::Result<()> {
Ok(())
}
}

let translated_message = je.translator.translate_messages(&diag.messages, &args);

Expand All @@ -382,13 +369,15 @@ impl Diagnostic {
children
.insert(0, Diagnostic::from_sub_diagnostic(&diag.emitted_at_sub_diag(), &args, je));
}
let buf = BufWriter::default();
let mut dst: Destination = Box::new(buf.clone());
let buf = BufWriter(Arc::new(Mutex::new(Vec::new())));
let short = je.json_rendered.short();
match je.color_config {
ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)),
ColorConfig::Never => {}
}
let dst: Destination = AutoStream::new(
Box::new(buf.clone()),
match je.color_config.to_color_choice() {
ColorChoice::Auto => ColorChoice::Always,
choice => choice,
},
);
HumanEmitter::new(dst, je.translator.clone())
.short_message(short)
.sm(je.sm.clone())
Expand Down
Loading
Loading