about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/messages.ftl3
-rw-r--r--compiler/rustc_infer/messages.ftl8
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_parse/messages.ftl4
-rw-r--r--compiler/rustc_passes/messages.ftl5
-rw-r--r--src/tools/tidy/src/fluent_alphabetical.rs58
-rw-r--r--src/tools/tidy/src/fluent_used.rs43
-rw-r--r--src/tools/tidy/src/lib.rs1
8 files changed, 96 insertions, 28 deletions
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 81c9e02e2ee..f3af633b4e5 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -146,9 +146,6 @@ const_eval_intern_kind = {$kind ->
     *[other] {""}
 }
 
-const_eval_invalid_align =
-    align has to be a power of 2
-
 const_eval_invalid_align_details =
     invalid align passed to `{$name}`: {$align} is {$err_kind ->
         [not_power_of_two] not a power of 2
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl
index 2de87cbe631..e44a6ae3b3f 100644
--- a/compiler/rustc_infer/messages.ftl
+++ b/compiler/rustc_infer/messages.ftl
@@ -181,14 +181,6 @@ infer_more_targeted = {$has_param_name ->
 
 infer_msl_introduces_static = introduces a `'static` lifetime requirement
 infer_msl_unmet_req = because this has an unmet lifetime requirement
-infer_need_type_info_in_coroutine =
-    type inside {$coroutine_kind ->
-    [async_block] `async` block
-    [async_closure] `async` closure
-    [async_fn] `async fn` body
-    *[coroutine] coroutine
-    } must be known in this context
-
 
 infer_nothing = {""}
 
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 63e2fe47659..8bf9d0b9d4a 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -562,8 +562,6 @@ lint_suspicious_double_ref_clone =
 lint_suspicious_double_ref_deref =
     using `.deref()` on a double reference, which returns `{$ty}` instead of dereferencing the inner type
 
-lint_trivial_untranslatable_diag = diagnostic with static strings only
-
 lint_ty_qualified = usage of qualified `ty::{$ty}`
     .suggestion = try importing it and using it unqualified
 
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 60cc138fd7b..a100e2d47bb 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -392,9 +392,6 @@ parse_invalid_identifier_with_leading_number = identifiers cannot start with a n
 
 parse_invalid_interpolated_expression = invalid interpolated expression
 
-parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid
-    .label = invalid suffix `{$suffix}`
-
 parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid
     .label = invalid suffix `{$suffix}`
     .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases
@@ -609,7 +606,6 @@ parse_nonterminal_expected_item_keyword = expected an item keyword
 parse_nonterminal_expected_lifetime = expected a lifetime, found `{$token}`
 
 parse_nonterminal_expected_statement = expected a statement
-parse_not_supported = not supported
 
 parse_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
 
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index c223b847528..7fc523ffe0d 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -302,9 +302,6 @@ passes_export_name =
     attribute should be applied to a free function, impl method or static
     .label = not a free function, impl method or static
 
-passes_expr_not_allowed_in_context =
-    {$expr} is not allowed in a `{$context}`
-
 passes_extern_main =
     the `main` function cannot be declared in an `extern` block
 
@@ -405,8 +402,6 @@ passes_lang_item_on_incorrect_target =
     `{$name}` language item must be applied to a {$expected_target}
     .label = attribute should be applied to a {$expected_target}, not a {$actual_target}
 
-passes_layout =
-    layout error: {$layout_error}
 passes_layout_abi =
     abi: {$abi}
 passes_layout_align =
diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_alphabetical.rs
index 67b745373f0..9803b6eab2d 100644
--- a/src/tools/tidy/src/fluent_alphabetical.rs
+++ b/src/tools/tidy/src/fluent_alphabetical.rs
@@ -1,6 +1,7 @@
 //! Checks that all Flunt files have messages in alphabetical order
 
 use crate::walk::{filter_dirs, walk};
+use std::collections::HashMap;
 use std::{fs::OpenOptions, io::Write, path::Path};
 
 use regex::Regex;
@@ -13,11 +14,27 @@ fn filter_fluent(path: &Path) -> bool {
     if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true }
 }
 
-fn check_alphabetic(filename: &str, fluent: &str, bad: &mut bool) {
+fn check_alphabetic(
+    filename: &str,
+    fluent: &str,
+    bad: &mut bool,
+    all_defined_msgs: &mut HashMap<String, String>,
+) {
     let mut matches = MESSAGE.captures_iter(fluent).peekable();
     while let Some(m) = matches.next() {
+        let name = m.get(1).unwrap();
+        if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) {
+            tidy_error!(
+                bad,
+                "{filename}: message `{}` is already defined in {}",
+                name.as_str(),
+                defined_filename,
+            );
+        }
+
+        all_defined_msgs.insert(name.as_str().to_owned(), filename.to_owned());
+
         if let Some(next) = matches.peek() {
-            let name = m.get(1).unwrap();
             let next = next.get(1).unwrap();
             if name.as_str() > next.as_str() {
                 tidy_error!(
@@ -34,13 +51,29 @@ run `./x.py test tidy --bless` to sort the file correctly",
     }
 }
 
-fn sort_messages(fluent: &str) -> String {
+fn sort_messages(
+    filename: &str,
+    fluent: &str,
+    bad: &mut bool,
+    all_defined_msgs: &mut HashMap<String, String>,
+) -> String {
     let mut chunks = vec![];
     let mut cur = String::new();
     for line in fluent.lines() {
-        if MESSAGE.is_match(line) {
+        if let Some(name) = MESSAGE.find(line) {
+            if let Some(defined_filename) = all_defined_msgs.get(name.as_str()) {
+                tidy_error!(
+                    bad,
+                    "{filename}: message `{}` is already defined in {}",
+                    name.as_str(),
+                    defined_filename,
+                );
+            }
+
+            all_defined_msgs.insert(name.as_str().to_owned(), filename.to_owned());
             chunks.push(std::mem::take(&mut cur));
         }
+
         cur += line;
         cur.push('\n');
     }
@@ -53,20 +86,33 @@ fn sort_messages(fluent: &str) -> String {
 }
 
 pub fn check(path: &Path, bless: bool, bad: &mut bool) {
+    let mut all_defined_msgs = HashMap::new();
     walk(
         path,
         |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)),
         &mut |ent, contents| {
             if bless {
-                let sorted = sort_messages(contents);
+                let sorted = sort_messages(
+                    ent.path().to_str().unwrap(),
+                    contents,
+                    bad,
+                    &mut all_defined_msgs,
+                );
                 if sorted != contents {
                     let mut f =
                         OpenOptions::new().write(true).truncate(true).open(ent.path()).unwrap();
                     f.write(sorted.as_bytes()).unwrap();
                 }
             } else {
-                check_alphabetic(ent.path().to_str().unwrap(), contents, bad);
+                check_alphabetic(
+                    ent.path().to_str().unwrap(),
+                    contents,
+                    bad,
+                    &mut all_defined_msgs,
+                );
             }
         },
     );
+
+    crate::fluent_used::check(path, all_defined_msgs, bad);
 }
diff --git a/src/tools/tidy/src/fluent_used.rs b/src/tools/tidy/src/fluent_used.rs
new file mode 100644
index 00000000000..b73e79cb38d
--- /dev/null
+++ b/src/tools/tidy/src/fluent_used.rs
@@ -0,0 +1,43 @@
+//! Checks that all Fluent messages appear at least twice
+
+use crate::walk::{filter_dirs, walk};
+use regex::Regex;
+use std::collections::HashMap;
+use std::path::Path;
+
+lazy_static::lazy_static! {
+    static ref WORD: Regex = Regex::new(r"\w+").unwrap();
+}
+
+fn filter_used_messages(
+    contents: &str,
+    msgs_not_appeared_yet: &mut HashMap<String, String>,
+    msgs_appeared_only_once: &mut HashMap<String, String>,
+) {
+    // we don't just check messages never appear in Rust files,
+    // because messages can be used as parts of other fluent messages in Fluent files,
+    // so we do checking messages appear only once in all Rust and Fluent files.
+    let mut matches = WORD.find_iter(contents);
+    while let Some(name) = matches.next() {
+        if let Some((name, filename)) = msgs_not_appeared_yet.remove_entry(name.as_str()) {
+            // if one msg appears for the first time,
+            // remove it from `msgs_not_appeared_yet` and insert it into `msgs_appeared_only_once`.
+            msgs_appeared_only_once.insert(name, filename);
+        } else {
+            // if one msg appears for the second time,
+            // remove it from `msgs_appeared_only_once`.
+            msgs_appeared_only_once.remove(name.as_str());
+        }
+    }
+}
+
+pub fn check(path: &Path, mut all_defined_msgs: HashMap<String, String>, bad: &mut bool) {
+    let mut msgs_appear_only_once = HashMap::new();
+    walk(path, |path, _| filter_dirs(path), &mut |_, contents| {
+        filter_used_messages(contents, &mut all_defined_msgs, &mut msgs_appear_only_once);
+    });
+
+    for (name, filename) in msgs_appear_only_once {
+        tidy_error!(bad, "{filename}: message `{}` is not used", name,);
+    }
+}
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 6f3ade0ab58..670b7eb2be9 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -65,6 +65,7 @@ pub mod ext_tool_checks;
 pub mod extdeps;
 pub mod features;
 pub mod fluent_alphabetical;
+mod fluent_used;
 pub(crate) mod iter_header;
 pub mod mir_opt_tests;
 pub mod pal;