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

Add a tidy rule to check that fluent messages and attrs don't end in . #126811

Merged
merged 2 commits into from
Jun 22, 2024
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
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5700,6 +5700,7 @@ name = "tidy"
version = "0.1.0"
dependencies = [
"cargo_metadata 0.15.4",
"fluent-syntax",
"ignore",
"miropt-test-tools",
"regex",
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ ast_lowering_inline_asm_unsupported_target =
ast_lowering_invalid_abi =
invalid ABI: found `{$abi}`
.label = invalid ABI
.note = invoke `{$command}` for a full list of supported calling conventions.
.note = invoke `{$command}` for a full list of supported calling conventions

ast_lowering_invalid_abi_clobber_abi =
invalid ABI for `clobber_abi`
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_const_eval/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,7 @@ const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in
const_eval_unallowed_heap_allocations =
allocations are not allowed in {const_eval_const_context}s
.label = allocation not allowed in {const_eval_const_context}s
.teach_note =
The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.
.teach_note = The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on the heap at runtime, and therefore cannot be done at compile time.

const_eval_unallowed_inline_asm =
inline assembly is not allowed in {const_eval_const_context}s
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ hir_analysis_inherent_ty_outside = cannot define inherent `impl` for a type outs
.span_help = alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items

hir_analysis_inherent_ty_outside_new = cannot define inherent `impl` for a type outside of the crate where the type is defined
.label = impl for type defined outside of crate.
.label = impl for type defined outside of crate
.note = define and implement a trait or new type instead

hir_analysis_inherent_ty_outside_primitive = cannot define inherent `impl` for primitive types outside of `core`
Expand Down Expand Up @@ -544,7 +544,7 @@ hir_analysis_unrecognized_intrinsic_function =

hir_analysis_unused_associated_type_bounds =
unnecessary associated type bound for not object safe associated type
.note = this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
.note = this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
.suggestion = remove this bound

hir_analysis_unused_generic_parameter =
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_lint/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ lint_builtin_deprecated_attr_default_suggestion = remove this attribute
lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
.msg_suggestion = {$msg}
.default_suggestion = remove this attribute
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used
lint_builtin_deref_nullptr = dereferencing a null pointer
.label = this code causes undefined behavior when executed

Expand Down Expand Up @@ -213,7 +213,7 @@ lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better pe
lint_default_source = `forbid` lint level is the default for {$id}

lint_deprecated_lint_name =
lint name `{$name}` is deprecated and may not have an effect in the future.
lint name `{$name}` is deprecated and may not have an effect in the future
.suggestion = change it to
.help = change it to {$replace}

Expand Down Expand Up @@ -244,11 +244,11 @@ lint_duplicate_matcher_binding = duplicate matcher binding

lint_enum_intrinsics_mem_discriminant =
the return value of `mem::discriminant` is unspecified when called with a non-enum type
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum.
.note = the argument to `discriminant` should be a reference to an enum, but it was passed a reference to a `{$ty_param}`, which is not an enum

lint_enum_intrinsics_mem_variant =
the return value of `mem::variant_count` is unspecified when called with a non-enum type
.note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum.
.note = the type parameter of `variant_count` should be an enum, but it was instantiated with the type `{$ty_param}`, which is not an enum

lint_expectation = this lint expectation is unfulfilled
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,13 @@ metadata_rustc_lib_required =
.help = try adding `extern crate rustc_driver;` at the top level of this crate

metadata_stable_crate_id_collision =
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values.
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values

metadata_std_required =
`std` is required by `{$current_crate}` because it does not declare `#![no_std]`

metadata_symbol_conflicts_current =
the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments, so this will result in symbol conflicts between the two

metadata_target_no_std_support =
the `{$locator_triple}` target may not support the standard library
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_build/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
.label = dereference of raw pointer

mir_build_exceeds_mcdc_condition_limit = Number of conditions in decision ({$num_conditions}) exceeds limit ({$max_conditions}). MC/DC analysis will not count this expression.
mir_build_exceeds_mcdc_condition_limit = number of conditions in decision ({$num_conditions}) exceeds limit ({$max_conditions}), so MC/DC analysis will not count this expression

mir_build_extern_static_requires_unsafe =
use of extern static is unsafe and requires unsafe block
Expand Down
18 changes: 9 additions & 9 deletions compiler/rustc_passes/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ passes_abi_of =
fn_abi_of({$fn_name}) = {$fn_abi}

passes_allow_incoherent_impl =
`rustc_allow_incoherent_impl` attribute should be applied to impl items.
`rustc_allow_incoherent_impl` attribute should be applied to impl items
.label = the only currently supported targets are inherent methods

passes_allow_internal_unstable =
Expand Down Expand Up @@ -253,8 +253,8 @@ passes_doc_test_unknown_spotlight =
.no_op_note = `doc(spotlight)` is now a no-op

passes_duplicate_diagnostic_item_in_crate =
duplicate diagnostic item in crate `{$crate_name}`: `{$name}`.
.note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
duplicate diagnostic item in crate `{$crate_name}`: `{$name}`
.note = the diagnostic item is first defined in crate `{$orig_crate_name}`

passes_duplicate_feature_err =
the feature `{$feature}` has already been declared
Expand All @@ -263,27 +263,27 @@ passes_duplicate_lang_item =
found duplicate lang item `{$lang_item_name}`
.first_defined_span = the lang item is first defined here
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
.second_definition_local = second definition in the local crate (`{$crate_name}`)
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
.second_definition_path = second definition in `{$crate_name}` loaded from {$path}

passes_duplicate_lang_item_crate =
duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}`.
duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}`
.first_defined_span = the lang item is first defined here
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
.second_definition_local = second definition in the local crate (`{$crate_name}`)
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
.second_definition_path = second definition in `{$crate_name}` loaded from {$path}

