# Errors and lints
<!-- toc -->
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 structure
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
| ^^^^
```
- Level (`error`, `warning`, etc.). It indicates the severity of the message.
(See [diagnostic levels](#diagnostic-levels))
- 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. Not all diagnostic have a
code. For example, diagnostics created by lints don't have one.
- 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 describe the problem in such a
way that if it were 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_:
```txt
error: the fobrulator needs to be krontrificated
```
When code or an identifier must appear in a message or label, it should be
surrounded with backticks:
```txt
error: the identifier `foo.bar` is invalid
```
### Error codes and explanations
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
it's better to put all the information in the emitted error itself. However,
sometimes that would make the error verbose or there are too many possible
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.
### Lints versus fixed diagnostics
Some messages are emitted via [lints](#lints), where the user can control the
level. Most diagnostics are hard-coded such that the user cannot control the
level.
Usually it is obvious whether a diagnostic should be "fixed" or a lint, but