From 2deacf8eaad547c0aa415b0a07998fddaf0cb702 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 10 Apr 2017 12:12:00 -0700 Subject: [PATCH] Detect incorrect remote type without getter --- serde_derive/src/ser.rs | 21 +++++++++++++++---- .../tests/compile-fail/remote/wrong_ser.rs | 16 ++++++++++++++ 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 test_suite/tests/compile-fail/remote/wrong_ser.rs diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 39c479c2..7b893e44 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -61,11 +61,15 @@ struct Parameters { /// Generics including any explicit and inferred bounds for the impl. generics: syn::Generics, + + /// Type has a `serde(remote = "...")` attribute. + is_remote: bool, } impl Parameters { fn new(item: &Item) -> Self { - let self_var = if item.attrs.remote().is_some() { + let is_remote = item.attrs.remote().is_some(); + let self_var = if is_remote { Ident::new("__self") } else { Ident::new("self") @@ -82,6 +86,7 @@ impl Parameters { self_var: self_var, this: this, generics: generics, + is_remote: is_remote, } } @@ -834,14 +839,22 @@ fn get_field(params: &Parameters, field: &Field, ident: I) -> Tokens where I: Into { let self_var = ¶ms.self_var; - match field.attrs.getter() { - None => { + match (params.is_remote, field.attrs.getter()) { + (false, None) => { let ident = ident.into(); quote!(&#self_var.#ident) } - Some(getter) => { + (true, None) => { + let ty = field.ty; + let ident = ident.into(); + quote!(_serde::private::ser::constrain::<#ty>(&#self_var.#ident)) + } + (true, Some(getter)) => { let ty = field.ty; quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var))) } + (false, Some(_)) => { + unreachable!("getter is only allowed for remote impls"); + } } } diff --git a/test_suite/tests/compile-fail/remote/wrong_ser.rs b/test_suite/tests/compile-fail/remote/wrong_ser.rs new file mode 100644 index 00000000..bd4ca1a2 --- /dev/null +++ b/test_suite/tests/compile-fail/remote/wrong_ser.rs @@ -0,0 +1,16 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + pub a: u16, + } +} + +#[derive(Serialize)] //~ ERROR: mismatched types +#[serde(remote = "remote::S")] +struct S { + a: u8, //~^^^ expected u8, found u16 +} + +fn main() {}