Skip to content
Merged
Show file tree
Hide file tree
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
2 changes: 0 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3808,7 +3808,6 @@ name = "rustc_error_messages"
version = "0.0.0"
dependencies = [
"fluent-bundle",
"fluent-syntax",
"icu_list",
"icu_locale",
"intl-memoizer",
Expand All @@ -3819,7 +3818,6 @@ dependencies = [
"rustc_macros",
"rustc_serialize",
"rustc_span",
"tracing",
"unic-langid",
]

Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use rustc_data_structures::jobserver::{self, Acquired};
use rustc_data_structures::memmap::Mmap;
use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
use rustc_errors::emitter::Emitter;
use rustc_errors::translation::Translator;
use rustc_errors::{
Diag, DiagArgMap, DiagCtxt, DiagCtxtHandle, DiagMessage, ErrCode, FatalError, FatalErrorMarker,
Level, MultiSpan, Style, Suggestions, catch_fatal_errors,
Expand Down Expand Up @@ -2010,10 +2009,6 @@ impl Emitter for SharedEmitter {
fn source_map(&self) -> Option<&SourceMap> {
None
}

fn translator(&self) -> &Translator {
panic!("shared emitter attempted to translate a diagnostic");
}
}

impl SharedEmitterMain {
Expand Down
7 changes: 0 additions & 7 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ use rustc_data_structures::profiling::{
};
pub use rustc_errors::catch_fatal_errors;
use rustc_errors::emitter::stderr_destination;
use rustc_errors::translation::Translator;
use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, PResult, markdown};
use rustc_feature::find_gated_cfg;
// This avoids a false positive with `-Wunused_crate_dependencies`.
Expand Down Expand Up @@ -107,10 +106,6 @@ use crate::session_diagnostics::{
RLinkWrongFileType, RlinkCorruptFile, RlinkNotAFile, RlinkUnableToRead, UnstableFeatureUsage,
};

pub fn default_translator() -> Translator {
Translator::new()
}

/// Exit status code used for successful compilation and help output.
pub const EXIT_SUCCESS: i32 = 0;

Expand Down Expand Up @@ -1525,11 +1520,9 @@ fn report_ice(
extra_info: fn(&DiagCtxt),
using_internal_features: &AtomicBool,
) {
let translator = Translator::new();
let emitter =
Box::new(rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter::new(
stderr_destination(rustc_errors::ColorConfig::Auto),
translator,
));
let dcx = rustc_errors::DiagCtxt::new(emitter);
let dcx = dcx.handle();
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_error_messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ edition = "2024"
[dependencies]
# tidy-alphabetical-start
fluent-bundle = "0.16"
fluent-syntax = "0.12"
icu_list = { version = "2.0", default-features = false, features = ["alloc"] }
icu_locale = { version = "2.0", default-features = false }
intl-memoizer = "0.5.1"
Expand All @@ -17,6 +16,5 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_span = { path = "../rustc_span" }
tracing = "0.1"
unic-langid = { version = "0.9.0", features = ["macros"] }
# tidy-alphabetical-end
207 changes: 0 additions & 207 deletions compiler/rustc_error_messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,194 +4,16 @@
// tidy-alphabetical-end

use std::borrow::Cow;
use std::error::Error;
use std::path::Path;
use std::sync::{Arc, LazyLock};
use std::{fmt, fs, io};

use fluent_bundle::FluentResource;
pub use fluent_bundle::types::FluentType;
pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
use fluent_syntax::parser::ParserError;
use intl_memoizer::concurrent::IntlLangMemoizer;
use rustc_data_structures::sync::{DynSend, IntoDynSyncSend};
use rustc_macros::{Decodable, Encodable};
use rustc_span::Span;
use tracing::{instrument, trace};
pub use unic_langid::{LanguageIdentifier, langid};

mod diagnostic_impls;
pub use diagnostic_impls::DiagArgFromDisplay;

pub type FluentBundle =
IntoDynSyncSend<fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>>;

fn new_bundle(locales: Vec<LanguageIdentifier>) -> FluentBundle {
IntoDynSyncSend(fluent_bundle::bundle::FluentBundle::new_concurrent(locales))
}

#[derive(Debug)]
pub enum TranslationBundleError {
/// Failed to read from `.ftl` file.
ReadFtl(io::Error),
/// Failed to parse contents of `.ftl` file.
ParseFtl(ParserError),
/// Failed to add `FluentResource` to `FluentBundle`.
AddResource(FluentError),
/// `$sysroot/share/locale/$locale` does not exist.
MissingLocale,
/// Cannot read directory entries of `$sysroot/share/locale/$locale`.
ReadLocalesDir(io::Error),
/// Cannot read directory entry of `$sysroot/share/locale/$locale`.
ReadLocalesDirEntry(io::Error),
/// `$sysroot/share/locale/$locale` is not a directory.
LocaleIsNotDir,
}

impl fmt::Display for TranslationBundleError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TranslationBundleError::ReadFtl(e) => write!(f, "could not read ftl file: {e}"),
TranslationBundleError::ParseFtl(e) => {
write!(f, "could not parse ftl file: {e}")
}
TranslationBundleError::AddResource(e) => write!(f, "failed to add resource: {e}"),
TranslationBundleError::MissingLocale => write!(f, "missing locale directory"),
TranslationBundleError::ReadLocalesDir(e) => {
write!(f, "could not read locales dir: {e}")
}
TranslationBundleError::ReadLocalesDirEntry(e) => {
write!(f, "could not read locales dir entry: {e}")
}
TranslationBundleError::LocaleIsNotDir => {
write!(f, "`$sysroot/share/locales/$locale` is not a directory")
}
}
}
}

