diff --git a/book.toml b/book.toml index a5d794b50..96b9e3fe1 100644 --- a/book.toml +++ b/book.toml @@ -48,5 +48,6 @@ warning-policy = "error" [output.html.redirect] "/compiletest.html" = "tests/compiletest.html" -"/diagnostics/sessiondiagnostic.html" = "diagnostics/diagnostic-structs.html" +"/diagnostics/sessiondiagnostic.html" = "diagnostic-structs.html" +"/diagnostics/diagnostic-codes.html" = "error-codes.html" "/miri.html" = "const-eval/interpret.html" diff --git a/src/SUMMARY.md b/src/SUMMARY.md index adc397fd8..b558fb2b2 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -146,7 +146,7 @@ - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md) - [Translation](./diagnostics/translation.md) - [`LintStore`](./diagnostics/lintstore.md) - - [Diagnostic codes](./diagnostics/diagnostic-codes.md) + - [Error codes](./diagnostics/error-codes.md) - [Diagnostic items](./diagnostics/diagnostic-items.md) - [`ErrorGuaranteed`](./diagnostics/error-guaranteed.md) diff --git a/src/diagnostics.md b/src/diagnostics.md index d32de068e..daaffba7b 100644 --- a/src/diagnostics.md +++ b/src/diagnostics.md @@ -69,17 +69,12 @@ surrounded with backticks: error: the identifier `foo.bar` is invalid ``` -### Error explanations +### Error codes and explanations -Some errors include long form descriptions. They may be viewed with the -`--explain` flag, or via the [error index]. Each explanation comes with an -example of how to trigger it and advice on how to fix it. - -Please read [RFC 1567] for details on how to format and write long error -codes. - -The descriptions are written in Markdown, and all of them are linked in the -[`rustc_error_codes`] crate. +Most errors have an associated error code. Error codes are linked to long-form +explanations which contains an example of how to trigger the error and in-depth +details about the error. They may be viewed with the `--explain` flag, or via +the [error index]. As a general rule, give an error a code (with an associated explanation) if the explanation would give more information than the error itself. A lot of the time @@ -89,12 +84,15 @@ triggers to include useful information for all cases in the error, in which case it's a good idea to add an explanation.[^estebank] As always, if you are not sure, just ask your reviewer! +If you decide to add a new error with an associated error code, please read +[this section][error-codes] for a guide and important details about the +process. + [^estebank]: This rule of thumb was suggested by **@estebank** [here][estebank-comment]. -[`rustc_error_codes`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_error_codes/error_codes/index.html [error index]: https://doc.rust-lang.org/error-index.html -[RFC 1567]: https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md [estebank-comment]: https://github.com/rust-lang/rustc-dev-guide/pull/967#issuecomment-733218283 +[error-codes]: ./diagnostics/error-codes.md ### Lints versus fixed diagnostics diff --git a/src/diagnostics/diagnostic-codes.md b/src/diagnostics/diagnostic-codes.md deleted file mode 100644 index 3618b43cd..000000000 --- a/src/diagnostics/diagnostic-codes.md +++ /dev/null @@ -1,79 +0,0 @@ -# Diagnostic 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. The codes come in two varieties: those -that have an extended write-up, and those that do not. Whenever possible, if you -are making a new code, you should write an extended write-up. - -### 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 with `tidy`: - -``` -./x.py test tidy -``` - -This will invoke the tidy script, which generally checks that your code obeys -our coding conventions. One of those jobs is to check that diagnostic codes are -indeed unique. Once it is finished with that, tidy will print out the lowest -unused code: - -``` -... -tidy check (x86_64-apple-darwin) -* 470 error codes -* highest error code: E0591 -... -``` - -Here we see the highest error code in use is `E0591`, so we _probably_ want -`E0592`. To be sure, run `rg E0592` and check, you should see no references. - -Ideally, you will write an extended description for your error, -which will go in `rustc_error_codes/src/error_codes/E0592.md`. -To register the error, open `rustc_error_codes/src/error_codes.rs` and add the -code (in its proper numerical order) into` register_diagnostics!` macro, like -this: - -```rust -register_diagnostics! { - ... - E0592: include_str!("./error_codes/E0592.md"), -} -``` - -But you can also add it without an extended description: - -```rust -register_diagnostics! { - ... - E0592, // put a description here -} -``` - -To actually issue the error, you can use the `struct_span_err!` macro: - -```rust -struct_span_err!(self.tcx.sess, // some path to the session here - span, // whatever span in the source you want - E0592, // 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()`: - -```rust -struct_span_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]. - -[#76143]: https://github.com/rust-lang/rust/pull/76143 diff --git a/src/diagnostics/error-codes.md b/src/diagnostics/error-codes.md new file mode 100644 index 000000000..2dbdb53fe --- /dev/null +++ b/src/diagnostics/error-codes.md @@ -0,0 +1,95 @@ +# 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 +effort[^new-explanations] 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 +overhauled[^new-explanations] it is a bit open as to how exactly they should be +written, as always: ask your reviewer or ask around on the Rust Discord or Zulip. + +[^new-explanations]: See the draft RFC [here][new-explanations-rfc]. + +[`rustc_error_codes`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_error_codes/error_codes/index.html +[CommonMark Spec]: https://spec.commonmark.org/current/ +[RFC 1567]: https://github.com/rust-lang/rfcs/blob/master/text/1567-long-error-codes-explanation-normalization.md +[new-explanations-rfc]: https://github.com/rust-lang/rfcs/pull/3370 + +## 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 with `tidy`: + +``` +./x.py test tidy +``` + +This will invoke the tidy script, which generally checks that your code obeys +our coding conventions. Some of these jobs check error codes and ensure that +there aren't duplicates, etc (the tidy check is defined in +`src/tools/tidy/src/error_codes.rs`). Once it is finished with that, tidy will +print out the highest used error code: + +``` +... +tidy check +Found 505 error codes +Highest error code: `E0591` +... +``` + +Here we see the highest error code in use is `E0591`, so we _probably_ want +`E0592`. To be sure, run `rg E0592` 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/E0592.md`. +To register the error, open `rustc_error_codes/src/error_codes.rs` and add the +code (in its proper numerical order) into` register_diagnostics!` macro, like +this: + +```rust +register_diagnostics! { + ... + E0592: include_str!("./error_codes/E0592.md"), +} +``` + +To actually issue the error, you can use the `struct_span_err!` macro: + +```rust +struct_span_err!(self.tcx.sess, // some path to the session here + span, // whatever span in the source you want + E0592, // 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()`: + +```rust +struct_span_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]. + +[#76143]: https://github.com/rust-lang/rust/pull/76143