about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-03-29 21:19:50 +0200
committerGitHub <noreply@github.com>2023-03-29 21:19:50 +0200
commit5937ec1915c09f6891825f393bc6d0e592a1d511 (patch)
tree1eb8c5b858e6e010bc80339458c06bac6c06e0fb
parentc62bb46fb32d00b448105590d0f9bd5782da7f71 (diff)
parent979c265a5d54a3a267563153859f2921db717b1d (diff)
downloadrust-5937ec1915c09f6891825f393bc6d0e592a1d511.tar.gz
rust-5937ec1915c09f6891825f393bc6d0e592a1d511.zip
Rollup merge of #109700 - clubby789:tidy-fluent-escape, r=compiler-errors
Lint against escape sequences in Fluent files

Fixes #109686 by checking for `\n`, `\"` and `\'` in Fluent files. It might be useful to have a way to opt out of this check, but all messages with violations currently do seem to be incorrect.
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl3
-rw-r--r--compiler/rustc_const_eval/messages.ftl16
-rw-r--r--compiler/rustc_incremental/messages.ftl2
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_macros/src/diagnostics/fluent.rs12
-rw-r--r--tests/ui-fulldeps/fluent-messages/invalid-escape.ftl1
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.rs9
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.stderr26
-rw-r--r--tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr2
9 files changed, 64 insertions, 9 deletions
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index e5df417370b..b6d7484bcce 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -27,7 +27,8 @@ codegen_llvm_error_calling_dlltool =
     Error calling dlltool: {$error}
 
 codegen_llvm_dlltool_fail_import_library =
-    Dlltool could not create import library: {$stdout}\n{$stderr}
+    Dlltool could not create import library: {$stdout}
+    {$stderr}
 
 codegen_llvm_target_feature_disable_or_enable =
     the target features {$features} must all be either enabled or disabled together
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 33bb116d6fa..f6751df443f 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -39,17 +39,25 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn
 const_eval_unallowed_mutable_refs =
     mutable references are not allowed in the final value of {$kind}s
     .teach_note =
-        References in statics and constants may only refer to immutable values.\n\n
+        References in statics and constants may only refer to immutable values.
+
+
         Statics are shared everywhere, and if they refer to mutable data one might violate memory
-        safety since holding multiple mutable references to shared data is not allowed.\n\n
+        safety since holding multiple mutable references to shared data is not allowed.
+
+
         If you really want global mutable state, try using static mut or a global UnsafeCell.
 
 const_eval_unallowed_mutable_refs_raw =
     raw mutable references are not allowed in the final value of {$kind}s
     .teach_note =
-        References in statics and constants may only refer to immutable values.\n\n
+        References in statics and constants may only refer to immutable values.
+
+
         Statics are shared everywhere, and if they refer to mutable data one might violate memory
-        safety since holding multiple mutable references to shared data is not allowed.\n\n
+        safety since holding multiple mutable references to shared data is not allowed.
+
+
         If you really want global mutable state, try using static mut or a global UnsafeCell.
 
 const_eval_non_const_fmt_macro_call =
diff --git a/compiler/rustc_incremental/messages.ftl b/compiler/rustc_incremental/messages.ftl
index 4852ee0d959..b760620e3d4 100644
--- a/compiler/rustc_incremental/messages.ftl
+++ b/compiler/rustc_incremental/messages.ftl
@@ -24,7 +24,7 @@ incremental_field_associated_value_expected = associated value expected for `{$n
 incremental_no_field = no field `{$name}`
 
 incremental_assertion_auto =
-    `except` specified DepNodes that can not be affected for \"{$name}\": \"{$e}\"
+    `except` specified DepNodes that can not be affected for "{$name}": "{$e}"
 
 incremental_undefined_clean_dirty_assertions_item =
     clean/dirty auto-assertions not yet defined for Node::Item.node={$kind}
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 5b7e994e035..d9c8142226d 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -91,7 +91,7 @@ lint_ty_qualified = usage of qualified `ty::{$ty}`
 lint_lintpass_by_hand = implementing `LintPass` by hand
     .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead
 
-lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]`
+lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = "...")]`
     .help = only existing keywords are allowed in core/std
 
 lint_diag_out_of_impl =
diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs
index 38c0f4895db..3b2f5cfdc73 100644
--- a/compiler/rustc_macros/src/diagnostics/fluent.rs
+++ b/compiler/rustc_macros/src/diagnostics/fluent.rs
@@ -111,6 +111,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
             .emit();
         return failed(&crate_name);
     }
+    let mut bad = false;
+    for esc in ["\\n", "\\\"", "\\'"] {
+        for _ in resource_contents.matches(esc) {
+            bad = true;
+            Diagnostic::spanned(resource_span, Level::Error, format!("invalid escape `{esc}` in Fluent resource"))
+                .note("Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>)")
+                .emit();
+        }
+    }
+    if bad {
+        return failed(&crate_name);
+    }
 
     let resource = match FluentResource::try_new(resource_contents) {
         Ok(resource) => resource,
diff --git a/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl
new file mode 100644
index 00000000000..e28852ea005
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl
@@ -0,0 +1 @@
+no_crate_bad_escape = don't use \n, \', or \"
diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs
index 66575eb8e30..1ee7227a8e9 100644
--- a/tests/ui-fulldeps/fluent-messages/test.rs
+++ b/tests/ui-fulldeps/fluent-messages/test.rs
@@ -92,3 +92,12 @@ mod missing_message_ref {
     fluent_messages! { "./missing-message-ref.ftl" }
     //~^ ERROR referenced message `message` does not exist
 }
+
+mod bad_escape {
+    use super::fluent_messages;
+
+    fluent_messages! { "./invalid-escape.ftl" }
+    //~^ ERROR invalid escape `\n`
+    //~| ERROR invalid escape `\"`
+    //~| ERROR invalid escape `\'`
+}
diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr
index c7961ed22f2..8a6a4a91cc2 100644
--- a/tests/ui-fulldeps/fluent-messages/test.stderr
+++ b/tests/ui-fulldeps/fluent-messages/test.stderr
@@ -83,5 +83,29 @@ LL |     fluent_messages! { "./missing-message-ref.ftl" }
    |
    = help: you may have meant to use a variable reference (`{$message}`)
 
-error: aborting due to 10 previous errors
+error: invalid escape `\n` in Fluent resource
+  --> $DIR/test.rs:99:24
+   |
+LL |     fluent_messages! { "./invalid-escape.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: os-specific message
+
+error: invalid escape `\"` in Fluent resource
+  --> $DIR/test.rs:99:24
+   |
+LL |     fluent_messages! { "./invalid-escape.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: os-specific message
+
+error: invalid escape `\'` in Fluent resource
+  --> $DIR/test.rs:99:24
+   |
+LL |     fluent_messages! { "./invalid-escape.ftl" }
+   |                        ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: os-specific message
+
+error: aborting due to 13 previous errors
 
diff --git a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
index 4e296fff6d0..5110b9be08a 100644
--- a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
+++ b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr
@@ -1,4 +1,4 @@
-error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]`
+error: found non-existing keyword `tadam` used in `#[doc(keyword = "...")]`
   --> $DIR/existing_doc_keyword.rs:10:1
    |
 LL | #[doc(keyword = "tadam")]