diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 002d36e55..5993a60af 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -508,7 +508,7 @@ fn deserialize_tuple( let nfields = fields.len(); let visit_newtype_struct = match form { - TupleForm::Tuple if nfields == 1 => { + TupleForm::Tuple if field_count == 1 => { let visit_newtype_struct = Stmts(read_fields_in_order( &type_path, params, @@ -564,7 +564,7 @@ fn deserialize_tuple( } }; let dispatch = match form { - TupleForm::Tuple if nfields == 1 => { + TupleForm::Tuple if field_count != 0 && nfields == 1 => { let type_name = cattrs.name().deserialize_name(); quote! { _serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr) @@ -648,34 +648,27 @@ fn deserialize_tuple_in_place( let nfields = fields.len(); - let visit_newtype_struct = if !is_enum && nfields == 1 { + let visit_newtype_struct = if !is_enum && field_count == 1 { // 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); + .map(Index::from) + .unwrap(); 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 { + if nfields > 1 { + 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 + }); deserialize = quote! { match #deserialize { _serde::__private::Ok(_) => { @@ -715,7 +708,7 @@ fn deserialize_tuple_in_place( quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #field_count, #visitor_expr)) } else if is_enum { quote!(_serde::de::VariantAccess::tuple_variant(__variant, #field_count, #visitor_expr)) - } else if nfields == 1 { + } else if field_count != 0 && nfields == 1 { let type_name = cattrs.name().deserialize_name(); quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) } else { diff --git a/serde_derive/src/ser.rs b/serde_derive/src/ser.rs index 1792d3fec..937ff1169 100644 --- a/serde_derive/src/ser.rs +++ b/serde_derive/src/ser.rs @@ -228,6 +228,11 @@ fn serialize_newtype_struct( field: &Field, cattrs: &attr::Container, ) -> Fragment { + // For `struct Tuple1as0(#[serde(skip)] u8);` cases + if field.attrs.skip_serializing() { + return serialize_tuple_struct(params, &[], cattrs); + } + let type_name = cattrs.name().serialize_name(); let mut field_expr = get_member( diff --git a/test_suite/tests/test_skip.rs b/test_suite/tests/test_skip.rs index 73dd87f85..1b865ec8e 100644 --- a/test_suite/tests/test_skip.rs +++ b/test_suite/tests/test_skip.rs @@ -87,7 +87,6 @@ mod tuple_struct { ); } - /* FIXME: compilation error: https://github.com/serde-rs/serde/issues/2105 #[test] fn tuple1as0() { /// This newtype struct in the serialized form the same as `struct Tuple0();` @@ -107,7 +106,7 @@ mod tuple_struct { Token::TupleStructEnd, ], ); - }*/ + } #[test] fn tuple2as0() {