Skip to content

Commit

Permalink
Rollup merge of #100379 - davidtwco:triagebot-diag, r=Mark-Simulacrum
Browse files Browse the repository at this point in the history
triagebot: add translation-related mention groups

- Move some code around so that triagebot can ping relevant parties when translation logic is modified.
- Add mention groups to triagebot for translation-related files/folders.
- Auto-label pull requests with changes to translation-related files/folders with `A-translation`.

r? `@Mark-Simulacrum`
  • Loading branch information
matthiaskrgr authored Aug 17, 2022
2 parents d5dca26 + ae02014 commit 989e4ff
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 163 deletions.
20 changes: 11 additions & 9 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_data_structures::profiling::TimingGuard;
use rustc_data_structures::profiling::VerboseTimingGuard;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::Emitter;
use rustc_errors::{DiagnosticId, FatalError, Handler, Level};
use rustc_errors::{translation::Translate, DiagnosticId, FatalError, Handler, Level};
use rustc_fs_util::link_or_copy;
use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
use rustc_incremental::{
Expand Down Expand Up @@ -1740,6 +1740,16 @@ impl SharedEmitter {
}
}

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

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

impl Emitter for SharedEmitter {
fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
let fluent_args = self.to_fluent_args(diag.args());
Expand All @@ -1761,14 +1771,6 @@ impl Emitter for SharedEmitter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
None
}

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

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

impl SharedEmitterMain {
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use crate::emitter::FileWithAnnotatedLines;
use crate::snippet::Line;
use crate::translation::Translate;
use crate::{
CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, Emitter, FluentBundle,
LazyFallbackBundle, Level, MultiSpan, Style, SubDiagnostic,
Expand All @@ -32,6 +33,16 @@ pub struct AnnotateSnippetEmitterWriter {
macro_backtrace: bool,
}

impl Translate for AnnotateSnippetEmitterWriter {
fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
self.fluent_bundle.as_ref()
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
}
}

impl Emitter for AnnotateSnippetEmitterWriter {
/// The entry point for the diagnostics generation
fn emit_diagnostic(&mut self, diag: &Diagnostic) {
Expand Down Expand Up @@ -63,14 +74,6 @@ impl Emitter for AnnotateSnippetEmitterWriter {
self.source_map.as_ref()
}

fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
self.fluent_bundle.as_ref()
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
}

fn should_show_explain(&self) -> bool {
!self.short_message
}
Expand Down
128 changes: 18 additions & 110 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ use rustc_span::{FileLines, SourceFile, Span};

use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString};
use crate::styled_buffer::StyledBuffer;
use crate::translation::Translate;
use crate::{
CodeSuggestion, Diagnostic, DiagnosticArg, DiagnosticId, DiagnosticMessage, FluentBundle,
Handler, LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight,
SuggestionStyle,
CodeSuggestion, Diagnostic, DiagnosticId, DiagnosticMessage, FluentBundle, Handler,
LazyFallbackBundle, Level, MultiSpan, SubDiagnostic, SubstitutionHighlight, SuggestionStyle,
};

use rustc_lint_defs::pluralize;
Expand Down Expand Up @@ -200,7 +200,7 @@ impl Margin {
const ANONYMIZED_LINE_NUM: &str = "LL";

/// Emitter trait for emitting errors.
pub trait Emitter {
pub trait Emitter: Translate {
/// Emit a structured diagnostic.
fn emit_diagnostic(&mut self, diag: &Diagnostic);

Expand Down Expand Up @@ -231,102 +231,6 @@ pub trait Emitter {

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

/// Return `FluentBundle` with localized diagnostics for the locale requested by the user. If no
/// language was requested by the user then this will be `None` and `fallback_fluent_bundle`
/// should be used.
fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>>;

/// Return `FluentBundle` with localized diagnostics for the default locale of the compiler.
/// Used when the user has not requested a specific language or when a localized diagnostic is
/// unavailable for the requested locale.
fn fallback_fluent_bundle(&self) -> &FluentBundle;

/// Convert diagnostic arguments (a rustc internal type that exists to implement
/// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
///
/// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
/// passed around as a reference thereafter.
fn to_fluent_args<'arg>(&self, args: &[DiagnosticArg<'arg>]) -> FluentArgs<'arg> {
FromIterator::from_iter(args.to_vec().drain(..))
}

/// Convert `DiagnosticMessage`s to a string, performing translation if necessary.
fn translate_messages(
&self,
messages: &[(DiagnosticMessage, Style)],
args: &FluentArgs<'_>,
) -> Cow<'_, str> {
Cow::Owned(
messages.iter().map(|(m, _)| self.translate_message(m, args)).collect::<String>(),
)
}

/// Convert a `DiagnosticMessage` to a string, performing translation if necessary.
fn translate_message<'a>(
&'a self,
message: &'a DiagnosticMessage,
args: &'a FluentArgs<'_>,
) -> Cow<'_, str> {
trace!(?message, ?args);
let (identifier, attr) = match message {
DiagnosticMessage::Str(msg) => return Cow::Borrowed(&msg),
DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
};

