Address reviewers' comments
This commit is contained in:
parent
750267798f
commit
9fe44f3f5a
86
src/diag.md
86
src/diag.md
|
|
@ -22,12 +22,13 @@ reporting errors.
|
||||||
|
|
||||||
[errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html
|
[errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html
|
||||||
|
|
||||||
Most "session"-like types in the compiler (e.g. [`Session`][session]) have
|
[`Session`][session] and [`ParseSess`][parsesses] have
|
||||||
methods (or fields with methods) that allow reporting errors. These methods
|
methods (or fields with methods) that allow reporting errors. These methods
|
||||||
usually have names like `span_err` or `struct_span_err` or `span_warn`, etc...
|
usually have names like `span_err` or `struct_span_err` or `span_warn`, etc...
|
||||||
There are lots of them; they emit different types of "errors", such as
|
There are lots of them; they emit different types of "errors", such as
|
||||||
warnings, errors, fatal errors, suggestions, etc.
|
warnings, errors, fatal errors, suggestions, etc.
|
||||||
|
|
||||||
|
[parsesses]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax/parse/struct.ParseSess.html
|
||||||
[session]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/session/struct.Session.html
|
[session]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/session/struct.Session.html
|
||||||
|
|
||||||
In general, there are two class of such methods: ones that emit an error
|
In general, there are two class of such methods: ones that emit an error
|
||||||
|
|
@ -45,20 +46,64 @@ before emitting it by calling the [`emit`][emit] method. See the
|
||||||
[diagbuild]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html
|
[diagbuild]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html
|
||||||
[emit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html#method.emit
|
[emit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html#method.emit
|
||||||
|
|
||||||
For example, to add a help message to an error, one might do:
|
```rust,ignore
|
||||||
|
// Get a DiagnosticBuilder. This does _not_ emit an error yet.
|
||||||
|
let mut err = sess.struct_span_err(sp, "oh no! this is an error!");
|
||||||
|
|
||||||
|
// In some cases, you might need to check if `sp` is generated by a macro to
|
||||||
|
// avoid printing weird errors about macro-generated code.
|
||||||
|
|
||||||
|
if let Some(snippet) = sess.codemap().span_to_snippet(sp) {
|
||||||
|
// Use the snippet to generate a suggested fix
|
||||||
|
err.span_suggestion(suggestion_sp, "try using a qux here", format!("qux {}", snip));
|
||||||
|
} else {
|
||||||
|
// If we weren't able to generate a snippet, then emit a "help" message
|
||||||
|
// instead of a concrete "suggestion". In practice this is unlikely to be
|
||||||
|
// reached.
|
||||||
|
err.span_help(suggestion_sp, "you could use a qux here instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
// emit the error
|
||||||
|
err.emit();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Suggestions
|
||||||
|
|
||||||
|
We would like to make edition transitions as smooth as possible. To that end,
|
||||||
|
`rustfix` can use compiler suggestions to automatically fix code. For example,
|
||||||
|
we could use `rustfix` to mechanically apply the `qux` suggestion from the
|
||||||
|
previous example. However, not all suggestions are mechanically applicable. We
|
||||||
|
use the [`span_suggestion_with_applicability`][sswa] method of
|
||||||
|
`DiagnosticBuilder` to inform the emitter of whether a suggestion is
|
||||||
|
mechanically applicable or not. This information, in turn, is outputed by
|
||||||
|
rustc when the error format is `json`, which is used by `rustfix`.
|
||||||
|
|
||||||
|
[sswa]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagnosticBuilder.html#method.span_suggestion_with_applicability
|
||||||
|
|
||||||
|
For example, to make our `qux` suggestion machine-applicable, we would do:
|
||||||
|
|
||||||
```rust,ignore
|
```rust,ignore
|
||||||
let snip = sess.codemap().span_to_snippet(sp);
|
let mut err = sess.struct_span_err(sp, "oh no! this is an error!");
|
||||||
|
|
||||||
sess.struct_span_err(sp, "oh no! this is an error!")
|
if let Some(snippet) = sess.codemap().span_to_snippet(sp) {
|
||||||
.span_suggestion(other_sp, "try using a qux here", format!("qux {}", snip))
|
// Add applicability info!
|
||||||
.emit();
|
err.span_suggestion_with_applicability(
|
||||||
|
suggestion_sp,
|
||||||
|
"try using a qux here",
|
||||||
|
format!("qux {}", snip),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
err.span_help(suggestion_sp, "you could use a qux here instead");
|
||||||
|
}
|
||||||
|
|
||||||
|
err.emit();
|
||||||
```
|
```
|
||||||
|
|
||||||
This might emit an error like
|
This might emit an error like
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ rustc mycode.rs
|
$ rustc mycode.rs
|
||||||
error[E0999]: oh no! this is an error!
|
error[E0999]: oh no! this is an error!
|
||||||
--> mycode.rs:3:5
|
--> mycode.rs:3:5
|
||||||
|
|
|
|
||||||
|
|
@ -70,10 +115,29 @@ error: aborting due to previous error
|
||||||
For more information about this error, try `rustc --explain E0999`.
|
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`.
|
||||||
|
```
|
||||||
|
|
||||||
## Lints
|
## Lints
|
||||||
|
|
||||||
The compiler linting infrastructure is defined in the [`rustc::lint`][rlint]
|
The compiler linting infrastructure is defined in the [`rustc::lint`][rlint]
|
||||||
module.
|
module.
|
||||||
|
|
||||||
[rlint]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/index.html
|
[rlint]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/index.html
|
||||||
|
|
||||||
|
|
@ -138,7 +202,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Edition Lints
|
### Edition-gated Lints
|
||||||
|
|
||||||
Sometimes we want to change the behavior of a lint in a new edition. To do this,
|
Sometimes we want to change the behavior of a lint in a new edition. To do this,
|
||||||
we just add the transition to our invocation of `declare_lint!`:
|
we just add the transition to our invocation of `declare_lint!`:
|
||||||
|
|
@ -155,6 +219,10 @@ declare_lint! {
|
||||||
This makes the `ANONYMOUS_PARAMETERS` lint allow-by-default in the 2015 edition
|
This makes the `ANONYMOUS_PARAMETERS` lint allow-by-default in the 2015 edition
|
||||||
but warn-by-default in the 2018 edition.
|
but warn-by-default in the 2018 edition.
|
||||||
|
|
||||||
|
Lints that represent an incompatibility (i.e. error) in the upcoming edition should
|
||||||
|
also be registered as `FutureIncompatibilityLint`s in
|
||||||
|
[`register_builtins`][rbuiltins] function in [`rustc_lint::lib`][builtin].
|
||||||
|
|
||||||
### Lint Groups
|
### Lint Groups
|
||||||
|
|
||||||
Lints can be turned on in groups. These groups are declared in the
|
Lints can be turned on in groups. These groups are declared in the
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue