Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error codes

We generally try to assign each error message a unique code like E0123. These codes are defined in the compiler in the diagnostics.rs files found in each crate, which basically consist of macros. All error codes have an associated explanation: new error codes must include them. Note that not all historical (no longer emitted) error codes have explanations.

Error explanations

The explanations are written in Markdown (see the CommonMark Spec for specifics around syntax), and all of them are linked in the rustc_error_codes crate. Please read RFC 1567 for details on how to format and write long error codes. As of February 2023, there is an effort1 to replace this largely outdated RFC with a new more flexible standard.

Error explanations should expand on the error message and provide details about why the error occurs. It is not helpful for users to copy-paste a quick fix; explanations should help users understand why their code cannot be accepted by the compiler. Rust prides itself on helpful error messages and long-form explanations are no exception. However, before error explanations are overhauled1 it is a bit open as to how exactly they should be written, as always: ask your reviewer or ask around on the Rust Zulip.

Allocating a fresh code

Error codes are stored in compiler/rustc_error_codes.

To create a new error, you first need to find the next available code. You can find it by opening rustc_error_codes/src/lib.rs and scrolling down to the end of the error_codes! macro declaration.

Here we might see the highest error code in use is E0805, so we probably want E0806. To be sure, run rg E0806 and check, you should see no references.

You will have to write an extended description for your error, which will go in rustc_error_codes/src/error_codes/E0806.md. To register the error, add the code (in its proper numerical order) to the error_codes! macro, like this:

#![allow(unused)]
fn main() {
macro_rules! error_codes {
...
0806,
}
}

To actually issue the error, you can use the struct_span_code_err! macro:

#![allow(unused)]
fn main() {
struct_span_code_err!(self.dcx(), // some path to the `DiagCtxt` here
                 span, // whatever span in the source you want
                 E0806, // your new error code
                 fluent::example::an_error_message)
    .emit() // actually issue the error
}

If you want to add notes or other snippets, you can invoke methods before you call .emit():

#![allow(unused)]
fn main() {
struct_span_code_err!(...)
    .span_label(another_span, fluent::example::example_label)
    .span_note(another_span, fluent::example::separate_note)
    .emit()
}

For an example of a PR adding an error code, see #76143.

Running error code doctests

To test the examples added in rustc_error_codes/src/error_codes, run the error index generator using:

./x test ./src/tools/error_index_generator

  1. See the draft RFC here. ↩2