let translate_with_bundle = |bundle: &'a FluentBundle| -> Option<(Cow<'_, str>, Vec<_>)> {
let message = bundle.get_message(&identifier)?;
let value = match attr {
Some(attr) => message.get_attribute(attr)?.value(),
None => message.value()?,
};
debug!(?message, ?value);

let mut errs = vec![];
let translated = bundle.format_pattern(value, Some(&args), &mut errs);
debug!(?translated, ?errs);
Some((translated, errs))
};

self.fluent_bundle()
.and_then(|bundle| translate_with_bundle(bundle))
// If `translate_with_bundle` returns `None` with the primary bundle, this is likely
// just that the primary bundle doesn't contain the message being translated, so
// proceed to the fallback bundle.
//
// However, when errors are produced from translation, then that means the translation
// is broken (e.g. `{$foo}` exists in a translation but `foo` isn't provided).
//
// In debug builds, assert so that compiler devs can spot the broken translation and
// fix it..
.inspect(|(_, errs)| {
debug_assert!(
errs.is_empty(),
"identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
identifier,
attr,
args,
errs
);
})
// ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
// just hide it and try with the fallback bundle.
.filter(|(_, errs)| errs.is_empty())
.or_else(|| translate_with_bundle(self.fallback_fluent_bundle()))
.map(|(translated, errs)| {
// Always bail out for errors with the fallback bundle.
assert!(
errs.is_empty(),
"identifier: {:?}, attr: {:?}, args: {:?}, errors: {:?}",
identifier,
attr,
args,
errs
);
translated
})
.expect("failed to find message in primary or fallback fluent bundles")
}

/// Formats the substitutions of the primary_span
///
/// There are a lot of conditions to this method, but in short:
Expand Down Expand Up @@ -616,18 +520,20 @@ pub trait Emitter {
}
}

impl Emitter for EmitterWriter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
self.sm.as_ref()
}

impl Translate for EmitterWriter {
fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
self.fluent_bundle.as_ref()
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
}
}

impl Emitter for EmitterWriter {
fn source_map(&self) -> Option<&Lrc<SourceMap>> {
self.sm.as_ref()
}

fn emit_diagnostic(&mut self, diag: &Diagnostic) {
let fluent_args = self.to_fluent_args(diag.args());
Expand Down Expand Up @@ -672,18 +578,20 @@ pub struct SilentEmitter {
pub fatal_note: Option<String>,
}

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

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

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

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

fn emit_diagnostic(&mut self, d: &Diagnostic) {
if d.level == Level::Fatal {
Expand Down
19 changes: 11 additions & 8 deletions compiler/rustc_errors/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use rustc_span::source_map::{FilePathMapping, SourceMap};

use crate::emitter::{Emitter, HumanReadableErrorType};
use crate::registry::Registry;
use crate::translation::Translate;
use crate::DiagnosticId;
use crate::{
CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, SubDiagnostic,
Expand Down Expand Up @@ -122,6 +123,16 @@ impl JsonEmitter {
}
}

impl Translate for JsonEmitter {
fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
self.fluent_bundle.as_ref()
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
}
}

impl Emitter for JsonEmitter {
fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) {
let data = Diagnostic::from_errors_diagnostic(diag, self);
Expand Down Expand Up @@ -189,14 +200,6 @@ impl Emitter for JsonEmitter {
Some(&self.sm)
}

fn fluent_bundle(&self) -> Option<&Lrc<FluentBundle>> {
self.fluent_bundle.as_ref()
}

fn fallback_fluent_bundle(&self) -> &FluentBundle {
&**self.fallback_bundle
}

fn should_show_explain(&self) -> bool {
!matches!(self.json_rendered, HumanReadableErrorType::Short(_))
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ mod lock;
pub mod registry;
mod snippet;
mod styled_buffer;
pub mod translation;

pub use snippet::Style;

Expand Down
Loading

0 comments on commit 989e4ff

Please sign in to comment.