From 25cf1ef47bcf5804e8073d5dca2808dae679e12d Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 15 Sep 2023 10:29:41 +0800 Subject: [PATCH] add check_unused_messages in tidy --- compiler/rustc_hir_analysis/messages.ftl | 2 - compiler/rustc_infer/messages.ftl | 4 -- compiler/rustc_monomorphize/messages.ftl | 2 - compiler/rustc_parse/messages.ftl | 30 ---------- compiler/rustc_query_system/messages.ftl | 2 - compiler/rustc_resolve/messages.ftl | 12 ---- compiler/rustc_session/messages.ftl | 2 - ...luent_alphabetical.rs => fluent_checks.rs} | 57 +++++++++++++++++-- src/tools/tidy/src/lib.rs | 2 +- src/tools/tidy/src/main.rs | 2 +- 10 files changed, 55 insertions(+), 60 deletions(-) rename src/tools/tidy/src/{fluent_alphabetical.rs => fluent_checks.rs} (50%) diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 50da227831200..19526b417499b 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -72,8 +72,6 @@ hir_analysis_enum_discriminant_overflowed = enum discriminant overflowed .label = overflowed on value after {$discr} .note = explicitly set `{$item_name} = {$wrapped_discr}` if that is desired outcome -hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` - hir_analysis_field_already_declared = field `{$field_name}` is already declared .label = field already declared diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl index 4d0e770636721..868c4a8bdb265 100644 --- a/compiler/rustc_infer/messages.ftl +++ b/compiler/rustc_infer/messages.ftl @@ -66,7 +66,6 @@ infer_await_both_futures = consider `await`ing on both `Future`s infer_await_future = consider `await`ing on the `Future` infer_await_note = calling an async function returns a future -infer_borrowed_too_long = a value of type `{$ty}` is borrowed for too long infer_but_calling_introduces = {$has_param_name -> [true] `{$param_name}` *[false] `fn` parameter @@ -181,8 +180,6 @@ infer_more_targeted = {$has_param_name -> } but calling `{$ident}` introduces an implicit `'static` lifetime requirement infer_msl_introduces_static = introduces a `'static` lifetime requirement -infer_msl_trait_note = this has an implicit `'static` lifetime requirement -infer_msl_trait_sugg = consider relaxing the implicit `'static` requirement infer_msl_unmet_req = because this has an unmet lifetime requirement infer_need_type_info_in_generator = type inside {$generator_kind -> @@ -229,7 +226,6 @@ infer_prlf_known_limitation = this is a known limitation that will be removed in infer_prlf_must_outlive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here infer_prlf_must_outlive_without_sup = ...must outlive the lifetime defined here infer_reborrow = ...so that reference does not outlive borrowed content -infer_reborrow_upvar = ...so that closure can access `{$name}` infer_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references infer_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at diff --git a/compiler/rustc_monomorphize/messages.ftl b/compiler/rustc_monomorphize/messages.ftl index 2b7d9bd341393..cf23d79afaf16 100644 --- a/compiler/rustc_monomorphize/messages.ftl +++ b/compiler/rustc_monomorphize/messages.ftl @@ -7,8 +7,6 @@ monomorphize_couldnt_dump_mono_stats = monomorphize_encountered_error_while_instantiating = the above error was encountered while instantiating `{$formatted_item}` -monomorphize_fatal_error = {$error_message} - monomorphize_large_assignments = moving {$size} bytes .label = value moved from here diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 2c4bc7bb5687f..f0124ff1bdf51 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -59,7 +59,6 @@ parse_bare_cr = {$double_quotes -> parse_bare_cr_in_raw_string = bare CR not allowed in raw string -parse_binary_float_literal_not_supported = binary float literal is not supported parse_bounds_not_allowed_on_trait_aliases = bounds are not allowed on trait aliases parse_box_not_pat = expected pattern, found {$descr} @@ -284,7 +283,6 @@ parse_generics_in_path = unexpected generic arguments in path parse_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` parse_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` -parse_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported parse_if_expression_missing_condition = missing condition for `if` expression .condition_label = expected condition here .block_label = if this block is the condition of the `if` expression, then it must be followed by another block @@ -356,8 +354,6 @@ parse_inner_doc_comment_not_permitted = expected outer doc comment .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item} .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style -parse_int_literal_too_large = integer literal is too large - parse_invalid_block_macro_segment = cannot use a `block` macro fragment here .label = the `block` fragment is within this context .suggestion = wrap this in another block @@ -382,18 +378,8 @@ parse_invalid_dyn_keyword = invalid `dyn` keyword .suggestion = remove this keyword parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else` -parse_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal - .label = invalid suffix `{$suffix}` - .help = valid suffixes are `f32` and `f64` - -parse_invalid_float_literal_width = invalid width `{$width}` for float literal - .help = valid widths are 32 and 64 - parse_invalid_identifier_with_leading_number = identifiers cannot start with a number -parse_invalid_int_literal_width = invalid width `{$width}` for integer literal - .help = valid widths are 8, 16, 32, 64 and 128 - parse_invalid_interpolated_expression = invalid interpolated expression parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid @@ -412,14 +398,6 @@ parse_invalid_logical_operator = `{$incorrect}` is not a logical operator parse_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}` -parse_invalid_num_literal_base_prefix = invalid base prefix for number literal - .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase - .suggestion = try making the prefix lowercase - -parse_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal - .label = invalid suffix `{$suffix}` - .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) - parse_invalid_unicode_escape = invalid unicode character escape .label = invalid escape .help = unicode escape must {$surrogate -> @@ -603,13 +581,6 @@ parse_no_brace_unicode_escape = incorrect unicode escape sequence parse_no_digits_literal = no valid digits found for number -parse_non_item_in_item_list = non-item in item list - .suggestion_use_const_not_let = consider using `const` instead of `let` for associated const - .label_list_start = item list starts here - .label_non_item = non-item starts here - .label_list_end = item list ends here - .suggestion_remove_semicolon = consider removing this semicolon - parse_non_string_abi_literal = non-string ABI literal .suggestion = specify the ABI with a string literal @@ -626,7 +597,6 @@ parse_note_mut_pattern_usage = `mut` may be followed by `variable` and `variable parse_note_pattern_alternatives_use_single_vert = alternatives in or-patterns are separated with `|`, not `||` -parse_octal_float_literal_not_supported = octal float literal is not supported parse_or_pattern_not_allowed_in_fn_parameters = top-level or-patterns are not allowed in function parameters parse_or_pattern_not_allowed_in_let_binding = top-level or-patterns are not allowed in `let` bindings parse_out_of_range_hex_escape = out of range hex escape diff --git a/compiler/rustc_query_system/messages.ftl b/compiler/rustc_query_system/messages.ftl index d5fed8fe179fd..d7ab755751118 100644 --- a/compiler/rustc_query_system/messages.ftl +++ b/compiler/rustc_query_system/messages.ftl @@ -15,8 +15,6 @@ query_system_cycle_stack_single = ...which immediately requires {$stack_bottom} query_system_cycle_usage = cycle used when {$usage} -query_system_cycle_which_requires = ...which requires {$desc}... - query_system_increment_compilation = internal compiler error: encountered incremental compilation error with {$dep_node} .help = This is a known issue with the compiler. Run {$run_cmd} to allow your project to compile diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl index 9a970f5db397e..272483d4a9876 100644 --- a/compiler/rustc_resolve/messages.ftl +++ b/compiler/rustc_resolve/messages.ftl @@ -130,9 +130,6 @@ resolve_generic_params_from_outer_item_ty_param = type parameter from outer item resolve_glob_import_doesnt_reexport = glob import doesn't reexport anything because no candidate is public enough -resolve_help_try_using_local_generic_param = - try using a local generic parameter instead - resolve_ident_bound_more_than_once_in_parameter_list = identifier `{$identifier}` is bound more than once in this parameter list .label = used as parameter more than once @@ -249,9 +246,6 @@ resolve_self_in_generic_param_default = generic parameters cannot use `Self` in their defaults .label = `Self` in generic parameter default -resolve_self_type_implicitly_declared_by_impl = - `Self` type implicitly declared here, by this `impl` - resolve_tool_module_imported = cannot use a tool module through an import .note = the tool module imported here @@ -267,12 +261,6 @@ resolve_trait_impl_mismatch = .label = does not match trait .label_trait_item = item in trait -resolve_try_adding_local_generic_param_on_method = - try adding a local generic parameter in this method instead - -resolve_try_using_local_generic_parameter = - try using a local generic parameter instead - resolve_try_using_similarly_named_label = try using similarly named label diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index e06b638094452..b356b503aa541 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -25,8 +25,6 @@ session_feature_diagnostic_for_issue = session_feature_diagnostic_help = add `#![feature({$feature})]` to the crate attributes to enable -session_feature_gate_error = {$explain} - session_file_is_not_writeable = output file {$file} is not writeable -- check its permissions session_file_write_fail = failed to write `{$path}` due to error `{$err}` diff --git a/src/tools/tidy/src/fluent_alphabetical.rs b/src/tools/tidy/src/fluent_checks.rs similarity index 50% rename from src/tools/tidy/src/fluent_alphabetical.rs rename to src/tools/tidy/src/fluent_checks.rs index 67b745373f019..aca4e316bbfea 100644 --- a/src/tools/tidy/src/fluent_alphabetical.rs +++ b/src/tools/tidy/src/fluent_checks.rs @@ -1,4 +1,5 @@ //! Checks that all Flunt files have messages in alphabetical order +//! Checks that all messages are referenced in the code use crate::walk::{filter_dirs, walk}; use std::{fs::OpenOptions, io::Write, path::Path}; @@ -13,6 +14,10 @@ fn filter_fluent(path: &Path) -> bool { if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true } } +fn filter_not_rust(path: &Path) -> bool { + path.extension() != Some(std::ffi::OsStr::new("rs")) && !path.is_dir() +} + fn check_alphabetic(filename: &str, fluent: &str, bad: &mut bool) { let mut matches = MESSAGE.captures_iter(fluent).peekable(); while let Some(m) = matches.next() { @@ -34,16 +39,58 @@ run `./x.py test tidy --bless` to sort the file correctly", } } -fn sort_messages(fluent: &str) -> String { +fn check_unused_messages( + filename: &str, + fluent: &str, + bad: &mut bool, + report: bool, +) -> Vec { + let mut matches = MESSAGE.captures_iter(fluent).peekable(); + let mut sources: Vec = vec![]; + if matches.peek().is_some() { + let src_dir = Path::new(filename).parent().unwrap().join("src"); + walk( + &src_dir, + |path, is_dir| filter_dirs(path) || (!is_dir && filter_not_rust(path)), + &mut |_ent, contents| { + sources.push(contents.to_string()); + }, + ); + } + let mut unused_messages = vec![]; + while let Some(m) = matches.next() { + let name = m.get(1).unwrap(); + // message maybe referenced as {name} in fluent files + let name_var = "{".to_string() + name.as_str() + "}"; + if !sources.iter().any(|file| file.contains(name.as_str())) && !fluent.contains(&name_var) { + unused_messages.push(name.as_str().to_owned()); + if report { + tidy_error!( + bad, + "{filename}: message `{}` is not referenced in the code", + name.as_str() + ); + } + } + } + unused_messages +} + +fn sort_messages(filename: &str, fluent: &str) -> String { let mut chunks = vec![]; let mut cur = String::new(); + let unused_messages = check_unused_messages(filename, fluent, &mut false, false); for line in fluent.lines() { if MESSAGE.is_match(line) { - chunks.push(std::mem::take(&mut cur)); + let chunk = std::mem::take(&mut cur); + if !unused_messages.iter().any(|key| chunk.starts_with(key)) { + chunks.push(chunk); + } } cur += line; cur.push('\n'); } + chunks.push(cur); chunks.sort(); let mut out = chunks.join(""); @@ -57,15 +104,17 @@ pub fn check(path: &Path, bless: bool, bad: &mut bool) { path, |path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)), &mut |ent, contents| { + let filename = ent.path().to_str().unwrap(); if bless { - let sorted = sort_messages(contents); + let sorted = sort_messages(filename, contents); 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(filename, contents, bad); + check_unused_messages(filename, contents, bad, true); } }, ); diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs index 9b19b8eecc7b8..a90c7015f7e5b 100644 --- a/src/tools/tidy/src/lib.rs +++ b/src/tools/tidy/src/lib.rs @@ -60,7 +60,7 @@ pub mod error_codes; pub mod ext_tool_checks; pub mod extdeps; pub mod features; -pub mod fluent_alphabetical; +pub mod fluent_checks; pub mod mir_opt_tests; pub mod pal; pub mod primitive_docs; diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 5fa91715a07a9..31e0d348d2f75 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -107,7 +107,7 @@ fn main() { // Checks that only make sense for the compiler. check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose); - check!(fluent_alphabetical, &compiler_path, bless); + check!(fluent_checks, &compiler_path, bless); // Checks that only make sense for the std libs. check!(pal, &library_path);