Skip to content

Commit 1916b3d

Browse files
Rollup merge of #126811 - compiler-errors:tidy-ftl, r=estebank
Add a tidy rule to check that fluent messages and attrs don't end in `.` This adds a new dependency on `fluent-parse` to `tidy` -- we already rely on it in rustc so I feel like it's not that big of a deal. This PR also adjusts many error messages that currently end in `.`; not all of them since I added an `ALLOWLIST`, excluded `rustc_codegen_*` ftl files, and `.teach_note` attributes. r? ``@estebank`` ``@oli-obk``
2 parents 539090e + ffd72b1 commit 1916b3d

29 files changed

+149
-62
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -5700,6 +5700,7 @@ name = "tidy"
57005700
version = "0.1.0"
57015701
dependencies = [
57025702
"cargo_metadata 0.15.4",
5703+
"fluent-syntax",
57035704
"ignore",
57045705
"miropt-test-tools",
57055706
"regex",

compiler/rustc_ast_lowering/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ ast_lowering_inline_asm_unsupported_target =
7878
ast_lowering_invalid_abi =
7979
invalid ABI: found `{$abi}`
8080
.label = invalid ABI
81-
.note = invoke `{$command}` for a full list of supported calling conventions.
81+
.note = invoke `{$command}` for a full list of supported calling conventions
8282
8383
ast_lowering_invalid_abi_clobber_abi =
8484
invalid ABI for `clobber_abi`

compiler/rustc_const_eval/messages.ftl

+1-2
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,7 @@ const_eval_unallowed_fn_pointer_call = function pointer calls are not allowed in
341341
const_eval_unallowed_heap_allocations =
342342
allocations are not allowed in {const_eval_const_context}s
343343
.label = allocation not allowed in {const_eval_const_context}s
344-
.teach_note =
345-
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.
344+
.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.
346345
347346
const_eval_unallowed_inline_asm =
348347
inline assembly is not allowed in {const_eval_const_context}s

compiler/rustc_hir_analysis/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ hir_analysis_unrecognized_intrinsic_function =
544544
545545
hir_analysis_unused_associated_type_bounds =
546546
unnecessary associated type bound for not object safe associated type
547-
.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`.
547+
.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`
548548
.suggestion = remove this bound
549549
550550
hir_analysis_unused_generic_parameter =

compiler/rustc_lint/messages.ftl

+4-4
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ lint_builtin_deprecated_attr_default_suggestion = remove this attribute
7575
lint_builtin_deprecated_attr_link = use of deprecated attribute `{$name}`: {$reason}. See {$link}
7676
.msg_suggestion = {$msg}
7777
.default_suggestion = remove this attribute
78-
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used.
78+
lint_builtin_deprecated_attr_used = use of deprecated attribute `{$name}`: no longer used
7979
lint_builtin_deref_nullptr = dereferencing a null pointer
8080
.label = this code causes undefined behavior when executed
8181
@@ -213,7 +213,7 @@ lint_default_hash_types = prefer `{$preferred}` over `{$used}`, it has better pe
213213
lint_default_source = `forbid` lint level is the default for {$id}
214214
215215
lint_deprecated_lint_name =
216-
lint name `{$name}` is deprecated and may not have an effect in the future.
216+
lint name `{$name}` is deprecated and may not have an effect in the future
217217
.suggestion = change it to
218218
.help = change it to {$replace}
219219
@@ -244,11 +244,11 @@ lint_duplicate_matcher_binding = duplicate matcher binding
244244
245245
lint_enum_intrinsics_mem_discriminant =
246246
the return value of `mem::discriminant` is unspecified when called with a non-enum type
247-
.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.
247+
.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
248248
249249
lint_enum_intrinsics_mem_variant =
250250
the return value of `mem::variant_count` is unspecified when called with a non-enum type
251-
.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.
251+
.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
252252
253253
lint_expectation = this lint expectation is unfulfilled
254254
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message

compiler/rustc_metadata/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,13 @@ metadata_rustc_lib_required =
248248
.help = try adding `extern crate rustc_driver;` at the top level of this crate
249249
250250
metadata_stable_crate_id_collision =
251-
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values.
251+
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values
252252
253253
metadata_std_required =
254254
`std` is required by `{$current_crate}` because it does not declare `#![no_std]`
255255
256256
metadata_symbol_conflicts_current =
257-
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.
257+
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
258258
259259
metadata_target_no_std_support =
260260
the `{$locator_triple}` target may not support the standard library

compiler/rustc_mir_build/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed =
103103
.note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
104104
.label = dereference of raw pointer
105105
106-
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.
106+
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
107107
108108
mir_build_extern_static_requires_unsafe =
109109
use of extern static is unsafe and requires unsafe block

compiler/rustc_passes/messages.ftl

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ passes_abi_of =
1414
fn_abi_of({$fn_name}) = {$fn_abi}
1515
1616
passes_allow_incoherent_impl =
17-
`rustc_allow_incoherent_impl` attribute should be applied to impl items.
17+
`rustc_allow_incoherent_impl` attribute should be applied to impl items
1818
.label = the only currently supported targets are inherent methods
1919
2020
passes_allow_internal_unstable =
@@ -253,8 +253,8 @@ passes_doc_test_unknown_spotlight =
253253
.no_op_note = `doc(spotlight)` is now a no-op
254254
255255
passes_duplicate_diagnostic_item_in_crate =
256-
duplicate diagnostic item in crate `{$crate_name}`: `{$name}`.
257-
.note = the diagnostic item is first defined in crate `{$orig_crate_name}`.
256+
duplicate diagnostic item in crate `{$crate_name}`: `{$name}`
257+
.note = the diagnostic item is first defined in crate `{$orig_crate_name}`
258258
259259
passes_duplicate_feature_err =
260260
the feature `{$feature}` has already been declared
@@ -263,27 +263,27 @@ passes_duplicate_lang_item =
263263
found duplicate lang item `{$lang_item_name}`
264264
.first_defined_span = the lang item is first defined here
265265
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
266-
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
266+
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
267267
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
268268
.second_definition_local = second definition in the local crate (`{$crate_name}`)
269269
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
270270
.second_definition_path = second definition in `{$crate_name}` loaded from {$path}
271271
272272
passes_duplicate_lang_item_crate =
273-
duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}`.
273+
duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}`
274274
.first_defined_span = the lang item is first defined here
275275
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
276-
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
276+
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
277277
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
278278
.second_definition_local = second definition in the local crate (`{$crate_name}`)
279279
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
280280
.second_definition_path = second definition in `{$crate_name}` loaded from {$path}
281281
282282
passes_duplicate_lang_item_crate_depends =
283-
duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}`.
283+
duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}`
284284
.first_defined_span = the lang item is first defined here
285285
.first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)
286-
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`.
286+
.first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}`
287287
.first_definition_local = first definition in the local crate (`{$orig_crate_name}`)
288288
.second_definition_local = second definition in the local crate (`{$crate_name}`)
289289
.first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path}
@@ -315,7 +315,7 @@ passes_ffi_pure_invalid_target =
315315
`#[ffi_pure]` may only be used on foreign functions
316316
317317
passes_has_incoherent_inherent_impl =
318-
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
318+
`rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits
319319
.label = only adts, extern types and traits are supported
320320
321321
passes_ignored_attr =

compiler/rustc_resolve/messages.ftl

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ resolve_label_with_similar_name_reachable =
240240
241241
resolve_lending_iterator_report_error =
242242
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
243-
.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.
243+
.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
244244
245245
resolve_lifetime_param_in_enum_discriminant =
246246
lifetime parameters may not be used in enum discriminant values

compiler/rustc_session/messages.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ session_octal_float_literal_not_supported = octal float literal is not supported
8282
8383
session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg}
8484
85-
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist.
85+
session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C profile-sample-use` does not exist
8686
87-
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist.
87+
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist
8888
8989
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`
9090

src/tools/tidy/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ignore = "0.4.18"
1313
semver = "1.0"
1414
termcolor = "1.1.3"
1515
rustc-hash = "1.1.0"
16+
fluent-syntax = "0.11.1"
1617

1718
[[bin]]
1819
name = "rust-tidy"

src/tools/tidy/src/fluent_period.rs

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//! Checks that no Fluent messages or attributes end in periods (except ellipses)
2+
3+
use fluent_syntax::ast::{Entry, PatternElement};
4+
5+
use crate::walk::{filter_dirs, walk};
6+
use std::path::Path;
7+
8+
fn filter_fluent(path: &Path) -> bool {
9+
if let Some(ext) = path.extension() { ext.to_str() != Some("ftl") } else { true }
10+
}
11+
12+
/// Messages allowed to have `.` at their end.
13+
///
14+
/// These should probably be reworked eventually.
15+
const ALLOWLIST: &[&str] = &[
16+
"const_eval_long_running",
17+
"const_eval_validation_failure_note",
18+
"driver_impl_ice",
19+
"incremental_corrupt_file",
20+
"mir_build_pointer_pattern",
21+
];
22+
23+
fn check_period(filename: &str, contents: &str, bad: &mut bool) {
24+
if filename.contains("codegen") {
25+
// FIXME: Too many codegen messages have periods right now...
26+
return;
27+
}
28+
29+
let (Ok(parse) | Err((parse, _))) = fluent_syntax::parser::parse(contents);
30+
for entry in &parse.body {
31+
if let Entry::Message(m) = entry {
32+
if ALLOWLIST.contains(&m.id.name) {
33+
continue;
34+
}
35+
36+
if let Some(pat) = &m.value {
37+
if let Some(PatternElement::TextElement { value }) = pat.elements.last() {
38+
// We don't care about ellipses.
39+
if value.ends_with(".") && !value.ends_with("...") {
40+
let ll = find_line(contents, *value);
41+
let name = m.id.name;
42+
tidy_error!(bad, "{filename}:{ll}: message `{name}` ends in a period");
43+
}
44+
}
45+
}
46+
47+
for attr in &m.attributes {
48+
// Teach notes usually have long messages.
49+
if attr.id.name == "teach_note" {
50+
continue;
51+
}
52+
53+
if let Some(PatternElement::TextElement { value }) = attr.value.elements.last() {
54+
if value.ends_with(".") && !value.ends_with("...") {
55+
let ll = find_line(contents, *value);
56+
let name = attr.id.name;
57+
tidy_error!(bad, "{filename}:{ll}: attr `{name}` ends in a period");
58+
}
59+
}
60+
}
61+
}
62+
}
63+
}
64+
65+
/// Evil cursed bad hack. Requires that `value` be a substr (in memory) of `contents`.
66+
fn find_line(haystack: &str, needle: &str) -> usize {
67+
for (ll, line) in haystack.lines().enumerate() {
68+
if line.as_ptr() > needle.as_ptr() {
69+
return ll;
70+
}
71+
}
72+
73+
1
74+
}
75+
76+
pub fn check(path: &Path, bad: &mut bool) {
77+
walk(
78+
path,
79+
|path, is_dir| filter_dirs(path) || (!is_dir && filter_fluent(path)),
80+
&mut |ent, contents| {
81+
check_period(ent.path().to_str().unwrap(), contents, bad);
82+
},
83+
);
84+
}

src/tools/tidy/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub mod ext_tool_checks;
7272
pub mod extdeps;
7373
pub mod features;
7474
pub mod fluent_alphabetical;
75+
pub mod fluent_period;
7576
mod fluent_used;
7677
pub(crate) mod iter_header;
7778
pub mod known_bug;

src/tools/tidy/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ fn main() {
115115
// Checks that only make sense for the compiler.
116116
check!(error_codes, &root_path, &[&compiler_path, &librustdoc_path], verbose);
117117
check!(fluent_alphabetical, &compiler_path, bless);
118+
check!(fluent_period, &compiler_path);
118119
check!(target_policy, &root_path);
119120

120121
// Checks that only make sense for the std libs.

tests/ui/abi/abi-typo-unstable.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `rust-intrinsec`
44
LL | extern "rust-intrinsec" fn rust_intrinsic() {}
55
| ^^^^^^^^^^^^^^^^ invalid ABI
66
|
7-
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
7+
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
88

99
error: aborting due to 1 previous error
1010

tests/ui/abi/riscv-discoverability-guidance.riscv32.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | extern "riscv-interrupt" fn isr() {}
77
| invalid ABI
88
| help: did you mean: `"riscv-interrupt-m"`
99
|
10-
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
10+
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
1111
= note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively
1212

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

2525
error: aborting due to 2 previous errors

tests/ui/abi/riscv-discoverability-guidance.riscv64.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | extern "riscv-interrupt" fn isr() {}
77
| invalid ABI
88
| help: did you mean: `"riscv-interrupt-m"`
99
|
10-
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
10+
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
1111
= note: please use one of riscv-interrupt-m or riscv-interrupt-s for machine- or supervisor-level interrupts, respectively
1212

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

2525
error: aborting due to 2 previous errors

tests/ui/codemap_tests/unicode.normal.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0703]: invalid ABI: found `路濫狼á́́`
44
LL | extern "路濫狼á́́" fn foo() {}
55
| ^^^^^^^^^ invalid ABI
66
|
7-
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions.
7+
= note: invoke `rustc --print=calling-conventions` for a full list of supported calling conventions
88

99
error: aborting due to 1 previous error
1010

tests/ui/error-codes/E0519.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
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.
1+
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
22
--> $DIR/E0519.rs:8:1
33
|
44
LL | extern crate crateresolve1;

tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,15 @@ warning: unknown lint: `x5100`
186186
LL | #[deny(x5100)] impl S { }
187187
| ^^^^^
188188

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

197-
warning: use of deprecated attribute `no_start`: no longer used.
197+
warning: use of deprecated attribute `no_start`: no longer used
198198
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:94:1
199199
|
200200
LL | #![no_start]

tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
warning: Number of conditions in decision (7) exceeds limit (6). MC/DC analysis will not count this expression.
1+
warning: number of conditions in decision (7) exceeds limit (6), so MC/DC analysis will not count this expression
22
--> $DIR/mcdc-condition-limit.rs:29:8
33
|
44
LL | if a && b && c && d && e && f && g {

tests/ui/instrument-coverage/mcdc-condition-limit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fn main() {
2626
fn main() {
2727
// 7 conditions is too many, so issue a diagnostic.
2828
let [a, b, c, d, e, f, g] = <[bool; 7]>::default();
29-
if a && b && c && d && e && f && g { //[bad]~ WARNING Number of conditions in decision
29+
if a && b && c && d && e && f && g { //[bad]~ WARNING number of conditions in decision
3030
core::hint::black_box("hello");
3131
}
3232
}

0 commit comments

Comments
 (0)