From 5a18412c93a32811b135ed4a6ac8fdc2df33226b Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 28 Feb 2026 18:34:17 +0100 Subject: [PATCH 1/2] Remove `TranslationError` --- compiler/rustc_errors/src/error.rs | 139 ----------------------- compiler/rustc_errors/src/lib.rs | 4 +- compiler/rustc_errors/src/translation.rs | 13 +-- 3 files changed, 5 insertions(+), 151 deletions(-) delete mode 100644 compiler/rustc_errors/src/error.rs diff --git a/compiler/rustc_errors/src/error.rs b/compiler/rustc_errors/src/error.rs deleted file mode 100644 index 462467d9fa0bf..0000000000000 --- a/compiler/rustc_errors/src/error.rs +++ /dev/null @@ -1,139 +0,0 @@ -use std::borrow::Cow; -use std::error::Error; -use std::fmt; - -use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError}; -use rustc_error_messages::{FluentArgs, FluentError}; - -#[derive(Debug)] -pub enum TranslateError<'args> { - One { - id: &'args Cow<'args, str>, - args: &'args FluentArgs<'args>, - kind: TranslateErrorKind<'args>, - }, - Two { - primary: Box>, - fallback: Box>, - }, -} - -impl<'args> TranslateError<'args> { - pub fn message(id: &'args Cow<'args, str>, args: &'args FluentArgs<'args>) -> Self { - Self::One { id, args, kind: TranslateErrorKind::MessageMissing } - } - - pub fn primary(id: &'args Cow<'args, str>, args: &'args FluentArgs<'args>) -> Self { - Self::One { id, args, kind: TranslateErrorKind::PrimaryBundleMissing } - } - - pub fn attribute( - id: &'args Cow<'args, str>, - args: &'args FluentArgs<'args>, - attr: &'args str, - ) -> Self { - Self::One { id, args, kind: TranslateErrorKind::AttributeMissing { attr } } - } - - pub fn value(id: &'args Cow<'args, str>, args: &'args FluentArgs<'args>) -> Self { - Self::One { id, args, kind: TranslateErrorKind::ValueMissing } - } - - pub fn fluent( - id: &'args Cow<'args, str>, - args: &'args FluentArgs<'args>, - errs: Vec, - ) -> Self { - Self::One { id, args, kind: TranslateErrorKind::Fluent { errs } } - } - - pub fn and(self, fallback: TranslateError<'args>) -> TranslateError<'args> { - Self::Two { primary: Box::new(self), fallback: Box::new(fallback) } - } -} - -#[derive(Debug)] -pub enum TranslateErrorKind<'args> { - MessageMissing, - PrimaryBundleMissing, - AttributeMissing { attr: &'args str }, - ValueMissing, - Fluent { errs: Vec }, -} - -impl fmt::Display for TranslateError<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use TranslateErrorKind::*; - - match self { - Self::One { id, args, kind } => { - writeln!(f, "failed while formatting fluent string `{id}`: ")?; - match kind { - MessageMissing => writeln!(f, "message was missing")?, - PrimaryBundleMissing => writeln!(f, "the primary bundle was missing")?, - AttributeMissing { attr } => { - writeln!(f, "the attribute `{attr}` was missing")?; - writeln!(f, "help: add `.{attr} = `")?; - } - ValueMissing => writeln!(f, "the value was missing")?, - Fluent { errs } => { - for err in errs { - match err { - FluentError::ResolverError(ResolverError::Reference( - ReferenceKind::Message { id, .. } - | ReferenceKind::Variable { id, .. }, - )) => { - if args.iter().any(|(arg_id, _)| arg_id == id) { - writeln!( - f, - "argument `{id}` exists but was not referenced correctly" - )?; - writeln!(f, "help: try using `{{${id}}}` instead")?; - } else { - writeln!( - f, - "the fluent string has an argument `{id}` that was not found." - )?; - let vars: Vec<&str> = - args.iter().map(|(a, _v)| a).collect(); - match &*vars { - [] => writeln!(f, "help: no arguments are available")?, - [one] => writeln!( - f, - "help: the argument `{one}` is available" - )?, - [first, middle @ .., last] => { - write!(f, "help: the arguments `{first}`")?; - for a in middle { - write!(f, ", `{a}`")?; - } - writeln!(f, " and `{last}` are available")?; - } - } - } - } - _ => writeln!(f, "{err}")?, - } - } - } - } - } - // If someone cares about primary bundles, they'll probably notice it's missing - // regardless or will be using `debug_assertions` - // so we skip the arm below this one to avoid confusing the regular user. - Self::Two { primary: box Self::One { kind: PrimaryBundleMissing, .. }, fallback } => { - fmt::Display::fmt(fallback, f)?; - } - Self::Two { primary, fallback } => { - writeln!( - f, - "first, fluent formatting using the primary bundle failed:\n {primary}\n \ - while attempting to recover by using the fallback bundle instead, another error occurred:\n{fallback}" - )?; - } - } - Ok(()) - } -} - -impl Error for TranslateError<'_> {} diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 837a41c191e15..0386ce9eed95b 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -21,7 +21,6 @@ extern crate self as rustc_errors; use std::backtrace::{Backtrace, BacktraceStatus}; use std::borrow::Cow; use std::cell::Cell; -use std::error::Report; use std::ffi::OsStr; use std::hash::Hash; use std::io::Write; @@ -78,7 +77,6 @@ mod decorate_diag; mod diagnostic; mod diagnostic_impls; pub mod emitter; -pub mod error; pub mod json; mod lock; pub mod markdown; @@ -1437,7 +1435,7 @@ impl DiagCtxtInner { args: impl Iterator>, ) -> String { let args = crate::translation::to_fluent_args(args); - format_diag_message(&message, &args).map_err(Report::new).unwrap().to_string() + format_diag_message(&message, &args).to_string() } fn eagerly_translate_for_subdiag( diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index 5317132018325..612bcf22c90c7 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -1,11 +1,9 @@ use std::borrow::Cow; -use std::error::Report; pub use rustc_error_messages::FluentArgs; use rustc_error_messages::{langid, register_functions}; use tracing::{debug, trace}; -use crate::error::TranslateError; use crate::fluent_bundle::FluentResource; use crate::{DiagArg, DiagMessage, Style, fluent_bundle}; @@ -42,13 +40,10 @@ pub fn format_diag_messages( } /// Convert a `DiagMessage` to a string -pub fn format_diag_message<'a>( - message: &'a DiagMessage, - args: &'a FluentArgs<'_>, -) -> Result, TranslateError<'a>> { +pub fn format_diag_message<'a>(message: &'a DiagMessage, args: &'a FluentArgs<'_>) -> Cow<'a, str> { trace!(?message, ?args); match message { - DiagMessage::Str(msg) => Ok(Cow::Borrowed(msg)), + DiagMessage::Str(msg) => 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. @@ -67,9 +62,9 @@ pub fn format_diag_message<'a>( let translated = bundle.format_pattern(value, Some(args), &mut errs).to_string(); debug!(?translated, ?errs); if errs.is_empty() { - Ok(Cow::Owned(translated)) + Cow::Owned(translated) } else { - Err(TranslateError::fluent(&Cow::Borrowed(GENERATED_MSG_ID), args, errs)) + panic!("Fluent errors while formatting message: {errs:?}"); } } } From 6e8d9c12426d5409f419235f3ad6f6d3cbbb34b0 Mon Sep 17 00:00:00 2001 From: Jonathan Brouwer Date: Sat, 28 Feb 2026 18:34:38 +0100 Subject: [PATCH 2/2] Adjust uses of `format_diag_message` to remove unwrap --- .../src/annotate_snippet_emitter_writer.rs | 12 +++--------- compiler/rustc_errors/src/emitter.rs | 3 +-- compiler/rustc_errors/src/json.rs | 9 ++------- compiler/rustc_errors/src/translation.rs | 7 +------ .../passes/lint/check_code_block_syntax.rs | 3 +-- 5 files changed, 8 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index b68b5e87df1db..bc1a56b5c092b 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -6,7 +6,6 @@ //! [annotate_snippets]: https://docs.rs/crate/annotate-snippets/ use std::borrow::Cow; -use std::error::Report; use std::fmt::Debug; use std::io; use std::io::Write; @@ -361,10 +360,7 @@ impl AnnotateSnippetEmitter { if substitutions.is_empty() { continue; } - let mut msg = format_diag_message(&suggestion.msg, args) - .map_err(Report::new) - .unwrap() - .to_string(); + let mut msg = format_diag_message(&suggestion.msg, args).to_string(); let lo = substitutions .iter() @@ -547,7 +543,7 @@ impl AnnotateSnippetEmitter { ) -> String { msgs.iter() .filter_map(|(m, style)| { - let text = format_diag_message(m, args).map_err(Report::new).unwrap(); + let text = format_diag_message(m, args); let style = style.anstyle(level); if text.is_empty() { None } else { Some(format!("{style}{text}{style:#}")) } }) @@ -694,9 +690,7 @@ fn collect_annotations( let kind = if is_primary { AnnotationKind::Primary } else { AnnotationKind::Context }; - let label = label.as_ref().map(|m| { - normalize_whitespace(&format_diag_message(m, args).map_err(Report::new).unwrap()) - }); + let label = label.as_ref().map(|m| normalize_whitespace(&format_diag_message(m, args))); let ann = Annotation { kind, span, label }; if sm.is_valid_span(ann.span).is_ok() { diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 8571f1584fe8d..e50d8ab67e6cb 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -8,7 +8,6 @@ //! The output types are defined in `rustc_session::config::ErrorOutputType`. use std::borrow::Cow; -use std::error::Report; use std::io::prelude::*; use std::io::{self, IsTerminal}; use std::iter; @@ -106,7 +105,7 @@ pub trait Emitter { fluent_args: &FluentArgs<'_>, ) { if let Some((sugg, rest)) = suggestions.split_first() { - let msg = format_diag_message(&sugg.msg, fluent_args).map_err(Report::new).unwrap(); + let msg = format_diag_message(&sugg.msg, fluent_args); if rest.is_empty() // ^ if there is only one suggestion // don't display multi-suggestions as labels diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index f956fe9490796..ab7a685e0461f 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -9,7 +9,6 @@ // FIXME: spec the JSON output properly. -use std::error::Report; use std::io::{self, Write}; use std::path::{Path, PathBuf}; use std::sync::{Arc, Mutex}; @@ -301,8 +300,7 @@ impl Diagnostic { fn from_errors_diagnostic(diag: crate::DiagInner, je: &JsonEmitter) -> Diagnostic { let args = to_fluent_args(diag.args.iter()); let sugg_to_diag = |sugg: &CodeSuggestion| { - let translated_message = - format_diag_message(&sugg.msg, &args).map_err(Report::new).unwrap(); + let translated_message = format_diag_message(&sugg.msg, &args); Diagnostic { message: translated_message.to_string(), code: None, @@ -417,10 +415,7 @@ impl DiagnosticSpan { Self::from_span_etc( span.span, span.is_primary, - span.label - .as_ref() - .map(|m| format_diag_message(m, args).unwrap()) - .map(|m| m.to_string()), + span.label.as_ref().map(|m| format_diag_message(m, args)).map(|m| m.to_string()), suggestion, je, ) diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index 612bcf22c90c7..0ae1451482068 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -31,12 +31,7 @@ pub fn format_diag_messages( messages: &[(DiagMessage, Style)], args: &FluentArgs<'_>, ) -> Cow<'static, str> { - Cow::Owned( - messages - .iter() - .map(|(m, _)| format_diag_message(m, args).map_err(Report::new).unwrap()) - .collect::(), - ) + Cow::Owned(messages.iter().map(|(m, _)| format_diag_message(m, args)).collect::()) } /// Convert a `DiagMessage` to a string diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index b3199f11a680a..a755efe515477 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -151,8 +151,7 @@ impl Emitter for BufferEmitter { let mut buffer = self.buffer.borrow_mut(); let fluent_args = to_fluent_args(diag.args.iter()); - let translated_main_message = format_diag_message(&diag.messages[0].0, &fluent_args) - .unwrap_or_else(|e| panic!("{e}")); + let translated_main_message = format_diag_message(&diag.messages[0].0, &fluent_args); buffer.messages.push(format!("error from rustc: {translated_main_message}")); if diag.is_error() {