Skip to content

Commit 273c4a5

Browse files
committed
errors: share SilentEmitter between rustc and rustfmt
Signed-off-by: David Wood <[email protected]>
1 parent eb1f279 commit 273c4a5

File tree

3 files changed

+43
-74
lines changed

3 files changed

+43
-74
lines changed

compiler/rustc_errors/src/emitter.rs

+8-26
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
use rustc_span::source_map::SourceMap;
1111
use rustc_span::{FileLines, FileName, SourceFile, Span};
1212

13-
use crate::error::TranslateError;
1413
use crate::snippet::{
1514
Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString,
1615
};
@@ -556,20 +555,9 @@ impl Emitter for HumanEmitter {
556555
/// Fatal diagnostics are forwarded to `fatal_dcx` to avoid silent
557556
/// failures of rustc, as witnessed e.g. in issue #89358.
558557
pub struct SilentEmitter {
558+
pub fallback_bundle: LazyFallbackBundle,
559559
pub fatal_dcx: DiagCtxt,
560-
pub fatal_note: String,
561-
}
562-
563-
pub fn silent_translate<'a>(
564-
message: &'a DiagnosticMessage,
565-
) -> Result<Cow<'_, str>, TranslateError<'_>> {
566-
match message {
567-
DiagnosticMessage::Str(msg) | DiagnosticMessage::Translated(msg) => Ok(Cow::Borrowed(msg)),
568-
DiagnosticMessage::FluentIdentifier(identifier, _) => {
569-
// Any value works here.
570-
Ok(identifier.clone())
571-
}
572-
}
560+
pub fatal_note: Option<String>,
573561
}
574562

575563
impl Translate for SilentEmitter {
@@ -578,17 +566,9 @@ impl Translate for SilentEmitter {
578566
}
579567

580568
fn fallback_fluent_bundle(&self) -> &FluentBundle {
581-
panic!("silent emitter attempted to translate message")
582-
}
583-
584-
// Override `translate_message` for the silent emitter because eager translation of
585-
// subdiagnostics result in a call to this.
586-
fn translate_message<'a>(
587-
&'a self,
588-
message: &'a DiagnosticMessage,
589-
_: &'a FluentArgs<'_>,
590-
) -> Result<Cow<'_, str>, TranslateError<'_>> {
591-
silent_translate(message)
569+
// Ideally this field wouldn't be necessary and the fallback bundle in `fatal_dcx` would be
570+
// used but the lock prevents this.
571+
&self.fallback_bundle
592572
}
593573
}
594574

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

600580
fn emit_diagnostic(&mut self, mut diag: Diagnostic) {
601581
if diag.level == Level::Fatal {
602-
diag.note(self.fatal_note.clone());
582+
if let Some(fatal_note) = &self.fatal_note {
583+
diag.note(fatal_note.clone());
584+
}
603585
self.fatal_dcx.emit_diagnostic(diag);
604586
}
605587
}

