about summary refs log tree commit diff
path: root/src/doc
diff options
context:
space:
mode:
authorMark Mansi <markm@cs.wisc.edu>2018-05-22 14:55:55 -0500
committerWho? Me?! <mark-i-m@users.noreply.github.com>2018-05-27 19:44:55 -0500
commit385457dc99728cc382276467ccf5cf127d5572af (patch)
tree6698a17f9d31178180f288c73437e2e7c605fba7 /src/doc
parent96e5a9d04000c7440b90d9a25a0b697c6ac9ea93 (diff)
downloadrust-385457dc99728cc382276467ccf5cf127d5572af.tar.gz
rust-385457dc99728cc382276467ccf5cf127d5572af.zip
Address reviewers' comments
Diffstat (limited to 'src/doc')
-rw-r--r--src/doc/rustc-dev-guide/src/diag.md86
1 files changed, 77 insertions, 9 deletions
diff --git a/src/doc/rustc-dev-guide/src/diag.md b/src/doc/rustc-dev-guide/src/diag.md
index 6679e424941..a2ec3bb7e35 100644
--- a/src/doc/rustc-dev-guide/src/diag.md
+++ b/src/doc/rustc-dev-guide/src/diag.md
@@ -22,12 +22,13 @@ reporting errors.
 
 [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
 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
 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
 
 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
 [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
-let snip = sess.codemap().span_to_snippet(sp);
+let mut err = sess.struct_span_err(sp, "oh no! this is an error!");
+
+if let Some(snippet) = sess.codemap().span_to_snippet(sp) {
+    // Add applicability info!
+    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");
+}
 
-sess.struct_span_err(sp, "oh no! this is an error!")
-    .span_suggestion(other_sp, "try using a qux here", format!("qux {}", snip))
-    .emit();
+err.emit();
 ```
 
 This might emit an error like
 
 ```console
-$ rustc mycode.rs 
+$ rustc mycode.rs
 error[E0999]: oh no! this is an error!
  --> mycode.rs:3:5
   |
@@ -70,10 +115,29 @@ 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`.
+```
+
 ## Lints
 
 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
 
@@ -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,
 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
 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
 
 Lints can be turned on in groups. These groups are declared in the