From f04ea6c7e1cdac012b31efcd97973f426571a97a Mon Sep 17 00:00:00 2001
From: Eric Huss <eric@huss.org>
Date: Mon, 30 Sep 2019 10:59:32 -0700
Subject: [PATCH] Document JSON message output.

---
 src/doc/rustc/src/SUMMARY.md                |   1 +
 src/doc/rustc/src/command-line-arguments.md |   9 +-
 src/doc/rustc/src/json.md                   | 231 ++++++++++++++++++++
 3 files changed, 240 insertions(+), 1 deletion(-)
 create mode 100644 src/doc/rustc/src/json.md

diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 3cda8d927973c..d5564fd798f39 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -10,6 +10,7 @@
         - [Warn-by-default lints](lints/listing/warn-by-default.md)
         - [Deny-by-default lints](lints/listing/deny-by-default.md)
 - [Codegen options](codegen-options/index.md)
+- [JSON Output](json.md)
 - [Targets](targets/index.md)
     - [Built-in Targets](targets/built-in.md)
     - [Custom Targets](targets/custom.md)
diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md
index 5eea9c8687900..b2cc65c11fd2c 100644
--- a/src/doc/rustc/src/command-line-arguments.md
+++ b/src/doc/rustc/src/command-line-arguments.md
@@ -92,6 +92,7 @@ information about editions may be found in the [edition guide].
 [edition guide]: ../edition-guide/introduction.html
 
 ## `--emit`: specifies the types of output files to generate
+ <a id="option-emit"></a>
 
 This flag controls the types of output files generated by the compiler. It
 accepts a comma-separated list of values, and may be specified multiple times.
@@ -241,12 +242,13 @@ The "sysroot" is where `rustc` looks for the crates that come with the Rust
 distribution; this flag allows that to be overridden.
 
 ## `--error-format`: control how errors are produced
+ <a id="option-error-format"></a>
 
 This flag lets you control the format of messages. Messages are printed to
 stderr. The valid options are:
 
 - `human` — Human-readable output. This is the default.
-- `json` — Structured JSON output.
+- `json` — Structured JSON output. See [the JSON chapter] for more detail.
 - `short` — Short, one-line messages.
 
 ## `--color`: configure coloring of output
@@ -273,6 +275,7 @@ pathname syntax. For example `--remap-path-prefix foo=bar` will match
 `foo/lib.rs` but not `./foo/lib.rs`.
 
 ## `--json`: configure json messages printed by the compiler
+ <a id="option-json"></a>
 
 When the `--error-format=json` option is passed to rustc then all of the
 compiler's diagnostic output will be emitted in the form of JSON blobs. The
@@ -305,9 +308,13 @@ to customize the output:
 Note that it is invalid to combine the `--json` argument with the `--color`
 argument, and it is required to combine `--json` with `--error-format=json`.
 
+See [the JSON chapter] for more detail.
+
 ## `@path`: load command-line flags from a path
 
 If you specify `@path` on the command-line, then it will open `path` and read
 command line options from it. These options are one per line; a blank line indicates
 an empty option. The file can use Unix or Windows style line endings, and must be
 encoded as UTF-8.