compiler/rustc_session/src/parse.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,14 @@ impl ParseSess {
261261
pub fn with_silent_emitter(fatal_note: String) -> Self {
262262
let fallback_bundle = fallback_fluent_bundle(Vec::new(), false);
263263
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
264-
let fatal_dcx = DiagCtxt::with_tty_emitter(None, fallback_bundle).disable_warnings();
265-
let dcx = DiagCtxt::with_emitter(Box::new(SilentEmitter { fatal_dcx, fatal_note }))
266-
.disable_warnings();
264+
let fatal_dcx =
265+
DiagCtxt::with_tty_emitter(None, fallback_bundle.clone()).disable_warnings();
266+
let dcx = DiagCtxt::with_emitter(Box::new(SilentEmitter {
267+
fallback_bundle,
268+
fatal_dcx,
269+
fatal_note: Some(fatal_note),
270+
}))
271+
.disable_warnings();
267272
ParseSess::with_dcx(dcx, sm)
268273
}
269274

src/tools/rustfmt/src/parse/session.rs

+27-45
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
use std::borrow::Cow;
21
use std::path::Path;
32
use std::sync::atomic::{AtomicBool, Ordering};
43

54
use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
6-
use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
5+
use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, SilentEmitter};
76
use rustc_errors::translation::Translate;
87
use rustc_errors::{
98
ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, Level as DiagnosticLevel,
@@ -30,41 +29,6 @@ pub(crate) struct ParseSess {
3029
can_reset_errors: Lrc<AtomicBool>,
3130
}
3231

33-
/// Emitter which discards every error.
34-
struct SilentEmitter;
35-
36-
impl Translate for SilentEmitter {
37-
fn fluent_bundle(&self) -> Option<&Lrc<rustc_errors::FluentBundle>> {
38-
None
39-
}
40-
41-
fn fallback_fluent_bundle(&self) -> &rustc_errors::FluentBundle {
42-
panic!("silent emitter attempted to translate a diagnostic");
43-
}
44-
45-
// Override `translate_message` for the silent emitter because eager translation of
46-
// subdiagnostics result in a call to this.
47-
fn translate_message<'a>(
48-
&'a self,
49-
message: &'a rustc_errors::DiagnosticMessage,
50-
_: &'a rustc_errors::translation::FluentArgs<'_>,
51-
) -> Result<Cow<'_, str>, rustc_errors::error::TranslateError<'_>> {
52-
rustc_errors::emitter::silent_translate(message)
53-
}
54-
}
55-
56-
impl Emitter for SilentEmitter {
57-
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
58-
None
59-
}
60-
61-
fn emit_diagnostic(&mut self, _db: Diagnostic) {}
62-
}
63-
64-
fn silent_emitter() -> Box<DynEmitter> {
65-
Box::new(SilentEmitter {})
66-
}
67-
6832
/// Emit errors against every files expect ones specified in the `ignore_path_set`.
6933
struct SilentOnIgnoredFilesEmitter {
7034
ignore_path_set: IntoDynSyncSend<Lrc<IgnorePathSet>>,
@@ -145,15 +109,19 @@ fn default_dcx(
145109
ColorConfig::Never
146110
};
147111

148-
let emitter = if hide_parse_errors {
149-
silent_emitter()
112+
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
113+
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
114+
false,
115+
);
116+
let emitter =
117+
Box::new(HumanEmitter::stderr(emit_color, fallback_bundle.clone()).sm(Some(source_map.clone())));
118+
119+
let emitter: Box<DynEmitter> = if hide_parse_errors {
120+
Box::new(SilentEmitter { fallback_bundle, fatal_dcx: DiagCtxt::with_emitter(emitter), fatal_note: None })
150121
} else {
151-
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
152-
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
153-
false,
154-
);
155-
Box::new(HumanEmitter::stderr(emit_color, fallback_bundle).sm(Some(source_map.clone())))
122+
emitter
156123
};
124+
157125
DiagCtxt::with_emitter(Box::new(SilentOnIgnoredFilesEmitter {
158126
has_non_ignorable_parser_errors: false,
159127
source_map,
@@ -231,7 +199,21 @@ impl ParseSess {
231199
}
232200

233201
pub(crate) fn set_silent_emitter(&mut self) {
234-
self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter());
202+
// Ideally this invocation wouldn't be necessary and the fallback bundle in
203+
// `self.parse_sess.dcx` could be used.
204+
let fallback_bundle = rustc_errors::fallback_fluent_bundle(
205+
rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
206+
false,
207+
);
208+
// SAFETY: `fatal_dcx` will not be dropped while it is referenced by `self.parse_sess.dcx`,
209+
// and `self.parse_sess.dcx` is written to by `ptr::write` so won't drop `fatal_dcx`.
210+
unsafe {
211+
let fatal_dcx = std::ptr::read(&self.parse_sess.dcx);
212+
std::ptr::write(
213+
&mut self.parse_sess.dcx,
214+
DiagCtxt::with_emitter(Box::new(SilentEmitter { fallback_bundle, fatal_dcx, fatal_note: None }))
215+
);
216+
}
235217
}
236218

237219
pub(crate) fn span_to_filename(&self, span: Span) -> FileName {

0 commit comments

Comments
 (0)