diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index b7eab3ab..8f4e1ee8 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -16,6 +16,7 @@ use bound; use fragment::{Expr, Fragment, Match, Stmts}; use internals::ast::{Container, Data, Field, Style, Variant}; use internals::{self, attr}; +use try; use std::collections::BTreeSet; @@ -63,10 +64,12 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result #type_path(#value)); + let mut result = quote_spanned!(Span::call_site()=> #type_path(__field0)); if params.has_getter { let this = ¶ms.this; result = quote! { @@ -745,6 +748,7 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result where __E: _serde::Deserializer<#delife> { + let __field0 = #value; _serde::export::Ok(#result) } } diff --git a/serde_derive/src/lib.rs b/serde_derive/src/lib.rs index 1793751d..5fe932ff 100644 --- a/serde_derive/src/lib.rs +++ b/serde_derive/src/lib.rs @@ -58,6 +58,7 @@ mod fragment; mod de; mod ser; +mod try; #[proc_macro_derive(Serialize, attributes(serde))] pub fn derive_serialize(input: TokenStream) -> TokenStream { diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index cf7db09b..992084f6 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -15,6 +15,7 @@ use bound; use fragment::{Fragment, Match, Stmts}; use internals::ast::{Container, Data, Field, Style, Variant}; use internals::{attr, Ctxt}; +use try; use std::u32; @@ -55,10 +56,12 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result Tokens { + // Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it. + let dollar = Op::new('$', Spacing::Alone); + + quote! { + #[allow(unused_macros)] + macro_rules! try { + (#dollar __expr:expr) => { + match #dollar __expr { + _serde::export::Ok(__val) => __val, + _serde::export::Err(__err) => { + return _serde::export::Err(__err); + } + } + } + } + } +}