Skip to content

Commit

Permalink
Auto merge of #536 - serde-rs:mutempty, r=oli-obk
Browse files Browse the repository at this point in the history
Fix "variable does not need to be mutable" warning

Fixes #534.

cc @elidupree
  • Loading branch information
homu committed Sep 5, 2016
2 parents bf779ea + e03deda commit 1ff2053
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
41 changes: 35 additions & 6 deletions serde_codegen/src/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use syntax::ast::{self, Ident, MetaItem};
use syntax::codemap::Span;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ptr::P;
use syntax::tokenstream::TokenTree;

use bound;
use span;
Expand Down Expand Up @@ -226,9 +227,10 @@ fn serialize_tuple_struct(

let type_name = name_expr(builder, item_attrs.name());
let len = serialize_stmts.len();
let let_mut = mut_if(cx, len > 0);

quote_block!(cx, {
let mut state = try!(_serializer.serialize_tuple_struct($type_name, $len));
let $let_mut state = try!(_serializer.serialize_tuple_struct($type_name, $len));
$serialize_stmts
_serializer.serialize_tuple_struct_end(state)
}).unwrap()
Expand All @@ -253,8 +255,14 @@ fn serialize_struct(
);

let type_name = name_expr(builder, item_attrs.name());
let len = fields.iter()

let mut serialized_fields = fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();

let let_mut = mut_if(cx, serialized_fields.peek().is_some());

let len = serialized_fields
.map(|field| {
let ident = field.ident.expect("struct has unnamed fields");
let field_expr = quote_expr!(cx, &self.$ident);
Expand All @@ -267,7 +275,7 @@ fn serialize_struct(
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));

quote_block!(cx, {
let mut state = try!(_serializer.serialize_struct($type_name, $len));
let $let_mut state = try!(_serializer.serialize_struct($type_name, $len));
$serialize_fields
_serializer.serialize_struct_end(state)
}).unwrap()
Expand Down Expand Up @@ -458,9 +466,10 @@ fn serialize_tuple_variant(
);

let len = serialize_stmts.len();
let let_mut = mut_if(cx, len > 0);

quote_block!(cx, {
let mut state = try!(_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, $len));
let $let_mut state = try!(_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, $len));
$serialize_stmts
_serializer.serialize_tuple_variant_end(state)
}).unwrap()
Expand Down Expand Up @@ -488,8 +497,14 @@ fn serialize_struct_variant(
);

let item_name = name_expr(builder, item_attrs.name());
let len = fields.iter()

let mut serialized_fields = fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();

let let_mut = mut_if(cx, serialized_fields.peek().is_some());

let len = serialized_fields
.map(|field| {
let ident = field.ident.expect("struct has unnamed fields");
let field_expr = quote_expr!(cx, $ident);
Expand All @@ -502,7 +517,7 @@ fn serialize_struct_variant(
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));

quote_block!(cx, {
let mut state = try!(_serializer.serialize_struct_variant(
let $let_mut state = try!(_serializer.serialize_struct_variant(
$item_name,
$variant_index,
$variant_name,
Expand Down Expand Up @@ -641,3 +656,17 @@ fn name_expr(
) -> P<ast::Expr> {
builder.expr().str(name.serialize_name())
}

// Serialization of an empty struct results in code like:
//
// let mut state = try!(serializer.serialize_struct("S", 0));
// serializer.serialize_struct_end(state)
//
// where we want to omit the `mut` to avoid a warning.
fn mut_if(cx: &ExtCtxt, is_mut: bool) -> Vec<TokenTree> {
if is_mut {
quote_tokens!(cx, mut)
} else {
Vec::new()
}
}
10 changes: 10 additions & 0 deletions testing/tests/test_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,16 @@ fn test_gen() {
#[serde(bound(deserialize = "T::Owned: Deserialize"))]
struct CowT<'a, T: ?Sized + 'a + ToOwned>(Cow<'a, T>);
assert::<CowT<str>>();

#[derive(Serialize, Deserialize)]
struct EmptyStruct {}
assert::<EmptyStruct>();

#[derive(Serialize, Deserialize)]
enum EmptyEnumVariant {
EmptyStruct {},
}
assert::<EmptyEnumVariant>();
}

//////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 1ff2053

Please sign in to comment.