diff options
| author | bors <bors@rust-lang.org> | 2023-08-05 06:22:33 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-08-05 06:22:33 +0000 |
| commit | 3d9e8f16b31586f1d4f9e9a0b9cd626d63454ed8 (patch) | |
| tree | 0594fecff57824ca58e21237eac1ef2ce2d377a2 /compiler/rustc_errors/src | |
| parent | 646f5643aba41e0dfd62fc9d5cdfa955e4e6fa2a (diff) | |
| parent | 621aeeb096d8e4f3eb656259fc286a1f32862ed3 (diff) | |
| download | rust-3d9e8f16b31586f1d4f9e9a0b9cd626d63454ed8.tar.gz rust-3d9e8f16b31586f1d4f9e9a0b9cd626d63454ed8.zip | |
Auto merge of #3014 - RalfJung:rustup, r=RalfJung
Rustup
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/emitter.rs | 251 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/json.rs | 32 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 13 |
3 files changed, 104 insertions, 192 deletions
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 44654571d43..0cae06881b1 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -7,8 +7,6 @@ //! //! The output types are defined in `rustc_session::config::ErrorOutputType`. -use Destination::*; - use rustc_span::source_map::SourceMap; use rustc_span::{FileLines, SourceFile, Span}; @@ -24,6 +22,7 @@ use crate::{ }; use rustc_lint_defs::pluralize; +use derive_setters::Setters; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::sync::Lrc; use rustc_error_messages::{FluentArgs, SpanLabel}; @@ -35,8 +34,8 @@ use std::io::prelude::*; use std::io::{self, IsTerminal}; use std::iter; use std::path::Path; -use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream}; -use termcolor::{Buffer, Color, WriteColor}; +use termcolor::{Ansi, Buffer, BufferWriter, ColorChoice, ColorSpec, StandardStream}; +use termcolor::{Color, WriteColor}; /// Default column width, used in tests and when terminal dimensions cannot be determined. const DEFAULT_COLUMN_WIDTH: usize = 140; @@ -60,31 +59,15 @@ impl HumanReadableErrorType { } pub fn new_emitter( self, - dst: Box<dyn Write + Send>, - source_map: Option<Lrc<SourceMap>>, - bundle: Option<Lrc<FluentBundle>>, + mut dst: Box<dyn WriteColor + Send>, fallback_bundle: LazyFallbackBundle, - teach: bool, - diagnostic_width: Option<usize>, - macro_backtrace: bool, - track_diagnostics: bool, - terminal_url: TerminalUrl, ) -> EmitterWriter { let (short, color_config) = self.unzip(); let color = color_config.suggests_using_colors(); - EmitterWriter::new( - dst, - source_map, - bundle, - fallback_bundle, - short, - teach, - color, - diagnostic_width, - macro_backtrace, - track_diagnostics, - terminal_url, - ) + if !dst.supports_color() && color { + dst = Box::new(Ansi::new(dst)); + } + EmitterWriter::new(dst, fallback_bundle).short_message(short) } } @@ -639,10 +622,13 @@ impl ColorConfig { } /// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short` +#[derive(Setters)] pub struct EmitterWriter { + #[setters(skip)] dst: Destination, sm: Option<Lrc<SourceMap>>, fluent_bundle: Option<Lrc<FluentBundle>>, + #[setters(skip)] fallback_bundle: LazyFallbackBundle, short_message: bool, teach: bool, @@ -662,65 +648,32 @@ pub struct FileWithAnnotatedLines { } impl EmitterWriter { - pub fn stderr( - color_config: ColorConfig, - source_map: Option<Lrc<SourceMap>>, - fluent_bundle: Option<Lrc<FluentBundle>>, - fallback_bundle: LazyFallbackBundle, - short_message: bool, - teach: bool, - diagnostic_width: Option<usize>, - macro_backtrace: bool, - track_diagnostics: bool, - terminal_url: TerminalUrl, - ) -> EmitterWriter { - let dst = Destination::from_stderr(color_config); + pub fn stderr(color_config: ColorConfig, fallback_bundle: LazyFallbackBundle) -> EmitterWriter { + let dst = from_stderr(color_config); + Self::create(dst, fallback_bundle) + } + + fn create(dst: Destination, fallback_bundle: LazyFallbackBundle) -> EmitterWriter { EmitterWriter { dst, - sm: source_map, - fluent_bundle, + sm: None, + fluent_bundle: None, fallback_bundle, - short_message, - teach, + short_message: false, + teach: false, ui_testing: false, - diagnostic_width, - macro_backtrace, - track_diagnostics, - terminal_url, + diagnostic_width: None, + macro_backtrace: false, + track_diagnostics: false, + terminal_url: TerminalUrl::No, } } pub fn new( - dst: Box<dyn Write + Send>, - source_map: Option<Lrc<SourceMap>>, - fluent_bundle: Option<Lrc<FluentBundle>>, + dst: Box<dyn WriteColor + Send>, fallback_bundle: LazyFallbackBundle, - short_message: bool, - teach: bool, - colored: bool, - diagnostic_width: Option<usize>, - macro_backtrace: bool, - track_diagnostics: bool, - terminal_url: TerminalUrl, ) -> EmitterWriter { - EmitterWriter { - dst: Raw(dst, colored), - sm: source_map, - fluent_bundle, - fallback_bundle, - short_message, - teach, - ui_testing: false, - diagnostic_width, - macro_backtrace, - track_diagnostics, - terminal_url, - } - } - - pub fn ui_testing(mut self, ui_testing: bool) -> Self { - self.ui_testing = ui_testing; - self + Self::create(dst, fallback_bundle) } fn maybe_anonymized(&self, line_num: usize) -> Cow<'static, str> { @@ -2203,11 +2156,10 @@ impl EmitterWriter { Err(e) => panic!("failed to emit error: {e}"), } - let mut dst = self.dst.writable(); - match writeln!(dst) { + match writeln!(self.dst) { Err(e) => panic!("failed to emit error: {e}"), _ => { - if let Err(e) = dst.flush() { + if let Err(e) = self.dst.flush() { panic!("failed to emit error: {e}") } } @@ -2618,8 +2570,6 @@ fn emit_to_destination( ) -> io::Result<()> { use crate::lock; - let mut dst = dst.writable(); - // In order to prevent error message interleaving, where multiple error lines get intermixed // when multiple compiler processes error simultaneously, we emit errors with additional // steps. @@ -2635,7 +2585,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 { - dst.apply_style(*lvl, part.style)?; + let style = part.style.color_spec(*lvl); + dst.set_color(&style)?; write!(dst, "{}", part.text)?; dst.reset()?; } @@ -2647,61 +2598,69 @@ fn emit_to_destination( Ok(()) } -pub enum Destination { - Terminal(StandardStream), - Buffered(BufferWriter), - // The bool denotes whether we should be emitting ansi color codes or not - Raw(Box<(dyn Write + Send)>, bool), -} +pub type Destination = Box<(dyn WriteColor + Send)>; -pub enum WritableDst<'a> { - Terminal(&'a mut StandardStream), - Buffered(&'a mut BufferWriter, Buffer), - Raw(&'a mut (dyn Write + Send)), - ColoredRaw(Ansi<&'a mut (dyn Write + Send)>), +struct Buffy { + buffer_writer: BufferWriter, + buffer: Buffer, } -impl Destination { - fn from_stderr(color: ColorConfig) -> Destination { - let choice = color.to_color_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) { - Terminal(StandardStream::stderr(choice)) - } else { - Buffered(BufferWriter::stderr(choice)) - } +impl Write for Buffy { + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { + self.buffer.write(buf) } - fn writable(&mut self) -> WritableDst<'_> { - match *self { - Destination::Terminal(ref mut t) => WritableDst::Terminal(t), - Destination::Buffered(ref mut t) => { - let buf = t.buffer(); - WritableDst::Buffered(t, buf) - } - Destination::Raw(ref mut t, false) => WritableDst::Raw(t), - Destination::Raw(ref mut t, true) => WritableDst::ColoredRaw(Ansi::new(t)), + fn flush(&mut self) -> io::Result<()> { + self.buffer_writer.print(&self.buffer)?; + self.buffer.clear(); + Ok(()) + } +} + +impl Drop for Buffy { + fn drop(&mut self) { + if !self.buffer.is_empty() { + self.flush().unwrap(); + panic!("buffers need to be flushed in order to print their contents"); } } +} +impl WriteColor for Buffy { fn supports_color(&self) -> bool { - match *self { - Self::Terminal(ref stream) => stream.supports_color(), - Self::Buffered(ref buffer) => buffer.buffer().supports_color(), - Self::Raw(_, supports_color) => supports_color, - } + 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() + } +} + +fn from_stderr(color: ColorConfig) -> Destination { + let choice = color.to_color_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)) + } else { + let buffer_writer = BufferWriter::stderr(choice); + let buffer = buffer_writer.buffer(); + Box::new(Buffy { buffer_writer, buffer }) } } -impl<'a> WritableDst<'a> { - fn apply_style(&mut self, lvl: Level, style: Style) -> io::Result<()> { +impl Style { + fn color_spec(&self, lvl: Level) -> ColorSpec { let mut spec = ColorSpec::new(); - match style { + match self { Style::Addition => { spec.set_fg(Some(Color::Green)).set_intense(true); } @@ -2746,53 +2705,7 @@ impl<'a> WritableDst<'a> { spec.set_bold(true); } } - self.set_color(&spec) - } - - fn set_color(&mut self, color: &ColorSpec) -> io::Result<()> { - match *self { - WritableDst::Terminal(ref mut t) => t.set_color(color), - WritableDst::Buffered(_, ref mut t) => t.set_color(color), - WritableDst::ColoredRaw(ref mut t) => t.set_color(color), - WritableDst::Raw(_) => Ok(()), - } - } - - fn reset(&mut self) -> io::Result<()> { - match *self { - WritableDst::Terminal(ref mut t) => t.reset(), - WritableDst::Buffered(_, ref mut t) => t.reset(), - WritableDst::ColoredRaw(ref mut t) => t.reset(), - WritableDst::Raw(_) => Ok(()), - } - } -} - -impl<'a> Write for WritableDst<'a> { - fn write(&mut self, bytes: &[u8]) -> io::Result<usize> { - match *self { - WritableDst::Terminal(ref mut t) => t.write(bytes), - WritableDst::Buffered(_, ref mut buf) => buf.write(bytes), - WritableDst::Raw(ref mut w) => w.write(bytes), - WritableDst::ColoredRaw(ref mut t) => t.write(bytes), - } - } - - fn flush(&mut self) -> io::Result<()> { - match *self { - WritableDst::Terminal(ref mut t) => t.flush(), - WritableDst::Buffered(_, ref mut buf) => buf.flush(), - WritableDst::Raw(ref mut w) => w.flush(), - WritableDst::ColoredRaw(ref mut w) => w.flush(), - } - } -} - -impl<'a> Drop for WritableDst<'a> { - fn drop(&mut self) { - if let WritableDst::Buffered(ref mut dst, ref mut buf) = self { - drop(dst.print(buf)); - } + spec } } diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 55f7c485024..b8f58e3057c 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -10,6 +10,7 @@ // FIXME: spec the JSON output properly. use rustc_span::source_map::{FilePathMapping, SourceMap}; +use termcolor::{ColorSpec, WriteColor}; use crate::emitter::{Emitter, HumanReadableErrorType}; use crate::registry::Registry; @@ -356,20 +357,29 @@ 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 buf = BufWriter::default(); let output = buf.clone(); je.json_rendered - .new_emitter( - Box::new(buf), - Some(je.sm.clone()), - je.fluent_bundle.clone(), - je.fallback_bundle.clone(), - false, - je.diagnostic_width, - je.macro_backtrace, - je.track_diagnostics, - je.terminal_url, - ) + .new_emitter(Box::new(buf), je.fallback_bundle.clone()) + .sm(Some(je.sm.clone())) + .fluent_bundle(je.fluent_bundle.clone()) + .diagnostic_width(je.diagnostic_width) + .macro_backtrace(je.macro_backtrace) + .track_diagnostics(je.track_diagnostics) + .terminal_url(je.terminal_url) .ui_testing(je.ui_testing) .emit_diagnostic(diag); let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 3b753629128..7d660d2dbaa 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -557,18 +557,7 @@ impl Handler { sm: Option<Lrc<SourceMap>>, fallback_bundle: LazyFallbackBundle, ) -> Self { - let emitter = Box::new(EmitterWriter::stderr( - ColorConfig::Auto, - sm, - None, - fallback_bundle, - false, - false, - None, - false, - false, - TerminalUrl::No, - )); + let emitter = Box::new(EmitterWriter::stderr(ColorConfig::Auto, fallback_bundle).sm(sm)); Self::with_emitter(emitter) } pub fn disable_warnings(mut self) -> Self { |
