Skip to content

Commit

Permalink
errors: share SilentEmitter between rustc and rustfmt
Browse files Browse the repository at this point in the history
Signed-off-by: David Wood <david@davidtw.co>
  • Loading branch information
davidtwco committed Feb 21, 2024
1 parent 7168c13 commit d420015
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 82 deletions.
34 changes: 8 additions & 26 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
use rustc_span::source_map::SourceMap;
use rustc_span::{FileLines, FileName, SourceFile, Span};

use crate::error::TranslateError;
use crate::snippet::{
Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString,
};
Expand Down Expand Up @@ -556,20 +555,9 @@ impl Emitter for HumanEmitter {
/// Fatal diagnostics are forwarded to `fatal_dcx` to avoid silent
/// failures of rustc, as witnessed e.g. in issue #89358.
pub struct SilentEmitter {
pub fallback_bundle: LazyFallbackBundle,
pub fatal_dcx: DiagCtxt,
pub fatal_note: String,
}

pub fn silent_translate<'a>(
message: &'a DiagnosticMessage,
) -> Result<Cow<'_, str>, TranslateError<'_>> {
match message {
DiagnosticMessage::Str(msg) | DiagnosticMessage::Translated(msg) => Ok(Cow::Borrowed(msg)),
DiagnosticMessage::FluentIdentifier(identifier, _) => {
// Any value works here.
Ok(identifier.clone())
}
}
pub fatal_note: Option<String>,
}

impl Translate for SilentEmitter {
Expand All @@ -578,17 +566,9 @@ impl Translate for SilentEmitter {
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
panic!("silent emitter attempted to translate message")
}

// Override `translate_message` for the silent emitter because eager translation of
// subdiagnostics result in a call to this.
fn translate_message<'a>(
&'a self,
message: &'a DiagnosticMessage,
_: &'a FluentArgs<'_>,
) -> Result<Cow<'_, str>, TranslateError<'_>> {
silent_translate(message)
// Ideally this field wouldn't be necessary and the fallback bundle in `fatal_dcx` would be
// used but the lock prevents this.
&self.fallback_bundle
}
}

