Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 1 addition & 90 deletions compiler/rustc_errors/src/translation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,96 +75,7 @@ impl Translator {
message: &'a DiagMessage,
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),
// 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.
DiagMessage::Inline(msg) => {
const GENERATED_MSG_ID: &str = "generated_msg";
let resource =
FluentResource::try_new(format!("{GENERATED_MSG_ID} = {msg}\n")).unwrap();
let mut bundle = fluent_bundle::FluentBundle::new(vec![langid!("en-US")]);
bundle.set_use_isolating(false);
bundle.add_resource(resource).unwrap();
register_functions(&mut bundle);
let message = bundle.get_message(GENERATED_MSG_ID).unwrap();
let value = message.value().unwrap();

let mut errs = vec![];
let translated = bundle.format_pattern(value, Some(args), &mut errs).to_string();
debug!(?translated, ?errs);
return 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))?,
}
}
Ok(Cow::Borrowed("Temporary message"))
}
}

Expand Down
Loading