1
1
# Translation
2
+
2
3
rustc's diagnostic infrastructure supports translatable diagnostics using
3
4
[ Fluent] .
4
5
5
6
## Writing translatable diagnostics
7
+
6
8
There are two ways of writing translatable diagnostics:
7
9
8
10
1 . For simple diagnostics, using a diagnostic (or subdiagnostic) derive
@@ -13,12 +15,17 @@ There are two ways of writing translatable diagnostics:
13
15
2 . Using typed identifiers with ` DiagnosticBuilder ` APIs (in
14
16
` Diagnostic ` implementations).
15
17
16
- When adding or changing a translatable diagnostic, you don't need to worry
17
- about the translations, only updating the original English message. Currently,
18
+ When adding or changing a translatable diagnostic,
19
+ you don't need to worry about the translations.
20
+ Only updating the original English message is required.
21
+ Currently,
18
22
each crate which defines translatable diagnostics has its own Fluent resource,
19
- such as ` parser.ftl ` or ` typeck.ftl ` .
23
+ which is a file named ` messages.ftl ` ,
24
+ located in the root of the crate
25
+ (such as` compiler/rustc_expand/messages.ftl ` ).
20
26
21
27
## Fluent
28
+
22
29
Fluent is built around the idea of "asymmetric localization", which aims to
23
30
decouple the expressiveness of translations from the grammar of the source
24
31
language (English in rustc's case). Prior to translation, rustc's diagnostics
@@ -68,13 +75,15 @@ You can consult the [Fluent] documentation for other usage examples of Fluent
68
75
and its syntax.
69
76
70
77
### Guideline for message naming
78
+
71
79
Usually, fluent uses ` - ` for separating words inside a message name. However,
72
80
` _ ` is accepted by fluent as well. As ` _ ` fits Rust's use cases better, due to
73
81
the identifiers on the Rust side using ` _ ` as well, inside rustc, ` - ` is not
74
82
allowed for separating words, and instead ` _ ` is recommended. The only exception
75
83
is for leading ` - ` s, for message names like ` -passes_see_issue ` .
76
84
77
85
### Guidelines for writing translatable messages
86
+
78
87
For a message to be translatable into different languages, all of the
79
88
information required by any language must be provided to the diagnostic as an
80
89
argument (not just the information required in the English message).
@@ -86,10 +95,6 @@ excellent examples of translating messages into different locales and the
86
95
information that needs to be provided by the code to do so.
87
96
88
97
### Compile-time validation and typed identifiers
89
- Currently, each crate which defines translatable diagnostics has its own
90
- Fluent resource in a file named ` messages.ftl ` , such as
91
- [ ` compiler/rustc_borrowck/messages.ftl ` ] and
92
- [ ` compiler/rustc_parse/messages.ftl ` ] .
93
98
94
99
rustc's ` fluent_messages ` macro performs compile-time validation of Fluent
95
100
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
100
105
resources from causing panics in the compiler. Compile-time validation also
101
106
emits an error if multiple Fluent messages have the same identifier.
102
107
103
- In ` rustc_error_messages ` , ` fluent_messages ` also generates a constant for each
104
- Fluent message which can be used to refer to messages when emitting
105
- diagnostics and guarantee that the message exists.
106
-
107
- ``` rust
108
- fluent_messages! {
109
- typeck => " ../locales/en-US/typeck.ftl" ,
110
- }
111
- ```
112
-
113
- For example, given the following Fluent...
114
-
115
- ``` fluent
116
- typeck_field_multiply_specified_in_initializer =
117
- field `{$ident}` specified more than once
118
- .label = used more than once
119
- .label_previous_use = first use of `{$ident}`
120
- ```
121
-
122
- ...then the ` fluent_messages ` macro will generate:
123
-
124
- ``` rust
125
- pub static DEFAULT_LOCALE_RESOURCES : & 'static [& 'static str ] = & [
126
- include_str! (" ../locales/en-US/typeck.ftl" ),
127
- ];
128
-
129
- mod fluent_generated {
130
- pub const typeck_field_multiply_specified_in_initializer : DiagnosticMessage =
131
- DiagnosticMessage :: new (" typeck_field_multiply_specified_in_initializer" );
132
- pub const label : SubdiagnosticMessage =
133
- SubdiagnosticMessage :: attr (" label" );
134
- pub const label_previous_use : SubdiagnosticMessage =
135
- SubdiagnosticMessage :: attr (" previous_use_label" );
136
- }
137
- ```
138
-
139
- ` rustc_error_messages::fluent_generated ` is re-exported and primarily used as
140
- ` rustc_errors::fluent ` .
141
-
142
- ``` rust
143
- use rustc_errors :: fluent;
144
- let mut err = sess . struct_span_err (span , fluent :: typeck_field_multiply_specified_in_initializer );
145
- err . span_label (span , fluent :: label );
146
- err . span_label (previous_use_span , fluent :: previous_use_label );
147
- err . emit ();
148
- ```
149
-
150
- When emitting a diagnostic, these constants can be used like shown above.
151
-
152
108
## Internals
109
+
153
110
Various parts of rustc's diagnostic internals are modified in order to support
154
111
translation.
155
112
156
113
### Messages
114
+
157
115
All of rustc's traditional diagnostic APIs (e.g. ` struct_span_err ` or ` note ` )
158
116
take any message that can be converted into a ` DiagnosticMessage ` (or
159
117
` SubdiagnosticMessage ` ).
@@ -182,6 +140,7 @@ non-translatable diagnostics - this keeps all existing diagnostic calls
182
140
working.
183
141
184
142
### Arguments
143
+
185
144
Additional context for Fluent messages which are interpolated into message
186
145
contents needs to be provided to translatable diagnostics.
187
146
@@ -191,13 +150,14 @@ additional context to a diagnostic.
191
150
Arguments have both a name (e.g. "what" in the earlier example) and a value.
192
151
Argument values are represented using the ` DiagnosticArgValue ` type, which is
193
152
just a string or a number. rustc types can implement ` IntoDiagnosticArg ` with
194
- conversion into a string or a number, common types like ` Ty<'tcx> ` already
153
+ conversion into a string or a number, and common types like ` Ty<'tcx> ` already
195
154
have such implementations.
196
155
197
156
` set_arg ` calls are handled transparently by diagnostic derives but need to be
198
157
added manually when using diagnostic builder APIs.
199
158
200
159
### Loading
160
+
201
161
rustc makes a distinction between the "fallback bundle" for ` en-US ` that is used
202
162
by default and when another locale is missing a message; and the primary fluent
203
163
bundle which is requested by the user.
@@ -222,9 +182,8 @@ returned by `Emitter::fluent_bundle`. This bundle is used preferentially when
222
182
translating messages, the fallback bundle is only used if the primary bundle is
223
183
missing a message or not provided.
224
184
225
- As of <!-- date-check --> Jan 2023, there are no locale bundles
226
- distributed with the compiler, but mechanisms are implemented for loading
227
- bundles.
185
+ There are no locale bundles distributed with the compiler,
186
+ but mechanisms are implemented for loading them.
228
187
229
188
- ` -Ztranslate-additional-ftl ` can be used to load a specific resource as the
230
189
primary bundle for testing purposes.
0 commit comments