Skip to content

Commit 62dadd2

Browse files
authored
Unrolled build for #142650
Rollup merge of #142650 - camsteffen:refactor-translator, r=petrochenkov Refactor Translator My main motivation was to simplify the usage of `SilentEmitter` for users like rustfmt. A few refactoring opportunities arose along the way. * Replace `Translate` trait with `Translator` struct * Replace `Emitter: Translate` with `Emitter::translator` * Split `SilentEmitter` into `FatalOnlyEmitter` and `SilentEmitter`
2 parents 5526a2f + 3388d83 commit 62dadd2

File tree

19 files changed

+221
-303
lines changed

19 files changed

+221
-303
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ use rustc_data_structures::jobserver::{self, Acquired};
1414
use rustc_data_structures::memmap::Mmap;
1515
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
1616
use rustc_errors::emitter::Emitter;
17-
use rustc_errors::translation::Translate;
17+
use rustc_errors::translation::Translator;
1818
use rustc_errors::{
19-
Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FluentBundle, Level, MultiSpan,
20-
Style, Suggestions,
19+
Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, Level, MultiSpan, Style,
20+
Suggestions,
2121
};
2222
use rustc_fs_util::link_or_copy;
2323
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -1889,16 +1889,6 @@ impl SharedEmitter {
18891889
}
18901890
}
18911891

1892-
impl Translate for SharedEmitter {
1893-
fn fluent_bundle(&self) -> Option<&FluentBundle> {
1894-
None
1895-
}
1896-
1897-
fn fallback_fluent_bundle(&self) -> &FluentBundle {
1898-
panic!("shared emitter attempted to translate a diagnostic");
1899-
}
1900-
}
1901-
19021892
impl Emitter for SharedEmitter {
19031893
fn emit_diagnostic(
19041894
&mut self,
@@ -1932,6 +1922,10 @@ impl Emitter for SharedEmitter {
19321922
fn source_map(&self) -> Option<&SourceMap> {
19331923
None
19341924
}
1925+
1926+
fn translator(&self) -> &Translator {
1927+
panic!("shared emitter attempted to translate a diagnostic");
1928+
}
19351929
}
19361930

19371931
impl SharedEmitterMain {

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ use rustc_data_structures::profiling::{
3838
};
3939
use rustc_errors::emitter::stderr_destination;
4040
use rustc_errors::registry::Registry;
41+
use rustc_errors::translation::Translator;
4142
use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, FatalError, PResult, markdown};
4243
use rustc_feature::find_gated_cfg;
4344
// This avoids a false positive with `-Wunused_crate_dependencies`.
@@ -109,6 +110,10 @@ use crate::session_diagnostics::{
109110

110111
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
111112

113+
pub fn default_translator() -> Translator {
114+
Translator::with_fallback_bundle(DEFAULT_LOCALE_RESOURCES.to_vec(), false)
115+
}
116+
112117
pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
113118
// tidy-alphabetical-start
114119
crate::DEFAULT_LOCALE_RESOURCE,
@@ -1413,11 +1418,10 @@ fn report_ice(
14131418
extra_info: fn(&DiagCtxt),
14141419
using_internal_features: &AtomicBool,
14151420
) {
1416-
let fallback_bundle =
1417-
rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false);
1421+
let translator = default_translator();
14181422
let emitter = Box::new(rustc_errors::emitter::HumanEmitter::new(
14191423
stderr_destination(rustc_errors::ColorConfig::Auto),
1420-
fallback_bundle,
1424+
translator,
14211425
));
14221426
let dcx = rustc_errors::DiagCtxt::new(emitter);
14231427
let dcx = dcx.handle();

compiler/rustc_error_messages/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
1818
use fluent_syntax::parser::ParserError;
1919
use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker};
2020
use intl_memoizer::concurrent::IntlLangMemoizer;
21-
use rustc_data_structures::sync::IntoDynSyncSend;
21+
use rustc_data_structures::sync::{DynSend, IntoDynSyncSend};
2222
use rustc_macros::{Decodable, Encodable};
2323
use rustc_span::Span;
2424
use smallvec::SmallVec;
@@ -204,16 +204,16 @@ fn register_functions(bundle: &mut FluentBundle) {
204204

205205
/// Type alias for the result of `fallback_fluent_bundle` - a reference-counted pointer to a lazily
206206
/// evaluated fluent bundle.
207-
pub type LazyFallbackBundle = Arc<LazyLock<FluentBundle, impl FnOnce() -> FluentBundle>>;
207+
pub type LazyFallbackBundle =
208+
Arc<LazyLock<FluentBundle, Box<dyn FnOnce() -> FluentBundle + DynSend>>>;
208209

209210
/// Return the default `FluentBundle` with standard "en-US" diagnostic messages.
210211
#[instrument(level = "trace", skip(resources))]
211-
#[define_opaque(LazyFallbackBundle)]
212212
pub fn fallback_fluent_bundle(
213213
resources: Vec<&'static str>,
214214
with_directionality_markers: bool,
215215
) -> LazyFallbackBundle {
216-
Arc::new(LazyLock::new(move || {
216+
Arc::new(LazyLock::new(Box::new(move || {
217217
let mut fallback_bundle = new_bundle(vec![langid!("en-US")]);
218218

219219
register_functions(&mut fallback_bundle);
@@ -228,7 +228,7 @@ pub fn fallback_fluent_bundle(
228228
}
229229

230230
fallback_bundle
231-
}))
231+
})))
232232
}
233233

234234
/// Identifier for the Fluent message/attribute corresponding to a diagnostic message.

compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,15 @@ use rustc_span::source_map::SourceMap;
1515
use crate::emitter::FileWithAnnotatedLines;
1616
use crate::registry::Registry;
1717
use crate::snippet::Line;
18-
use crate::translation::{Translate, to_fluent_args};
18+
use crate::translation::{Translator, to_fluent_args};
1919
use crate::{
20-
CodeSuggestion, DiagInner, DiagMessage, Emitter, ErrCode, FluentBundle, LazyFallbackBundle,
21-
Level, MultiSpan, Style, Subdiag,
20+
CodeSuggestion, DiagInner, DiagMessage, Emitter, ErrCode, Level, MultiSpan, Style, Subdiag,
2221
};
2322

2423
/// Generates diagnostics using annotate-snippet
2524
pub struct AnnotateSnippetEmitter {
2625
source_map: Option<Arc<SourceMap>>,
27-
fluent_bundle: Option<Arc<FluentBundle>>,
28-
fallback_bundle: LazyFallbackBundle,
26+
translator: Translator,
2927

3028
/// If true, hides the longer explanation text
3129
short_message: bool,
@@ -35,16 +33,6 @@ pub struct AnnotateSnippetEmitter {
3533
macro_backtrace: bool,
3634
}
3735

38-
impl Translate for AnnotateSnippetEmitter {
39-
fn fluent_bundle(&self) -> Option<&FluentBundle> {
40-
self.fluent_bundle.as_deref()
41-
}
42-
43-
fn fallback_fluent_bundle(&self) -> &FluentBundle {
44-
&self.fallback_bundle
45-
}
46-
}
47-
4836
impl Emitter for AnnotateSnippetEmitter {
4937
/// The entry point for the diagnostics generation
5038
fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) {
@@ -78,6 +66,10 @@ impl Emitter for AnnotateSnippetEmitter {
7866
fn should_show_explain(&self) -> bool {
7967
!self.short_message
8068
}
69+
70+
fn translator(&self) -> &Translator {
71+
&self.translator
72+
}
8173
}
8274

8375
/// Provides the source string for the given `line` of `file`
@@ -104,19 +96,11 @@ fn annotation_level_for_level(level: Level) -> annotate_snippets::Level {
10496
impl AnnotateSnippetEmitter {
10597
pub fn new(
10698
source_map: Option<Arc<SourceMap>>,
107-
fluent_bundle: Option<Arc<FluentBundle>>,
108-
fallback_bundle: LazyFallbackBundle,
99+
translator: Translator,
109100
short_message: bool,
110101
macro_backtrace: bool,
111102
) -> Self {
112-
Self {
113-
source_map,
114-
fluent_bundle,
115-
fallback_bundle,
116-
short_message,
117-
ui_testing: false,
118-
macro_backtrace,
119-
}
103+
Self { source_map, translator, short_message, ui_testing: false, macro_backtrace }
120104
}
121105

122106
/// Allows to modify `Self` to enable or disable the `ui_testing` flag.
@@ -137,7 +121,7 @@ impl AnnotateSnippetEmitter {
137121
_children: &[Subdiag],
138122
_suggestions: &[CodeSuggestion],
139123
) {
140-
let message = self.translate_messages(messages, args);
124+
let message = self.translator.translate_messages(messages, args);
141125
if let Some(source_map) = &self.source_map {
142126
// Make sure our primary file comes first
143127
let primary_lo = if let Some(primary_span) = msp.primary_span().as_ref() {

compiler/rustc_errors/src/emitter.rs

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ use crate::snippet::{
3535
};
3636
use crate::styled_buffer::StyledBuffer;
3737
use crate::timings::TimingRecord;
38-
use crate::translation::{Translate, to_fluent_args};
38+
use crate::translation::{Translator, to_fluent_args};
3939
use crate::{
40-
CodeSuggestion, DiagInner, DiagMessage, ErrCode, FluentBundle, LazyFallbackBundle, Level,
41-
MultiSpan, Subdiag, SubstitutionHighlight, SuggestionStyle, TerminalUrl,
40+
CodeSuggestion, DiagInner, DiagMessage, ErrCode, Level, MultiSpan, Subdiag,
41+
SubstitutionHighlight, SuggestionStyle, TerminalUrl,
4242
};
4343

4444
/// Default column width, used in tests and when terminal dimensions cannot be determined.
@@ -175,7 +175,7 @@ const ANONYMIZED_LINE_NUM: &str = "LL";
175175
pub type DynEmitter = dyn Emitter + DynSend;
176176

177177
/// Emitter trait for emitting errors and other structured information.
178-
pub trait Emitter: Translate {
178+
pub trait Emitter {
179179
/// Emit a structured diagnostic.
180180
fn emit_diagnostic(&mut self, diag: DiagInner, registry: &Registry);
181181

@@ -212,6 +212,8 @@ pub trait Emitter: Translate {
212212

213213
fn source_map(&self) -> Option<&SourceMap>;
214214

215+
fn translator(&self) -> &Translator;
216+
215217
/// Formats the substitutions of the primary_span
216218
///
217219
/// There are a lot of conditions to this method, but in short:
@@ -224,13 +226,17 @@ pub trait Emitter: Translate {
224226
/// * If the current `DiagInner` has multiple suggestions,
225227
/// we leave `primary_span` and the suggestions untouched.
226228
fn primary_span_formatted(
227-
&mut self,
229+
&self,
228230
primary_span: &mut MultiSpan,
229231
suggestions: &mut Vec<CodeSuggestion>,
230232
fluent_args: &FluentArgs<'_>,
231233
) {
232234
if let Some((sugg, rest)) = suggestions.split_first() {
233-
let msg = self.translate_message(&sugg.msg, fluent_args).map_err(Report::new).unwrap();
235+
let msg = self
236+
.translator()
237+
.translate_message(&sugg.msg, fluent_args)
238+
.map_err(Report::new)
239+
.unwrap();
234240
if rest.is_empty()
235241
// ^ if there is only one suggestion
236242
// don't display multi-suggestions as labels
@@ -491,16 +497,6 @@ pub trait Emitter: Translate {
491497
}
492498
}
493499

494-
impl Translate for HumanEmitter {
495-
fn fluent_bundle(&self) -> Option<&FluentBundle> {
496-
self.fluent_bundle.as_deref()
497-
}
498-
499-
fn fallback_fluent_bundle(&self) -> &FluentBundle {
500-
&self.fallback_bundle
501-
}
502-
}
503-
504500
impl Emitter for HumanEmitter {
505501
fn source_map(&self) -> Option<&SourceMap> {
506502
self.sm.as_deref()
@@ -538,39 +534,52 @@ impl Emitter for HumanEmitter {
538534
fn supports_color(&self) -> bool {
539535
self.dst.supports_color()
540536
}
537+
538+
fn translator(&self) -> &Translator {
539+
&self.translator
540+
}
541541
}
542542

543543
/// An emitter that does nothing when emitting a non-fatal diagnostic.
544544
/// Fatal diagnostics are forwarded to `fatal_emitter` to avoid silent
545545
/// failures of rustc, as witnessed e.g. in issue #89358.
546-
pub struct SilentEmitter {
546+
pub struct FatalOnlyEmitter {
547547
pub fatal_emitter: Box<dyn Emitter + DynSend>,
548548
pub fatal_note: Option<String>,
549-
pub emit_fatal_diagnostic: bool,
550549
}
551550

552-
impl Translate for SilentEmitter {
553-
fn fluent_bundle(&self) -> Option<&FluentBundle> {
551+
impl Emitter for FatalOnlyEmitter {
552+
fn source_map(&self) -> Option<&SourceMap> {
554553
None
555554
}
556555

557-
fn fallback_fluent_bundle(&self) -> &FluentBundle {
558-
self.fatal_emitter.fallback_fluent_bundle()
556+
fn emit_diagnostic(&mut self, mut diag: DiagInner, registry: &Registry) {
557+
if diag.level == Level::Fatal {
558+
if let Some(fatal_note) = &self.fatal_note {
559+
diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
560+
}
561+
self.fatal_emitter.emit_diagnostic(diag, registry);
562+
}
563+
}
564+
565+
fn translator(&self) -> &Translator {
566+
self.fatal_emitter.translator()
559567
}
560568
}
561569

570+
pub struct SilentEmitter {
571+
pub translator: Translator,
572+
}
573+
562574
impl Emitter for SilentEmitter {
563575
fn source_map(&self) -> Option<&SourceMap> {
564576
None
565577
}
566578

567-
fn emit_diagnostic(&mut self, mut diag: DiagInner, registry: &Registry) {
568-
if self.emit_fatal_diagnostic && diag.level == Level::Fatal {
569-
if let Some(fatal_note) = &self.fatal_note {
570-
diag.sub(Level::Note, fatal_note.clone(), MultiSpan::new());
571-
}
572-
self.fatal_emitter.emit_diagnostic(diag, registry);
573-
}
579+
fn emit_diagnostic(&mut self, _diag: DiagInner, _registry: &Registry) {}
580+
581+
fn translator(&self) -> &Translator {
582+
&self.translator
574583
}
575584
}
576585

@@ -615,9 +624,8 @@ pub struct HumanEmitter {
615624
#[setters(skip)]
616625
dst: IntoDynSyncSend<Destination>,
617626
sm: Option<Arc<SourceMap>>,
618-
fluent_bundle: Option<Arc<FluentBundle>>,
619627
#[setters(skip)]
620-
fallback_bundle: LazyFallbackBundle,
628+
translator: Translator,
621629
short_message: bool,
622630
ui_testing: bool,
623631
ignored_directories_in_source_blocks: Vec<String>,
@@ -637,12 +645,11 @@ pub(crate) struct FileWithAnnotatedLines {
637645
}
638646

639647
impl HumanEmitter {
640-
pub fn new(dst: Destination, fallback_bundle: LazyFallbackBundle) -> HumanEmitter {
648+
pub fn new(dst: Destination, translator: Translator) -> HumanEmitter {
641649
HumanEmitter {
642650
dst: IntoDynSyncSend(dst),
643651
sm: None,
644-
fluent_bundle: None,
645-
fallback_bundle,
652+
translator,
646653
short_message: false,
647654
ui_testing: false,
648655
ignored_directories_in_source_blocks: Vec::new(),
@@ -1433,7 +1440,7 @@ impl HumanEmitter {
14331440
// very *weird* formats
14341441
// see?
14351442
for (text, style) in msgs.iter() {
1436-
let text = self.translate_message(text, args).map_err(Report::new).unwrap();
1443+
let text = self.translator.translate_message(text, args).map_err(Report::new).unwrap();
14371444
let text = &normalize_whitespace(&text);
14381445
let lines = text.split('\n').collect::<Vec<_>>();
14391446
if lines.len() > 1 {
@@ -1528,7 +1535,8 @@ impl HumanEmitter {
15281535
}
15291536
let mut line = 0;
15301537
for (text, style) in msgs.iter() {
1531-
let text = self.translate_message(text, args).map_err(Report::new).unwrap();
1538+
let text =
1539+
self.translator.translate_message(text, args).map_err(Report::new).unwrap();
15321540
// Account for newlines to align output to its label.
15331541
for text in normalize_whitespace(&text).lines() {
15341542
buffer.append(
@@ -1560,7 +1568,7 @@ impl HumanEmitter {
15601568
.into_iter()
15611569
.filter_map(|label| match label.label {
15621570
Some(msg) if label.is_primary => {
1563-
let text = self.translate_message(&msg, args).ok()?;
1571+
let text = self.translator.translate_message(&msg, args).ok()?;
15641572
if !text.trim().is_empty() { Some(text.to_string()) } else { None }
15651573
}
15661574
_ => None,
@@ -3104,7 +3112,11 @@ impl FileWithAnnotatedLines {
31043112

31053113
let label = label.as_ref().map(|m| {
31063114
normalize_whitespace(
3107-
&emitter.translate_message(m, args).map_err(Report::new).unwrap(),
3115+
&emitter
3116+
.translator()
3117+
.translate_message(m, args)
3118+
.map_err(Report::new)
3119+
.unwrap(),
31083120
)
31093121
});
31103122

0 commit comments

Comments
 (0)