From 9d8987bde88b48b2f0668f80bdcdd140ddd4fd0f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 9 Apr 2017 10:59:54 -0700 Subject: [PATCH] Require getters to return the correct type --- serde/src/private/ser.rs | 6 +++++ serde_derive/src/ser.rs | 5 +++- .../tests/compile-fail/remote/wrong_getter.rs | 23 +++++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test_suite/tests/compile-fail/remote/wrong_getter.rs diff --git a/serde/src/private/ser.rs b/serde/src/private/ser.rs index c8d09d0b..333cb742 100644 --- a/serde/src/private/ser.rs +++ b/serde/src/private/ser.rs @@ -8,6 +8,12 @@ use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMap #[cfg(feature = "std")] use std::error; +/// Used to check that serde(getter) attributes return the expected type. +/// Not public API. +pub fn constrain(t: &T) -> &T { + t +} + /// Not public API. pub fn serialize_tagged_newtype(serializer: S, type_ident: &'static str, diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 179c5d99..39c479c2 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -839,6 +839,9 @@ fn get_field(params: &Parameters, field: &Field, ident: I) -> Tokens let ident = ident.into(); quote!(&#self_var.#ident) } - Some(getter) => quote!(&#getter(#self_var)), + Some(getter) => { + let ty = field.ty; + quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var))) + } } } diff --git a/test_suite/tests/compile-fail/remote/wrong_getter.rs b/test_suite/tests/compile-fail/remote/wrong_getter.rs new file mode 100644 index 00000000..f767263d --- /dev/null +++ b/test_suite/tests/compile-fail/remote/wrong_getter.rs @@ -0,0 +1,23 @@ +#[macro_use] +extern crate serde_derive; + +mod remote { + pub struct S { + a: u8, + } + + impl S { + pub fn get(&self) -> u16 { + self.a as u16 + } + } +} + +#[derive(Serialize)] //~ ERROR: mismatched types +#[serde(remote = "remote::S")] +struct S { + #[serde(getter = "remote::S::get")] + a: u8, //~^^^^ expected u8, found u16 +} + +fn main() {}