Skip to main content

rustc_errors/
translation.rs

1use std::borrow::Cow;
2use std::error::Report;
3
4pub use rustc_error_messages::FluentArgs;
5use rustc_error_messages::{langid, register_functions};
6use tracing::{debug, trace};
7
8use crate::error::TranslateError;
9use crate::fluent_bundle::FluentResource;
10use crate::{DiagArg, DiagMessage, Style, fluent_bundle};
11
12/// Convert diagnostic arguments (a rustc internal type that exists to implement
13/// `Encodable`/`Decodable`) into `FluentArgs` which is necessary to perform translation.
14///
15/// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then
16/// passed around as a reference thereafter.
17pub fn to_fluent_args<'iter>(iter: impl Iterator<Item = DiagArg<'iter>>) -> FluentArgs<'static> {
18    let mut args = if let Some(size) = iter.size_hint().1 {
19        FluentArgs::with_capacity(size)
20    } else {
21        FluentArgs::new()
22    };
23
24    for (k, v) in iter {
25        args.set(k.clone(), v.clone());
26    }
27
28    args
29}
30
31/// Convert `DiagMessage`s to a string
32pub fn format_diag_messages(
33    messages: &[(DiagMessage, Style)],
34    args: &FluentArgs<'_>,
35) -> Cow<'static, str> {
36    Cow::Owned(
37        messages
38            .iter()
39            .map(|(m, _)| format_diag_message(m, args).map_err(Report::new).unwrap())
40            .collect::<String>(),
41    )
42}
43
44/// Convert a `DiagMessage` to a string
45pub fn format_diag_message<'a>(
46    message: &'a DiagMessage,
47    args: &'a FluentArgs<'_>,
48) -> Result<Cow<'a, str>, TranslateError<'a>> {
49    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_errors/src/translation.rs:49",
                        "rustc_errors::translation", ::tracing::Level::TRACE,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/translation.rs"),
                        ::tracing_core::__macro_support::Option::Some(49u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_errors::translation"),
                        ::tracing_core::field::FieldSet::new(&["message", "args"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::TRACE <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::TRACE <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&message) as
                                            &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&args) as
                                            &dyn Value))])
            });
    } else { ; }
};trace!(?message, ?args);
50    match message {
51        DiagMessage::Str(msg) => Ok(Cow::Borrowed(msg)),
52        // This translates an inline fluent diagnostic message
53        // It does this by creating a new `FluentBundle` with only one message,
54        // and then translating using this bundle.
55        DiagMessage::Inline(msg) => {
56            const GENERATED_MSG_ID: &str = "generated_msg";
57            let resource =
58                FluentResource::try_new(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} = {1}\n", GENERATED_MSG_ID,
                msg))
    })format!("{GENERATED_MSG_ID} = {msg}\n")).unwrap();
59            let mut bundle = fluent_bundle::FluentBundle::new(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [{
                    #[allow(dead_code)]
                    enum ProcMacroHack { Value = ("\"en-US\"", 0).1, }
                    macro_rules! proc_macro_call {
                        () =>
                        {
                            unsafe
                            {
                                $crate :: LanguageIdentifier ::
                                from_raw_parts_unchecked(unsafe
                                {
                                    $crate :: subtags :: Language ::
                                    from_raw_unchecked(28261u64)
                                }, None,
                                Some(unsafe
                                {
                                    $crate :: subtags :: Region :: from_raw_unchecked(21333u32)
                                }), None)
                            }
                        }
                    }
                    unsafe {
                        ::unic_langid_macros::LanguageIdentifier::from_raw_parts_unchecked(unsafe
                                {
                                ::unic_langid_macros::subtags::Language::from_raw_unchecked(28261u64)
                            }, None,
                            Some(unsafe {
                                    ::unic_langid_macros::subtags::Region::from_raw_unchecked(21333u32)
                                }), None)
                    }
                }]))vec![langid!("en-US")]);
60            bundle.set_use_isolating(false);
61            bundle.add_resource(resource).unwrap();
62            register_functions(&mut bundle);
63            let message = bundle.get_message(GENERATED_MSG_ID).unwrap();
64            let value = message.value().unwrap();
65
66            let mut errs = ::alloc::vec::Vec::new()vec![];
67            let translated = bundle.format_pattern(value, Some(args), &mut errs).to_string();
68            {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_errors/src/translation.rs:68",
                        "rustc_errors::translation", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/translation.rs"),
                        ::tracing_core::__macro_support::Option::Some(68u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_errors::translation"),
                        ::tracing_core::field::FieldSet::new(&["translated",
                                        "errs"], ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&translated)
                                            as &dyn Value)),
                                (&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&debug(&errs) as
                                            &dyn Value))])
            });
    } else { ; }
};debug!(?translated, ?errs);
69            if errs.is_empty() {
70                Ok(Cow::Owned(translated))
71            } else {
72                Err(TranslateError::fluent(&Cow::Borrowed(GENERATED_MSG_ID), args, errs))
73            }
74        }
75    }
76}