Skip to content

Commit

Permalink
Correctly process skipped fields in visit_newtype_struct
Browse files Browse the repository at this point in the history
Changes in generated code (see the file attached to PR):
  Tuple1as0:
  Tuple1as0Default:
  Tuple1as0With:
    fixed visit_newtype_struct: use default value instead of deserializing it

This fixes compilation error for Deserialize side of Tuple1as0(Skipped) tuple
  • Loading branch information
Mingun committed Oct 25, 2024
1 parent 8b68ced commit e946309
Showing 1 changed file with 65 additions and 30 deletions.
95 changes: 65 additions & 30 deletions serde_derive/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,40 +509,41 @@ fn deserialize_tuple(

let visit_newtype_struct = match form {
TupleForm::Tuple if nfields == 1 => {
let field = &fields[0];
let field_ty = field.ty;

let deserialize = match field.attrs.deserialize_with() {
None => {
let span = field.original.span();
quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize)
}
Some(path) => {
// If #path 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 = "...")]
// ^^^^^
quote_spanned!(path.span()=> #path)
}
};
let visit_newtype_struct = Stmts(read_fields_in_order(
&type_path,
params,
fields,
false,
cattrs,
expecting,
|_, _, field, _, _| {
let deserialize = match field.attrs.deserialize_with() {
None => {
let field_ty = field.ty;

let mut result = quote!(#type_path(__field0));
if params.has_getter {
let this_type = &params.this_type;
let (_, ty_generics, _) = params.generics.split_for_impl();
result = quote! {
_serde::__private::Into::<#this_type #ty_generics>::into(#result)
};
}
let span = field.original.span();
quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize)
}
Some(path) => {
// If #path 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 = "...")]
// ^^^^^
quote_spanned!(path.span()=> #path)
}
};
// __e cannot be in quote_spanned! because of macro hygiene
quote!(#deserialize(__e)?)
},
));

Some(quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
where
__E: _serde::Deserializer<#delife>,
{
let __field0: #field_ty = #deserialize(__e)?;
_serde::__private::Ok(#result)
#visit_newtype_struct
}
})
}
Expand Down Expand Up @@ -648,17 +649,51 @@ fn deserialize_tuple_in_place(
let nfields = fields.len();

let visit_newtype_struct = if nfields == 1 {
// We do not generate deserialize_in_place if every field has a
// deserialize_with.
assert!(fields[0].attrs.deserialize_with().is_none());
// We deserialize newtype, so only one field is not skipped
let index = fields
.iter()
.position(|field| !field.attrs.skip_deserializing())
.unwrap_or(0);
let index = Index::from(index);
let mut deserialize = quote! {
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.#index)
};
let write_defaults = fields.iter().enumerate().filter_map(|(index, field)| {
if field.attrs.skip_deserializing() {
let index = Index::from(index);
let default = Expr(expr_is_missing(field, cattrs));
return Some(quote!(self.place.#index = #default;));
}
None
});
// If there are no deserialized fields, write only defaults
if field_count == 0 {
deserialize = quote! {
#(#write_defaults)*
_serde::__private::Ok(())
}
} else
// Deserialize and write defaults if at least one field is skipped,
// otherwise only deserialize
if nfields > field_count {
deserialize = quote! {
match #deserialize {
_serde::__private::Ok(_) => {
#(#write_defaults)*
_serde::__private::Ok(())
}
_serde::__private::Err(__err) => _serde::__private::Err(__err),
}
}
}

Some(quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
where
__E: _serde::Deserializer<#delife>,
{
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
#deserialize
}
})
} else {
Expand Down

0 comments on commit e946309

Please sign in to comment.