review comments: move text to more relevant section

This commit is contained in:
Esteban Küber 2019-11-25 18:41:50 -08:00 committed by Who? Me?!
parent d738fed623
commit 4266d9d902
2 changed files with 105 additions and 108 deletions

View File

@ -3,6 +3,90 @@
A lot of effort has been put into making `rustc` have great error messages.
This chapter is about how to emit compile errors and lints from the compiler.
## Diagnostic output style guide
The main parts of a diagnostic error are the following:
```
error[E0000]: main error message
--> file.rs:LL:CC
|
LL | <code>
| -^^^^- secondary label
| |
| primary label
|
= note: note without a `Span`, created with `.note`
note: sub-diagnostic message for `.span_note`
--> file.rs:LL:CC
|
LL | more code
| ^^^^
```
- Description (`error`, `warning`, etc.).
- Code (for example, for "mismatched types", it is `E0308`). It helps
users get more information about the current error through an extended
description of the problem in the error code index.
- Message. It is the main description of the problem. It should be general and
able to stand on its own, so that it can make sense even in isolation.
- Diagnostic window. This contains several things:
- The path, line number and column of the beginning of the primary span.
- The users' affected code and its surroundings.
- Primary and secondary spans underlying the users' code. These spans can
optionally contain one or more labels.
- Primary spans should have enough text to descrive the problem in such a
way that if it where the only thing being displayed (for example, in an
IDE) it would still make sense. Because it is "spatially aware" (it
points at the code), it can generally be more succinct than the error
message.
- If cluttered output can be foreseen in cases when multiple span labels
overlap, it is a good idea to tweak the output appropriately. For
example, the `if/else arms have incompatible types` error uses different
spans depending on whether the arms are all in the same line, if one of
the arms is empty and if none of those cases applies.
- Sub-diagnostics. Any error can have multiple sub-diagnostics that look
similar to the main part of the error. These are used for cases where the
order of the explanation might not correspond with the order of the code. If
the order of the explanation can be "order free", leveraging secondary labels
in the main diagnostic is preferred, as it is typically less verbose.
The text should be matter of fact and avoid capitalization and periods, unless
multiple sentences are _needed_:
```
error: the fobrulator needs to be krontrificated
```
When code or an identifier must appear in an message or label, it should be
surrounded with single acute accents \`.
## Helpful tips and options
### Finding the source of errors
There are two main ways to find where a given error is emitted:
- `grep` for either a sub-part of the error message/label or error code. This
usually works well and is straightforward, but there are some cases where
the error emitting code is removed from the code where the error is
constructed behind a relatively deep call-stack. Even then, it is a good way
to get your bearings.
- Invoking `rustc` with the nightly-only flag `-Ztreat-err-as-bug=1`, which
will treat the first error being emitted as an Internal Compiler Error, which
allows you to use the environment variable `RUST_BACKTRACE=full` to get a
stack trace at the point the error has been emitted. Change the `1` to
something else if you whish to trigger on a later error. Some limitations
with this approach is that some calls get elided from the stack trace because
they get inlined in the compiled `rustc`, and the same problem we faced with
the prior approach, where the _construction_ of the error is far away from
where it is _emitted_. In some cases we buffer multiple errors in order to
emit them in order.
The regular development practices apply: judicious use of `debug!()` statements
and use of a debugger to trigger break points in order to figure out in what
order things are happening.
## `Span`
[`Span`][span] is the primary data structure in `rustc` used to represent a
@ -84,11 +168,29 @@ Server][rls] and [`rustfix`][rustfix].
[rls]: https://github.com/rust-lang/rls
[rustfix]: https://github.com/rust-lang/rustfix
Not all suggestions should be applied mechanically. Use the
Not all suggestions should be applied mechanically, they have a degree of
confidence in the suggested code, from high
(`Applicability::MachineApplicable`) to low (`Applicability::MaybeIncorrect`).
Be conservative when choosing the level. Use the
[`span_suggestion`][span_suggestion] method of `DiagnosticBuilder` to
make a suggestion. The last argument provides a hint to tools whether
the suggestion is mechanically applicable or not.
Suggestions point to one or more spans with corresponding code that will
replace their current content.
The message that accompanies them should be understandable in the following
contexts:
- shown as an independent sug-diagnostic (this is the default output)
- shown as a label pointing at the affected span (this is done automatically if
the some heuristics for verbosity are met)
- shown as a `help` sub-diagnostic with no content (used for cases where the
suggestion is obvious from the text, but we still want to let tools to apply
them))
- not shown (used for _very_ obvious cases, but we still want to allow tools to
apply them)
[span_suggestion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagnosticBuilder.html#method.span_suggestion
For example, to make our `qux` suggestion machine-applicable, we would do:

View File

@ -38,111 +38,6 @@ but don't.
[D-edition]: https://github.com/rust-lang/rust/labels/D-edition
[A-diagnostic-suggestions]: https://github.com/rust-lang/rust/labels/A-diagnostic-suggestions
## Diagnostic output style guide
For more information, visit the [diagnostics page].
The main parts of a diagnostic error are the following:
```
error[E0000]: main error message
--> file.rs:LL:CC
|
LL | <code>
| -^^^^- secondary label
| |
| primary label
|
= note: note without a `Span`, created with `.note`
note: sub-diagnostic message for `.span_note`
--> file.rs:LL:CC
|
LL | more code
| ^^^^
```
- Description (`error`, `warning`, etc.).
- Code (for example, for "mismatched types", it is `E0308`). It helps
users get more information about the current error through an extended
description of the problem in the error code index.
- Message. It is the main description of the problem. It should be general and
able to stand on its own, so that it can make sense even in isolation.
- Diagnostic window. This contains several things:
- The path, line number and column of the beginning of the primary span.
- The users' affected code and its surroundings.
- Primary and secondary spans underlying the users' code. These spans can
optionally contain one or more labels.
- Primary spans should have enough text to descrive the problem in such a
way that if it where the only thing being displayed (for example, in an
IDE) it would still make sense. Because it is "spatially aware" (it
points at the code), it can generally be more succinct than the error
message.
- If cluttered output can be foreseen in cases when multiple span labels
overlap, it is a good idea to tweak the output appropriately. For
example, the `if/else arms have incompatible types` error uses different
spans depending on whether the arms are all in the same line, if one of
the arms is empty and if none of those cases applies.
- Sub-diagnostics. Any error can have multiple sub-diagnostics that look
similar to the main part of the error. These are used for cases where the
order of the explanation might not correspond with the order of the code. If
the order of the explanation can be "order free", leveraging secondary labels
in the main diagnostic is preferred, as it is typically less verbose.
The text should be matter of fact and avoid capitalization and periods, unless
multiple sentences are _needed_:
```
error: the fobrulator needs to be krontrificated
```
When code or an identifier must appear in an message or label, it should be
surrounded with single acute accents \`.
### Structured suggestions
Structured suggestions are a special kind of annotation in a diagnostic that
let third party tools (like `rustfix` and `rust-analyzer`) apply these changes
with no or minimal user interaction. These suggestions have a degree of
confidence in the suggested code, from high
(`Applicability::MachineApplicable`) to low (`Applicability::MaybeIncorrect`).
Be conservative when choosing the level.
They point to one or more spans with corresponding code that will replace their
current content.
The message that accompanies them should be understandable in the following
contexts:
- shown as an independent sug-diagnostic (this is the default output)
- shown as a label pointing at the affected span (this is done automatically if
the some heuristics for verbosity are met)
- shown as a `help` sub-diagnostic with no content (used for cases where the
suggestion is obvious from the text, but we still want to let tools to apply
them))
- not shown (used for _very_ obvious cases, but we still want to allow tools to
apply them)
## Helpful tips and options
### Finding the source of errors
There are two main ways to find where a given error is emitted:
- `grep` for either a sub-part of the error message/label or error code. This
usually works well and is straightforward, but there are some cases where
the error emitting code is removed from the code where the error is
constructed behind a relatively deep call-stack. Even then, it is a good way
to get your bearings.
- Invoking `rustc` with the nightly-only flag `-Ztreat-err-as-bug=1`, which
will treat the first error being emitted as an Internal Compiler Error, which
allows you to use the environment variable `RUST_BACKTRACE=full` to get a
stack trace at the point the error has been emitted. Change the `1` to
something else if you whish to trigger on a later error. Some limitations
with this approach is that some calls get elided from the stack trace because
they get inlined in the compiled `rustc`, and the same problem we faced with
the prior approach, where the _construction_ of the error is far away from
where it is _emitted_. In some cases we buffer multiple errors in order to
emit them in order.
The regular development practices apply: judicious use of `debug!()` statements
and use of a debugger to trigger break points in order to figure out in what
order things are happening.
[diagnostics page]: ../diagnostics.md