impl Error for TranslationBundleError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
TranslationBundleError::ReadFtl(e) => Some(e),
TranslationBundleError::ParseFtl(e) => Some(e),
TranslationBundleError::AddResource(e) => Some(e),
TranslationBundleError::MissingLocale => None,
TranslationBundleError::ReadLocalesDir(e) => Some(e),
TranslationBundleError::ReadLocalesDirEntry(e) => Some(e),
TranslationBundleError::LocaleIsNotDir => None,
}
}
}

impl From<(FluentResource, Vec<ParserError>)> for TranslationBundleError {
fn from((_, mut errs): (FluentResource, Vec<ParserError>)) -> Self {
TranslationBundleError::ParseFtl(errs.pop().expect("failed ftl parse with no errors"))
}
}

impl From<Vec<FluentError>> for TranslationBundleError {
fn from(mut errs: Vec<FluentError>) -> Self {
TranslationBundleError::AddResource(
errs.pop().expect("failed adding resource to bundle with no errors"),
)
}
}

/// Returns Fluent bundle with the user's locale resources from
/// `$sysroot/share/locale/$requested_locale/*.ftl`.
///
/// If `-Z additional-ftl-path` was provided, load that resource and add it to the bundle
/// (overriding any conflicting messages).
#[instrument(level = "trace")]
pub fn fluent_bundle(
sysroot_candidates: &[&Path],
requested_locale: Option<LanguageIdentifier>,
additional_ftl_path: Option<&Path>,
with_directionality_markers: bool,
) -> Result<Option<Arc<FluentBundle>>, TranslationBundleError> {
if requested_locale.is_none() && additional_ftl_path.is_none() {
return Ok(None);
}

let fallback_locale = langid!("en-US");
let requested_fallback_locale = requested_locale.as_ref() == Some(&fallback_locale);
trace!(?requested_fallback_locale);
if requested_fallback_locale && additional_ftl_path.is_none() {
return Ok(None);
}
// If there is only `-Z additional-ftl-path`, assume locale is "en-US", otherwise use user
// provided locale.
let locale = requested_locale.clone().unwrap_or(fallback_locale);
trace!(?locale);
let mut bundle = new_bundle(vec![locale]);

// Add convenience functions available to ftl authors.
register_functions(&mut bundle);

// Fluent diagnostics can insert directionality isolation markers around interpolated variables
// indicating that there may be a shift from right-to-left to left-to-right text (or
// vice-versa). These are disabled because they are sometimes visible in the error output, but
// may be worth investigating in future (for example: if type names are left-to-right and the
// surrounding diagnostic messages are right-to-left, then these might be helpful).
bundle.set_use_isolating(with_directionality_markers);

// If the user requests the default locale then don't try to load anything.
if let Some(requested_locale) = requested_locale {
let mut found_resources = false;
for sysroot in sysroot_candidates {
let mut sysroot = sysroot.to_path_buf();
sysroot.push("share");
sysroot.push("locale");
sysroot.push(requested_locale.to_string());
trace!(?sysroot);

if !sysroot.exists() {
trace!("skipping");
continue;
}

if !sysroot.is_dir() {
return Err(TranslationBundleError::LocaleIsNotDir);
}

for entry in sysroot.read_dir().map_err(TranslationBundleError::ReadLocalesDir)? {
let entry = entry.map_err(TranslationBundleError::ReadLocalesDirEntry)?;
let path = entry.path();
trace!(?path);
if path.extension().and_then(|s| s.to_str()) != Some("ftl") {
trace!("skipping");
continue;
}

let resource_str =
fs::read_to_string(path).map_err(TranslationBundleError::ReadFtl)?;
let resource =
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
trace!(?resource);
bundle.add_resource(resource).map_err(TranslationBundleError::from)?;
found_resources = true;
}
}

if !found_resources {
return Err(TranslationBundleError::MissingLocale);
}
}

if let Some(additional_ftl_path) = additional_ftl_path {
let resource_str =
fs::read_to_string(additional_ftl_path).map_err(TranslationBundleError::ReadFtl)?;
let resource =
FluentResource::try_new(resource_str).map_err(TranslationBundleError::from)?;
trace!(?resource);
bundle.add_resource_overriding(resource);
}

let bundle = Arc::new(bundle);
Ok(Some(bundle))
}

pub fn register_functions<R, M>(bundle: &mut fluent_bundle::bundle::FluentBundle<R, M>) {
bundle
.add_function("STREQ", |positional, _named| match positional {
Expand All @@ -201,35 +23,6 @@ pub fn register_functions<R, M>(bundle: &mut fluent_bundle::bundle::FluentBundle
.expect("Failed to add a function to the bundle.");
}

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

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

register_functions(&mut fallback_bundle);

// See comment in `fluent_bundle`.
fallback_bundle.set_use_isolating(with_directionality_markers);

for resource in resources {
let resource = FluentResource::try_new(resource.to_string())
.expect("failed to parse fallback fluent resource");
fallback_bundle.add_resource_overriding(resource);
}

fallback_bundle
})))
}

/// Abstraction over a message in a diagnostic to support both translatable and non-translatable
/// diagnostic messages.
///
Expand Down
Loading
Loading