Rollup merge of #121783 - nnethercote:emitter-cleanups, r=oli-obk
Emitter cleanups Some cleanups I made when reading emitter code. In particular, `HumanEmitter` and `JsonEmitter` have gone from three constructors to one. r? `@oli-obk`
This commit is contained in:
commit
0e9f02d6fa
@ -373,7 +373,7 @@ pub struct CodegenContext<B: WriteBackendMethods> {
|
||||
|
||||
impl<B: WriteBackendMethods> CodegenContext<B> {
|
||||
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 {
|
||||
|
@ -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.
|
||||
|
@ -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<dyn WriteColor + Send>,
|
||||
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<SourceFile>,
|
||||
pub lines: Vec<Line>,
|
||||
pub(crate) struct FileWithAnnotatedLines {
|
||||
pub(crate) file: Lrc<SourceFile>,
|
||||
pub(crate) lines: Vec<Line>,
|
||||
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<dyn WriteColor + Send>,
|
||||
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<dyn WriteColor + Send>;
|
||||
|
||||
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
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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<Box<dyn Write + Send>>,
|
||||
registry: Option<Registry>,
|
||||
#[setters(skip)]
|
||||
sm: Lrc<SourceMap>,
|
||||
fluent_bundle: Option<Lrc<FluentBundle>>,
|
||||
#[setters(skip)]
|
||||
fallback_bundle: LazyFallbackBundle,
|
||||
#[setters(skip)]
|
||||
pretty: bool,
|
||||
ui_testing: bool,
|
||||
ignored_directories_in_source_blocks: Vec<String>,
|
||||
#[setters(skip)]
|
||||
json_rendered: HumanReadableErrorType,
|
||||
diagnostic_width: Option<usize>,
|
||||
macro_backtrace: bool,
|
||||
@ -53,98 +60,30 @@ pub struct JsonEmitter {
|
||||
}
|
||||
|
||||
impl JsonEmitter {
|
||||
pub fn stderr(
|
||||
registry: Option<Registry>,
|
||||
source_map: Lrc<SourceMap>,
|
||||
fluent_bundle: Option<Lrc<FluentBundle>>,
|
||||
fallback_bundle: LazyFallbackBundle,
|
||||
pretty: bool,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
diagnostic_width: Option<usize>,
|
||||
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<Lrc<FluentBundle>>,
|
||||
fallback_bundle: LazyFallbackBundle,
|
||||
diagnostic_width: Option<usize>,
|
||||
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<dyn Write + Send>,
|
||||
registry: Option<Registry>,
|
||||
source_map: Lrc<SourceMap>,
|
||||
fluent_bundle: Option<Lrc<FluentBundle>>,
|
||||
sm: Lrc<SourceMap>,
|
||||
fallback_bundle: LazyFallbackBundle,
|
||||
pretty: bool,
|
||||
json_rendered: HumanReadableErrorType,
|
||||
diagnostic_width: Option<usize>,
|
||||
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<String>) -> 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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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<Lrc<SourceMap>>,
|
||||
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<DynEmitter>) -> Self {
|
||||
pub fn new(emitter: Box<DynEmitter>) -> Self {
|
||||
Self {
|
||||
inner: Lock::new(DiagCtxtInner {
|
||||
flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
|
||||
|
@ -33,7 +33,7 @@ fn create_test_handler() -> (DiagCtxt, Lrc<SourceMap>, Arc<Mutex<Vec<u8>>>) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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<DynEmitter> {
|
||||
let emitter: Box<DynEmitter> = 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
|
||||
|
@ -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.
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user