Add internal-only rustc_serialize_exclude_null attribute for making the field only exist in the json if the flag is passed

This commit is contained in:
Manish Goregaokar 2018-01-24 11:50:30 +05:30
parent a53bdc6212
commit 540f95d9fa
4 changed files with 22 additions and 2 deletions

View File

@ -788,6 +788,11 @@ pub fn is_builtin_attr(attr: &ast::Attribute) -> bool {
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 \

View File

@ -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>>,

View File

@ -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)]

View File

@ -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()