passes_duplicate_lang_item_crate_depends =
duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}`.
duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}`
.first_defined_span = the lang item is first defined here
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
.second_definition_local = second definition in the local crate (`{$crate_name}`)
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
Expand Down Expand Up @@ -315,7 +315,7 @@ passes_ffi_pure_invalid_target =
`#[ffi_pure]` may only be used on foreign functions

passes_has_incoherent_inherent_impl =
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits
.label = only adts, extern types and traits are supported

passes_ignored_attr =
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ resolve_label_with_similar_name_reachable =

resolve_lending_iterator_report_error =
associated type `Iterator::Item` is declared without lifetime parameters, so using a borrowed type for them requires that lifetime to come from the implemented type
.note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type.
.note = you can't create an `Iterator` that borrows each `Item` from itself, but you can instead create a new type that borrows your existing type and implement `Iterator` for that new type

resolve_lifetime_param_in_enum_discriminant =
lifetime parameters may not be used in enum discriminant values
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_session/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ session_octal_float_literal_not_supported = octal float literal is not supported

session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg}

session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist.
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist

session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist.
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist

session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`

Expand Down
1 change: 1 addition & 0 deletions src/tools/tidy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ ignore = "0.4.18"
semver = "1.0"
termcolor = "1.1.3"
rustc-hash = "1.1.0"
fluent-syntax = "0.11.1"

[[bin]]
name = "rust-tidy"
Expand Down
84 changes: 84 additions & 0 deletions src/tools/tidy/src/fluent_period.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! Checks that no Fluent messages or attributes end in periods (except ellipses)

use fluent_syntax::ast::{Entry, PatternElement};

use crate::walk::{filter_dirs, walk};
use std::path::Path;

fn filter_fluent(path: &Path) -> bool {
if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true }
Comment on lines +8 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not this PR's fault, but I find the inverted filter condition odd

}

/// Messages allowed to have `.` at their end.
///
/// These should probably be reworked eventually.
const ALLOWLIST: &[&str] = &[
"const_eval_long_running",
"const_eval_validation_failure_note",
"driver_impl_ice",
"incremental_corrupt_file",
"mir_build_pointer_pattern",
];

fn check_period(filename: &str, contents: &str, bad: &mut bool) {
if filename.contains("codegen") {
// FIXME: Too many codegen messages have periods right now...
return;
}

let (Ok(parse) | Err((parse, _))) = fluent_syntax::parser::parse(contents);
for entry in &parse.body {
if let Entry::Message(m) = entry {
if ALLOWLIST.contains(&m.id.name) {
continue;
}

if let Some(pat) = &m.value {
if let Some(PatternElement::TextElement { value }) = pat.elements.last() {
// We don't care about ellipses.
if value.ends_with(".") && !value.ends_with("...") {
let ll = find_line(contents, *value);
let name = m.id.name;
tidy_error!(bad, "{filename}:{ll}: message `{name}` ends in a period");
}
}
}

for attr in &m.attributes {
// Teach notes usually have long messages.
if attr.id.name == "teach_note" {
continue;
}

if let Some(PatternElement::TextElement { value }) = attr.value.elements.last() {
if value.ends_with(".") && !value.ends_with("...") {
let ll = find_line(contents, *value);
let name = attr.id.name;
tidy_error!(bad, "{filename}:{ll}: attr `{name}` ends in a period");
}
}
}
}
}
}

/// Evil cursed bad hack. Requires that `value` be a substr (in memory) of `contents`.
fn find_line(haystack: &str, needle: &str) -> usize {
for (ll, line) in haystack.lines().enumerate() {
if line.as_ptr() > needle.as_ptr() {
return ll;
}
}

1
}

pub fn check(path: &Path, bad: &mut bool) {
walk(
path,
|path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)),
&mut |ent, contents| {
check_period(ent.path().to_str().unwrap(), contents, bad);
},
);
}
1 change: 1 addition & 0 deletions src/tools/tidy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub mod ext_tool_checks;
pub mod extdeps;
pub mod features;
pub mod fluent_alphabetical;
pub mod fluent_period;
mod fluent_used;
pub(crate) mod iter_header;
pub mod known_bug;
Expand Down
1 change: 1 addition & 0 deletions src/tools/tidy/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,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_period, &compiler_path);
check!(target_policy, &root_path);

// Checks that only make sense for the std libs.
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/abi/abi-typo-unstable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `rust-intrinsec`
LL | extern "rust-intrinsec" fn rust_intrinsic() {}
| ^^^^^^^^^^^^^^^^ invalid ABI
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions

error: aborting due to 1 previous error

Expand Down
4 changes: 2 additions & 2 deletions tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | extern "riscv-interrupt" fn isr() {}
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
= note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively

error[E0703]: invalid ABI: found `riscv-interrupt-u`
Expand All @@ -19,7 +19,7 @@ LL | extern "riscv-interrupt-u" fn isr_U() {}
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
= note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314

error: aborting due to 2 previous errors
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LL | extern "riscv-interrupt" fn isr() {}
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
= note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively

error[E0703]: invalid ABI: found `riscv-interrupt-u`
Expand All @@ -19,7 +19,7 @@ LL | extern "riscv-interrupt-u" fn isr_U() {}
| invalid ABI
| help: did you mean: `"riscv-interrupt-m"`
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
= note: user-mode interrupt handlers have been removed from LLVM pending standardization, see: https://reviews.llvm.org/D149314

error: aborting due to 2 previous errors
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/codemap_tests/unicode.normal.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
LL | extern "路濫狼á́́" fn foo() {}
| ^^^^^^^^^ invalid ABI
|
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions

error: aborting due to 1 previous error

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0116.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0116]: cannot define inherent `impl` for a type outside of the crate wher
--> $DIR/E0116.rs:1:1
|
LL | impl Vec<u8> {}
| ^^^^^^^^^^^^ impl for type defined outside of crate.
| ^^^^^^^^^^^^ impl for type defined outside of crate
|
= note: define and implement a trait or new type instead

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0519.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0519]: the current crate is indistinguishable from one of its dependencies: it has the same crate-name `crateresolve1` and was compiled with the same `-C metadata` arguments. This will result in symbol conflicts between the two.
error[E0519]: the current crate is indistinguishable from one of its dependencies: it has the same crate-name `crateresolve1` and was compiled with the same `-C metadata` arguments, so this will result in symbol conflicts between the two
--> $DIR/E0519.rs:8:1
|
LL | extern crate crateresolve1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,15 @@ warning: unknown lint: `x5100`
LL | #[deny(x5100)] impl S { }
| ^^^^^

warning: use of deprecated attribute `crate_id`: no longer used.
warning: use of deprecated attribute `crate_id`: no longer used
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:84:1
|
LL | #![crate_id = "10"]
| ^^^^^^^^^^^^^^^^^^^ help: remove this attribute
|
= note: `#[warn(deprecated)]` on by default

warning: use of deprecated attribute `no_start`: no longer used.
warning: use of deprecated attribute `no_start`: no longer used
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:94:1
|
LL | #![no_start]
Expand Down
Loading
Loading