+
+[the JSON chapter]: json.md
diff --git a/src/doc/rustc/src/json.md b/src/doc/rustc/src/json.md
new file mode 100644
index 0000000000000..b737849516310
--- /dev/null
+++ b/src/doc/rustc/src/json.md
@@ -0,0 +1,231 @@
+# JSON Output
+
+This chapter documents the JSON structures emitted by `rustc`. JSON may be
+enabled with the [`--error-format=json` flag][option-error-format]. Additional
+options may be specified with the [`--json` flag][option-json] which can
+change which messages are generated, and the format of the messages.
+
+JSON messages are emitted one per line to stderr.
+
+If parsing the output with Rust, the
+[`cargo_metadata`](https://crates.io/crates/cargo_metadata) crate provides
+some support for parsing the messages.
+
+When parsing, care should be taken to be forwards-compatible with future changes
+to the format. Optional values may be `null`. New fields may be added. Enumerated
+fields like "level" or "suggestion_applicability" may add new values.
+
+## Diagnostics
+
+Diagnostic messages provide errors or possible concerns generated during
+compilation. `rustc` provides detailed information about where the diagnostic
+originates, along with hints and suggestions.
+
+Diagnostics are arranged in a parent/child relationship where the parent
+diagnostic value is the core of the diagnostic, and the attached children
+provide additional context, help, and information.
+
+Diagnostics have the following format:
+
+```javascript
+{
+    /* The primary message. */
+    "message": "unused variable: `x`",
+    /* The diagnostic code.
+       Some messages may set this value to null.
+    */
+    "code": {
+        /* A unique string identifying which diagnostic triggered. */
+        "code": "unused_variables",
+        /* An optional string explaining more detail about the diagnostic code. */
+        "explanation": null
+    },
+    /* The severity of the diagnostic.
+       Values may be:
+       - "error": A fatal error that prevents compilation.
+       - "warning": A possible error or concern.
+       - "note": Additional information or context about the diagnostic.
+       - "help": A suggestion on how to resolve the diagnostic.
+       - "failure-note": A note attached to the message for further information.
+       - "error: internal compiler error": Indicates a bug within the compiler.
+    */
+    "level": "warning",
+    /* An array of source code locations to point out specific details about
+       where the diagnostic originates from. This may be empty, for example
+       for some global messages, or child messages attached to a parent.
+
+       Character offsets are offsets of Unicode Scalar Values.
+    */
+    "spans": [
+        {
+            /* The file where the span is located.
+               For spans located within a macro expansion, this will be the
+               name of the expanded macro in the format "<MACRONAME macros>".
+            */
+            "file_name": "lib.rs",
+            /* The byte offset where the span starts (0-based, inclusive). */
+            "byte_start": 21,
+            /* The byte offset where the span ends (0-based, exclusive). */
+            "byte_end": 22,
+            /* The first line number of the span (1-based, inclusive). */
+            "line_start": 2,
+            /* The last line number of the span (1-based, inclusive). */
+            "line_end": 2,
+            /* The first character offset of the line_start (1-based, inclusive). */
+            "column_start": 9,
+            /* The last character offset of the line_end (1-based, exclusive). */
+            "column_end": 10,
+            /* Whether or not this is the "primary" span.
+
+               This indicates that this span is the focal point of the
+               diagnostic.
+
+               There are rare cases where multiple spans may be marked as
+               primary. For example, "immutable borrow occurs here" and
+               "mutable borrow ends here" can be two separate primary spans.
+
+               The top (parent) message should always have at least one
+               primary span, unless it has zero spans. Child messages may have
+               zero or more primary spans.
+            */
+            "is_primary": true,
+            /* An array of objects showing the original source code for this
+               span. This shows the entire lines of text where the span is
+               located. A span across multiple lines will have a separate
+               value for each line.
+            */
+            "text": [
+                {
+                    /* The entire line of the original source code. */
+                    "text": "    let x = 123;",
+                    /* The first character offset of the line of
+                       where the span covers this line (1-based, inclusive). */
+                    "highlight_start": 9,
+                    /* The last character offset of the line of
+                       where the span covers this line (1-based, exclusive). */
+                    "highlight_end": 10
+                }
+            ],
+            /* An optional message to display at this span location.
+               This is typically null for primary spans.
+            */
+            "label": null,
+            /* An optional string of a suggested replacement for this span to
+               solve the issue. Tools may try to replace the contents of the
+               span with this text.
+            */
+            "suggested_replacement": null,
+            /* An optional string that indicates the confidence of the
+               "suggested_replacement". Tools may use this value to determine
+               whether or not suggestions should be automatically applied.
+
+               Possible values may be:
+               - "MachineApplicable": The suggestion is definitely what the
+                 user intended. This suggestion should be automatically
+                 applied.
+               - "MaybeIncorrect": The suggestion may be what the user
+                 intended, but it is uncertain. The suggestion should result
+                 in valid Rust code if it is applied.
+               - "HasPlaceholders": The suggestion contains placeholders like
+                 `(...)`. The suggestion cannot be applied automatically
+                 because it will not result in valid Rust code. The user will
+                 need to fill in the placeholders.
+               - "Unspecified": The applicability of the suggestion is unknown.
+            */
+            "suggestion_applicability": null,
+            /* An optional object indicating the expansion of a macro within
+               this span.
+
+               If a message occurs within a macro invocation, this object will
+               provide details of where within the macro expansion the message
+               is located.
+            */
+            "expansion": {
+                /* The span of the macro invocation.
+                   Uses the same span definition as the "spans" array.
+                */
+                "span": {/*...*/}
+                /* Name of the macro, such as "foo!" or "#[derive(Eq)]". */
+                "macro_decl_name": "some_macro!",
+                /* Optional span where the relevant part of the macro is
+                  defined. */
+                "def_site_span": {/*...*/},
+            }
+        }
+    ],
+    /* Array of attached diagnostic messages.
+       This is an array of objects using the same format as the parent
+       message. Children are not nested (children do not themselves
+       contain "children" definitions).
+    */
+    "children": [
+        {
+            "message": "`#[warn(unused_variables)]` on by default",
+            "code": null,
+            "level": "note",
+            "spans": [],
+            "children": [],
+            "rendered": null
+        },
+        {
+            "message": "consider prefixing with an underscore",
+            "code": null,
+            "level": "help",
+            "spans": [
+                {
+                    "file_name": "lib.rs",
+                    "byte_start": 21,
+                    "byte_end": 22,
+                    "line_start": 2,
+                    "line_end": 2,
+                    "column_start": 9,
+                    "column_end": 10,
+                    "is_primary": true,
+                    "text": [
+                        {
+                            "text": "    let x = 123;",
+                            "highlight_start": 9,
+                            "highlight_end": 10
+                        }
+                    ],
+                    "label": null,
+                    "suggested_replacement": "_x",
+                    "suggestion_applicability": "MachineApplicable",
+                    "expansion": null
+                }
+            ],
+            "children": [],
+            "rendered": null
+        }
+    ],
+    /* Optional string of the rendered version of the diagnostic as displayed
+       by rustc. Note that this may be influenced by the `--json` flag.
+    */
+    "rendered": "warning: unused variable: `x`\n --> lib.rs:2:9\n  |\n2 |     let x = 123;\n  |         ^ help: consider prefixing with an underscore: `_x`\n  |\n  = note: `#[warn(unused_variables)]` on by default\n\n"
+}
+```
+
+## Artifact notifications
+
+Artifact notifications are emitted when the [`--json=artifacts`
+flag][option-json] is used. They indicate that a file artifact has been saved
+to disk. More information about emit kinds may be found in the [`--emit`
+flag][option-emit] documentation.
+
+```javascript
+{
+    /* The filename that was generated. */
+    "artifact": "libfoo.rlib",
+    /* The kind of artifact that was generated. Possible values:
+       - "link": The generated crate as specified by the crate-type.
+       - "dep-info": The `.d` file with dependency information in a Makefile-like syntax.
+       - "metadata": The Rust `.rmeta` file containing metadata about the crate.
+       - "save-analysis": A JSON file emitted by the `-Zsave-analysis` feature.
+    */
+    "emit": "link"
+}
+```
+
+[option-emit]: command-line-arguments.md#option-emit
+[option-error-format]: command-line-arguments.md#option-error-format
+[option-json]: command-line-arguments.md#option-json