From c1f01638af37ec287fe09ae41a6c784b42875438 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 09:09:19 +1100 Subject: [PATCH 01/14] Minor visibility and formatting improvements. --- compiler/rustc_errors/src/emitter.rs | 20 +++++++++++--------- compiler/rustc_errors/src/error.rs | 3 +++ compiler/rustc_errors/src/lib.rs | 12 ++++++------ 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 304922018ebe7..967b7674e0507 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -130,8 +130,8 @@ impl Margin { fn was_cut_right(&self, line_len: usize) -> bool { let right = if self.computed_right == self.span_right || self.computed_right == self.label_right { - // Account for the "..." padding given above. Otherwise we end up with code lines that - // do fit but end in "..." as if they were trimmed. + // Account for the "..." padding given above. Otherwise we end up with code lines + // that do fit but end in "..." as if they were trimmed. self.computed_right - 6 } else { self.computed_right @@ -657,9 +657,9 @@ pub struct HumanEmitter { } #[derive(Debug)] -pub struct FileWithAnnotatedLines { - pub file: Lrc, - pub lines: Vec, +pub(crate) struct FileWithAnnotatedLines { + pub(crate) file: Lrc, + pub(crate) lines: Vec, multiline_depth: usize, } @@ -724,8 +724,9 @@ impl HumanEmitter { .skip(left) .take_while(|ch| { // Make sure that the trimming on the right will fall within the terminal width. - // FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` is. - // For now, just accept that sometimes the code line will be longer than desired. + // FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` + // is. For now, just accept that sometimes the code line will be longer than + // desired. let next = unicode_width::UnicodeWidthChar::width(*ch).unwrap_or(1); if taken + next > right - left { return false; @@ -2228,8 +2229,8 @@ impl HumanEmitter { buffer.puts(*row_num - 1, max_line_num_len + 3, &line, Style::NoStyle); *row_num += 1; } - // If the last line is exactly equal to the line we need to add, we can skip both of them. - // This allows us to avoid output like the following: + // If the last line is exactly equal to the line we need to add, we can skip both of + // them. This allows us to avoid output like the following: // 2 - & // 2 + if true { true } else { false } // 3 - if true { true } else { false } @@ -2586,6 +2587,7 @@ fn num_overlap( let extra = if inclusive { 1 } else { 0 }; (b_start..b_end + extra).contains(&a_start) || (a_start..a_end + extra).contains(&b_start) } + fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool { num_overlap( a1.start_col.display, diff --git a/compiler/rustc_errors/src/error.rs b/compiler/rustc_errors/src/error.rs index ec0a2fe8cd8d0..ca818a4d832d1 100644 --- a/compiler/rustc_errors/src/error.rs +++ b/compiler/rustc_errors/src/error.rs @@ -23,9 +23,11 @@ impl<'args> TranslateError<'args> { pub fn message(id: &'args Cow<'args, str>, args: &'args FluentArgs<'args>) -> Self { Self::One { id, args, kind: TranslateErrorKind::MessageMissing } } + pub fn primary(id: &'args Cow<'args, str>, args: &'args FluentArgs<'args>) -> Self { Self::One { id, args, kind: TranslateErrorKind::PrimaryBundleMissing } } + pub fn attribute( id: &'args Cow<'args, str>, args: &'args FluentArgs<'args>, @@ -33,6 +35,7 @@ impl<'args> TranslateError<'args> { ) -> Self { Self::One { id, args, kind: TranslateErrorKind::AttributeMissing { attr } } } + pub fn value(id: &'args Cow<'args, str>, args: &'args FluentArgs<'args>) -> Self { Self::One { id, args, kind: TranslateErrorKind::ValueMissing } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index bc338b01d8bb6..bb6f031cec629 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -217,10 +217,10 @@ impl CodeSuggestion { use rustc_span::{CharPos, Pos}; - /// Extracts a substring from the provided `line_opt` based on the specified low and high indices, - /// appends it to the given buffer `buf`, and returns the count of newline characters in the substring - /// for accurate highlighting. - /// If `line_opt` is `None`, a newline character is appended to the buffer, and 0 is returned. + /// Extracts a substring from the provided `line_opt` based on the specified low and high + /// indices, appends it to the given buffer `buf`, and returns the count of newline + /// characters in the substring for accurate highlighting. If `line_opt` is `None`, a + /// newline character is appended to the buffer, and 0 is returned. /// /// ## Returns /// @@ -486,8 +486,8 @@ struct DiagCtxtInner { /// have been converted. check_unstable_expect_diagnostics: bool, - /// Expected [`DiagInner`][struct@diagnostic::DiagInner]s store a [`LintExpectationId`] as part of - /// the lint level. [`LintExpectationId`]s created early during the compilation + /// Expected [`DiagInner`][struct@diagnostic::DiagInner]s store a [`LintExpectationId`] as part + /// of the lint level. [`LintExpectationId`]s created early during the compilation /// (before `HirId`s have been defined) are not stable and can therefore not be /// stored on disk. This buffer stores these diagnostics until the ID has been /// replaced by a stable [`LintExpectationId`]. The [`DiagInner`][struct@diagnostic::DiagInner]s From 869bd03a04fa2c6f95dc78523d098ed6b1e88b04 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 09:27:11 +1100 Subject: [PATCH 02/14] Simplify `UnusedExterns` lifetimes. In practice, 'a and 'b and 'c are always the same. This change makes `UnusedExterns` more like `ArtifactNotification`, which uses a single lifetime 'a in multiple ways. --- compiler/rustc_errors/src/json.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 88a83c8bf785d..35030638f4c8d 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -162,7 +162,7 @@ enum EmitTyped<'a> { Diagnostic(Diagnostic), Artifact(ArtifactNotification<'a>), FutureIncompat(FutureIncompatReport<'a>), - UnusedExtern(UnusedExterns<'a, 'a, 'a>), + UnusedExtern(UnusedExterns<'a>), } impl Translate for JsonEmitter { @@ -332,11 +332,11 @@ struct FutureIncompatReport<'a> { // We could unify this struct the one in rustdoc but they have different // ownership semantics, so doing so would create wasteful allocations. #[derive(Serialize)] -struct UnusedExterns<'a, 'b, 'c> { +struct UnusedExterns<'a> { /// The severity level of the unused dependencies lint lint_level: &'a str, /// List of unused externs by their names. - unused_extern_names: &'b [&'c str], + unused_extern_names: &'a [&'a str], } impl Diagnostic { From 3c3f15cafe2945bd3b0db899b5288c678d392b2c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 10:14:21 +1100 Subject: [PATCH 03/14] Use `Destination` more. --- compiler/rustc_errors/src/emitter.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 967b7674e0507..cbe973330dc51 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -60,7 +60,7 @@ impl HumanReadableErrorType { } pub fn new_emitter( self, - mut dst: Box, + mut dst: Destination, fallback_bundle: LazyFallbackBundle, ) -> HumanEmitter { let (short, color_config) = self.unzip(); @@ -686,10 +686,7 @@ impl HumanEmitter { } } - pub fn new( - dst: Box, - fallback_bundle: LazyFallbackBundle, - ) -> HumanEmitter { + pub fn new(dst: Destination, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { Self::create(dst, fallback_bundle) } @@ -2634,7 +2631,7 @@ fn emit_to_destination( Ok(()) } -pub type Destination = Box<(dyn WriteColor + Send)>; +pub type Destination = Box; struct Buffy { buffer_writer: BufferWriter, From 805e50e71bfdb870011b4bb128929c6103af602f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 13:36:46 +1100 Subject: [PATCH 04/14] Remove unnecessary `diagnostic_width` call. This `HumanEmitter` is only created to test if it supports colour. The diagnostic width isn't relevant. --- src/librustdoc/doctest.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index e2b4ec5908b9d..8390b34dba9de 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -576,9 +576,8 @@ pub(crate) fn make_test( rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false, ); - supports_color = HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle.clone()) - .diagnostic_width(Some(80)) - .supports_color(); + supports_color = + HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle.clone()).supports_color(); let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); From ca5b79ddf7325fa7f6a88c170edbffa1757b149e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 13:55:16 +1100 Subject: [PATCH 05/14] Remove unnecessary `output` local variable. --- compiler/rustc_errors/src/json.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 35030638f4c8d..94d0c5d060ec7 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -405,9 +405,8 @@ impl Diagnostic { .collect(); let buf = BufWriter::default(); - let output = buf.clone(); je.json_rendered - .new_emitter(Box::new(buf), je.fallback_bundle.clone()) + .new_emitter(Box::new(buf.clone()), je.fallback_bundle.clone()) .sm(Some(je.sm.clone())) .fluent_bundle(je.fluent_bundle.clone()) .diagnostic_width(je.diagnostic_width) @@ -417,8 +416,8 @@ impl Diagnostic { .ui_testing(je.ui_testing) .ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone()) .emit_diagnostic(diag); - let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap(); - let output = String::from_utf8(output).unwrap(); + let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap(); + let buf = String::from_utf8(buf).unwrap(); Diagnostic { message: translated_message.to_string(), @@ -426,7 +425,7 @@ impl Diagnostic { level, spans, children, - rendered: Some(output), + rendered: Some(buf), } } From f9eef38e32f5e362006122d4a11d8e1f41e2f033 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 11:40:50 +1100 Subject: [PATCH 06/14] Inline and remove `DiagCtxt::with_tty_emitter` It only has two call sites, and one of those doesn't set the source map. --- compiler/rustc_errors/src/lib.rs | 11 ++--------- compiler/rustc_session/src/parse.rs | 12 ++++++++---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index bb6f031cec629..72b3c88ee0349 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -59,11 +59,11 @@ pub use snippet::Style; // See https://github.com/rust-lang/rust/pull/115393. pub use termcolor::{Color, ColorSpec, WriteColor}; -use emitter::{is_case_difference, DynEmitter, Emitter, HumanEmitter}; +use emitter::{is_case_difference, DynEmitter, Emitter}; use registry::Registry; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; -use rustc_data_structures::sync::{Lock, Lrc}; +use rustc_data_structures::sync::Lock; use rustc_data_structures::AtomicRef; use rustc_lint_defs::LintExpectationId; use rustc_span::source_map::SourceMap; @@ -586,13 +586,6 @@ impl Drop for DiagCtxtInner { } impl DiagCtxt { - pub fn with_tty_emitter( - sm: Option>, - fallback_bundle: LazyFallbackBundle, - ) -> Self { - let emitter = Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle).sm(sm)); - Self::with_emitter(emitter) - } pub fn disable_warnings(mut self) -> Self { self.inner.get_mut().flags.can_emit_warnings = false; self diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 752bb05f3d79d..c88a118696587 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -13,9 +13,10 @@ use crate::Session; use rustc_ast::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc}; -use rustc_errors::{emitter::SilentEmitter, DiagCtxt}; +use rustc_errors::emitter::{HumanEmitter, SilentEmitter}; use rustc_errors::{ - fallback_fluent_bundle, Diag, DiagnosticMessage, EmissionGuarantee, MultiSpan, StashKey, + fallback_fluent_bundle, ColorConfig, Diag, DiagCtxt, DiagnosticMessage, EmissionGuarantee, + MultiSpan, StashKey, }; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_span::edition::Edition; @@ -236,7 +237,9 @@ impl ParseSess { pub fn new(locale_resources: Vec<&'static str>, file_path_mapping: FilePathMapping) -> Self { let fallback_bundle = fallback_fluent_bundle(locale_resources, false); let sm = Lrc::new(SourceMap::new(file_path_mapping)); - let dcx = DiagCtxt::with_tty_emitter(Some(sm.clone()), fallback_bundle); + let emitter = + Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle).sm(Some(sm.clone()))); + let dcx = DiagCtxt::with_emitter(emitter); ParseSess::with_dcx(dcx, sm) } @@ -265,7 +268,8 @@ impl ParseSess { pub fn with_silent_emitter(fatal_note: String) -> Self { let fallback_bundle = fallback_fluent_bundle(Vec::new(), false); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fatal_dcx = DiagCtxt::with_tty_emitter(None, fallback_bundle).disable_warnings(); + let emitter = Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle)); + let fatal_dcx = DiagCtxt::with_emitter(emitter); let dcx = DiagCtxt::with_emitter(Box::new(SilentEmitter { fatal_dcx, fatal_note })) .disable_warnings(); ParseSess::with_dcx(dcx, sm) From 880c1c585f1252a8b63b402b44def940cac6f134 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 11:50:32 +1100 Subject: [PATCH 07/14] Rename `DiagCtxt::with_emitter` as `DiagCtxt::new`. Because it's now the only constructor. --- compiler/rustc_codegen_ssa/src/back/write.rs | 2 +- compiler/rustc_driver_impl/src/lib.rs | 2 +- compiler/rustc_errors/src/json/tests.rs | 2 +- compiler/rustc_errors/src/lib.rs | 2 +- compiler/rustc_expand/src/tests.rs | 2 +- compiler/rustc_session/src/parse.rs | 8 ++++---- compiler/rustc_session/src/session.rs | 8 ++++---- src/librustdoc/core.rs | 2 +- src/librustdoc/doctest.rs | 4 ++-- src/librustdoc/passes/lint/check_code_block_syntax.rs | 2 +- .../clippy/clippy_lints/src/doc/needless_doctest_main.rs | 2 +- src/tools/rustfmt/src/parse/session.rs | 4 ++-- 12 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index c784ee4867596..97089dff31bb6 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -373,7 +373,7 @@ pub struct CodegenContext { impl CodegenContext { pub fn create_dcx(&self) -> DiagCtxt { - DiagCtxt::with_emitter(Box::new(self.diag_emitter.clone())) + DiagCtxt::new(Box::new(self.diag_emitter.clone())) } pub fn config(&self, kind: ModuleKind) -> &ModuleConfig { diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 692c059beb0c4..10188026a97c3 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -1388,7 +1388,7 @@ fn report_ice( rustc_errors::ColorConfig::Auto, fallback_bundle, )); - let dcx = rustc_errors::DiagCtxt::with_emitter(emitter); + let dcx = rustc_errors::DiagCtxt::new(emitter); // a .span_bug or .bug call has already printed what // it wants to print. diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 303de0a93f633..ba8d58e159e55 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -61,7 +61,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { ); let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1)); - let dcx = DiagCtxt::with_emitter(Box::new(je)); + let dcx = DiagCtxt::new(Box::new(je)); dcx.span_err(span, "foo"); let bytes = output.lock().unwrap(); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 72b3c88ee0349..a5e6aed13eb46 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -601,7 +601,7 @@ impl DiagCtxt { self } - pub fn with_emitter(emitter: Box) -> Self { + pub fn new(emitter: Box) -> Self { Self { inner: Lock::new(DiagCtxtInner { flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() }, diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 3c14ad5e7b824..b242ce795fd05 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -33,7 +33,7 @@ fn create_test_handler() -> (DiagCtxt, Lrc, Arc>>) { let emitter = HumanEmitter::new(Box::new(Shared { data: output.clone() }), fallback_bundle) .sm(Some(source_map.clone())) .diagnostic_width(Some(140)); - let dcx = DiagCtxt::with_emitter(Box::new(emitter)); + let dcx = DiagCtxt::new(Box::new(emitter)); (dcx, source_map, output) } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index c88a118696587..5e8acf693ddf7 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -239,7 +239,7 @@ impl ParseSess { let sm = Lrc::new(SourceMap::new(file_path_mapping)); let emitter = Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle).sm(Some(sm.clone()))); - let dcx = DiagCtxt::with_emitter(emitter); + let dcx = DiagCtxt::new(emitter); ParseSess::with_dcx(dcx, sm) } @@ -269,9 +269,9 @@ impl ParseSess { let fallback_bundle = fallback_fluent_bundle(Vec::new(), false); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let emitter = Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle)); - let fatal_dcx = DiagCtxt::with_emitter(emitter); - let dcx = DiagCtxt::with_emitter(Box::new(SilentEmitter { fatal_dcx, fatal_note })) - .disable_warnings(); + let fatal_dcx = DiagCtxt::new(emitter); + let dcx = + DiagCtxt::new(Box::new(SilentEmitter { fatal_dcx, fatal_note })).disable_warnings(); ParseSess::with_dcx(dcx, sm) } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index e9db96dc3562a..aa45958c07ba0 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1080,8 +1080,8 @@ pub fn build_session( ); let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle); - let mut dcx = DiagCtxt::with_emitter(emitter) - .with_flags(sopts.unstable_opts.dcx_flags(can_emit_warnings)); + let mut dcx = + DiagCtxt::new(emitter).with_flags(sopts.unstable_opts.dcx_flags(can_emit_warnings)); if let Some(ice_file) = ice_file { dcx = dcx.with_ice_file(ice_file); } @@ -1402,7 +1402,7 @@ pub struct EarlyDiagCtxt { impl EarlyDiagCtxt { pub fn new(output: ErrorOutputType) -> Self { let emitter = mk_emitter(output); - Self { dcx: DiagCtxt::with_emitter(emitter) } + Self { dcx: DiagCtxt::new(emitter) } } /// Swap out the underlying dcx once we acquire the user's preference on error emission @@ -1412,7 +1412,7 @@ impl EarlyDiagCtxt { self.dcx.abort_if_errors(); let emitter = mk_emitter(output); - self.dcx = DiagCtxt::with_emitter(emitter); + self.dcx = DiagCtxt::new(emitter); } #[allow(rustc::untranslatable_diagnostic)] diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index c662f054d0524..65ce24fe10e3a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -172,7 +172,7 @@ pub(crate) fn new_dcx( } }; - rustc_errors::DiagCtxt::with_emitter(emitter).with_flags(unstable_opts.dcx_flags(true)) + rustc_errors::DiagCtxt::new(emitter).with_flags(unstable_opts.dcx_flags(true)) } /// Parse, resolve, and typecheck the given crate. diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 8390b34dba9de..05df32812c3a4 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -582,7 +582,7 @@ pub(crate) fn make_test( let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); // FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser - let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings(); + let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); let sess = ParseSess::with_dcx(dcx, sm); let mut found_main = false; @@ -767,7 +767,7 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); - let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings(); + let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); let sess = ParseSess::with_dcx(dcx, sm); let mut parser = match maybe_new_parser_from_source_str(&sess, filename, source.to_owned()) { diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index c6571e72fc558..5145d8babef9d 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -42,7 +42,7 @@ fn check_rust_syntax( let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle }; let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings(); + let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); let source = dox[code_block.code].to_owned(); let sess = ParseSess::with_dcx(dcx, sm); diff --git a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs index 58656140352f9..fdb9ceb7179a5 100644 --- a/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs +++ b/src/tools/clippy/clippy_lints/src/doc/needless_doctest_main.rs @@ -45,7 +45,7 @@ pub fn check( let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false); let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); - let dcx = DiagCtxt::with_emitter(Box::new(emitter)).disable_warnings(); + let dcx = DiagCtxt::new(Box::new(emitter)).disable_warnings(); #[expect(clippy::arc_with_non_send_sync)] // `Lrc` is expected by with_dcx let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let sess = ParseSess::with_dcx(dcx, sm); diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index e33f1ca755ca2..ad36e022b8dd1 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -154,7 +154,7 @@ fn default_dcx( ); Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone()))) }; - DiagCtxt::with_emitter(Box::new(SilentOnIgnoredFilesEmitter { + DiagCtxt::new(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, source_map, emitter, @@ -235,7 +235,7 @@ impl ParseSess { } pub(crate) fn set_silent_emitter(&mut self) { - self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter()); + self.parse_sess.dcx = DiagCtxt::new(silent_emitter()); } pub(crate) fn span_to_filename(&self, span: Span) -> FileName { From d3727413ed96a8feedcca9931b9b8abb72632492 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 10:17:28 +1100 Subject: [PATCH 08/14] Merge HumanEmitter::{new,create}. They have the same signature, and the former just calls the latter. --- compiler/rustc_errors/src/emitter.rs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index cbe973330dc51..89015a3ca2ef3 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -665,11 +665,10 @@ pub(crate) struct FileWithAnnotatedLines { impl HumanEmitter { pub fn stderr(color_config: ColorConfig, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { - let dst = from_stderr(color_config); - Self::create(dst, fallback_bundle) + Self::new(from_stderr(color_config), fallback_bundle) } - fn create(dst: Destination, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { + pub fn new(dst: Destination, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { HumanEmitter { dst: IntoDynSyncSend(dst), sm: None, @@ -686,10 +685,6 @@ impl HumanEmitter { } } - pub fn new(dst: Destination, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { - Self::create(dst, fallback_bundle) - } - fn maybe_anonymized(&self, line_num: usize) -> Cow<'static, str> { if self.ui_testing { Cow::Borrowed(ANONYMIZED_LINE_NUM) From 437325bdd4e5fc54b0f78491e63fa386ebfffbba Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 14:47:09 +1100 Subject: [PATCH 09/14] Inline and remove `HumanReadableErrorType::new_emitter`. And likewise with `ColorConfig::suggests_using_colors`. They both have a single call site. And note that `BufWriter::supports_color()` always returns false, which enables a small bit of constant folding along the way. --- compiler/rustc_errors/src/emitter.rs | 20 +------------------- compiler/rustc_errors/src/json.rs | 18 +++++++++++++++--- compiler/rustc_errors/src/json/tests.rs | 1 - 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 89015a3ca2ef3..ff105b4d46f30 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -35,7 +35,7 @@ use std::io::prelude::*; use std::io::{self, IsTerminal}; use std::iter; use std::path::Path; -use termcolor::{Ansi, Buffer, BufferWriter, ColorChoice, ColorSpec, StandardStream}; +use termcolor::{Buffer, BufferWriter, ColorChoice, ColorSpec, StandardStream}; use termcolor::{Color, WriteColor}; /// Default column width, used in tests and when terminal dimensions cannot be determined. @@ -58,18 +58,6 @@ impl HumanReadableErrorType { HumanReadableErrorType::AnnotateSnippet(cc) => (false, cc), } } - pub fn new_emitter( - self, - mut dst: Destination, - fallback_bundle: LazyFallbackBundle, - ) -> HumanEmitter { - let (short, color_config) = self.unzip(); - let color = color_config.suggests_using_colors(); - if !dst.supports_color() && color { - dst = Box::new(Ansi::new(dst)); - } - HumanEmitter::new(dst, fallback_bundle).short_message(short) - } } #[derive(Clone, Copy, Debug)] @@ -628,12 +616,6 @@ impl ColorConfig { ColorConfig::Auto => ColorChoice::Never, } } - fn suggests_using_colors(self) -> bool { - match self { - ColorConfig::Always | ColorConfig::Auto => true, - ColorConfig::Never => false, - } - } } /// Handles the writing of `HumanReadableErrorType::Default` and `HumanReadableErrorType::Short` diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 94d0c5d060ec7..ab2ed5ebaebc5 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -12,7 +12,10 @@ use rustc_span::source_map::{FilePathMapping, SourceMap}; use termcolor::{ColorSpec, WriteColor}; -use crate::emitter::{should_show_source_code, Emitter, HumanReadableErrorType}; +use crate::emitter::{ + should_show_source_code, ColorConfig, Destination, Emitter, HumanEmitter, + HumanReadableErrorType, +}; use crate::registry::Registry; use crate::translation::{to_fluent_args, Translate}; use crate::{ @@ -405,8 +408,17 @@ impl Diagnostic { .collect(); let buf = BufWriter::default(); - je.json_rendered - .new_emitter(Box::new(buf.clone()), je.fallback_bundle.clone()) + let mut dst: Destination = Box::new(buf.clone()); + let (short, color_config) = je.json_rendered.unzip(); + let color = match color_config { + ColorConfig::Always | ColorConfig::Auto => true, + ColorConfig::Never => false, + }; + if color { + dst = Box::new(termcolor::Ansi::new(dst)); + } + HumanEmitter::new(dst, je.fallback_bundle.clone()) + .short_message(short) .sm(Some(je.sm.clone())) .fluent_bundle(je.fluent_bundle.clone()) .diagnostic_width(je.diagnostic_width) diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index ba8d58e159e55..e541f4ca7d41e 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -1,6 +1,5 @@ use super::*; -use crate::emitter::ColorConfig; use crate::DiagCtxt; use rustc_span::BytePos; From 067d7c3d00a05989bd4b7d4b5648d61748f80848 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 15:37:38 +1100 Subject: [PATCH 10/14] Inline and remove `HumanEmitter::stderr`. Because `HumanEmitter::new` is enough, in conjunction with the (renamed) `stderr_destination` function. --- compiler/rustc_driver_impl/src/lib.rs | 5 +++-- compiler/rustc_errors/src/emitter.rs | 6 +----- compiler/rustc_errors/src/json/tests.rs | 1 + compiler/rustc_session/src/parse.rs | 11 +++++++---- compiler/rustc_session/src/session.rs | 9 ++++++--- src/librustdoc/core.rs | 4 ++-- src/librustdoc/doctest.rs | 4 +++- src/tools/rustfmt/src/parse/session.rs | 7 +++++-- 8 files changed, 28 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 10188026a97c3..410e7eba30a9c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -21,6 +21,7 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{ get_resident_set_size, print_time_passes_entry, TimePassesFormat, }; +use rustc_errors::emitter::stderr_destination; use rustc_errors::registry::Registry; use rustc_errors::{ markdown, ColorConfig, DiagCtxt, ErrCode, ErrorGuaranteed, FatalError, PResult, @@ -1384,8 +1385,8 @@ fn report_ice( ) { let fallback_bundle = rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false); - let emitter = Box::new(rustc_errors::emitter::HumanEmitter::stderr( - rustc_errors::ColorConfig::Auto, + let emitter = Box::new(rustc_errors::emitter::HumanEmitter::new( + stderr_destination(rustc_errors::ColorConfig::Auto), fallback_bundle, )); let dcx = rustc_errors::DiagCtxt::new(emitter); diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index ff105b4d46f30..87e4a5ead4daf 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -646,10 +646,6 @@ pub(crate) struct FileWithAnnotatedLines { } impl HumanEmitter { - pub fn stderr(color_config: ColorConfig, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { - Self::new(from_stderr(color_config), fallback_bundle) - } - pub fn new(dst: Destination, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { HumanEmitter { dst: IntoDynSyncSend(dst), @@ -2650,7 +2646,7 @@ impl WriteColor for Buffy { } } -fn from_stderr(color: ColorConfig) -> Destination { +pub fn stderr_destination(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 diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index e541f4ca7d41e..fc9948cb2fc6a 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -1,6 +1,7 @@ use super::*; use crate::DiagCtxt; +use rustc_span::source_map::FilePathMapping; use rustc_span::BytePos; use std::str; diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 5e8acf693ddf7..18c8652aaf20a 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -13,7 +13,7 @@ use crate::Session; use rustc_ast::node_id::NodeId; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc}; -use rustc_errors::emitter::{HumanEmitter, SilentEmitter}; +use rustc_errors::emitter::{stderr_destination, HumanEmitter, SilentEmitter}; use rustc_errors::{ fallback_fluent_bundle, ColorConfig, Diag, DiagCtxt, DiagnosticMessage, EmissionGuarantee, MultiSpan, StashKey, @@ -237,8 +237,10 @@ impl ParseSess { pub fn new(locale_resources: Vec<&'static str>, file_path_mapping: FilePathMapping) -> Self { let fallback_bundle = fallback_fluent_bundle(locale_resources, false); let sm = Lrc::new(SourceMap::new(file_path_mapping)); - let emitter = - Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle).sm(Some(sm.clone()))); + let emitter = Box::new( + HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle) + .sm(Some(sm.clone())), + ); let dcx = DiagCtxt::new(emitter); ParseSess::with_dcx(dcx, sm) } @@ -268,7 +270,8 @@ impl ParseSess { pub fn with_silent_emitter(fatal_note: String) -> Self { let fallback_bundle = fallback_fluent_bundle(Vec::new(), false); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let emitter = Box::new(HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle)); + let emitter = + Box::new(HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle)); let fatal_dcx = DiagCtxt::new(emitter); let dcx = DiagCtxt::new(Box::new(SilentEmitter { fatal_dcx, fatal_note })).disable_warnings(); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index aa45958c07ba0..9ac49f663abf9 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -18,7 +18,7 @@ use rustc_data_structures::sync::{ AtomicU64, DynSend, DynSync, Lock, Lrc, MappedReadGuard, ReadGuard, RwLock, }; use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter; -use rustc_errors::emitter::{DynEmitter, HumanEmitter, HumanReadableErrorType}; +use rustc_errors::emitter::{stderr_destination, DynEmitter, HumanEmitter, HumanReadableErrorType}; use rustc_errors::json::JsonEmitter; use rustc_errors::registry::Registry; use rustc_errors::{ @@ -982,7 +982,7 @@ fn default_emitter( ); Box::new(emitter.ui_testing(sopts.unstable_opts.ui_testing)) } else { - let emitter = HumanEmitter::stderr(color_config, fallback_bundle) + let emitter = HumanEmitter::new(stderr_destination(color_config), fallback_bundle) .fluent_bundle(bundle) .sm(Some(source_map)) .short_message(short) @@ -1473,7 +1473,10 @@ fn mk_emitter(output: ErrorOutputType) -> Box { let emitter: Box = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); - Box::new(HumanEmitter::stderr(color_config, fallback_bundle).short_message(short)) + Box::new( + HumanEmitter::new(stderr_destination(color_config), fallback_bundle) + .short_message(short), + ) } config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic( pretty, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 65ce24fe10e3a..bcc72857d0aa8 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -1,7 +1,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; use rustc_data_structures::unord::UnordSet; -use rustc_errors::emitter::{DynEmitter, HumanEmitter}; +use rustc_errors::emitter::{stderr_destination, DynEmitter, HumanEmitter}; use rustc_errors::json::JsonEmitter; use rustc_errors::{codes::*, ErrorGuaranteed, TerminalUrl}; use rustc_feature::UnstableFeatures; @@ -141,7 +141,7 @@ pub(crate) fn new_dcx( ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); Box::new( - HumanEmitter::stderr(color_config, fallback_bundle) + HumanEmitter::new(stderr_destination(color_config), fallback_bundle) .sm(source_map.map(|sm| sm as _)) .short_message(short) .teach(unstable_opts.teach) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 05df32812c3a4..3d92444364f68 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1,6 +1,7 @@ use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; +use rustc_errors::emitter::stderr_destination; use rustc_errors::{ColorConfig, ErrorGuaranteed, FatalError}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{self as hir, intravisit, CRATE_HIR_ID}; @@ -577,7 +578,8 @@ pub(crate) fn make_test( false, ); supports_color = - HumanEmitter::stderr(ColorConfig::Auto, fallback_bundle.clone()).supports_color(); + HumanEmitter::new(stderr_destination(ColorConfig::Auto), fallback_bundle.clone()) + .supports_color(); let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index ad36e022b8dd1..7e6517a66dd97 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -3,7 +3,7 @@ use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; -use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter}; +use rustc_errors::emitter::{stderr_destination, DynEmitter, Emitter, HumanEmitter}; use rustc_errors::translation::Translate; use rustc_errors::{ ColorConfig, Diag, DiagCtxt, DiagInner, ErrorGuaranteed, Level as DiagnosticLevel, @@ -152,7 +152,10 @@ fn default_dcx( rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), false, ); - Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone()))) + Box::new( + HumanEmitter::new(stderr_destination(emit_color), fallback_bundle) + .sm(Some(source_map.clone())), + ) }; DiagCtxt::new(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, From 2999d8dc72e9ed9e895d6a9e2d3d34f1cd4370ba Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 09:21:02 +1100 Subject: [PATCH 11/14] Inline and remove `JsonEmitter::{basic,stderr}`. They are so similar to `JsonEmitter::new` it's not worth having separate functions, it makes the code harder to read. --- compiler/rustc_errors/src/json.rs | 56 +-------------------------- compiler/rustc_session/src/session.rs | 15 ++++--- src/librustdoc/core.rs | 4 +- 3 files changed, 14 insertions(+), 61 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index ab2ed5ebaebc5..e99a70c393e19 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -9,7 +9,7 @@ // FIXME: spec the JSON output properly. -use rustc_span::source_map::{FilePathMapping, SourceMap}; +use rustc_span::source_map::SourceMap; use termcolor::{ColorSpec, WriteColor}; use crate::emitter::{ @@ -56,60 +56,6 @@ pub struct JsonEmitter { } impl JsonEmitter { - pub fn stderr( - registry: Option, - source_map: Lrc, - fluent_bundle: Option>, - fallback_bundle: LazyFallbackBundle, - pretty: bool, - json_rendered: HumanReadableErrorType, - diagnostic_width: Option, - macro_backtrace: bool, - track_diagnostics: bool, - terminal_url: TerminalUrl, - ) -> JsonEmitter { - JsonEmitter { - dst: IntoDynSyncSend(Box::new(io::BufWriter::new(io::stderr()))), - registry, - sm: source_map, - fluent_bundle, - fallback_bundle, - pretty, - ui_testing: false, - ignored_directories_in_source_blocks: Vec::new(), - json_rendered, - diagnostic_width, - macro_backtrace, - track_diagnostics, - terminal_url, - } - } - - pub fn basic( - pretty: bool, - json_rendered: HumanReadableErrorType, - fluent_bundle: Option>, - fallback_bundle: LazyFallbackBundle, - diagnostic_width: Option, - macro_backtrace: bool, - track_diagnostics: bool, - terminal_url: TerminalUrl, - ) -> JsonEmitter { - let file_path_mapping = FilePathMapping::empty(); - JsonEmitter::stderr( - None, - Lrc::new(SourceMap::new(file_path_mapping)), - fluent_bundle, - fallback_bundle, - pretty, - json_rendered, - diagnostic_width, - macro_backtrace, - track_diagnostics, - terminal_url, - ) - } - pub fn new( dst: Box, registry: Option, diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 9ac49f663abf9..2979d880dbd0f 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -28,7 +28,7 @@ use rustc_errors::{ use rustc_macros::HashStable_Generic; pub use rustc_span::def_id::StableCrateId; use rustc_span::edition::Edition; -use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMap}; +use rustc_span::source_map::{FileLoader, FilePathMapping, RealFileLoader, SourceMap}; use rustc_span::{SourceFileHashAlgorithm, Span, Symbol}; use rustc_target::asm::InlineAsmArch; use rustc_target::spec::{CodeModel, PanicStrategy, RelocModel, RelroLevel}; @@ -39,6 +39,7 @@ use rustc_target::spec::{ use std::any::Any; use std::env; use std::fmt; +use std::io; use std::ops::{Div, Mul}; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -998,7 +999,8 @@ fn default_emitter( } } config::ErrorOutputType::Json { pretty, json_rendered } => Box::new( - JsonEmitter::stderr( + JsonEmitter::new( + Box::new(io::BufWriter::new(io::stderr())), Some(registry), source_map, bundle, @@ -1478,11 +1480,14 @@ fn mk_emitter(output: ErrorOutputType) -> Box { .short_message(short), ) } - config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::basic( - pretty, - json_rendered, + config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::new( + Box::new(io::BufWriter::new(io::stderr())), + None, + Lrc::new(SourceMap::new(FilePathMapping::empty())), None, fallback_bundle, + pretty, + json_rendered, None, false, false, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index bcc72857d0aa8..463b8385d435c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -20,6 +20,7 @@ use rustc_span::symbol::sym; use rustc_span::{source_map, Span}; use std::cell::RefCell; +use std::io; use std::mem; use std::rc::Rc; use std::sync::LazyLock; @@ -155,7 +156,8 @@ pub(crate) fn new_dcx( Lrc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty())) }); Box::new( - JsonEmitter::stderr( + JsonEmitter::new( + Box::new(io::BufWriter::new(io::stderr())), None, source_map, None, From 9ff4487999ccd02065ec56fdc8cee665feae9680 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 16:03:59 +1100 Subject: [PATCH 12/14] Make `JsonEmitter` more like `HumanEmitter`. Use `derive(Setters)` to derive setters, and then change `JsonEmitter::new` to only have the arguments that are always used. --- compiler/rustc_errors/src/emitter.rs | 3 +- compiler/rustc_errors/src/json.rs | 48 ++++++++++--------------- compiler/rustc_errors/src/json/tests.rs | 8 +---- compiler/rustc_session/src/session.rs | 20 ++++------- src/librustdoc/core.rs | 11 +++--- 5 files changed, 32 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 87e4a5ead4daf..5637c05d04c69 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -21,12 +21,11 @@ use crate::{ FluentBundle, LazyFallbackBundle, Level, MultiSpan, Subdiag, SubstitutionHighlight, SuggestionStyle, TerminalUrl, }; -use rustc_lint_defs::pluralize; - use derive_setters::Setters; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::sync::{DynSend, IntoDynSyncSend, Lrc}; use rustc_error_messages::{FluentArgs, SpanLabel}; +use rustc_lint_defs::pluralize; use rustc_span::hygiene::{ExpnKind, MacroKind}; use std::borrow::Cow; use std::cmp::{max, min, Reverse}; diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index e99a70c393e19..3166768e9e272 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -9,9 +9,6 @@ // FIXME: spec the JSON output properly. -use rustc_span::source_map::SourceMap; -use termcolor::{ColorSpec, WriteColor}; - use crate::emitter::{ should_show_source_code, ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, @@ -22,32 +19,39 @@ use crate::{ diagnostic::IsLint, CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, Subdiag, TerminalUrl, }; -use rustc_lint_defs::Applicability; - +use derive_setters::Setters; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_error_messages::FluentArgs; +use rustc_lint_defs::Applicability; use rustc_span::hygiene::ExpnData; +use rustc_span::source_map::SourceMap; use rustc_span::Span; +use serde::Serialize; use std::error::Report; use std::io::{self, Write}; use std::path::Path; use std::sync::{Arc, Mutex}; use std::vec; - -use serde::Serialize; +use termcolor::{ColorSpec, WriteColor}; #[cfg(test)] mod tests; +#[derive(Setters)] pub struct JsonEmitter { + #[setters(skip)] dst: IntoDynSyncSend>, registry: Option, + #[setters(skip)] sm: Lrc, fluent_bundle: Option>, + #[setters(skip)] fallback_bundle: LazyFallbackBundle, + #[setters(skip)] pretty: bool, ui_testing: bool, ignored_directories_in_source_blocks: Vec, + #[setters(skip)] json_rendered: HumanReadableErrorType, diagnostic_width: Option, macro_backtrace: bool, @@ -58,42 +62,28 @@ pub struct JsonEmitter { impl JsonEmitter { pub fn new( dst: Box, - registry: Option, - source_map: Lrc, - fluent_bundle: Option>, + sm: Lrc, fallback_bundle: LazyFallbackBundle, pretty: bool, json_rendered: HumanReadableErrorType, - diagnostic_width: Option, - macro_backtrace: bool, - track_diagnostics: bool, - terminal_url: TerminalUrl, ) -> JsonEmitter { JsonEmitter { dst: IntoDynSyncSend(dst), - registry, - sm: source_map, - fluent_bundle, + registry: None, + sm, + fluent_bundle: None, fallback_bundle, pretty, ui_testing: false, ignored_directories_in_source_blocks: Vec::new(), json_rendered, - diagnostic_width, - macro_backtrace, - track_diagnostics, - terminal_url, + diagnostic_width: None, + macro_backtrace: false, + track_diagnostics: false, + terminal_url: TerminalUrl::No, } } - pub fn ui_testing(self, ui_testing: bool) -> Self { - Self { ui_testing, ..self } - } - - pub fn ignored_directories_in_source_blocks(self, value: Vec) -> Self { - Self { ignored_directories_in_source_blocks: value, ..self } - } - fn emit(&mut self, val: EmitTyped<'_>) -> io::Result<()> { if self.pretty { serde_json::to_writer_pretty(&mut *self.dst, &val)? diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index fc9948cb2fc6a..80b4d2bf75c0c 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -48,16 +48,10 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { let output = Arc::new(Mutex::new(Vec::new())); let je = JsonEmitter::new( Box::new(Shared { data: output.clone() }), - None, sm, - None, fallback_bundle, - true, + true, // pretty HumanReadableErrorType::Short(ColorConfig::Never), - None, - false, - false, - TerminalUrl::No, ); let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1)); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 2979d880dbd0f..09fb6aa5d8f98 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1001,21 +1001,21 @@ fn default_emitter( config::ErrorOutputType::Json { pretty, json_rendered } => Box::new( JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), - Some(registry), source_map, - bundle, fallback_bundle, pretty, json_rendered, - sopts.diagnostic_width, - macro_backtrace, - track_diagnostics, - terminal_url, ) + .registry(Some(registry)) + .fluent_bundle(bundle) .ui_testing(sopts.unstable_opts.ui_testing) .ignored_directories_in_source_blocks( sopts.unstable_opts.ignore_directory_in_diagnostics_source_blocks.clone(), - ), + ) + .diagnostic_width(sopts.diagnostic_width) + .macro_backtrace(macro_backtrace) + .track_diagnostics(track_diagnostics) + .terminal_url(terminal_url), ), } } @@ -1482,16 +1482,10 @@ fn mk_emitter(output: ErrorOutputType) -> Box { } config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), - None, Lrc::new(SourceMap::new(FilePathMapping::empty())), - None, fallback_bundle, pretty, json_rendered, - None, - false, - false, - TerminalUrl::No, )), }; emitter diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 463b8385d435c..9ba79cf5d29f1 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -158,18 +158,15 @@ pub(crate) fn new_dcx( Box::new( JsonEmitter::new( Box::new(io::BufWriter::new(io::stderr())), - None, source_map, - None, fallback_bundle, pretty, json_rendered, - diagnostic_width, - false, - unstable_opts.track_diagnostics, - TerminalUrl::No, ) - .ui_testing(unstable_opts.ui_testing), + .ui_testing(unstable_opts.ui_testing) + .diagnostic_width(diagnostic_width) + .track_diagnostics(unstable_opts.track_diagnostics) + .terminal_url(TerminalUrl::No), ) } }; From 58f45059a5e39135ac5e26a662821dc13c0e4e56 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 16:15:44 +1100 Subject: [PATCH 13/14] Add a useful comment. It took me a while to work this out. --- compiler/rustc_errors/src/json.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 3166768e9e272..77e4f9a0767d5 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -279,6 +279,7 @@ struct UnusedExterns<'a> { } impl Diagnostic { + /// Converts from `rustc_errors::DiagInner` to `Diagnostic`. fn from_errors_diagnostic(diag: crate::DiagInner, je: &JsonEmitter) -> Diagnostic { let args = to_fluent_args(diag.args.iter()); let sugg = diag.suggestions.iter().flatten().map(|sugg| { From 607bf653c2bed1ec3f7979d9511f3c9cef604bc3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 29 Feb 2024 20:12:43 +1100 Subject: [PATCH 14/14] Avoid unnecessary `color` local variable. --- compiler/rustc_errors/src/json.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 77e4f9a0767d5..bc1822f83fc14 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -347,12 +347,9 @@ impl Diagnostic { let buf = BufWriter::default(); let mut dst: Destination = Box::new(buf.clone()); let (short, color_config) = je.json_rendered.unzip(); - let color = match color_config { - ColorConfig::Always | ColorConfig::Auto => true, - ColorConfig::Never => false, - }; - if color { - dst = Box::new(termcolor::Ansi::new(dst)); + match color_config { + ColorConfig::Always | ColorConfig::Auto => dst = Box::new(termcolor::Ansi::new(dst)), + ColorConfig::Never => {} } HumanEmitter::new(dst, je.fallback_bundle.clone()) .short_message(short)