1use std::borrow::Cow;
2
3pub use rustc_error_messages::FluentArgs;
4use rustc_error_messages::{DiagArgMap, DiagArgName, IntoDiagArg, langid, register_functions};
5use tracing::{debug, trace};
6
7use crate::fluent_bundle::FluentResource;
8use crate::{DiagArg, DiagMessage, Style, fluent_bundle};
9
10fn to_fluent_args<'iter>(iter: impl Iterator<Item = DiagArg<'iter>>) -> FluentArgs<'static> {
13 let mut args = if let Some(size) = iter.size_hint().1 {
14 FluentArgs::with_capacity(size)
15 } else {
16 FluentArgs::new()
17 };
18
19 for (k, v) in iter {
20 args.set(k.clone(), v.clone());
21 }
22
23 args
24}
25
26pub fn format_diag_messages(
28 messages: &[(DiagMessage, Style)],
29 args: &DiagArgMap,
30) -> Cow<'static, str> {
31 Cow::Owned(messages.iter().map(|(m, _)| format_diag_message(m, args)).collect::<String>())
32}
33
34pub fn format_diag_message<'a>(message: &'a DiagMessage, args: &DiagArgMap) -> Cow<'a, str> {
36 match message {
37 DiagMessage::Str(msg) => Cow::Borrowed(msg),
38 DiagMessage::Inline(msg) => format_fluent_str(msg, args),
39 }
40}
41
42fn format_fluent_str(message: &str, args: &DiagArgMap) -> Cow<'static, str> {
43 {
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/formatting.rs:43",
"rustc_errors::formatting", ::tracing::Level::TRACE,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/formatting.rs"),
::tracing_core::__macro_support::Option::Some(43u32),
::tracing_core::__macro_support::Option::Some("rustc_errors::formatting"),
::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);
44 const GENERATED_MSG_ID: &str = "generated_msg";
45 let resource = FluentResource::try_new(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} = {1}\n", GENERATED_MSG_ID,
message))
})format!("{GENERATED_MSG_ID} = {message}\n")).unwrap();
46 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")]);
47 bundle.set_use_isolating(false);
48 bundle.add_resource(resource).unwrap();
49 register_functions(&mut bundle);
50 let message = bundle.get_message(GENERATED_MSG_ID).unwrap();
51 let value = message.value().unwrap();
52 let args = to_fluent_args(args.iter());
53
54 let mut errs = ::alloc::vec::Vec::new()vec![];
55 let formatted = bundle.format_pattern(value, Some(&args), &mut errs).to_string();
56 {
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/formatting.rs:56",
"rustc_errors::formatting", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_errors/src/formatting.rs"),
::tracing_core::__macro_support::Option::Some(56u32),
::tracing_core::__macro_support::Option::Some("rustc_errors::formatting"),
::tracing_core::field::FieldSet::new(&["formatted", "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(&formatted)
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!(?formatted, ?errs);
57 if errs.is_empty() {
58 Cow::Owned(formatted)
59 } else {
60 {
::core::panicking::panic_fmt(format_args!("Fluent errors while formatting message: {0:?}",
errs));
};panic!("Fluent errors while formatting message: {errs:?}");
61 }
62}
63
64pub trait DiagMessageAddArg {
65 fn arg(self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg) -> EagerDiagMessageBuilder;
66}
67
68pub struct EagerDiagMessageBuilder {
69 fluent_str: Cow<'static, str>,
70 args: DiagArgMap,
71}
72
73impl DiagMessageAddArg for EagerDiagMessageBuilder {
74 fn arg(
75 mut self,
76 name: impl Into<DiagArgName>,
77 arg: impl IntoDiagArg,
78 ) -> EagerDiagMessageBuilder {
79 let name = name.into();
80 let value = arg.into_diag_arg(&mut None);
81 if true {
if !(!self.args.contains_key(&name) ||
self.args.get(&name) == Some(&value)) {
{
::core::panicking::panic_fmt(format_args!("arg {0} already exists",
name));
}
};
};debug_assert!(
82 !self.args.contains_key(&name) || self.args.get(&name) == Some(&value),
83 "arg {} already exists",
84 name
85 );
86 self.args.insert(name, value);
87 self
88 }
89}
90
91impl DiagMessageAddArg for DiagMessage {
92 fn arg(self, name: impl Into<DiagArgName>, arg: impl IntoDiagArg) -> EagerDiagMessageBuilder {
93 let DiagMessage::Inline(fluent_str) = self else {
94 {
::core::panicking::panic_fmt(format_args!("Tried to eagerly format an already formatted message"));
}panic!("Tried to eagerly format an already formatted message")
95 };
96 EagerDiagMessageBuilder { fluent_str, args: Default::default() }.arg(name, arg)
97 }
98}
99
100impl EagerDiagMessageBuilder {
101 pub fn format(self) -> DiagMessage {
102 DiagMessage::Str(format_fluent_str(&self.fluent_str, &self.args))
103 }
104}