Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect references to non-existant messages in Fluent resources #107096

Merged
merged 2 commits into from
Jan 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ codegen_gcc_invalid_monomorphization_unsupported_element =
invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}`
codegen_gcc_invalid_monomorphization_invalid_bitmask =
invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
codegen_gcc_invalid_monomorphization_simd_shuffle =
invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,9 @@ codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$
codegen_ssa_unsupported_arch = unsupported arch `{$arch}` for os `{$os}`
codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {error}
codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
codegen_ssa_read_file = failed to read file: {message}
codegen_ssa_read_file = failed to read file: {$message}
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
Expand Down
34 changes: 32 additions & 2 deletions compiler/rustc_macros/src/diagnostics/fluent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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('-') {
Expand All @@ -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`)
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
missing_message_ref = {message}
9 changes: 9 additions & 0 deletions tests/ui-fulldeps/fluent-messages/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
10 changes: 9 additions & 1 deletion tests/ui-fulldeps/fluent-messages/test.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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"
clubby789 marked this conversation as resolved.
Show resolved Hide resolved
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= 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`.