Skip to content

Commit f60324e

Browse files
committed
Reuse a single ContentRefDeserializer throughout untagged enum deserialization
1 parent 361c23a commit f60324e

File tree

2 files changed

+15
-15
lines changed

2 files changed

+15
-15
lines changed

serde/src/private/de.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,14 @@ mod content {
21932193
}
21942194
}
21952195

2196+
impl<'a, 'de: 'a, E> Copy for ContentRefDeserializer<'a, 'de, E> {}
2197+
2198+
impl<'a, 'de: 'a, E> Clone for ContentRefDeserializer<'a, 'de, E> {
2199+
fn clone(&self) -> Self {
2200+
*self
2201+
}
2202+
}
2203+
21962204
struct EnumRefDeserializer<'a, 'de: 'a, E>
21972205
where
21982206
E: de::Error,

serde_derive/src/de.rs

+7-15
Original file line numberDiff line numberDiff line change
@@ -1172,13 +1172,7 @@ fn deserialize_enum(
11721172
Some(variant_idx) => {
11731173
let (tagged, untagged) = variants.split_at(variant_idx);
11741174
let tagged_frag = Expr(deserialize_homogeneous_enum(params, tagged, cattrs));
1175-
let tagged_frag = |deserializer| {
1176-
Some(Expr(quote_block! {
1177-
let __deserializer = #deserializer;
1178-
#tagged_frag
1179-
}))
1180-
};
1181-
deserialize_untagged_enum_after(params, untagged, cattrs, tagged_frag)
1175+
deserialize_untagged_enum_after(params, untagged, cattrs, Some(tagged_frag))
11821176
}
11831177
None => deserialize_homogeneous_enum(params, variants, cattrs),
11841178
}
@@ -1689,17 +1683,16 @@ fn deserialize_untagged_enum(
16891683
variants: &[Variant],
16901684
cattrs: &attr::Container,
16911685
) -> Fragment {
1692-
deserialize_untagged_enum_after(params, variants, cattrs, |_| None)
1686+
let first_attempt = None;
1687+
deserialize_untagged_enum_after(params, variants, cattrs, first_attempt)
16931688
}
16941689

16951690
fn deserialize_untagged_enum_after(
16961691
params: &Parameters,
16971692
variants: &[Variant],
16981693
cattrs: &attr::Container,
1699-
first_attempt: impl FnOnce(TokenStream) -> Option<Expr>,
1694+
first_attempt: Option<Expr>,
17001695
) -> Fragment {
1701-
let deserializer =
1702-
quote!(_serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content));
17031696
let attempts = variants
17041697
.iter()
17051698
.filter(|variant| !variant.attrs.skip_deserializing())
@@ -1708,12 +1701,10 @@ fn deserialize_untagged_enum_after(
17081701
params,
17091702
variant,
17101703
cattrs,
1711-
deserializer.clone(),
1704+
quote!(__deserializer),
17121705
))
17131706
});
1714-
let attempts = first_attempt(deserializer.clone())
1715-
.into_iter()
1716-
.chain(attempts);
1707+
let attempts = first_attempt.into_iter().chain(attempts);
17171708
// TODO this message could be better by saving the errors from the failed
17181709
// attempts. The heuristic used by TOML was to count the number of fields
17191710
// processed before an error, and use the error that happened after the
@@ -1728,6 +1719,7 @@ fn deserialize_untagged_enum_after(
17281719

17291720
quote_block! {
17301721
let __content = try!(<_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer));
1722+
let __deserializer = _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content);
17311723

17321724
#(
17331725
if let _serde::__private::Ok(__ok) = #attempts {

0 commit comments

Comments
 (0)