diff options
| author | clubby789 <jamie@hill-daniel.co.uk> | 2023-01-19 23:48:08 +0000 |
|---|---|---|
| committer | clubby789 <jamie@hill-daniel.co.uk> | 2023-01-27 11:27:22 +0000 |
| commit | ed707a106cac7393db3b59d85b8b065d09840c61 (patch) | |
| tree | 09494db58a72442679c02b53d692ceaccfc288b8 | |
| parent | 5e37043d63bfe2f3be8fa5a05b07d6c0dad5775d (diff) | |
| download | rust-ed707a106cac7393db3b59d85b8b065d09840c61.tar.gz rust-ed707a106cac7393db3b59d85b8b065d09840c61.zip | |
Detect references to non-existant messages in Fluent resources
| -rw-r--r-- | compiler/rustc_macros/src/diagnostics/fluent.rs | 34 | ||||
| -rw-r--r-- | tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl | 1 | ||||
| -rw-r--r-- | tests/ui-fulldeps/fluent-messages/test.rs | 9 | ||||
| -rw-r--r-- | tests/ui-fulldeps/fluent-messages/test.stderr | 10 |
4 files changed, 51 insertions, 3 deletions
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 32338f9dfc5..08098c9bb2a 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -4,7 +4,10 @@ use annotate_snippets::{ }; use fluent_bundle::{FluentBundle, FluentError, FluentResource}; use fluent_syntax::{ - ast::{Attribute, Entry, Identifier, Message}, + ast::{ + Attribute, Entry, Expression, Identifier, InlineExpression, Message, Pattern, + PatternElement, + }, parser::ParserError, }; use proc_macro::{Diagnostic, Level, Span}; @@ -185,9 +188,12 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok }; let mut constants = TokenStream::new(); + let mut messagerefs = Vec::new(); for entry in resource.entries() { let span = res.krate.span(); - if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry { + if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) = + entry + { let _ = previous_defns.entry(name.to_string()).or_insert(path_span); if name.contains('-') { @@ -200,6 +206,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok .emit(); } + if let Some(Pattern { elements }) = value { + for elt in elements { + if let PatternElement::Placeable { + expression: + Expression::Inline(InlineExpression::MessageReference { id, .. }), + } = elt + { + messagerefs.push((id.name, *name)); + } + } + } + // Require that the message name starts with the crate name // `hir_typeck_foo_bar` (in `hir_typeck.ftl`) // `const_eval_baz` (in `const_eval.ftl`) @@ -258,6 +276,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok } } + for (mref, name) in messagerefs.into_iter() { + if !previous_defns.contains_key(mref) { + Diagnostic::spanned( + path_span, + Level::Error, + format!("referenced message `{mref}` does not exist (in message `{name}`)"), + ) + .help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)")) + .emit(); + } + } + if let Err(errs) = bundle.add_resource(resource) { for e in errs { match e { diff --git a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl new file mode 100644 index 00000000000..0cd8229b230 --- /dev/null +++ b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl @@ -0,0 +1 @@ +missing_message_ref = {message} diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 4e8147e2b76..74303e97dba 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -96,3 +96,12 @@ mod missing_crate_name { use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate_foo, with_hyphens}; } + +mod missing_message_ref { + use super::fluent_messages; + + fluent_messages! { + missing => "./missing-message-ref.ftl" +//~^ ERROR referenced message `message` does not exist + } +} diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr index d1cd4fe26da..2631b0a6232 100644 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ b/tests/ui-fulldeps/fluent-messages/test.stderr @@ -93,6 +93,14 @@ LL | test_crate => "./missing-crate-name.ftl", | = help: replace any '-'s with '_'s -error: aborting due to 10 previous errors +error: referenced message `message` does not exist (in message `missing_message_ref`) + --> $DIR/test.rs:104:20 + | +LL | missing => "./missing-message-ref.ftl" + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: you may have meant to use a variable reference (`{$message}`) + +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0428`. |
