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..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,11 +1385,11 @@ 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::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/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 304922018ebe7..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}; @@ -35,7 +34,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 +57,6 @@ impl HumanReadableErrorType { HumanReadableErrorType::AnnotateSnippet(cc) => (false, cc), } } - pub fn new_emitter( - self, - mut dst: Box, - 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)] @@ -130,8 +117,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 @@ -628,12 +615,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` @@ -657,19 +638,14 @@ 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, } impl HumanEmitter { - pub fn stderr(color_config: ColorConfig, fallback_bundle: LazyFallbackBundle) -> HumanEmitter { - let dst = from_stderr(color_config); - Self::create(dst, 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,13 +662,6 @@ impl HumanEmitter { } } - pub fn new( - dst: Box, - 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) @@ -724,8 +693,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 +2198,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 +2556,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, @@ -2632,7 +2603,7 @@ fn emit_to_destination( Ok(()) } -pub type Destination = Box<(dyn WriteColor + Send)>; +pub type Destination = Box; struct Buffy { buffer_writer: BufferWriter, @@ -2674,7 +2645,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/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/json.rs b/compiler/rustc_errors/src/json.rs index 88a83c8bf785d..bc1822f83fc14 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -9,42 +9,49 @@ // FIXME: spec the JSON output properly. -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::{ 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, @@ -53,98 +60,30 @@ 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, - 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)? @@ -162,7 +101,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,14 +271,15 @@ 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 { + /// 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| { @@ -405,9 +345,14 @@ impl Diagnostic { .collect(); let buf = BufWriter::default(); - let output = buf.clone(); - je.json_rendered - .new_emitter(Box::new(buf), je.fallback_bundle.clone()) + let mut dst: Destination = Box::new(buf.clone()); + let (short, color_config) = je.json_rendered.unzip(); + 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) .sm(Some(je.sm.clone())) .fluent_bundle(je.fluent_bundle.clone()) .diagnostic_width(je.diagnostic_width) @@ -417,8 +362,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 +371,7 @@ impl Diagnostic { level, spans, children, - rendered: Some(output), + rendered: Some(buf), } } diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 303de0a93f633..80b4d2bf75c0c 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -1,7 +1,7 @@ use super::*; -use crate::emitter::ColorConfig; use crate::DiagCtxt; +use rustc_span::source_map::FilePathMapping; use rustc_span::BytePos; use std::str; @@ -48,20 +48,14 @@ 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)); - 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 87c4d66e163eb..0a533833e64bd 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; @@ -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 /// @@ -482,8 +482,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 @@ -590,13 +590,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 @@ -612,7 +605,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 1b79786c1b832..9170b265748e1 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::{stderr_destination, 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; @@ -235,7 +236,11 @@ 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::new(stderr_destination(ColorConfig::Auto), fallback_bundle) + .sm(Some(sm.clone())), + ); + let dcx = DiagCtxt::new(emitter); ParseSess::with_dcx(dcx, sm) } @@ -264,9 +269,11 @@ 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 dcx = DiagCtxt::with_emitter(Box::new(SilentEmitter { fatal_dcx, fatal_note })) - .disable_warnings(); + 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(); ParseSess::with_dcx(dcx, sm) } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index e9db96dc3562a..09fb6aa5d8f98 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::{ @@ -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; @@ -982,7 +983,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) @@ -998,22 +999,23 @@ fn default_emitter( } } config::ErrorOutputType::Json { pretty, json_rendered } => Box::new( - JsonEmitter::stderr( - Some(registry), + JsonEmitter::new( + Box::new(io::BufWriter::new(io::stderr())), 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), ), } } @@ -1080,8 +1082,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 +1404,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 +1414,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)] @@ -1473,17 +1475,17 @@ 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( + config::ErrorOutputType::Json { pretty, json_rendered } => Box::new(JsonEmitter::new( + Box::new(io::BufWriter::new(io::stderr())), + Lrc::new(SourceMap::new(FilePathMapping::empty())), + fallback_bundle, pretty, json_rendered, - None, - fallback_bundle, - None, - false, - false, - TerminalUrl::No, )), }; emitter diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index c662f054d0524..9ba79cf5d29f1 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; @@ -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; @@ -141,7 +142,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) @@ -155,24 +156,22 @@ pub(crate) fn new_dcx( Lrc::new(source_map::SourceMap::new(source_map::FilePathMapping::empty())) }); Box::new( - JsonEmitter::stderr( - None, + JsonEmitter::new( + Box::new(io::BufWriter::new(io::stderr())), 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), ) } }; - 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 e2b4ec5908b9d..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}; @@ -576,14 +577,14 @@ 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::new(stderr_destination(ColorConfig::Auto), fallback_bundle.clone()) + .supports_color(); 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; @@ -768,7 +769,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 f5defe63c13ba..d6386a9504db7 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, Level as DiagnosticLevel}; use rustc_session::parse::ParseSess as RawParseSess; @@ -150,9 +150,12 @@ 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::with_emitter(Box::new(SilentOnIgnoredFilesEmitter { + DiagCtxt::new(Box::new(SilentOnIgnoredFilesEmitter { has_non_ignorable_parser_errors: false, source_map, emitter, @@ -229,7 +232,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 {