update some of the diagnostic translations info (#1711)
This commit is contained in:
parent
93aeba6e75
commit
9ad9d15da9
|
|
@ -1,8 +1,10 @@
|
||||||
# Translation
|
# Translation
|
||||||
|
|
||||||
rustc's diagnostic infrastructure supports translatable diagnostics using
|
rustc's diagnostic infrastructure supports translatable diagnostics using
|
||||||
[Fluent].
|
[Fluent].
|
||||||
|
|
||||||
## Writing translatable diagnostics
|
## Writing translatable diagnostics
|
||||||
|
|
||||||
There are two ways of writing translatable diagnostics:
|
There are two ways of writing translatable diagnostics:
|
||||||
|
|
||||||
1. For simple diagnostics, using a diagnostic (or subdiagnostic) derive
|
1. For simple diagnostics, using a diagnostic (or subdiagnostic) derive
|
||||||
|
|
@ -13,12 +15,17 @@ There are two ways of writing translatable diagnostics:
|
||||||
2. Using typed identifiers with `DiagnosticBuilder` APIs (in
|
2. Using typed identifiers with `DiagnosticBuilder` APIs (in
|
||||||
`Diagnostic` implementations).
|
`Diagnostic` implementations).
|
||||||
|
|
||||||
When adding or changing a translatable diagnostic, you don't need to worry
|
When adding or changing a translatable diagnostic,
|
||||||
about the translations, only updating the original English message. Currently,
|
you don't need to worry about the translations.
|
||||||
|
Only updating the original English message is required.
|
||||||
|
Currently,
|
||||||
each crate which defines translatable diagnostics has its own Fluent resource,
|
each crate which defines translatable diagnostics has its own Fluent resource,
|
||||||
such as `parser.ftl` or `typeck.ftl`.
|
which is a file named `messages.ftl`,
|
||||||
|
located in the root of the crate
|
||||||
|
(such as`compiler/rustc_expand/messages.ftl`).
|
||||||
|
|
||||||
## Fluent
|
## Fluent
|
||||||
|
|
||||||
Fluent is built around the idea of "asymmetric localization", which aims to
|
Fluent is built around the idea of "asymmetric localization", which aims to
|
||||||
decouple the expressiveness of translations from the grammar of the source
|
decouple the expressiveness of translations from the grammar of the source
|
||||||
language (English in rustc's case). Prior to translation, rustc's diagnostics
|
language (English in rustc's case). Prior to translation, rustc's diagnostics
|
||||||
|
|
@ -68,6 +75,7 @@ You can consult the [Fluent] documentation for other usage examples of Fluent
|
||||||
and its syntax.
|
and its syntax.
|
||||||
|
|
||||||
### Guideline for message naming
|
### Guideline for message naming
|
||||||
|
|
||||||
Usually, fluent uses `-` for separating words inside a message name. However,
|
Usually, fluent uses `-` for separating words inside a message name. However,
|
||||||
`_` is accepted by fluent as well. As `_` fits Rust's use cases better, due to
|
`_` is accepted by fluent as well. As `_` fits Rust's use cases better, due to
|
||||||
the identifiers on the Rust side using `_` as well, inside rustc, `-` is not
|
the identifiers on the Rust side using `_` as well, inside rustc, `-` is not
|
||||||
|
|
@ -75,6 +83,7 @@ allowed for separating words, and instead `_` is recommended. The only exception
|
||||||
is for leading `-`s, for message names like `-passes_see_issue`.
|
is for leading `-`s, for message names like `-passes_see_issue`.
|
||||||
|
|
||||||
### Guidelines for writing translatable messages
|
### Guidelines for writing translatable messages
|
||||||
|
|
||||||
For a message to be translatable into different languages, all of the
|
For a message to be translatable into different languages, all of the
|
||||||
information required by any language must be provided to the diagnostic as an
|
information required by any language must be provided to the diagnostic as an
|
||||||
argument (not just the information required in the English message).
|
argument (not just the information required in the English message).
|
||||||
|
|
@ -86,10 +95,6 @@ excellent examples of translating messages into different locales and the
|
||||||
information that needs to be provided by the code to do so.
|
information that needs to be provided by the code to do so.
|
||||||
|
|
||||||
### Compile-time validation and typed identifiers
|
### Compile-time validation and typed identifiers
|
||||||
Currently, each crate which defines translatable diagnostics has its own
|
|
||||||
Fluent resource in a file named `messages.ftl`, such as
|
|
||||||
[`compiler/rustc_borrowck/messages.ftl`] and
|
|
||||||
[`compiler/rustc_parse/messages.ftl`].
|
|
||||||
|
|
||||||
rustc's `fluent_messages` macro performs compile-time validation of Fluent
|
rustc's `fluent_messages` macro performs compile-time validation of Fluent
|
||||||
resources and generates code to make it easier to refer to Fluent messages in
|
resources and generates code to make it easier to refer to Fluent messages in
|
||||||
|
|
@ -100,60 +105,13 @@ from Fluent resources while building the compiler, preventing invalid Fluent
|
||||||
resources from causing panics in the compiler. Compile-time validation also
|
resources from causing panics in the compiler. Compile-time validation also
|
||||||
emits an error if multiple Fluent messages have the same identifier.
|
emits an error if multiple Fluent messages have the same identifier.
|
||||||
|
|
||||||
In `rustc_error_messages`, `fluent_messages` also generates a constant for each
|
|
||||||
Fluent message which can be used to refer to messages when emitting
|
|
||||||
diagnostics and guarantee that the message exists.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
fluent_messages! {
|
|
||||||
typeck => "../locales/en-US/typeck.ftl",
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For example, given the following Fluent...
|
|
||||||
|
|
||||||
```fluent
|
|
||||||
typeck_field_multiply_specified_in_initializer =
|
|
||||||
field `{$ident}` specified more than once
|
|
||||||
.label = used more than once
|
|
||||||
.label_previous_use = first use of `{$ident}`
|
|
||||||
```
|
|
||||||
|
|
||||||
...then the `fluent_messages` macro will generate:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
|
|
||||||
include_str!("../locales/en-US/typeck.ftl"),
|
|
||||||
];
|
|
||||||
|
|
||||||
mod fluent_generated {
|
|
||||||
pub const typeck_field_multiply_specified_in_initializer: DiagnosticMessage =
|
|
||||||
DiagnosticMessage::new("typeck_field_multiply_specified_in_initializer");
|
|
||||||
pub const label: SubdiagnosticMessage =
|
|
||||||
SubdiagnosticMessage::attr("label");
|
|
||||||
pub const label_previous_use: SubdiagnosticMessage =
|
|
||||||
SubdiagnosticMessage::attr("previous_use_label");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
`rustc_error_messages::fluent_generated` is re-exported and primarily used as
|
|
||||||
`rustc_errors::fluent`.
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use rustc_errors::fluent;
|
|
||||||
let mut err = sess.struct_span_err(span, fluent::typeck_field_multiply_specified_in_initializer);
|
|
||||||
err.span_label(span, fluent::label);
|
|
||||||
err.span_label(previous_use_span, fluent::previous_use_label);
|
|
||||||
err.emit();
|
|
||||||
```
|
|
||||||
|
|
||||||
When emitting a diagnostic, these constants can be used like shown above.
|
|
||||||
|
|
||||||
## Internals
|
## Internals
|
||||||
|
|
||||||
Various parts of rustc's diagnostic internals are modified in order to support
|
Various parts of rustc's diagnostic internals are modified in order to support
|
||||||
translation.
|
translation.
|
||||||
|
|
||||||
### Messages
|
### Messages
|
||||||
|
|
||||||
All of rustc's traditional diagnostic APIs (e.g. `struct_span_err` or `note`)
|
All of rustc's traditional diagnostic APIs (e.g. `struct_span_err` or `note`)
|
||||||
take any message that can be converted into a `DiagnosticMessage` (or
|
take any message that can be converted into a `DiagnosticMessage` (or
|
||||||
`SubdiagnosticMessage`).
|
`SubdiagnosticMessage`).
|
||||||
|
|
@ -182,6 +140,7 @@ non-translatable diagnostics - this keeps all existing diagnostic calls
|
||||||
working.
|
working.
|
||||||
|
|
||||||
### Arguments
|
### Arguments
|
||||||
|
|
||||||
Additional context for Fluent messages which are interpolated into message
|
Additional context for Fluent messages which are interpolated into message
|
||||||
contents needs to be provided to translatable diagnostics.
|
contents needs to be provided to translatable diagnostics.
|
||||||
|
|
||||||
|
|
@ -191,13 +150,14 @@ additional context to a diagnostic.
|
||||||
Arguments have both a name (e.g. "what" in the earlier example) and a value.
|
Arguments have both a name (e.g. "what" in the earlier example) and a value.
|
||||||
Argument values are represented using the `DiagnosticArgValue` type, which is
|
Argument values are represented using the `DiagnosticArgValue` type, which is
|
||||||
just a string or a number. rustc types can implement `IntoDiagnosticArg` with
|
just a string or a number. rustc types can implement `IntoDiagnosticArg` with
|
||||||
conversion into a string or a number, common types like `Ty<'tcx>` already
|
conversion into a string or a number, and common types like `Ty<'tcx>` already
|
||||||
have such implementations.
|
have such implementations.
|
||||||
|
|
||||||
`set_arg` calls are handled transparently by diagnostic derives but need to be
|
`set_arg` calls are handled transparently by diagnostic derives but need to be
|
||||||
added manually when using diagnostic builder APIs.
|
added manually when using diagnostic builder APIs.
|
||||||
|
|
||||||
### Loading
|
### Loading
|
||||||
|
|
||||||
rustc makes a distinction between the "fallback bundle" for `en-US` that is used
|
rustc makes a distinction between the "fallback bundle" for `en-US` that is used
|
||||||
by default and when another locale is missing a message; and the primary fluent
|
by default and when another locale is missing a message; and the primary fluent
|
||||||
bundle which is requested by the user.
|
bundle which is requested by the user.
|
||||||
|
|
@ -222,9 +182,8 @@ returned by `Emitter::fluent_bundle`. This bundle is used preferentially when
|
||||||
translating messages, the fallback bundle is only used if the primary bundle is
|
translating messages, the fallback bundle is only used if the primary bundle is
|
||||||
missing a message or not provided.
|
missing a message or not provided.
|
||||||
|
|
||||||
As of <!-- date-check --> Jan 2023, there are no locale bundles
|
There are no locale bundles distributed with the compiler,
|
||||||
distributed with the compiler, but mechanisms are implemented for loading
|
but mechanisms are implemented for loading them.
|
||||||
bundles.
|
|
||||||
|
|
||||||
- `-Ztranslate-additional-ftl` can be used to load a specific resource as the
|
- `-Ztranslate-additional-ftl` can be used to load a specific resource as the
|
||||||
primary bundle for testing purposes.
|
primary bundle for testing purposes.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue