From 65104aca9cddef98155fe2e2e284077f5cd8e95b Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 11 Dec 2017 17:55:23 -0800 Subject: [PATCH] Remove need for allow(unreachable_code) --- serde_derive/src/de.rs | 26 +++++++++++++++++++------- serde_derive/src/fragment.rs | 9 +++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 8b3ac944..e612c0ac 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -929,7 +929,6 @@ fn deserialize_from_struct( #visit_seq #[inline] - #[allow(unreachable_code)] fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result where __A: _serde::de::MapAccess<#delife> { @@ -2193,12 +2192,25 @@ fn deserialize_from_map( .filter(|&&(field, _)| !field.attrs.skip_deserializing()) .map( |&(field, ref name)| { - let missing_expr = Expr(expr_is_missing(&field, cattrs)); - let field_name = &field.ident; - quote! { - if !#name { - self.dest.#field_name = #missing_expr; - }; + let missing_expr = expr_is_missing(&field, cattrs); + // If missing_expr unconditionally returns an error, don't try + // to assign its value to self.dest. Maybe this could be handled + // more elegantly. + if missing_expr.as_ref().as_str().starts_with("return ") { + let missing_expr = Stmts(missing_expr); + quote! { + if !#name { + #missing_expr; + } + } + } else { + let field_name = &field.ident; + let missing_expr = Expr(missing_expr); + quote! { + if !#name { + self.dest.#field_name = #missing_expr; + }; + } } }, ); diff --git a/serde_derive/src/fragment.rs b/serde_derive/src/fragment.rs index 58cf0a2c..c882bcf9 100644 --- a/serde_derive/src/fragment.rs +++ b/serde_derive/src/fragment.rs @@ -73,3 +73,12 @@ impl ToTokens for Match { } } } + +impl AsRef for Fragment { + fn as_ref(&self) -> &Tokens { + match *self { + Fragment::Expr(ref expr) => expr, + Fragment::Block(ref block) => block, + } + } +}