Fix hygiene of macro-generated local variable accesses in serde(with) wrappers

This commit is contained in:
David Tolnay 2024-10-22 09:35:52 -07:00
parent 0058c7226e
commit 1e36ef551d
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
3 changed files with 14 additions and 6 deletions

View File

@ -2882,13 +2882,14 @@ fn wrap_deserialize_with(
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
split_with_de_lifetime(params); split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
let deserializer_var = quote!(__deserializer);
// If #deserialize_with returns wrong type, error will be reported here (^^^^^). // 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 // We attach span of the path to the function so it will be reported
// on the #[serde(with = "...")] // on the #[serde(with = "...")]
// ^^^^^ // ^^^^^
let value = quote_spanned! {deserialize_with.span()=> let value = quote_spanned! {deserialize_with.span()=>
#deserialize_with(__deserializer)? #deserialize_with(#deserializer_var)?
}; };
let wrapper = quote! { let wrapper = quote! {
#[doc(hidden)] #[doc(hidden)]
@ -2899,7 +2900,7 @@ fn wrap_deserialize_with(
} }
impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause { impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error> fn deserialize<__D>(#deserializer_var: __D) -> _serde::__private::Result<Self, __D::Error>
where where
__D: _serde::Deserializer<#delife>, __D: _serde::Deserializer<#delife>,
{ {

View File

@ -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. // 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 // We attach span of the path to this piece so error will be reported
// on the #[serde(with = "...")] // on the #[serde(with = "...")]
// ^^^^^ // ^^^^^
let wrapper_serialize = quote_spanned! {serialize_with.span()=> 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!({ quote!({
@ -1236,7 +1239,7 @@ fn wrap_serialize_with(
} }
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause { 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 where
__S: _serde::Serializer, __S: _serde::Serializer,
{ {

View File

@ -19,8 +19,10 @@ note: required by a bound in `w::serialize`
error[E0061]: this function takes 1 argument but 2 arguments were supplied error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> tests/ui/with/incorrect_type.rs:15:25 --> 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); 15 | struct W(#[serde(with = "w")] u8, u8);
| ^^^ unexpected argument #2 of type `__S` | ^^^
| |
note: function defined here note: function defined here
--> tests/ui/with/incorrect_type.rs:9:12 --> 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 error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> tests/ui/with/incorrect_type.rs:18:35 --> 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); 18 | struct S(#[serde(serialize_with = "w::serialize")] u8, u8);
| ^^^^^^^^^^^^^^ unexpected argument #2 of type `__S` | ^^^^^^^^^^^^^^
| |
note: function defined here note: function defined here
--> tests/ui/with/incorrect_type.rs:9:12 --> tests/ui/with/incorrect_type.rs:9:12