Skip to content

Commit 8a79f8b

Browse files
committed
Address reviewers' comments
1 parent c6ecc1f commit 8a79f8b

File tree

1 file changed

+77
-9
lines changed

1 file changed

+77
-9
lines changed

src/diag.md

+77-9
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ reporting errors.
2222

2323
[errors]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/index.html
2424

25-
Most "session"-like types in the compiler (e.g. [`Session`][session]) have
25+
[`Session`][session] and [`ParseSess`][parsesses] have
2626
methods (or fields with methods) that allow reporting errors. These methods
2727
usually have names like `span_err` or `struct_span_err` or `span_warn`, etc...
2828
There are lots of them; they emit different types of "errors", such as
2929
warnings, errors, fatal errors, suggestions, etc.
3030

31+
[parsesses]: https://doc.rust-lang.org/nightly/nightly-rustc/syntax/parse/struct.ParseSess.html
3132
[session]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/session/struct.Session.html
3233

3334
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
4546
[diagbuild]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html
4647
[emit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html#method.emit
4748

48-
For example, to add a help message to an error, one might do:
49+
```rust,ignore
50+
// Get a DiagnosticBuilder. This does _not_ emit an error yet.
51+
let mut err = sess.struct_span_err(sp, "oh no! this is an error!");
52+
53+
// In some cases, you might need to check if `sp` is generated by a macro to
54+
// avoid printing weird errors about macro-generated code.
55+
56+
if let Some(snippet) = sess.codemap().span_to_snippet(sp) {
57+
// Use the snippet to generate a suggested fix
58+
err.span_suggestion(suggestion_sp, "try using a qux here", format!("qux {}", snip));
59+
} else {
60+
// If we weren't able to generate a snippet, then emit a "help" message
61+
// instead of a concrete "suggestion". In practice this is unlikely to be
62+
// reached.
63+
err.span_help(suggestion_sp, "you could use a qux here instead");
64+
}
65+
66+
// emit the error
67+
err.emit();
68+
```
69+
70+
## Suggestions
71+
72+
We would like to make edition transitions as smooth as possible. To that end,
73+
`rustfix` can use compiler suggestions to automatically fix code. For example,
74+
we could use `rustfix` to mechanically apply the `qux` suggestion from the
75+
previous example. However, not all suggestions are mechanically applicable. We
76+
use the [`span_suggestion_with_applicability`][sswa] method of
77+
`DiagnosticBuilder` to inform the emitter of whether a suggestion is
78+
mechanically applicable or not. This information, in turn, is outputed by
79+
rustc when the error format is `json`, which is used by `rustfix`.
80+
81+
[sswa]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagnosticBuilder.html#method.span_suggestion_with_applicability
82+
83+
For example, to make our `qux` suggestion machine-applicable, we would do:
4984

5085
```rust,ignore
51-
let snip = sess.codemap().span_to_snippet(sp);
86+
let mut err = sess.struct_span_err(sp, "oh no! this is an error!");
87+
88+
if let Some(snippet) = sess.codemap().span_to_snippet(sp) {
89+
// Add applicability info!
90+
err.span_suggestion_with_applicability(
91+
suggestion_sp,
92+
"try using a qux here",
93+
format!("qux {}", snip),
94+
Applicability::MachineApplicable,
95+
);
96+
} else {
97+
err.span_help(suggestion_sp, "you could use a qux here instead");
98+
}
5299
53-
sess.struct_span_err(sp, "oh no! this is an error!")
54-
.span_suggestion(other_sp, "try using a qux here", format!("qux {}", snip))
55-
.emit();
100+
err.emit();
56101
```
57102

58103
This might emit an error like
59104

60105
```console
61-
$ rustc mycode.rs
106+
$ rustc mycode.rs
62107
error[E0999]: oh no! this is an error!
63108
--> mycode.rs:3:5
64109
|
@@ -70,10 +115,29 @@ error: aborting due to previous error
70115
For more information about this error, try `rustc --explain E0999`.
71116
```
72117

118+
In some cases, like when the suggestion spans multiple lines or when there are
119+
multiple suggestions, the suggestions are displayed on their own:
120+
121+
```console
122+
error[E0999]: oh no! this is an error!
123+
--> mycode.rs:3:5
124+
|
125+
3 | sad()
126+
| ^
127+
help: try using a qux here:
128+
|
129+
3 | qux sad()
130+
| ^^^
131+
132+
error: aborting due to previous error
133+
134+
For more information about this error, try `rustc --explain E0999`.
135+
```
136+
73137
## Lints
74138

75139
The compiler linting infrastructure is defined in the [`rustc::lint`][rlint]
76-
module.
140+
module.
77141

78142
[rlint]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/index.html
79143

@@ -138,7 +202,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue {
138202
}
139203
```
140204

141-
### Edition Lints
205+
### Edition-gated Lints
142206

143207
Sometimes we want to change the behavior of a lint in a new edition. To do this,
144208
we just add the transition to our invocation of `declare_lint!`:
@@ -155,6 +219,10 @@ declare_lint! {
155219
This makes the `ANONYMOUS_PARAMETERS` lint allow-by-default in the 2015 edition
156220
but warn-by-default in the 2018 edition.
157221

222+
Lints that represent an incompatibility (i.e. error) in the upcoming edition should
223+
also be registered as `FutureIncompatibilityLint`s in
224+
[`register_builtins`][rbuiltins] function in [`rustc_lint::lib`][builtin].
225+
158226
### Lint Groups
159227

160228
Lints can be turned on in groups. These groups are declared in the

0 commit comments

Comments
 (0)