Expand All @@ -599,7 +579,9 @@ impl Emitter for SilentEmitter {

fn emit_diagnostic(&mut self, mut diag: Diagnostic) {
if diag.level == Level::Fatal {
diag.sub(Level::Note, self.fatal_note.clone(), MultiSpan::new());
if let Some(fatal_note) = &self.fatal_note {
diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
}
self.fatal_dcx.emit_diagnostic(diag);
}
}
Expand Down
14 changes: 8 additions & 6 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ pub struct Compiler {
pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
cfgs.into_iter()
.map(|s| {
let sess = ParseSess::with_silent_emitter(format!(
"this error occurred on the command line: `--cfg={s}`"
));
let sess = ParseSess::with_silent_emitter(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
format!("this error occurred on the command line: `--cfg={s}`"),
);
let filename = FileName::cfg_spec_source_code(&s);

macro_rules! error {
Expand Down Expand Up @@ -107,9 +108,10 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
let mut check_cfg = CheckCfg { exhaustive_names, exhaustive_values, ..CheckCfg::default() };

for s in specs {
let sess = ParseSess::with_silent_emitter(format!(
"this error occurred on the command line: `--check-cfg={s}`"
));
let sess = ParseSess::with_silent_emitter(
vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE],
format!("this error occurred on the command line: `--check-cfg={s}`"),
);
let filename = FileName::cfg_spec_source_code(&s);

macro_rules! error {
Expand Down
15 changes: 10 additions & 5 deletions compiler/rustc_session/src/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,17 @@ impl ParseSess {
}
}

pub fn with_silent_emitter(fatal_note: String) -> Self {
let fallback_bundle = fallback_fluent_bundle(Vec::new(), false);
pub fn with_silent_emitter(locale_resources: Vec<&'static str>, fatal_note: String) -> Self {
let fallback_bundle = fallback_fluent_bundle(locale_resources, 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 fatal_dcx =
DiagCtxt::with_tty_emitter(None, fallback_bundle.clone()).disable_warnings();
let dcx = DiagCtxt::with_emitter(Box::new(SilentEmitter {
fallback_bundle,
fatal_dcx,
fatal_note: Some(fatal_note),
}))
.disable_warnings();
ParseSess::with_dcx(dcx, sm)
}

Expand Down
81 changes: 36 additions & 45 deletions src/tools/rustfmt/src/parse/session.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use std::borrow::Cow;
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::{DynEmitter, Emitter, HumanEmitter, SilentEmitter};
use rustc_errors::translation::Translate;
use rustc_errors::{
ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, Level as DiagnosticLevel,
Expand All @@ -30,41 +29,6 @@ pub(crate) struct ParseSess {
can_reset_errors: Lrc<AtomicBool>,
}

/// Emitter which discards every error.
struct SilentEmitter;

impl Translate for SilentEmitter {
fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
None
}

fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
panic!("silent emitter attempted to translate a diagnostic");
}

// Override `translate_message` for the silent emitter because eager translation of
// subdiagnostics result in a call to this.
fn translate_message<'a>(
&'a self,
message: &'a rustc_errors::DiagnosticMessage,
_: &'a rustc_errors::translation::FluentArgs<'_>,
) -> Result<Cow<'_, str>, rustc_errors::error::TranslateError<'_>> {
rustc_errors::emitter::silent_translate(message)
}
}

impl Emitter for SilentEmitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
None
}

fn emit_diagnostic(&mut self, _db: Diagnostic) {}
}

fn silent_emitter() -> Box<DynEmitter> {
Box::new(SilentEmitter {})
}

/// Emit errors against every files expect ones specified in the `ignore_path_set`.
struct SilentOnIgnoredFilesEmitter {
ignore_path_set: IntoDynSyncSend<Lrc<IgnorePathSet>>,
Expand Down Expand Up @@ -145,15 +109,24 @@ fn default_dcx(
ColorConfig::Never
};

let emitter = if hide_parse_errors {
silent_emitter()
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
let emitter = Box::new(
HumanEmitter::stderr(emit_color, fallback_bundle.clone()).sm(Some(source_map.clone())),
);

let emitter: Box<DynEmitter> = if hide_parse_errors {
Box::new(SilentEmitter {
fallback_bundle,
fatal_dcx: DiagCtxt::with_emitter(emitter),
fatal_note: None,
})
} else {
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone())))
emitter
};

DiagCtxt::with_emitter(Box::new(SilentOnIgnoredFilesEmitter {
has_non_ignorable_parser_errors: false,
source_map,
Expand Down Expand Up @@ -231,7 +204,25 @@ impl ParseSess {
}

pub(crate) fn set_silent_emitter(&mut self) {
self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter());
// Ideally this invocation wouldn't be necessary and the fallback bundle in
// `self.parse_sess.dcx` could be used.
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
false,
);
// SAFETY: `fatal_dcx` will not be dropped while it is referenced by `self.parse_sess.dcx`,
// and `self.parse_sess.dcx` is written to by `ptr::write` so won't drop `fatal_dcx`.
unsafe {
let fatal_dcx = std::ptr::read(&self.parse_sess.dcx);
std::ptr::write(
&mut self.parse_sess.dcx,
DiagCtxt::with_emitter(Box::new(SilentEmitter {
fallback_bundle,
fatal_dcx,
fatal_note: None,
})),
);
}
}

pub(crate) fn span_to_filename(&self, span: Span) -> FileName {
Expand Down
5 changes: 5 additions & 0 deletions src/tools/rustfmt/tests/source/issue-6082.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
macro_rules! test {
($T:ident, $b:lifetime) => {
Box<$T<$b>>
};
}
5 changes: 5 additions & 0 deletions src/tools/rustfmt/tests/target/issue-6082.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
macro_rules! test {
($T:ident, $b:lifetime) => {
Box<$T<$b>>
};
}

0 comments on commit d420015

Please sign in to comment.