diff options
| author | Jeremy Fitzhardinge <jeremy@goop.org> | 2021-01-18 14:10:31 -0800 |
|---|---|---|
| committer | Jeremy Fitzhardinge <jeremy@goop.org> | 2021-02-07 14:54:22 -0800 |
| commit | 50572d66295840ba13aee0cd500c20b9513e77f7 (patch) | |
| tree | 81da7e0ce69f23a750baf4138e3626f3f20934f3 /compiler/rustc_errors/src/json.rs | |
| parent | 82ccb6582a76d72fb5abaf7195dc7a653f1aa54b (diff) | |
| download | rust-50572d66295840ba13aee0cd500c20b9513e77f7.tar.gz rust-50572d66295840ba13aee0cd500c20b9513e77f7.zip | |
Implement Encoder for Diagnostic manually
...so we can skip serializing `tool_metadata` if it hasn't been set. This makes the output a bit cleaner, and avoiding having to update a bunch of unrelated tests.
Diffstat (limited to 'compiler/rustc_errors/src/json.rs')
| -rw-r--r-- | compiler/rustc_errors/src/json.rs | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 89e844879f7..f26c439add9 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -27,6 +27,7 @@ use std::sync::{Arc, Mutex}; use std::vec; use rustc_serialize::json::{as_json, as_pretty_json}; +use rustc_serialize::{Encodable, Encoder}; #[cfg(test)] mod tests; @@ -169,7 +170,8 @@ impl Emitter for JsonEmitter { // The following data types are provided just for serialisation. -#[derive(Encodable)] +// NOTE: this has a manual implementation of Encodable which needs to be updated in +// parallel. struct Diagnostic { /// The primary error message. message: String, @@ -185,6 +187,36 @@ struct Diagnostic { tool_metadata: ToolMetadata, } +macro_rules! encode_fields { + ($enc:expr, $s:expr, $idx:expr, [ $($name:ident),+$(,)? ]) => { + { + let mut idx = $idx; + $( + $enc.emit_struct_field(stringify!($name), idx, |enc| $s.$name.encode(enc))?; + idx += 1; + )+ + idx + } + }; +} + +// Special-case encoder to skip tool_metadata if not set +impl<E: Encoder> Encodable<E> for Diagnostic { + fn encode(&self, s: &mut E) -> Result<(), E::Error> { + s.emit_struct("diagnostic", 7, |s| { + let mut idx = 0; + + idx = encode_fields!(s, self, idx, [message, code, level, spans, children, rendered]); + if self.tool_metadata.is_set() { + idx = encode_fields!(s, self, idx, [tool_metadata]); + } + + let _ = idx; + Ok(()) + }) + } +} + #[derive(Encodable)] struct DiagnosticSpan { file_name: String, |
