Skip to content

Commit 43a898d

Browse files
committed
Add type field to json diagnostic outputs
Currently the json-formatted outputs have no way to unambiguously determine which kind of message is being output. A consumer can look for specific fields in the json object (eg "message"), but there's no guarantee that in future some other kind of output will have a field of the same name. This PR adds a `"type"` field to add json outputs which can be used to unambiguously determine which kind of output it is. The mapping is: diagnostic: regular compiler diagnostics artifact: artifact notifications future_incompat: Report of future incompatibility unused_extern: Unused crate warnings/errors This matches the "internally tagged" representation for serde enums.
1 parent b0b8c52 commit 43a898d

14 files changed

+59
-58
lines changed

compiler/rustc_errors/src/json.rs

+25-24
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,27 @@ impl JsonEmitter {
138138
pub fn ui_testing(self, ui_testing: bool) -> Self {
139139
Self { ui_testing, ..self }
140140
}
141+
142+
fn emit(
143+
&mut self,
144+
val: EmitTyped<'_>,
145+
) -> io::Result<()> {
146+
if self.pretty {
147+
writeln!(self.dst, "{}", serde_json::to_string_pretty(&val).unwrap())
148+
} else {
149+
writeln!(self.dst, "{}", serde_json::to_string(&val).unwrap())
150+
}
151+
.and_then(|_| self.dst.flush())
152+
}
153+
}
154+
155+
#[derive(Serialize)]
156+
#[serde(tag = "type", rename_all = "snake_case")]
157+
enum EmitTyped<'a> {
158+
Diagnostic(Diagnostic),
159+
Artifact(ArtifactNotification<'a>),
160+
FutureIncompat(FutureIncompatReport),
161+
UnusedExtern(UnusedExterns<'a, 'a, 'a>),
141162
}
142163

143164
impl Translate for JsonEmitter {
@@ -153,25 +174,15 @@ impl Translate for JsonEmitter {
153174
impl Emitter for JsonEmitter {
154175
fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) {
155176
let data = Diagnostic::from_errors_diagnostic(diag, self);
156-
let result = if self.pretty {
157-
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
158-
} else {
159-
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
160-
}
161-
.and_then(|_| self.dst.flush());
177+
let result = self.emit(EmitTyped::Diagnostic(data));
162178
if let Err(e) = result {
163179
panic!("failed to print diagnostics: {e:?}");
164180
}
165181
}
166182

167183
fn emit_artifact_notification(&mut self, path: &Path, artifact_type: &str) {
168184
let data = ArtifactNotification { artifact: path, emit: artifact_type };
169-
let result = if self.pretty {
170-
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
171-
} else {
172-
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
173-
}
174-
.and_then(|_| self.dst.flush());
185+
let result = self.emit(EmitTyped::Artifact(data));
175186
if let Err(e) = result {
176187
panic!("failed to print notification: {e:?}");
177188
}
@@ -188,12 +199,7 @@ impl Emitter for JsonEmitter {
188199
})
189200
.collect();
190201
let report = FutureIncompatReport { future_incompat_report: data };
191-
let result = if self.pretty {
192-
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&report).unwrap())
193-
} else {
194-
writeln!(&mut self.dst, "{}", serde_json::to_string(&report).unwrap())
195-
}
196-
.and_then(|_| self.dst.flush());
202+
let result = self.emit(EmitTyped::FutureIncompat(report));
197203
if let Err(e) = result {
198204
panic!("failed to print future breakage report: {e:?}");
199205
}
@@ -202,12 +208,7 @@ impl Emitter for JsonEmitter {
202208
fn emit_unused_externs(&mut self, lint_level: rustc_lint_defs::Level, unused_externs: &[&str]) {
203209
let lint_level = lint_level.as_str();
204210
let data = UnusedExterns { lint_level, unused_extern_names: unused_externs };
205-
let result = if self.pretty {
206-
writeln!(&mut self.dst, "{}", serde_json::to_string_pretty(&data).unwrap())
207-
} else {
208-
writeln!(&mut self.dst, "{}", serde_json::to_string(&data).unwrap())
209-
}
210-
.and_then(|_| self.dst.flush());
211+
let result = self.emit(EmitTyped::UnusedExtern(data));
211212
if let Err(e) = result {
212213
panic!("failed to print unused externs: {e:?}");
213214
}

tests/ui/diagnostic-width/flag-json.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
1+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
22

33
Erroneous code examples:
44

@@ -33,8 +33,8 @@ LL | ..._: () = 42;
3333
| expected due to this
3434

3535
"}
36-
{"message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error
36+
{"type":"diagnostic","message":"aborting due to previous error","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to previous error
3737

3838
"}
39-
{"message":"For more information about this error, try `rustc --explain E0308`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0308`.
39+
{"type":"diagnostic","message":"For more information about this error, try `rustc --explain E0308`.","code":null,"level":"failure-note","spans":[],"children":[],"rendered":"For more information about this error, try `rustc --explain E0308`.
4040
"}

tests/ui/json/json-bom-plus-crlf-multifile.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
1+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
22

33
Erroneous code examples:
44

@@ -26,7 +26,7 @@ most common being when calling a function and passing an argument which has a
2626
different type than the matching type in the function declaration.
2727
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":622,"byte_end":622,"line_start":17,"line_end":17,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types
2828
"}
29-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
29+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
3030

3131
Erroneous code examples:
3232

@@ -54,7 +54,7 @@ most common being when calling a function and passing an argument which has a
5454
different type than the matching type in the function declaration.
5555
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":682,"byte_end":682,"line_start":19,"line_end":19,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types
5656
"}
57-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
57+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
5858

5959
Erroneous code examples:
6060

@@ -82,7 +82,7 @@ most common being when calling a function and passing an argument which has a
8282
different type than the matching type in the function declaration.
8383
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":746,"byte_end":746,"line_start":23,"line_end":23,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types
8484
"}
85-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
85+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
8686

8787
Erroneous code examples:
8888

@@ -110,5 +110,5 @@ most common being when calling a function and passing an argument which has a
110110
different type than the matching type in the function declaration.
111111
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":801,"byte_end":809,"line_start":25,"line_end":26,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":" let s : String = (","highlight_start":22,"highlight_end":23},{"text":" ); // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":792,"byte_end":798,"line_start":25,"line_end":25,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:25:22: error[E0308]: mismatched types
112112
"}
113-
{"message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors
113+
{"type":"diagnostic","message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors
114114
"}

tests/ui/json/json-bom-plus-crlf.stderr

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
1+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
22

33
Erroneous code examples:
44

@@ -26,7 +26,7 @@ most common being when calling a function and passing an argument which has a
2626
different type than the matching type in the function declaration.
2727
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":607,"byte_end":607,"line_start":16,"line_end":16,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1; // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types
2828
"}
29-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
29+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
3030

3131
Erroneous code examples:
3232

@@ -54,7 +54,7 @@ most common being when calling a function and passing an argument which has a
5454
different type than the matching type in the function declaration.
5555
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":667,"byte_end":667,"line_start":18,"line_end":18,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":" let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types
5656
"}
57-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
57+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
5858

5959
Erroneous code examples:
6060

@@ -82,7 +82,7 @@ most common being when calling a function and passing an argument which has a
8282
different type than the matching type in the function declaration.
8383
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":731,"byte_end":731,"line_start":22,"line_end":22,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1; // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types
8484
"}
85-
{"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
85+
{"type":"diagnostic","message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
8686

8787
Erroneous code examples:
8888

@@ -110,5 +110,5 @@ most common being when calling a function and passing an argument which has a
110110
different type than the matching type in the function declaration.
111111
"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":786,"byte_end":794,"line_start":24,"line_end":25,"column_start":22,"column_end":6,"is_primary":true,"text":[{"text":" let s : String = (","highlight_start":22,"highlight_end":23},{"text":" ); // Error spanning the newline.","highlight_start":1,"highlight_end":6}],"label":"expected `String`, found `()`","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":777,"byte_end":783,"line_start":24,"line_end":24,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":" let s : String = (","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":"$DIR/json-bom-plus-crlf.rs:24:22: error[E0308]: mismatched types
112112
"}
113-
{"message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors
113+
{"type":"diagnostic","message":"aborting due to 4 previous errors","code":null,"level":"error","spans":[],"children":[],"rendered":"error: aborting due to 4 previous errors
114114
"}

tests/ui/json/json-multiple.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"}
1+
{"type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"}

tests/ui/json/json-options.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"}
1+
{"type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"}

0 commit comments

Comments
 (0)