diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 136da8e9f..a50010ca3 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -2882,13 +2882,14 @@ fn wrap_deserialize_with( let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params); let delife = params.borrowed.de_lifetime(); + let deserializer_var = quote!(__deserializer); // If #deserialize_with returns wrong type, error will be reported here (^^^^^). // We attach span of the path to the function so it will be reported // on the #[serde(with = "...")] // ^^^^^ let value = quote_spanned! {deserialize_with.span()=> - #deserialize_with(__deserializer)? + #deserialize_with(#deserializer_var)? }; let wrapper = quote! { #[doc(hidden)] @@ -2899,7 +2900,7 @@ fn wrap_deserialize_with( } impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause { - fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result + fn deserialize<__D>(#deserializer_var: __D) -> _serde::__private::Result where __D: _serde::Deserializer<#delife>, { diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 191c0def9..47384f16f 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -1220,12 +1220,15 @@ fn wrap_serialize_with( }) }); + let self_var = quote!(self); + let serializer_var = quote!(__s); + // If #serialize_with returns wrong type, error will be reported on here. // We attach span of the path to this piece so error will be reported // on the #[serde(with = "...")] // ^^^^^ let wrapper_serialize = quote_spanned! {serialize_with.span()=> - #serialize_with(#(self.values.#field_access, )* __s) + #serialize_with(#(#self_var.values.#field_access, )* #serializer_var) }; quote!({ @@ -1236,7 +1239,7 @@ fn wrap_serialize_with( } impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { - fn serialize<__S>(&self, __s: __S) -> _serde::__private::Result<__S::Ok, __S::Error> + fn serialize<__S>(&#self_var, #serializer_var: __S) -> _serde::__private::Result<__S::Ok, __S::Error> where __S: _serde::Serializer, { diff --git a/test_suite/tests/regression/issue2844.rs b/test_suite/tests/regression/issue2844.rs new file mode 100644 index 000000000..492718c8b --- /dev/null +++ b/test_suite/tests/regression/issue2844.rs @@ -0,0 +1,31 @@ +use serde_derive::{Deserialize, Serialize}; + +macro_rules! declare_in_macro { + ($with:literal) => { + #[derive(Serialize, Deserialize)] + pub struct S { + #[serde(with = $with)] + f: i32, + } + }; +} + +declare_in_macro!("with"); + +mod with { + use serde::{Deserializer, Serializer}; + + pub fn serialize(_: &i32, _: S) -> Result + where + S: Serializer, + { + unimplemented!() + } + + pub fn deserialize<'de, D>(_: D) -> Result + where + D: Deserializer<'de>, + { + unimplemented!() + } +} diff --git a/test_suite/tests/ui/with/incorrect_type.stderr b/test_suite/tests/ui/with/incorrect_type.stderr index d974fa4a1..cfddf1cec 100644 --- a/test_suite/tests/ui/with/incorrect_type.stderr +++ b/test_suite/tests/ui/with/incorrect_type.stderr @@ -19,8 +19,10 @@ note: required by a bound in `w::serialize` error[E0061]: this function takes 1 argument but 2 arguments were supplied --> tests/ui/with/incorrect_type.rs:15:25 | +14 | #[derive(Serialize, Deserialize)] + | --------- unexpected argument #2 of type `__S` 15 | struct W(#[serde(with = "w")] u8, u8); - | ^^^ unexpected argument #2 of type `__S` + | ^^^ | note: function defined here --> tests/ui/with/incorrect_type.rs:9:12 @@ -68,8 +70,10 @@ note: required by a bound in `w::serialize` error[E0061]: this function takes 1 argument but 2 arguments were supplied --> tests/ui/with/incorrect_type.rs:18:35 | +17 | #[derive(Serialize, Deserialize)] + | --------- unexpected argument #2 of type `__S` 18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8); - | ^^^^^^^^^^^^^^ unexpected argument #2 of type `__S` + | ^^^^^^^^^^^^^^ | note: function defined here --> tests/ui/with/incorrect_type.rs:9:12