Detect incorrect remote type without getter

This commit is contained in:
David Tolnay
2017-04-10 12:12:00 -07:00
parent 78f682590a
commit 2deacf8eaa
2 changed files with 33 additions and 4 deletions
+17 -4
View File
@@ -61,11 +61,15 @@ struct Parameters {
/// Generics including any explicit and inferred bounds for the impl. /// Generics including any explicit and inferred bounds for the impl.
generics: syn::Generics, generics: syn::Generics,
/// Type has a `serde(remote = "...")` attribute.
is_remote: bool,
} }
impl Parameters { impl Parameters {
fn new(item: &Item) -> Self { 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") Ident::new("__self")
} else { } else {
Ident::new("self") Ident::new("self")
@@ -82,6 +86,7 @@ impl Parameters {
self_var: self_var, self_var: self_var,
this: this, this: this,
generics: generics, generics: generics,
is_remote: is_remote,
} }
} }
@@ -834,14 +839,22 @@ fn get_field<I>(params: &Parameters, field: &Field, ident: I) -> Tokens
where I: Into<Ident> where I: Into<Ident>
{ {
let self_var = &params.self_var; let self_var = &params.self_var;
match field.attrs.getter() { match (params.is_remote, field.attrs.getter()) {
None => { (false, None) => {
let ident = ident.into(); let ident = ident.into();
quote!(&#self_var.#ident) 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; let ty = field.ty;
quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var))) quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var)))
} }
(false, Some(_)) => {
unreachable!("getter is only allowed for remote impls");
}
} }
} }
@@ -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() {}