Skip to content

Commit 7b5cb45

Browse files
committed
add FluentRaw to represent fluent raw content
1 parent 9c5e2ce commit 7b5cb45

File tree

9 files changed

+72
-38
lines changed

9 files changed

+72
-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

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use rustc_data_structures::stable_hasher::{Hash128, StableHasher};
3838
use rustc_data_structures::sync::{Lock, Lrc};
3939
use rustc_data_structures::AtomicRef;
4040
pub use rustc_error_messages::{
41-
fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle,
41+
fallback_fluent_bundle, fluent_bundle, fluent_raw, DelayDm, DiagnosticMessage, FluentBundle,
4242
LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage,
4343
};
4444
pub use rustc_lint_defs::{pluralize, Applicability};

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
@@ -69,7 +69,7 @@ impl<'a> DiagnosticDerive<'a> {
6969
}
7070
(None, Some(raw_label)) => {
7171
quote! {
72-
let mut #diag = #handler.struct_diagnostic(DiagnosticMessage::Str(#raw_label.into()));
72+
let mut #diag = #handler.struct_diagnostic(DiagnosticMessage::FluentRaw(#raw_label.into()));
7373
}
7474
}
7575
(Some(_slug), Some(_raw_label)) => {

compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
509509

510510
let suggestion_label = if let Some(raw_label) = raw_label {
511511
quote! {
512-
#raw_label
512+
DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label))
513513
}
514514
} else {
515515
quote! {
@@ -547,15 +547,15 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
547547
return quote! {
548548
#diag.#fn_name(
549549
#field_binding,
550-
#raw_label
550+
DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label))
551551
);
552552
};
553553
}
554554
if let Some(raw_label) = self.get_attr(kind.to_string().as_str()) {
555555
quote! {
556556
#diag.#fn_name(
557557
#field_binding,
558-
#raw_label
558+
DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label))
559559
);
560560
}
561561
} else {
@@ -579,12 +579,12 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
579579
let diag = &self.parent.diag;
580580
if let Some(raw_label) = raw_label {
581581
return quote! {
582-
#diag.#kind(#raw_label);
582+
#diag.#kind(DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label)));
583583
};
584584
}
585585
if let Some(raw_label) = self.get_attr(kind.to_string().as_str()) {
586586
quote! {
587-
#diag.#kind(#raw_label);
587+
#diag.#kind(DiagnosticMessage::FluentRaw(std::borrow::Cow::Borrowed(#raw_label)));
588588
}
589589
} else {
590590
quote! {

compiler/rustc_macros/src/diagnostics/subdiagnostic.rs

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

533533
let name = format_ident!(

compiler/rustc_parse/src/errors.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
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};
6-
use rustc_errors::DiagnosticMessage;
7+
use rustc_errors::{fluent_raw, DiagnosticMessage};
78
use rustc_errors::{AddToDiagnostic, Applicability, ErrorGuaranteed, IntoDiagnostic};
89
use rustc_macros::{Diagnostic, Subdiagnostic};
910
use rustc_session::errors::ExprParenthesesNeeded;
1011
use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
1112
use rustc_span::symbol::Ident;
1213
use rustc_span::{Span, Symbol};
1314

14-
use crate::parser::{ForbiddenLetReason, TokenDescription};
15-
1615
#[derive(Diagnostic)]
1716
#[diag("ambiguous `+` in a type")]
1817
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);
@@ -1305,14 +1308,18 @@ impl<'a> IntoDiagnostic<'a> for ExpectedSemi {
13051308

13061309
let mut diag = handler.struct_diagnostic(match token_descr {
13071310
Some(TokenDescription::ReservedIdentifier) => {
1308-
"expected `;`, found reserved identifier `{$token}`"
1311+
fluent_raw!("expected `;`, found reserved identifier `{$token}`")
1312+
}
1313+
Some(TokenDescription::Keyword) => {
1314+
fluent_raw!("expected `;`, found keyword `{$token}`")
13091315
}
1310-
Some(TokenDescription::Keyword) => "expected `;`, found keyword `{$token}`",
13111316
Some(TokenDescription::ReservedKeyword) => {
1312-
"expected `;`, found reserved keyword `{$token}`"
1317+
fluent_raw!("expected `;`, found reserved keyword `{$token}`")
1318+
}
1319+
Some(TokenDescription::DocComment) => {
1320+
fluent_raw!("expected `;`, found doc comment `{$token}`")
13131321
}
1314-
Some(TokenDescription::DocComment) => "expected `;`, found doc comment `{$token}`",
1315-
None => "expected `;`, found `{$token}`",
1322+
None => fluent_raw!("expected `;`, found `{$token}`"),
13161323
});
13171324
diag.set_span(self.span);
13181325
diag.set_arg("token", self.token);

compiler/rustc_parse/src/parser/attr.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ 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::fluent_raw;
7+
use rustc_errors::DiagnosticMessage;
68
use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult};
79
use rustc_span::{sym, BytePos, Span};
10+
use std::borrow::Cow;
811
use std::convert::TryInto;
912
use thin_vec::ThinVec;
1013
use tracing::debug;
@@ -175,10 +178,15 @@ impl<'a> Parser<'a> {
175178
Ok(Some(item)) => {
176179
// FIXME(#100717)
177180
err.set_arg("item", item.kind.descr());
178-
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+
);
179185
err.span_suggestion_verbose(
180186
replacement_span,
181-
"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+
),
182190
match attr_type {
183191
OuterAttributeType::Attribute => "",
184192
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, ErrorGuaranteed, IntoDiagnostic,
3031
PResult, StashKey,

0 commit comments

Comments
 (0)