diff --git a/ipc/codegen/src/codegen.rs b/ipc/codegen/src/codegen.rs index 1744f9a9c..9476c2d0e 100644 --- a/ipc/codegen/src/codegen.rs +++ b/ipc/codegen/src/codegen.rs @@ -298,14 +298,14 @@ fn implement_dispatch_arms( .map(|dispatch| { index = index + 1; implement_dispatch_arm(cx, builder, index as u32, dispatch, buffer, replacements) }).collect() } -fn strip_ptr(ty: &P) -> P { +pub fn strip_ptr(ty: &P) -> P { if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node { ptr_mut.ty.clone() } else { ty.clone() } } -fn has_ptr(ty: &P) -> bool { +pub fn has_ptr(ty: &P) -> bool { if let ast::TyKind::Rptr(_, ref ptr_mut) = ty.node { true } diff --git a/ipc/codegen/src/serialization.rs b/ipc/codegen/src/serialization.rs index 8a5a8716a..a7e172ee1 100644 --- a/ipc/codegen/src/serialization.rs +++ b/ipc/codegen/src/serialization.rs @@ -29,6 +29,8 @@ use syntax::ptr::P; pub struct Error; +use super::codegen; + pub fn expand_serialization_implementation( cx: &mut ExtCtxt, span: Span, @@ -162,7 +164,9 @@ fn binary_expr_struct( ) -> Result { let size_exprs: Vec> = fields.iter().enumerate().map(|(index, field)| { - let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty)); + let field_type_ident = builder.id( + &::syntax::print::pprust::ty_to_string( + &codegen::strip_ptr(&field.ty))); let index_ident = builder.id(format!("__field{}", index)); value_ident.and_then(|x| { let field_id = builder.id(field.ident.unwrap()); @@ -193,7 +197,9 @@ fn binary_expr_struct( map_stmts.push(quote_stmt!(cx, let mut map = vec![0usize; $field_amount];).unwrap()); map_stmts.push(quote_stmt!(cx, let mut total = 0usize;).unwrap()); for (index, field) in fields.iter().enumerate() { - let field_type_ident = builder.id(&::syntax::print::pprust::ty_to_string(&field.ty)); + let field_type_ident = builder.id( + &::syntax::print::pprust::ty_to_string( + &codegen::strip_ptr(&field.ty))); let member_expr = match value_ident { Some(x) => { @@ -225,13 +231,21 @@ fn binary_expr_struct( map_stmts.push(quote_stmt!(cx, total = total + size;).unwrap()); }; - let read_expr = if value_ident.is_some() { - let instance_create = named_fields_sequence(cx, &ty, fields); - quote_expr!(cx, { $map_stmts; $instance_create; Ok(result) }) - } - else { - let map_variant = P(fields_sequence(cx, &ty, fields, &instance_ident.unwrap_or(builder.id("Self")))); - quote_expr!(cx, { $map_stmts; Ok($map_variant) }) + let read_expr = match fields.iter().any(|f| codegen::has_ptr(&f.ty)) { + true => { + // cannot create structs with pointers + quote_expr!(cx, Err(::ipc::binary::BinaryConvertError)) + }, + false => { + if value_ident.is_some() { + let instance_create = named_fields_sequence(cx, &ty, fields); + quote_expr!(cx, { $map_stmts; $instance_create; Ok(result) }) + } + else { + let map_variant = P(fields_sequence(cx, &ty, fields, &instance_ident.unwrap_or(builder.id("Self")))); + quote_expr!(cx, { $map_stmts; Ok($map_variant) }) + } + } }; Ok(BinaryExpressions { @@ -553,6 +567,7 @@ fn binary_expr_variant( )); let (size_expr, write_expr, read_expr) = (binary_expr.size, vec![binary_expr.write], binary_expr.read); + Ok(BinaryArm { size: quote_arm!(cx, $pat => { $size_expr } ), write: quote_arm!(cx, diff --git a/ipc/tests/binary.rs b/ipc/tests/binary.rs index f6bf8d5b5..ab4adee39 100644 --- a/ipc/tests/binary.rs +++ b/ipc/tests/binary.rs @@ -14,6 +14,6 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -#![allow(dead_code, unused_assignments)] // codegen issues +#![allow(dead_code, unused_assignments, unused_variables)] // codegen issues include!(concat!(env!("OUT_DIR"), "/binary.rs")); diff --git a/ipc/tests/binary.rs.in b/ipc/tests/binary.rs.in index 689df8e27..710752237 100644 --- a/ipc/tests/binary.rs.in +++ b/ipc/tests/binary.rs.in @@ -31,3 +31,8 @@ pub struct DoubleRoot { pub x2: u64, pub x3: u32, } + +#[derive(Binary, PartialEq, Debug)] +pub struct ReferenceStruct<'a> { + pub ref_data: &'a u64, +}