Skip to content

Replace - with _ in fluent slugs to improve developer workflows #100377

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

Merged
merged 4 commits into from
Aug 15, 2022
Merged
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
12 changes: 6 additions & 6 deletions compiler/rustc_error_messages/locales/en-US/borrowck.ftl
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
borrowck-move-unsized =
borrowck_move_unsized =
cannot move a value of type `{$ty}`
.label = the size of `{$ty}` cannot be statically determined
borrowck-higher-ranked-lifetime-error =
borrowck_higher_ranked_lifetime_error =
higher-ranked lifetime error
borrowck-could-not-prove =
borrowck_could_not_prove =
could not prove `{$predicate}`
borrowck-could-not-normalize =
borrowck_could_not_normalize =
could not normalize `{$value}`
borrowck-higher-ranked-subtype-error =
borrowck_higher_ranked_subtype_error =
higher-ranked subtype error
generic-does-not-live-long-enough =
generic_does_not_live_long_enough =
`{$kind}` does not live long enough
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
builtin-macros-requires-cfg-pattern =
builtin_macros_requires_cfg_pattern =
macro requires a cfg-pattern as an argument
.label = cfg-pattern required
builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern
builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
26 changes: 13 additions & 13 deletions compiler/rustc_error_messages/locales/en-US/const_eval.ftl
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
const-eval-unstable-in-stable =
const_eval_unstable_in_stable =
const-stable function cannot use `#[feature({$gate})]`
.unstable-sugg = if it is not part of the public API, make this function unstably const
.bypass-sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
.unstable_sugg = if it is not part of the public API, make this function unstably const
.bypass_sugg = otherwise `#[rustc_allow_const_fn_unstable]` can be used to bypass stability checks
const-eval-thread-local-access =
const_eval_thread_local_access =
thread-local statics cannot be accessed at compile-time
const-eval-static-access =
const_eval_static_access =
{$kind}s cannot refer to statics
.help = consider extracting the value of the `static` to a `const`, and referring to that
.teach-note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
.teach-help = To fix this, the value can be extracted to a `const` and then used.
.teach_note = `static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.
.teach_help = To fix this, the value can be extracted to a `const` and then used.
const-eval-raw-ptr-to-int =
const_eval_raw_ptr_to_int =
pointers cannot be cast to integers during const eval
.note = at compile-time, pointers do not have an integer value
.note2 = avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
const-eval-raw-ptr-comparison =
const_eval_raw_ptr_comparison =
pointers cannot be reliably compared during const eval
.note = see issue #53020 <https://github.com/rust-lang/rust/issues/53020> for more information
const-eval-panic-non-str = argument to `panic!()` in a const context must have type `&str`
const_eval_panic_non_str = argument to `panic!()` in a const context must have type `&str`
const-eval-mut-deref =
const_eval_mut_deref =
mutation through a reference is not allowed in {$kind}s
const-eval-transient-mut-borrow = mutable references are not allowed in {$kind}s
const_eval_transient_mut_borrow = mutable references are not allowed in {$kind}s
const-eval-transient-mut-borrow-raw = raw mutable references are not allowed in {$kind}s
const_eval_transient_mut_borrow_raw = raw mutable references are not allowed in {$kind}s
4 changes: 2 additions & 2 deletions compiler/rustc_error_messages/locales/en-US/expand.ftl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
expand-explain-doc-comment-outer =
expand_explain_doc_comment_outer =
outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
expand-explain-doc-comment-inner =
expand_explain_doc_comment_inner =
inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
326 changes: 163 additions & 163 deletions compiler/rustc_error_messages/locales/en-US/lint.ftl

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions compiler/rustc_error_messages/locales/en-US/parser.ftl
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
parser-struct-literal-body-without-path =
parser_struct_literal_body_without_path =
struct literal body without path
.suggestion = you might have forgotten to add the struct literal inside the block
parser-maybe-report-ambiguous-plus =
parser_maybe_report_ambiguous_plus =
ambiguous `+` in a type
.suggestion = use parentheses to disambiguate
parser-maybe-recover-from-bad-type-plus =
parser_maybe_recover_from_bad_type_plus =
expected a path on the left-hand side of `+`, not `{$ty}`
parser-add-paren = try adding parentheses
parser_add_paren = try adding parentheses
parser-forgot-paren = perhaps you forgot parentheses?
parser_forgot_paren = perhaps you forgot parentheses?
parser-expect-path = expected a path
parser_expect_path = expected a path
parser-maybe-recover-from-bad-qpath-stage-2 =
parser_maybe_recover_from_bad_qpath_stage_2 =
missing angle brackets in associated item path
.suggestion = try: `{$ty}`
parser-incorrect-semicolon =
parser_incorrect_semicolon =
expected item, found `;`
.suggestion = remove this semicolon
.help = {$name} declarations are not followed by a semicolon
parser-incorrect-use-of-await =
parser_incorrect_use_of_await =
incorrect use of `await`
.parentheses-suggestion = `await` is not a method call, remove the parentheses
.postfix-suggestion = `await` is a postfix operation
.parentheses_suggestion = `await` is not a method call, remove the parentheses
.postfix_suggestion = `await` is a postfix operation
parser-in-in-typo =
parser_in_in_typo =
expected iterable, found keyword `in`
.suggestion = remove the duplicated `in`
228 changes: 114 additions & 114 deletions compiler/rustc_error_messages/locales/en-US/passes.ftl

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions compiler/rustc_error_messages/locales/en-US/privacy.ftl
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
privacy-field-is-private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
privacy-field-is-private-is-update-syntax-label = field `{$field_name}` is private
privacy-field-is-private-label = private field
privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
privacy_field_is_private_label = private field
privacy-item-is-private = {$kind} `{$descr}` is private
privacy_item_is_private = {$kind} `{$descr}` is private
.label = private {$kind}
privacy-unnamed-item-is-private = {$kind} is private
privacy_unnamed_item_is_private = {$kind} is private
.label = private {$kind}
privacy-in-public-interface = {$vis_descr} {$kind} `{$descr}` in public interface
privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interface
.label = can't leak {$vis_descr} {$kind}
.visibility-label = `{$descr}` declared as {$vis_descr}
.visibility_label = `{$descr}` declared as {$vis_descr}
privacy-from-private-dep-in-public-interface =
privacy_from_private_dep_in_public_interface =
{$kind} `{$descr}` from private dependency '{$krate}' in public interface
private-in-public-lint =
private_in_public_lint =
{$vis_descr} {$kind} `{$descr}` in public interface (error {$kind ->
[trait] E0445
*[other] E0446
74 changes: 37 additions & 37 deletions compiler/rustc_error_messages/locales/en-US/typeck.ftl
Original file line number Diff line number Diff line change
@@ -1,101 +1,101 @@
typeck-field-multiply-specified-in-initializer =
typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
.previous-use-label = first use of `{$ident}`
.previous_use_label = first use of `{$ident}`
typeck-unrecognized-atomic-operation =
typeck_unrecognized_atomic_operation =
unrecognized atomic operation function: `{$op}`
.label = unrecognized atomic operation
typeck-wrong-number-of-generic-arguments-to-intrinsic =
typeck_wrong_number_of_generic_arguments_to_intrinsic =
intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
.label = expected {$expected} {$descr} {$expected ->
[one] parameter
*[other] parameters
}
typeck-unrecognized-intrinsic-function =
typeck_unrecognized_intrinsic_function =
unrecognized intrinsic function: `{$name}`
.label = unrecognized intrinsic
typeck-lifetimes-or-bounds-mismatch-on-trait =
typeck_lifetimes_or_bounds_mismatch_on_trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
.generics-label = lifetimes in impl do not match this {$item_kind} in trait
.generics_label = lifetimes in impl do not match this {$item_kind} in trait
typeck-drop-impl-on-wrong-item =
typeck_drop_impl_on_wrong_item =
the `Drop` trait may only be implemented for structs, enums, and unions
.label = must be a struct, enum, or union
typeck-field-already-declared =
typeck_field_already_declared =
field `{$field_name}` is already declared
.label = field already declared
.previous-decl-label = `{$field_name}` first declared here
.previous_decl_label = `{$field_name}` first declared here
typeck-copy-impl-on-type-with-dtor =
typeck_copy_impl_on_type_with_dtor =
the trait `Copy` may not be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
typeck-multiple-relaxed-default-bounds =
typeck_multiple_relaxed_default_bounds =
type parameter has more than one relaxed default bound, only one is supported
typeck-copy-impl-on-non-adt =
typeck_copy_impl_on_non_adt =
the trait `Copy` may not be implemented for this type
.label = type is not a structure or enumeration
typeck-trait-object-declared-with-no-traits =
typeck_trait_object_declared_with_no_traits =
at least one trait is required for an object type
.alias-span = this alias does not contain a trait
.alias_span = this alias does not contain a trait
typeck-ambiguous-lifetime-bound =
typeck_ambiguous_lifetime_bound =
ambiguous lifetime bound, explicit lifetime bound required
typeck-assoc-type-binding-not-allowed =
typeck_assoc_type_binding_not_allowed =
associated type bindings are not allowed here
.label = associated type not allowed here
typeck-functional-record-update-on-non-struct =
typeck_functional_record_update_on_non_struct =
functional record update syntax requires a struct
typeck-typeof-reserved-keyword-used =
typeck_typeof_reserved_keyword_used =
`typeof` is a reserved keyword but unimplemented
.suggestion = consider replacing `typeof(...)` with an actual type
.label = reserved keyword
typeck-return-stmt-outside-of-fn-body =
typeck_return_stmt_outside_of_fn_body =
return statement outside of function body
.encl-body-label = the return is part of this body...
.encl-fn-label = ...not the enclosing function body
.encl_body_label = the return is part of this body...
.encl_fn_label = ...not the enclosing function body
typeck-yield-expr-outside-of-generator =
typeck_yield_expr_outside_of_generator =
yield expression outside of generator literal
typeck-struct-expr-non-exhaustive =
typeck_struct_expr_non_exhaustive =
cannot create non-exhaustive {$what} using struct expression
typeck-method-call-on-unknown-type =
typeck_method_call_on_unknown_type =
the type of this value must be known to call a method on a raw pointer on it
typeck-value-of-associated-struct-already-specified =
typeck_value_of_associated_struct_already_specified =
the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified
.label = re-bound here
.previous-bound-label = `{$item_name}` bound here first
.previous_bound_label = `{$item_name}` bound here first
typeck-address-of-temporary-taken = cannot take address of a temporary
typeck_address_of_temporary_taken = cannot take address of a temporary
.label = temporary value
typeck-add-return-type-add = try adding a return type
typeck_add_return_type_add = try adding a return type
typeck-add-return-type-missing-here = a return type might be missing here
typeck_add_return_type_missing_here = a return type might be missing here
typeck-expected-default-return-type = expected `()` because of default return type
typeck_expected_default_return_type = expected `()` because of default return type
typeck-expected-return-type = expected `{$expected}` because of return type
typeck_expected_return_type = expected `{$expected}` because of return type
typeck-unconstrained-opaque-type = unconstrained opaque type
typeck_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same module
typeck-missing-type-params =
typeck_missing_type_params =
the type {$parameterCount ->
[one] parameter
*[other] parameters
@@ -111,15 +111,15 @@ typeck-missing-type-params =
[one] type
*[other] types
}
.no-suggestion-label = missing {$parameterCount ->
.no_suggestion_label = missing {$parameterCount ->
[one] reference
*[other] references
} to {$parameters}
.note = because of the default `Self` reference, type parameters must be specified on object types
typeck-manual-implementation =
typeck_manual_implementation =
manual implementations of `{$trait_name}` are experimental
.label = manual implementations of `{$trait_name}` are experimental
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
typeck-substs-on-overridden-impl = could not resolve substs on overridden impl
typeck_substs_on_overridden_impl = could not resolve substs on overridden impl
32 changes: 27 additions & 5 deletions compiler/rustc_macros/src/diagnostics/fluent.rs
Original file line number Diff line number Diff line change
@@ -189,13 +189,25 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
if let Entry::Message(Message { id: Identifier { name }, attributes, .. }) = entry {
let _ = previous_defns.entry(name.to_string()).or_insert(ident_span);

// `typeck-foo-bar` => `foo_bar` (in `typeck.ftl`)
// `const-eval-baz` => `baz` (in `const_eval.ftl`)
if name.contains('-') {
Copy link
Member

Choose a reason for hiding this comment

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

Could you submit a PR to the dev guide documenting this and updating the examples there too? Please ping me on it :)

(this can be after this lands, just so that it happens)

Diagnostic::spanned(
ident_span,
Level::Error,
format!("name `{name}` contains a '-' character"),
)
.help("replace any '-'s with '_'s")
.emit();
}

// `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`)
// `const_eval_baz` => `baz` (in `const_eval.ftl`)
// `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`)
// The last case we error about above, but we want to fall back gracefully
// so that only the error is being emitted and not also one about the macro
// failing.
let snake_name = Ident::new(
// FIXME: should probably trim prefix, not replace all occurrences
&name
.replace(&format!("{}-", res.ident).replace('_', "-"), "")
.replace('-', "_"),
&name.replace('-', "_").replace(&format!("{}_", res.ident), ""),
span,
);
constants.extend(quote! {
@@ -212,6 +224,16 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
continue;
}

if attr_name.contains('-') {
Diagnostic::spanned(
ident_span,
Level::Error,
format!("attribute `{attr_name}` contains a '-' character"),
)
.help("replace any '-'s with '_'s")
.emit();
}

constants.extend(quote! {
pub const #snake_name: crate::SubdiagnosticMessage =
crate::SubdiagnosticMessage::FluentAttr(
16 changes: 8 additions & 8 deletions compiler/rustc_macros/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
@@ -38,9 +38,9 @@ use synstructure::Structure;
/// ```
///
/// ```fluent
/// move-out-of-borrow = cannot move out of {$name} because it is borrowed
/// move_out_of_borrow = cannot move out of {$name} because it is borrowed
/// .label = cannot move out of borrow
/// .first-borrow-label = `{$ty}` first borrowed here
/// .first_borrow_label = `{$ty}` first borrowed here
/// .suggestion = consider cloning here
/// ```
///
@@ -84,9 +84,9 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// ```
///
/// ```fluent
/// lint-atomic-ordering-invalid-fail-success = `{$method}`'s success ordering must be at least as strong as its failure ordering
/// .fail-label = `{$fail_ordering}` failure ordering
/// .success-label = `{$success_ordering}` success ordering
/// lint_atomic_ordering_invalid_fail_success = `{$method}`'s success ordering must be at least as strong as its failure ordering
/// .fail_label = `{$fail_ordering}` failure ordering
/// .success_label = `{$success_ordering}` success ordering
/// .suggestion = consider using `{$success_suggestion}` success ordering instead
/// ```
///
@@ -140,11 +140,11 @@ pub fn lint_diagnostic_derive(s: Structure<'_>) -> TokenStream {
/// ```
///
/// ```fluent
/// parser-expected-identifier = expected identifier
/// parser_expected_identifier = expected identifier
///
/// parser-expected-identifier-found = expected identifier, found {$found}
/// parser_expected_identifier-found = expected identifier, found {$found}
///
/// parser-raw-identifier = escape `{$ident}` to use it as an identifier
/// parser_raw_identifier = escape `{$ident}` to use it as an identifier
/// ```
///
/// Then, later, to add the subdiagnostic:
10 changes: 5 additions & 5 deletions compiler/rustc_macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -65,10 +65,10 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
/// ..where `typeck.ftl` has the following contents..
///
/// ```fluent
/// typeck-field-multiply-specified-in-initializer =
/// typeck_field_multiply_specified_in_initializer =
/// field `{$ident}` specified more than once
/// .label = used more than once
/// .label-previous-use = first use of `{$ident}`
/// .label_previous_use = first use of `{$ident}`
/// ```
/// ...then the macro parse the Fluent resource, emitting a diagnostic if it fails to do so, and
/// will generate the following code:
@@ -81,11 +81,11 @@ pub fn newtype_index(input: TokenStream) -> TokenStream {
/// mod fluent_generated {
/// mod typeck {
/// pub const field_multiply_specified_in_initializer: DiagnosticMessage =
/// DiagnosticMessage::fluent("typeck-field-multiply-specified-in-initializer");
/// DiagnosticMessage::fluent("typeck_field_multiply_specified_in_initializer");
/// pub const field_multiply_specified_in_initializer_label_previous_use: DiagnosticMessage =
/// DiagnosticMessage::fluent_attr(
/// "typeck-field-multiply-specified-in-initializer",
/// "previous-use-label"
/// "typeck_field_multiply_specified_in_initializer",
/// "previous_use_label"
/// );
/// }
/// }
2 changes: 1 addition & 1 deletion src/test/run-make/translation/broken.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# `foo` isn't provided by this diagnostic so it is expected that the fallback message is used.
parser-struct-literal-body-without-path = this is a {$foo} message
parser_struct_literal_body_without_path = this is a {$foo} message
.suggestion = this is a test suggestion
2 changes: 1 addition & 1 deletion src/test/run-make/translation/missing.ftl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# `parser-struct-literal-body-without-path` isn't provided by this resource at all, so the
# `parser_struct_literal_body_without_path` isn't provided by this resource at all, so the
# fallback should be used.
foo = bar
2 changes: 1 addition & 1 deletion src/test/run-make/translation/working.ftl
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
parser-struct-literal-body-without-path = this is a test message
parser_struct_literal_body_without_path = this is a test message
.suggestion = this is a test suggestion
2 changes: 2 additions & 0 deletions src/test/ui-fulldeps/fluent-messages/label-with-hyphens.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
some_slug = hi
.label-has-hyphens = test
2 changes: 1 addition & 1 deletion src/test/ui-fulldeps/fluent-messages/missing-message.ftl
Original file line number Diff line number Diff line change
@@ -1 +1 @@
missing-message =
missing_message =
1 change: 1 addition & 0 deletions src/test/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this-slug-has-hyphens = hi
18 changes: 18 additions & 0 deletions src/test/ui-fulldeps/fluent-messages/test.rs
Original file line number Diff line number Diff line change
@@ -55,6 +55,24 @@ mod duplicate {
}
}

mod slug_with_hyphens {
use super::fluent_messages;

fluent_messages! {
slug_with_hyphens => "./slug-with-hyphens.ftl",
//~^ ERROR name `this-slug-has-hyphens` contains a '-' character
}
}

mod label_with_hyphens {
use super::fluent_messages;

fluent_messages! {
label_with_hyphens => "./label-with-hyphens.ftl",
//~^ ERROR attribute `label-has-hyphens` contains a '-' character
}
}

mod valid {
use super::fluent_messages;

24 changes: 20 additions & 4 deletions src/test/ui-fulldeps/fluent-messages/test.stderr
Original file line number Diff line number Diff line change
@@ -22,11 +22,11 @@ LL | missing_message => "./missing-message.ftl",
|
= help: see additional errors emitted

error: expected a message field for "missing-message"
error: expected a message field for "missing_message"
--> ./missing-message.ftl:1:1
|
1 | missing-message =
| ^^^^^^^^^^^^^^^^^^
1 | missing_message =
| ^^^^^^^^^^^^^^^^^
|

error: overrides existing message: `key`
@@ -41,5 +41,21 @@ help: previously defined in this resource
LL | a => "./duplicate-a.ftl",
| ^

error: aborting due to 4 previous errors
error: name `this-slug-has-hyphens` contains a '-' character
--> $DIR/test.rs:62:9
|
LL | slug_with_hyphens => "./slug-with-hyphens.ftl",
| ^^^^^^^^^^^^^^^^^
|
= help: replace any '-'s with '_'s

error: attribute `label-has-hyphens` contains a '-' character
--> $DIR/test.rs:71:9
|
LL | label_with_hyphens => "./label-with-hyphens.ftl",
| ^^^^^^^^^^^^^^^^^^
|
= help: replace any '-'s with '_'s

error: aborting due to 6 previous errors