about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2018-01-24 11:50:30 +0530
committerManish Goregaokar <manishsmail@gmail.com>2018-01-29 11:41:03 +0530
commit540f95d9fad41a605e4c8b898d77f47374a76cbd (patch)
treef8b26690a103e16aec8df59b458e702700899fc7
parenta53bdc6212b9abf8538a877ebfde214120bf061f (diff)
downloadrust-540f95d9fad41a605e4c8b898d77f47374a76cbd.tar.gz
rust-540f95d9fad41a605e4c8b898d77f47374a76cbd.zip
Add internal-only rustc_serialize_exclude_null attribute for making the field only exist in the json if the flag is passed
-rw-r--r--src/libsyntax/feature_gate.rs5
-rw-r--r--src/libsyntax/json.rs2
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax_ext/deriving/encodable.rs16
4 files changed, 22 insertions, 2 deletions
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 9a2560b0458..3e523fca92a 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -788,6 +788,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                                        is just used for rustc unit tests \
                                                        and will never be stable",
                                                       cfg_fn!(rustc_attrs))),
+    ("rustc_serialize_exclude_null", Normal, Gated(Stability::Unstable,
+                                             "rustc_attrs",
+                                             "the `#[rustc_serialize_exclude_null]` attribute \
+                                              is an internal-only feature",
+                                             cfg_fn!(rustc_attrs))),
     ("rustc_synthetic", Whitelisted, Gated(Stability::Unstable,
                                                       "rustc_attrs",
                                                       "this attribute \
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 7a8717ada4c..681e14a6137 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -108,6 +108,7 @@ struct Diagnostic {
 }
 
 #[derive(RustcEncodable)]
+#[allow(unused_attributes)]
 struct DiagnosticSpan {
     file_name: String,
     byte_start: u32,
@@ -129,6 +130,7 @@ struct DiagnosticSpan {
     /// that should be sliced in atop this span.
     suggested_replacement: Option<String>,
     /// If the suggestion is approximate
+    #[rustc_serialize_exclude_null]
     suggestion_approximate: Option<bool>,
     /// Macro invocations that created the code at this span, if any.
     expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 3b4c5da10f2..9181cca215c 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -25,6 +25,7 @@
 #![feature(match_default_bindings)]
 #![feature(i128_type)]
 #![feature(const_atomic_usize_new)]
+#![feature(rustc_attrs)]
 
 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
 #[allow(unused_extern_crates)]
diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs
index 0e6e96438d8..743f22b6b31 100644
--- a/src/libsyntax_ext/deriving/encodable.rs
+++ b/src/libsyntax_ext/deriving/encodable.rs
@@ -190,7 +190,7 @@ fn encodable_substructure(cx: &mut ExtCtxt,
         Struct(_, ref fields) => {
             let emit_struct_field = cx.ident_of("emit_struct_field");
             let mut stmts = Vec::new();
-            for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
+            for (i, &FieldInfo { name, ref self_, span, attrs, .. }) in fields.iter().enumerate() {
                 let name = match name {
                     Some(id) => id.name,
                     None => Symbol::intern(&format!("_field{}", i)),
@@ -212,7 +212,19 @@ fn encodable_substructure(cx: &mut ExtCtxt,
                 } else {
                     cx.expr(span, ExprKind::Ret(Some(call)))
                 };
-                stmts.push(cx.stmt_expr(call));
+
+                // This exists for https://github.com/rust-lang/rust/pull/47540
+                //
+                // If we decide to stabilize that flag this can be removed
+                let expr = if attrs.iter().any(|a| a.check_name("rustc_serialize_exclude_null")) {
+                    let is_some = cx.ident_of("is_some");
+                    let condition = cx.expr_method_call(span, self_.clone(), is_some, vec![]);
+                    cx.expr_if(span, condition, call, None)
+                } else {
+                    call
+                };
+                let stmt = cx.stmt_expr(expr);
+                stmts.push(stmt);
             }
 
             // unit structs have no fields and need to return Ok()