1#![allow(internal_features)]
3#![feature(rustc_attrs)]
4use std::borrow::Cow;
7
8pub use fluent_bundle::types::FluentType;
9pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue};
10use rustc_macros::{Decodable, Encodable};
11use rustc_span::Span;
12pub use unic_langid::{LanguageIdentifier, langid};
13
14mod diagnostic_impls;
15pub use diagnostic_impls::DiagArgFromDisplay;
16
17pub fn register_functions<R, M>(bundle: &mut fluent_bundle::bundle::FluentBundle<R, M>) {
18 bundle
19 .add_function("STREQ", |positional, _named| match positional {
20 [FluentValue::String(a), FluentValue::String(b)] => ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}", (a == b)))
})format!("{}", (a == b)).into(),
21 _ => FluentValue::Error,
22 })
23 .expect("Failed to add a function to the bundle.");
24}
25
26#[derive(#[automatically_derived]
impl ::core::clone::Clone for DiagMessage {
#[inline]
fn clone(&self) -> DiagMessage {
match self {
DiagMessage::Str(__self_0) =>
DiagMessage::Str(::core::clone::Clone::clone(__self_0)),
DiagMessage::Inline(__self_0) =>
DiagMessage::Inline(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DiagMessage {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
DiagMessage::Str(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Str",
&__self_0),
DiagMessage::Inline(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Inline",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DiagMessage {
#[inline]
fn eq(&self, other: &DiagMessage) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(DiagMessage::Str(__self_0), DiagMessage::Str(__arg1_0)) =>
__self_0 == __arg1_0,
(DiagMessage::Inline(__self_0), DiagMessage::Inline(__arg1_0))
=> __self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for DiagMessage {
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Cow<'static, str>>;
let _: ::core::cmp::AssertParamIsEq<Cow<'static, str>>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for DiagMessage {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
DiagMessage::Str(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
DiagMessage::Inline(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for DiagMessage {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
DiagMessage::Str(ref __binding_0) => { 0usize }
DiagMessage::Inline(ref __binding_0) => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
DiagMessage::Str(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
DiagMessage::Inline(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for DiagMessage {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
DiagMessage::Str(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
DiagMessage::Inline(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `DiagMessage`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable)]
31#[rustc_diagnostic_item = "DiagMessage"]
32pub enum DiagMessage {
33 Str(Cow<'static, str>),
40 Inline(Cow<'static, str>),
42}
43
44impl DiagMessage {
45 pub fn as_str(&self) -> Option<&str> {
46 match self {
47 DiagMessage::Str(s) => Some(s),
48 DiagMessage::Inline(_) => None,
49 }
50 }
51}
52
53impl From<String> for DiagMessage {
54 fn from(s: String) -> Self {
55 DiagMessage::Str(Cow::Owned(s))
56 }
57}
58impl From<&'static str> for DiagMessage {
59 fn from(s: &'static str) -> Self {
60 DiagMessage::Str(Cow::Borrowed(s))
61 }
62}
63impl From<Cow<'static, str>> for DiagMessage {
64 fn from(s: Cow<'static, str>) -> Self {
65 DiagMessage::Str(s)
66 }
67}
68
69#[derive(#[automatically_derived]
impl ::core::clone::Clone for SpanLabel {
#[inline]
fn clone(&self) -> SpanLabel {
SpanLabel {
span: ::core::clone::Clone::clone(&self.span),
is_primary: ::core::clone::Clone::clone(&self.is_primary),
label: ::core::clone::Clone::clone(&self.label),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SpanLabel {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "SpanLabel",
"span", &self.span, "is_primary", &self.is_primary, "label",
&&self.label)
}
}Debug)]
71pub struct SpanLabel {
72 pub span: Span,
74
75 pub is_primary: bool,
78
79 pub label: Option<DiagMessage>,
81}
82
83#[derive(#[automatically_derived]
impl ::core::clone::Clone for MultiSpan {
#[inline]
fn clone(&self) -> MultiSpan {
MultiSpan {
primary_spans: ::core::clone::Clone::clone(&self.primary_spans),
span_labels: ::core::clone::Clone::clone(&self.span_labels),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for MultiSpan {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "MultiSpan",
"primary_spans", &self.primary_spans, "span_labels",
&&self.span_labels)
}
}Debug, #[automatically_derived]
impl ::core::hash::Hash for MultiSpan {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.primary_spans, state);
::core::hash::Hash::hash(&self.span_labels, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for MultiSpan {
#[inline]
fn eq(&self, other: &MultiSpan) -> bool {
self.primary_spans == other.primary_spans &&
self.span_labels == other.span_labels
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for MultiSpan {
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Vec<Span>>;
let _: ::core::cmp::AssertParamIsEq<Vec<(Span, DiagMessage)>>;
}
}Eq, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for MultiSpan {
fn encode(&self, __encoder: &mut __E) {
match *self {
MultiSpan {
primary_spans: ref __binding_0, span_labels: ref __binding_1
} => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for MultiSpan {
fn decode(__decoder: &mut __D) -> Self {
MultiSpan {
primary_spans: ::rustc_serialize::Decodable::decode(__decoder),
span_labels: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
92pub struct MultiSpan {
93 primary_spans: Vec<Span>,
94 span_labels: Vec<(Span, DiagMessage)>,
95}
96
97impl MultiSpan {
98 #[inline]
99 pub fn new() -> MultiSpan {
100 MultiSpan { primary_spans: ::alloc::vec::Vec::new()vec![], span_labels: ::alloc::vec::Vec::new()vec![] }
101 }
102
103 pub fn from_span(primary_span: Span) -> MultiSpan {
104 MultiSpan { primary_spans: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[primary_span]))vec![primary_span], span_labels: ::alloc::vec::Vec::new()vec![] }
105 }
106
107 pub fn from_spans(mut vec: Vec<Span>) -> MultiSpan {
108 vec.sort();
109 MultiSpan { primary_spans: vec, span_labels: ::alloc::vec::Vec::new()vec![] }
110 }
111
112 pub fn push_primary_span(&mut self, primary_span: Span) {
113 self.primary_spans.push(primary_span);
114 }
115
116 pub fn push_span_label(&mut self, span: Span, label: impl Into<DiagMessage>) {
117 self.span_labels.push((span, label.into()));
118 }
119
120 pub fn push_span_diag(&mut self, span: Span, diag: DiagMessage) {
121 self.span_labels.push((span, diag));
122 }
123
124 pub fn primary_span(&self) -> Option<Span> {
126 self.primary_spans.first().cloned()
127 }
128
129 pub fn primary_spans(&self) -> &[Span] {
131 &self.primary_spans
132 }
133
134 pub fn has_primary_spans(&self) -> bool {
136 !self.is_dummy()
137 }
138
139 pub fn is_dummy(&self) -> bool {
141 self.primary_spans.iter().all(|sp| sp.is_dummy())
142 }
143
144 pub fn replace(&mut self, before: Span, after: Span) -> bool {
147 let mut replacements_occurred = false;
148 for primary_span in &mut self.primary_spans {
149 if *primary_span == before {
150 *primary_span = after;
151 replacements_occurred = true;
152 }
153 }
154 for span_label in &mut self.span_labels {
155 if span_label.0 == before {
156 span_label.0 = after;
157 replacements_occurred = true;
158 }
159 }
160 replacements_occurred
161 }
162
163 pub fn span_labels(&self) -> Vec<SpanLabel> {
169 let is_primary = |span| self.primary_spans.contains(&span);
170
171 let mut span_labels = self
172 .span_labels
173 .iter()
174 .map(|&(span, ref label)| SpanLabel {
175 span,
176 is_primary: is_primary(span),
177 label: Some(label.clone()),
178 })
179 .collect::<Vec<_>>();
180
181 for &span in &self.primary_spans {
182 if !span_labels.iter().any(|sl| sl.span == span) {
183 span_labels.push(SpanLabel { span, is_primary: true, label: None });
184 }
185 }
186
187 span_labels
188 }
189
190 pub fn span_labels_raw(&self) -> &[(Span, DiagMessage)] {
192 &self.span_labels
193 }
194
195 pub fn has_span_labels(&self) -> bool {
197 self.span_labels.iter().any(|(sp, _)| !sp.is_dummy())
198 }
199
200 pub fn clone_ignoring_labels(&self) -> Self {
205 Self { primary_spans: self.primary_spans.clone(), ..MultiSpan::new() }
206 }
207}
208
209impl From<Span> for MultiSpan {
210 fn from(span: Span) -> MultiSpan {
211 MultiSpan::from_span(span)
212 }
213}
214
215impl From<Vec<Span>> for MultiSpan {
216 fn from(spans: Vec<Span>) -> MultiSpan {
217 MultiSpan::from_spans(spans)
218 }
219}
220
221fn icu_locale_from_unic_langid(lang: LanguageIdentifier) -> Option<icu_locale::Locale> {
222 icu_locale::Locale::try_from_str(&lang.to_string()).ok()
223}
224
225pub fn fluent_value_from_str_list_sep_by_and(l: Vec<Cow<'_, str>>) -> FluentValue<'_> {
226 #[derive(#[automatically_derived]
impl ::core::clone::Clone for FluentStrListSepByAnd {
#[inline]
fn clone(&self) -> FluentStrListSepByAnd {
FluentStrListSepByAnd(::core::clone::Clone::clone(&self.0))
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for FluentStrListSepByAnd {
#[inline]
fn eq(&self, other: &FluentStrListSepByAnd) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for FluentStrListSepByAnd {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"FluentStrListSepByAnd", &&self.0)
}
}Debug)]
228 struct FluentStrListSepByAnd(Vec<String>);
229
230 impl FluentType for FluentStrListSepByAnd {
231 fn duplicate(&self) -> Box<dyn FluentType + Send> {
232 Box::new(self.clone())
233 }
234
235 fn as_string(&self, intls: &intl_memoizer::IntlLangMemoizer) -> Cow<'static, str> {
236 let result = intls
237 .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| {
238 list_formatter.format_to_string(self.0.iter())
239 })
240 .unwrap();
241 Cow::Owned(result)
242 }
243
244 fn as_string_threadsafe(
245 &self,
246 intls: &intl_memoizer::concurrent::IntlLangMemoizer,
247 ) -> Cow<'static, str> {
248 let result = intls
249 .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| {
250 list_formatter.format_to_string(self.0.iter())
251 })
252 .unwrap();
253 Cow::Owned(result)
254 }
255 }
256
257 struct MemoizableListFormatter(icu_list::ListFormatter);
258
259 impl std::ops::Deref for MemoizableListFormatter {
260 type Target = icu_list::ListFormatter;
261 fn deref(&self) -> &Self::Target {
262 &self.0
263 }
264 }
265
266 impl intl_memoizer::Memoizable for MemoizableListFormatter {
267 type Args = ();
268 type Error = ();
269
270 fn construct(lang: LanguageIdentifier, _args: Self::Args) -> Result<Self, Self::Error>
271 where
272 Self: Sized,
273 {
274 let locale = icu_locale_from_unic_langid(lang)
275 .unwrap_or_else(|| rustc_baked_icu_data::supported_locales::EN);
276 let list_formatter = icu_list::ListFormatter::try_new_and_unstable(
277 &rustc_baked_icu_data::BakedDataProvider,
278 locale.into(),
279 icu_list::options::ListFormatterOptions::default()
280 .with_length(icu_list::options::ListLength::Wide),
281 )
282 .expect("Failed to create list formatter");
283
284 Ok(MemoizableListFormatter(list_formatter))
285 }
286 }
287
288 let l = l.into_iter().map(|x| x.into_owned()).collect();
289
290 FluentValue::Custom(Box::new(FluentStrListSepByAnd(l)))
291}
292
293pub type DiagArg<'iter> = (&'iter DiagArgName, &'iter DiagArgValue);
297
298pub type DiagArgName = Cow<'static, str>;
300
301#[derive(#[automatically_derived]
impl ::core::clone::Clone for DiagArgValue {
#[inline]
fn clone(&self) -> DiagArgValue {
match self {
DiagArgValue::Str(__self_0) =>
DiagArgValue::Str(::core::clone::Clone::clone(__self_0)),
DiagArgValue::Number(__self_0) =>
DiagArgValue::Number(::core::clone::Clone::clone(__self_0)),
DiagArgValue::StrListSepByAnd(__self_0) =>
DiagArgValue::StrListSepByAnd(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DiagArgValue {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
DiagArgValue::Str(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Str",
&__self_0),
DiagArgValue::Number(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Number",
&__self_0),
DiagArgValue::StrListSepByAnd(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"StrListSepByAnd", &__self_0),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DiagArgValue {
#[inline]
fn eq(&self, other: &DiagArgValue) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(DiagArgValue::Str(__self_0), DiagArgValue::Str(__arg1_0)) =>
__self_0 == __arg1_0,
(DiagArgValue::Number(__self_0),
DiagArgValue::Number(__arg1_0)) => __self_0 == __arg1_0,
(DiagArgValue::StrListSepByAnd(__self_0),
DiagArgValue::StrListSepByAnd(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for DiagArgValue {
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Cow<'static, str>>;
let _: ::core::cmp::AssertParamIsEq<i32>;
let _: ::core::cmp::AssertParamIsEq<Vec<Cow<'static, str>>>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for DiagArgValue {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
DiagArgValue::Str(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
DiagArgValue::Number(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
DiagArgValue::StrListSepByAnd(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for DiagArgValue {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
DiagArgValue::Str(ref __binding_0) => { 0usize }
DiagArgValue::Number(ref __binding_0) => { 1usize }
DiagArgValue::StrListSepByAnd(ref __binding_0) => { 2usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
DiagArgValue::Str(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
DiagArgValue::Number(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
DiagArgValue::StrListSepByAnd(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for DiagArgValue {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
DiagArgValue::Str(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => {
DiagArgValue::Number(::rustc_serialize::Decodable::decode(__decoder))
}
2usize => {
DiagArgValue::StrListSepByAnd(::rustc_serialize::Decodable::decode(__decoder))
}
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `DiagArgValue`, expected 0..3, actual {0}",
n));
}
}
}
}
};Decodable)]
304pub enum DiagArgValue {
305 Str(Cow<'static, str>),
306 Number(i32),
310 StrListSepByAnd(Vec<Cow<'static, str>>),
311}
312
313pub trait IntoDiagArg {
318 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue;
325}
326
327impl IntoDiagArg for DiagArgValue {
328 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
329 self
330 }
331}
332
333impl From<DiagArgValue> for FluentValue<'static> {
334 fn from(val: DiagArgValue) -> Self {
335 match val {
336 DiagArgValue::Str(s) => From::from(s),
337 DiagArgValue::Number(n) => From::from(n),
338 DiagArgValue::StrListSepByAnd(l) => fluent_value_from_str_list_sep_by_and(l),
339 }
340 }
341}