From 0647a7c1feafebacea6de4cb69f0aee9b2ba2919 Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 11 Aug 2024 18:16:19 +0500 Subject: [PATCH] Fix creating and filling a collections that was not read --- serde_derive/src/de.rs | 18 +++++++----------- test_suite/tests/test_gen.rs | 32 ++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index b87ababf..1ccecb26 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -281,13 +281,9 @@ fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment { } else if let attr::Identifier::No = cont.attrs.identifier() { match &cont.data { Data::Enum(variants) => deserialize_enum(params, variants, &cont.attrs), - Data::Struct(Style::Struct, fields) => deserialize_struct( - params, - fields, - &cont.attrs, - cont.attrs.has_flatten(), - StructForm::Struct, - ), + Data::Struct(Style::Struct, fields) => { + deserialize_struct(params, fields, &cont.attrs, StructForm::Struct) + } Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { deserialize_tuple( params, @@ -927,7 +923,6 @@ fn deserialize_struct( params: &Parameters, fields: &[Field], cattrs: &attr::Container, - has_flatten: bool, form: StructForm, ) -> Fragment { let this_type = ¶ms.this_type; @@ -976,6 +971,10 @@ fn deserialize_struct( ) }) .collect(); + + let has_flatten = fields + .iter() + .any(|field| field.attrs.flatten() && !field.attrs.skip_deserializing()); let field_visitor = deserialize_field_identifier(&field_names_idents, cattrs, has_flatten); // untagged struct variants do not get a visit_seq method. The same applies to @@ -1838,7 +1837,6 @@ fn deserialize_externally_tagged_variant( params, &variant.fields, cattrs, - variant.attrs.has_flatten(), StructForm::ExternallyTagged(variant_ident), ), } @@ -1882,7 +1880,6 @@ fn deserialize_internally_tagged_variant( params, &variant.fields, cattrs, - variant.attrs.has_flatten(), StructForm::InternallyTagged(variant_ident, deserializer), ), Style::Tuple => unreachable!("checked in serde_derive_internals"), @@ -1940,7 +1937,6 @@ fn deserialize_untagged_variant( params, &variant.fields, cattrs, - variant.attrs.has_flatten(), StructForm::Untagged(variant_ident, deserializer), ), } diff --git a/test_suite/tests/test_gen.rs b/test_suite/tests/test_gen.rs index 2f43b20b..ed9dc725 100644 --- a/test_suite/tests/test_gen.rs +++ b/test_suite/tests/test_gen.rs @@ -547,6 +547,12 @@ fn test_gen() { } assert::(); + #[derive(Serialize, Deserialize)] + pub struct Flatten { + #[serde(flatten)] + t: T, + } + #[derive(Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct FlattenDenyUnknown { @@ -554,6 +560,19 @@ fn test_gen() { t: T, } + #[derive(Serialize, Deserialize)] + pub struct SkipDeserializing { + #[serde(skip_deserializing)] + flat: T, + } + + #[derive(Serialize, Deserialize)] + #[serde(deny_unknown_fields)] + pub struct SkipDeserializingDenyUnknown { + #[serde(skip_deserializing)] + flat: T, + } + #[derive(Serialize, Deserialize)] pub struct StaticStrStruct<'a> { a: &'a str, @@ -720,14 +739,11 @@ fn test_gen() { flat: StdOption, } - #[allow(clippy::collection_is_never_read)] // FIXME - const _: () = { - #[derive(Serialize, Deserialize)] - pub struct FlattenSkipDeserializing { - #[serde(flatten, skip_deserializing)] - flat: T, - } - }; + #[derive(Serialize, Deserialize)] + pub struct FlattenSkipDeserializing { + #[serde(flatten, skip_deserializing)] + flat: T, + } #[derive(Serialize, Deserialize)] #[serde(untagged)]