Skip to content

Commit

Permalink
Merge pull request #2791 from dtolnay/flatten
Browse files Browse the repository at this point in the history
Skip collecting unmatched fields in variants that do not use flatten
  • Loading branch information
dtolnay committed Aug 8, 2024
2 parents e08c5de + 32958de commit c3eaf76
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 3 deletions.
9 changes: 6 additions & 3 deletions serde_derive/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2480,7 +2480,10 @@ fn deserialize_map(
});

// Collect contents for flatten fields into a buffer
let let_collect = if cattrs.has_flatten() {
let has_flatten = fields
.iter()
.any(|field| field.attrs.flatten() && !field.attrs.skip_deserializing());
let let_collect = if has_flatten {
Some(quote! {
let mut __collect = _serde::__private::Vec::<_serde::__private::Option<(
_serde::__private::de::Content,
Expand Down Expand Up @@ -2532,7 +2535,7 @@ fn deserialize_map(
});

// Visit ignored values to consume them
let ignored_arm = if cattrs.has_flatten() {
let ignored_arm = if has_flatten {
Some(quote! {
__Field::__other(__name) => {
__collect.push(_serde::__private::Some((
Expand Down Expand Up @@ -2602,7 +2605,7 @@ fn deserialize_map(
}
});

let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
let collected_deny_unknown_fields = if has_flatten && cattrs.deny_unknown_fields() {
Some(quote! {
if let _serde::__private::Some(_serde::__private::Some((__key, _))) =
__collect.into_iter().filter(_serde::__private::Option::is_some).next()
Expand Down
15 changes: 15 additions & 0 deletions test_suite/tests/test_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#![deny(warnings)]
#![allow(
confusable_idents,
unknown_lints,
mixed_script_confusables,
clippy::derive_partial_eq_without_eq,
Expand All @@ -19,6 +20,7 @@
clippy::trivially_copy_pass_by_ref,
clippy::type_repetition_in_bounds
)]
#![deny(clippy::collection_is_never_read)]

use serde::de::{Deserialize, DeserializeOwned, Deserializer};
use serde::ser::{Serialize, Serializer};
Expand Down Expand Up @@ -724,6 +726,19 @@ fn test_gen() {
flat: T,
}

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
pub enum Inner<T> {
Builder {
s: T,
#[serde(flatten)]
o: T,
},
Default {
s: T,
},
}

// https://github.com/serde-rs/serde/issues/1804
#[derive(Serialize, Deserialize)]
pub enum Message {
Expand Down

0 comments on commit c3eaf76

Please sign in to comment.