Skip to content

Diagnostic Translation #100717

Open
Open

Description

The Rust Diagnostics working group is leading an effort to add support for internationalization of error messages in the compiler, allowing the compiler to produce output in languages other than English. This issue tracks the current status of the effort, which was announced in the "Contribute to the diagnostic translation effort!" post on Inside Rust.

What's the current status?

Diagnostic translation will take a long time to be finished. At a high-level, there are four primary steps:

  • Implement initial translation infrastructure
  • Make diagnostics translatable through migration to new infrastructure (we are here)
  • Set up Pontoon for translators to use
  • Establish translation teams for different languages
  • Implement infrastructure for distributing language packs in collaboration with infrastructure/release teams (as appropriate)

Implementing the initial translation infrastructure provides the groundwork that enables diagnostic messages to be made translatable at all. That initial infrastructure is largely completed - there might be some gaps that we'll discover and patch up as we continue - but it's almost all there.

Next, all of the diagnostics in rustc need to be modified so that they can be translatable. There's some bad news - that's a lot of work. But there's also some good news - that's a lot of highly parallelizable work that you can help with! It doesn't require any familiarity with the Rust compiler, just an eagerness to get involved.

How to get started?

It's very easy to get started, the process looks like the following:

  1. Join our Zulip chat and say hello! Everyone is very friendly and eager to help if you have any trouble.
  2. Set up a development environment for the compiler.
  3. Identify a module to migrate (see "Identifying diagnostics to migrate" below).
  4. Migrate diagnostics (see "Migrate diagnostics" below).
  5. Open a pull request with your changes.
  6. Repeat and profit!

Identifying diagnostics to migrate

Our goal is to migrate every diagnostic in the compiler to be translatable and to switch from using a "diagnostic builder" to using "diagnostic structs". That's a lot of diagnostics, so we're splitting the work up by module in the compiler so that nobody steps on anyone else's toes.

Note: Some of these crates might not have diagnostics in them, in which case we'll just enable our internal lints on them. Some might have lots and lots of work that we can split up further, let us know! If there aren't many crates left, then feel free to leave a comment asking if someone is still working on their crate (check if they commented or have put a PR up recently).

Once you've picked a module (leave a comment letting us know!), how do you find the diagnostics to migrate? We've created rustc-internal lints that you can apply to a module which will produce an error for every diagnostic that hasn't been migrated.

#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]

(an example of using these would just be adding them to the top of a file)

After adding these attributes, you can run ./x.py check to build the compiler in check mode (just like cargo check in another project). You'll notice a bunch of errors that will look something like these:

error: diagnostics should only be created in `SessionDiagnostic`/`AddSubdiagnostic` impls
    --> compiler/rustc_parse/src/parser/mod.rs:1443:40
     |
1443 |     let mut err = sess.span_diagnostic.struct_span_err(
     |                                        ^^^^^^^^^^^^^^^

error: diagnostics should be created using translatable messages
    --> compiler/rustc_parse/src/parser/mod.rs:1443:40
     |
1443 |     let mut err = sess.span_diagnostic.struct_span_err(
     |                                        ^^^^^^^^^^^^^^^

There will be two errors for each diagnostic that isn't migrated:

  1. "diagnostics should be created using translatable messages"
    • This error occurs when a diagnostic function is being invoked with something that isn't a translatable message (like a string literal or a formatted string).
      • e.g. err.label("an example label") instead of err.label(fluent::example_label)
      • fluent::example_label corresponds to a message in a "Fluent resource" which we can provide different versions of for each language.
  2. "diagnostics should only be created in Diagnostic/Subdiagnostic impls"
    • This error occurs when a diagnostic function is being called outside of an impl of Diagnostic or Subdiagnostic. One of our goals with this migration is to move all diagnostic emission logic into impls on structs, as it helps keep the compiler tidy and works towards other goals of the diagnostics working group.
    • There are two ways to resolve this:
      1. Using a diagnostic derive to implement them automatically (preferred!)
      2. Implementing one of these traits (Diagnostic for errors and warnings, LintDiagnostic for lints, or Subdiagnsostic for parts of an error/warning/lint) manually.
    • See "Migrate diagnostics" for more on these.

We'll know we're finished when we can leave those attributes on every module in the compiler.

Migrate diagnostics

Okay, so you've got a diagnostic in front of you that you need to migrate.. now what?

While migrating diagnostics, there might be cases you run into that we've not run across yet. Let us know in Zulip, you might be able to experiment and teach us how to translate some diagnostics, or there may be an opportunity to extend our core infrastructure (e.g. the derives). Don't worry though, you can always skip a diagnostic and leave it for someone else too.

Where to get help?

Discussion is primarily happening in the #i18n stream on Zulip. Ask any questions you have in that chat and someone will try to help. If you don't get a response, feel free to ping @davidtwco or @t-compiler/wg-diagnostics.

One-off tasks

Sometimes there are one-off tasks which improve compiler infrastructure around translation or just make things easier to use, these are listed below, feel free to comment to take them:

Completed

In-progress

To-do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-translationArea: Translation infrastructure, and migrating existing diagnostics to SessionDiagnosticC-tracking-issueCategory: A tracking issue for an RFC or an unstable feature.S-tracking-impl-incompleteStatus: The implementation is incomplete.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions