Skip to content

Commit bb2eb3f

Browse files
committed
add FluentRaw to represent fluent raw content
1 parent d768dbb commit bb2eb3f

File tree

9 files changed

+78
-38
lines changed

9 files changed

+78
-38
lines changed

compiler/rustc_error_messages/src/lib.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ type FluentId = Cow<'static, str>;
263263
pub enum SubdiagnosticMessage {
264264
/// Non-translatable diagnostic message.
265265
Str(Cow<'static, str>),
266+
/// Translatable diagnostic message in Fluent raw format.
267+
FluentRaw(Cow<'static, str>),
266268
/// Translatable message which has already been translated eagerly.
267269
///
268270
/// Some diagnostics have repeated subdiagnostics where the same interpolated variables would
@@ -310,6 +312,8 @@ impl From<Cow<'static, str>> for SubdiagnosticMessage {
310312
pub enum DiagnosticMessage {
311313
/// Non-translatable diagnostic message.
312314
Str(Cow<'static, str>),
315+
/// Translatable diagnostic message in Fluent raw format.
316+
FluentRaw(Cow<'static, str>),
313317
/// Translatable message which has already been translated eagerly.
314318
///
315319
/// Some diagnostics have repeated subdiagnostics where the same interpolated variables would
@@ -339,6 +343,7 @@ impl DiagnosticMessage {
339343
pub fn with_subdiagnostic_message(&self, sub: SubdiagnosticMessage) -> Self {
340344
let attr = match sub {
341345
SubdiagnosticMessage::Str(s) => return DiagnosticMessage::Str(s),
346+
SubdiagnosticMessage::FluentRaw(s) => return DiagnosticMessage::FluentRaw(s),
342347
SubdiagnosticMessage::Eager(s) => return DiagnosticMessage::Eager(s),
343348
SubdiagnosticMessage::FluentIdentifier(id) => {
344349
return DiagnosticMessage::FluentIdentifier(id, None);
@@ -348,6 +353,7 @@ impl DiagnosticMessage {
348353

349354
match self {
350355
DiagnosticMessage::Str(s) => DiagnosticMessage::Str(s.clone()),
356+
DiagnosticMessage::FluentRaw(s) => DiagnosticMessage::FluentRaw(s.clone()),
351357
DiagnosticMessage::Eager(s) => DiagnosticMessage::Eager(s.clone()),
352358
DiagnosticMessage::FluentIdentifier(id, _) => {
353359
DiagnosticMessage::FluentIdentifier(id.clone(), Some(attr))
@@ -357,7 +363,9 @@ impl DiagnosticMessage {
357363

358364
pub fn as_str(&self) -> Option<&str> {
359365
match self {
360-
DiagnosticMessage::Eager(s) | DiagnosticMessage::Str(s) => Some(s),
366+
DiagnosticMessage::Eager(s)
367+
| DiagnosticMessage::Str(s)
368+
| DiagnosticMessage::FluentRaw(s) => Some(s),
361369
DiagnosticMessage::FluentIdentifier(_, _) => None,
362370
}
363371
}
@@ -379,6 +387,13 @@ impl From<Cow<'static, str>> for DiagnosticMessage {
379387
}
380388
}
381389

390+
#[macro_export]
391+
macro_rules! fluent_raw {
392+
($str:expr) => {
393+
DiagnosticMessage::FluentRaw(Cow::Borrowed($str))
394+
};
395+
}
396+
382397
/// A workaround for "good path" ICEs when formatting types in disabled lints.
383398
///
384399
/// Delays formatting until `.into(): DiagnosticMessage` is used.
@@ -399,6 +414,7 @@ impl Into<SubdiagnosticMessage> for DiagnosticMessage {
399414
fn into(self) -> SubdiagnosticMessage {
400415
match self {
401416
DiagnosticMessage::Str(s) => SubdiagnosticMessage::Str(s),
417+
DiagnosticMessage::FluentRaw(s) => SubdiagnosticMessage::FluentRaw(s),
402418
DiagnosticMessage::Eager(s) => SubdiagnosticMessage::Eager(s),
403419
DiagnosticMessage::FluentIdentifier(id, None) => {
404420
SubdiagnosticMessage::FluentIdentifier(id)

compiler/rustc_errors/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
6060
use rustc_data_structures::sync::{Lock, Lrc};
6161
use rustc_data_structures::AtomicRef;
6262
use rustc_lint_defs::LintExpectationId;
63+
pub use rustc_error_messages::{
64+
fallback_fluent_bundle, fluent_bundle, fluent_raw, DelayDm, DiagnosticMessage, FluentBundle,
65+
LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
66+
};
67+
pub use rustc_lint_defs::{pluralize, Applicability};
6368
use rustc_span::source_map::SourceMap;
6469
use rustc_span::{Loc, Span, DUMMY_SP};
6570
use std::backtrace::{Backtrace, BacktraceStatus};

compiler/rustc_errors/src/translation.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,23 @@ pub trait Translate {
6565
trace!(?message, ?args);
6666
let (identifier, attr) = match message {
6767
DiagnosticMessage::Str(msg) | DiagnosticMessage::Eager(msg) => {
68+
return Ok(Cow::Borrowed(msg));
69+
}
70+
DiagnosticMessage::FluentRaw(msg) => {
6871
// FIXME(yukang): A hack for raw fluent content for new diagnostics proc format
69-
let trimed = msg.replace(" ", "");
70-
if trimed.contains("$") || trimed.contains("{\"") || trimed.contains("\"}") {
71-
let fluent_text = format!("dummy = {}", msg);
72-
if let Ok(resource) = FluentResource::try_new(fluent_text) {
73-
let mut bundle = RawFluentBundle::new(vec![langid!("en-US")]);
74-
bundle.add_resource(resource).unwrap();
75-
let mut errors = vec![];
76-
let pattern = bundle.get_message("dummy").unwrap().value().unwrap();
77-
let res = bundle.format_pattern(&pattern, Some(args), &mut errors);
78-
return Ok(Cow::Owned(
79-
res.to_string().replace("\u{2068}", "").replace("\u{2069}", ""),
80-
));
81-
}
72+
let fluent_text = format!("dummy = {}", msg);
73+
if let Ok(resource) = FluentResource::try_new(fluent_text) {
74+
let mut bundle = RawFluentBundle::new(vec![langid!("en-US")]);
75+
bundle.add_resource(resource).unwrap();
76+
let mut errors = vec![];
77+
let pattern = bundle.get_message("dummy").unwrap().value().unwrap();
78+
let res = bundle.format_pattern(&pattern, Some(args), &mut errors);
79+
return Ok(Cow::Owned(
80+
res.to_string().replace("\u{2068}", "").replace("\u{2069}", ""),
81+
));
8282
}
83+
84+
// If the message is not a valid Fluent resource, just return the original
8385
return Ok(Cow::Borrowed(msg));
8486
}
8587
DiagnosticMessage::FluentIdentifier(identifier, attr) => (identifier, attr),

compiler/rustc_macros/src/diagnostics/diagnostic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ impl<'a> DiagnosticDerive<'a> {
6060
}
6161
(None, Some(raw_label)) => {
6262
quote! {
63-
let mut #diag = #handler.struct_diagnostic(DiagnosticMessage::Str(#raw_label.into()));
63+
let mut #diag = #handler.struct_diagnostic(DiagnosticMessage::FluentRaw(#raw_label.into()));
6464
}
6565
}
6666
(Some(_slug), Some(_raw_label)) => {

compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ impl DiagnosticDeriveVariantBuilder {
493493

494494
let suggestion_label = if let Some(raw_label) = raw_label {
495495
quote! {
496-
#raw_label
496+
DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label))
497497
}
498498
} else {
499499
quote! {
@@ -530,15 +530,15 @@ impl DiagnosticDeriveVariantBuilder {
530530
return quote! {
531531
#diag.#fn_name(
532532
#field_binding,
533-
#raw_label
533+
DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label))
534534
);
535535
};
536536
}
537537
if let Some(raw_label) = self.get_attr(kind.to_string().as_str()) {
538538
quote! {
539539
#diag.#fn_name(
540540
#field_binding,
541-
#raw_label
541+
DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label))
542542
);
543543
}
544544
} else {
@@ -562,12 +562,12 @@ impl DiagnosticDeriveVariantBuilder {
562562
let diag = &self.parent.diag;
563563
if let Some(raw_label) = raw_label {
564564
return quote! {
565-
#diag.#kind(#raw_label);
565+
#diag.#kind(DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label)));
566566
};
567567
}
568568
if let Some(raw_label) = self.get_attr(kind.to_string().as_str()) {
569569
quote! {
570-
#diag.#kind(#raw_label);
570+
#diag.#kind(DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label)));
571571
}
572572
} else {
573573
quote! {

compiler/rustc_macros/src/diagnostics/subdiagnostic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
526526
quote! { let #message = #f(#diag, crate::fluent_generated::#slug.into()); },
527527
);
528528
} else {
529-
calls.extend(quote! { let #message = #f(#diag, #raw_label.into()); });
529+
calls.extend(quote! { let #message = #f(#diag, DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label)).into()); });
530530
}
531531

532532
let name = format_ident!(

compiler/rustc_parse/src/errors.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// ignore-tidy-filelength
22
use std::borrow::Cow;
33

4+
use crate::parser::{ForbiddenLetReason, TokenDescription};
45
use rustc_ast::token::Token;
56
use rustc_ast::{Path, Visibility};
67
use rustc_errors::{
78
AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, IntoDiagnostic, Level,
8-
SubdiagnosticMessage, DiagnosticMessage
9+
SubdiagnosticMessage, DiagnosticMessage, fluent_raw
910
};
1011
use rustc_errors::{AddToDiagnostic, Applicability, ErrorGuaranteed, IntoDiagnostic};
1112
use rustc_macros::{Diagnostic, Subdiagnostic};
@@ -14,8 +15,6 @@ use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
1415
use rustc_span::symbol::Ident;
1516
use rustc_span::{Span, Symbol};
1617

17-
use crate::parser::{ForbiddenLetReason, TokenDescription};
18-
1918
#[derive(Diagnostic)]
2019
#[diag("ambiguous `+` in a type")]
2120
pub(crate) struct AmbiguousPlus {
@@ -1246,18 +1245,22 @@ impl<'a> IntoDiagnostic<'a> for ExpectedIdentifier {
12461245

12471246
let mut diag = handler.struct_diagnostic(match token_descr {
12481247
Some(TokenDescription::ReservedIdentifier) => {
1249-
"expected identifier, found reserved identifier `{$token}`"
1248+
fluent_raw!("expected identifier, found reserved identifier `{$token}`")
12501249
}
1251-
Some(TokenDescription::Keyword) => "expected identifier, found keyword `{$token}`",
1250+
Some(TokenDescription::Keyword) => {
1251+
fluent_raw!("expected identifier, found keyword `{$token}`")
1252+
}
1253+
12521254
Some(TokenDescription::ReservedKeyword) => {
1253-
"expected identifier, found reserved keyword `{$token}`"
1255+
fluent_raw!("expected identifier, found reserved keyword `{$token}`")
12541256
}
12551257

12561258
Some(TokenDescription::DocComment) => {
1257-
"expected identifier, found doc comment `{$token}`"
1259+
fluent_raw!("expected identifier, found doc comment `{$token}`")
1260+
}
1261+
None => {
1262+
fluent_raw!("expected identifier, found `{$token}`")
12581263
}
1259-
1260-
None => "expected identifier, found `{$token}`",
12611264
});
12621265
diag.set_span(self.span);
12631266
diag.set_arg("token", self.token);
@@ -1302,14 +1305,18 @@ impl<'a> IntoDiagnostic<'a> for ExpectedSemi {
13021305

13031306
let mut diag = handler.struct_diagnostic(match token_descr {
13041307
Some(TokenDescription::ReservedIdentifier) => {
1305-
"expected `;`, found reserved identifier `{$token}`"
1308+
fluent_raw!("expected `;`, found reserved identifier `{$token}`")
1309+
}
1310+
Some(TokenDescription::Keyword) => {
1311+
fluent_raw!("expected `;`, found keyword `{$token}`")
13061312
}
1307-
Some(TokenDescription::Keyword) => "expected `;`, found keyword `{$token}`",
13081313
Some(TokenDescription::ReservedKeyword) => {
1309-
"expected `;`, found reserved keyword `{$token}`"
1314+
fluent_raw!("expected `;`, found reserved keyword `{$token}`")
1315+
}
1316+
Some(TokenDescription::DocComment) => {
1317+
fluent_raw!("expected `;`, found doc comment `{$token}`")
13101318
}
1311-
Some(TokenDescription::DocComment) => "expected `;`, found doc comment `{$token}`",
1312-
None => "expected `;`, found `{$token}`",
1319+
None => fluent_raw!("expected `;`, found `{$token}`"),
13131320
});
13141321
diag.set_span(self.span);
13151322
diag.set_arg("token", self.token);

compiler/rustc_parse/src/parser/attr.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@ use crate::errors::{InvalidMetaItem, SuffixedLiteralInAttribute};
33
use rustc_ast as ast;
44
use rustc_ast::attr;
55
use rustc_ast::token::{self, Delimiter, Nonterminal};
6-
use rustc_errors::{error_code, Diagnostic, PResult};
6+
use rustc_errors::fluent_raw;
7+
use rustc_errors::DiagnosticMessage;
8+
use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
79
use rustc_span::{sym, BytePos, Span};
10+
use std::borrow::Cow;
11+
use std::convert::TryInto;
812
use thin_vec::ThinVec;
913
use tracing::debug;
1014

@@ -174,10 +178,15 @@ impl<'a> Parser<'a> {
174178
Ok(Some(item)) => {
175179
// FIXME(#100717)
176180
err.set_arg("item", item.kind.descr());
177-
err.span_label(item.span, "the inner {$item_type} doesn't annotate this {$item}");
181+
err.span_label(
182+
item.span,
183+
fluent_raw!("the inner {$item_type} doesn't annotate this {$item}"),
184+
);
178185
err.span_suggestion_verbose(
179186
replacement_span,
180-
"to annotate the {$item}, change the {$item_type} from inner to outer style",
187+
fluent_raw!(
188+
"to annotate the {$item}, change the {$item_type} from inner to outer style"
189+
),
181190
match attr_type {
182191
OuterAttributeType::Attribute => "",
183192
OuterAttributeType::DocBlockComment => "*",

compiler/rustc_parse/src/parser/expr.rs

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLim
2525
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
2626
use rustc_ast_pretty::pprust;
2727
use rustc_data_structures::stack::ensure_sufficient_stack;
28+
use rustc_errors::DiagnosticMessage;
2829
use rustc_errors::{
2930
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey,
3031
};

0 commit comments

Comments
 (0)