Remove DiagMessage::FluentIdentifier

This commit is contained in:
Jonathan Brouwer 2026-02-06 18:27:38 +01:00
parent 13c38730d9
commit ea8733133c
No known key found for this signature in database
GPG key ID: 13619B051B673C52
2 changed files with 8 additions and 105 deletions

View file

@ -230,9 +230,6 @@ pub fn fallback_fluent_bundle(
})))
}
/// Identifier for the Fluent message/attribute corresponding to a diagnostic message.
type FluentId = Cow<'static, str>;
/// Abstraction over a message in a subdiagnostic (i.e. label, note, help, etc) to support both
/// translatable and non-translatable diagnostic messages.
///
@ -244,18 +241,9 @@ type FluentId = Cow<'static, str>;
pub enum SubdiagMessage {
/// Non-translatable diagnostic message.
Str(Cow<'static, str>),
/// Identifier of a Fluent message. Instances of this variant are generated by the
/// `Subdiagnostic` derive.
FluentIdentifier(FluentId),
/// An inline Fluent message. Instances of this variant are generated by the
/// `Subdiagnostic` derive.
Inline(Cow<'static, str>),
/// Attribute of a Fluent message. Needs to be combined with a Fluent identifier to produce an
/// actual translated message. Instances of this variant are generated by the `fluent_messages`
/// macro.
///
/// <https://projectfluent.org/fluent/guide/attributes.html>
FluentAttr(FluentId),
}
impl From<String> for SubdiagMessage {
@ -288,12 +276,6 @@ pub enum DiagMessage {
/// are translated when they are added to the parent diagnostic. This is one of the ways
/// this variant of `DiagMessage` is produced.
Str(Cow<'static, str>),
/// Identifier for a Fluent message (with optional attribute) corresponding to the diagnostic
/// message. Yet to be translated.
///
/// <https://projectfluent.org/fluent/guide/hello.html>
/// <https://projectfluent.org/fluent/guide/attributes.html>
FluentIdentifier(FluentId, Option<FluentId>),
/// An inline Fluent message, containing the to be translated diagnostic message.
Inline(Cow<'static, str>),
}
@ -305,27 +287,16 @@ impl DiagMessage {
/// - If the `SubdiagMessage` is non-translatable then return the message as a `DiagMessage`.
/// - If `self` is non-translatable then return `self`'s message.
pub fn with_subdiagnostic_message(&self, sub: SubdiagMessage) -> Self {
let attr = match sub {
SubdiagMessage::Str(s) => return DiagMessage::Str(s),
SubdiagMessage::FluentIdentifier(id) => {
return DiagMessage::FluentIdentifier(id, None);
}
SubdiagMessage::Inline(s) => return DiagMessage::Inline(s),
SubdiagMessage::FluentAttr(attr) => attr,
};
match self {
DiagMessage::FluentIdentifier(id, _) => {
DiagMessage::FluentIdentifier(id.clone(), Some(attr))
}
_ => panic!("Tried to add a subdiagnostic to a message without a fluent identifier"),
match sub {
SubdiagMessage::Str(s) => DiagMessage::Str(s),
SubdiagMessage::Inline(s) => DiagMessage::Inline(s),
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
DiagMessage::Str(s) => Some(s),
DiagMessage::FluentIdentifier(_, _) | DiagMessage::Inline(_) => None,
DiagMessage::Inline(_) => None,
}
}
}
@ -355,10 +326,6 @@ impl From<DiagMessage> for SubdiagMessage {
fn from(val: DiagMessage) -> Self {
match val {
DiagMessage::Str(s) => SubdiagMessage::Str(s),
DiagMessage::FluentIdentifier(id, None) => SubdiagMessage::FluentIdentifier(id),
// There isn't really a sensible behaviour for this because it loses information but
// this is the most sensible of the behaviours.
DiagMessage::FluentIdentifier(_, Some(attr)) => SubdiagMessage::FluentAttr(attr),
DiagMessage::Inline(s) => SubdiagMessage::Inline(s),
}
}

View file

@ -1,5 +1,4 @@
use std::borrow::Cow;
use std::env;
use std::error::Report;
use std::sync::Arc;
@ -7,7 +6,7 @@ pub use rustc_error_messages::{FluentArgs, LazyFallbackBundle};
use rustc_error_messages::{langid, register_functions};
use tracing::{debug, trace};
use crate::error::{TranslateError, TranslateErrorKind};
use crate::error::TranslateError;
use crate::fluent_bundle::FluentResource;
use crate::{DiagArg, DiagMessage, FluentBundle, Style, fluent_bundle};
@ -76,11 +75,8 @@ impl Translator {
args: &'a FluentArgs<'_>,
) -> Result<Cow<'a, str>, TranslateError<'a>> {
trace!(?message, ?args);
let (identifier, attr) = match message {
DiagMessage::Str(msg) => {
return Ok(Cow::Borrowed(msg));
}
DiagMessage::FluentIdentifier(identifier, attr) => (identifier, attr),
match message {
DiagMessage::Str(msg) => Ok(Cow::Borrowed(msg)),
// This translates an inline fluent diagnostic message
// It does this by creating a new `FluentBundle` with only one message,
// and then translating using this bundle.
@ -98,71 +94,11 @@ impl Translator {
let mut errs = vec![];
let translated = bundle.format_pattern(value, Some(args), &mut errs).to_string();
debug!(?translated, ?errs);
return if errs.is_empty() {
if errs.is_empty() {
Ok(Cow::Owned(translated))
} else {
Err(TranslateError::fluent(&Cow::Borrowed(GENERATED_MSG_ID), args, errs))
};
}
};
let translate_with_bundle =
|bundle: &'a FluentBundle| -> Result<Cow<'_, str>, TranslateError<'_>> {
let message = bundle
.get_message(identifier)
.ok_or(TranslateError::message(identifier, args))?;
let value = match attr {
Some(attr) => message
.get_attribute(attr)
.ok_or(TranslateError::attribute(identifier, args, attr))?
.value(),
None => message.value().ok_or(TranslateError::value(identifier, args))?,
};
debug!(?message, ?value);
let mut errs = vec![];
let translated = bundle.format_pattern(value, Some(args), &mut errs);
debug!(?translated, ?errs);
if errs.is_empty() {
Ok(translated)
} else {
Err(TranslateError::fluent(identifier, args, errs))
}
};
try {
match self.fluent_bundle.as_ref().map(|b| translate_with_bundle(b)) {
// The primary bundle was present and translation succeeded
Some(Ok(t)) => t,
// If `translate_with_bundle` returns `Err` 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.
Some(Err(
primary @ TranslateError::One {
kind: TranslateErrorKind::MessageMissing, ..
},
)) => translate_with_bundle(&self.fallback_fluent_bundle)
.map_err(|fallback| primary.and(fallback))?,
// Always yeet out for errors on debug (unless
// `RUSTC_TRANSLATION_NO_DEBUG_ASSERT` is set in the environment - this allows
// local runs of the test suites, of builds with debug assertions, to test the
// behaviour in a normal build).
Some(Err(primary))
if cfg!(debug_assertions)
&& env::var("RUSTC_TRANSLATION_NO_DEBUG_ASSERT").is_err() =>
{
do yeet primary
}
// ..otherwise, for end users, an error about this wouldn't be useful or actionable, so
// just hide it and try with the fallback bundle.
Some(Err(primary)) => translate_with_bundle(&self.fallback_fluent_bundle)
.map_err(|fallback| primary.and(fallback))?,
// The primary bundle is missing, proceed to the fallback bundle
None => translate_with_bundle(&self.fallback_fluent_bundle)
.map_err(|fallback| TranslateError::primary(identifier, args).and(fallback))?,
}
}
}