error[E0999]: oh no! this is an error!
--> mycode.rs:3:5
|
3 | sad()
| ^ help: try using a qux here: `qux sad()`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0999`.
```
In some cases, like when the suggestion spans multiple lines or when there are
multiple suggestions, the suggestions are displayed on their own:
```console
error[E0999]: oh no! this is an error!
--> mycode.rs:3:5
|
3 | sad()
| ^
help: try using a qux here:
|
3 | qux sad()
| ^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0999`.
```
The possible values of [`Applicability`][appl] are:
- `MachineApplicable`: Can be applied mechanically.
- `HasPlaceholders`: Cannot be applied mechanically because it has placeholder
text in the suggestions. For example: ```try adding a type: `let x:
<type>` ```.
- `MaybeIncorrect`: Cannot be applied mechanically because the suggestion may
or may not be a good one.
- `Unspecified`: Cannot be applied mechanically because we don't know which
of the above cases it falls into.
[appl]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/enum.Applicability.html
### Suggestion Style Guide
- Suggestions should not be a question. In particular, language like "did you
mean" should be avoided. Sometimes, it's unclear why a particular suggestion
is being made. In these cases, it's better to be upfront about what the
suggestion is.
Compare "did you mean: `Foo`" vs. "there is a struct with a similar name: `Foo`".
- The message should not contain any phrases like "the following", "as shown",
etc. Use the span to convey what is being talked about.
- The message may contain further instruction such as "to do xyz, use" or "to do
xyz, use abc".
- The message may contain a name of a function, variable, or type, but avoid
whole expressions.
## Lints
The compiler linting infrastructure is defined in the [`rustc_middle::lint`][rlint]
module.
[rlint]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/index.html
### When do lints run?
Different lints will run at different times based on what information the lint
needs to do its job. Some lints get grouped into *passes* where the lints
within a pass are processed together via a single visitor. Some of the passes
are:
- Pre-expansion pass: Works on [AST nodes] before [macro expansion]. This
should generally be avoided.
- Example: [`keyword_idents`] checks for identifiers that will become
keywords in future editions, but is sensitive to identifiers used in
macros.
- Early lint pass: Works on [AST nodes] after [macro expansion] and name
resolution, just before [AST lowering]. These lints are for purely
syntactical lints.
- Example: The [`unused_parens`] lint checks for parenthesized-expressions
in situations where they are not needed, like an `if` condition.
- Late lint pass: Works on [HIR nodes], towards the end of [analysis] (after
borrow checking, etc.). These lints have full type information available.
Most lints are late.
- Example: The [`invalid_value`] lint (which checks for obviously invalid
uninitialized values) is a late lint because it needs type information to
figure out whether a type allows being left uninitialized.
- MIR pass: Works on [MIR nodes]. This isn't quite the same as other passes;
lints that work on MIR nodes have their own methods for running.
- Example: The [`arithmetic_overflow`] lint is emitted when it detects a
constant value that may overflow.
Most lints work well via the pass systems, and they have a fairly
straightforward interface and easy way to integrate (mostly just implementing
a specific `check` function). However, some lints are easier to write when
they live on a specific code path anywhere in the compiler. For example, the
[`unused_mut`] lint is implemented in the borrow checker as it requires some
information and state in the borrow checker.