diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 554196a66..f0a0ee683 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -2193,6 +2193,14 @@ mod content { } } + impl<'a, 'de: 'a, E> Copy for ContentRefDeserializer<'a, 'de, E> {} + + impl<'a, 'de: 'a, E> Clone for ContentRefDeserializer<'a, 'de, E> { + fn clone(&self) -> Self { + *self + } + } + struct EnumRefDeserializer<'a, 'de: 'a, E> where E: de::Error, diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index 137073bf3..a834a736e 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -1172,13 +1172,7 @@ fn deserialize_enum( Some(variant_idx) => { let (tagged, untagged) = variants.split_at(variant_idx); let tagged_frag = Expr(deserialize_homogeneous_enum(params, tagged, cattrs)); - let tagged_frag = |deserializer| { - Some(Expr(quote_block! { - let __deserializer = #deserializer; - #tagged_frag - })) - }; - deserialize_untagged_enum_after(params, untagged, cattrs, tagged_frag) + deserialize_untagged_enum_after(params, untagged, cattrs, Some(tagged_frag)) } None => deserialize_homogeneous_enum(params, variants, cattrs), } @@ -1689,17 +1683,16 @@ fn deserialize_untagged_enum( variants: &[Variant], cattrs: &attr::Container, ) -> Fragment { - deserialize_untagged_enum_after(params, variants, cattrs, |_| None) + let first_attempt = None; + deserialize_untagged_enum_after(params, variants, cattrs, first_attempt) } fn deserialize_untagged_enum_after( params: &Parameters, variants: &[Variant], cattrs: &attr::Container, - first_attempt: impl FnOnce(TokenStream) -> Option, + first_attempt: Option, ) -> Fragment { - let deserializer = - quote!(_serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content)); let attempts = variants .iter() .filter(|variant| !variant.attrs.skip_deserializing()) @@ -1708,12 +1701,10 @@ fn deserialize_untagged_enum_after( params, variant, cattrs, - deserializer.clone(), + quote!(__deserializer), )) }); - let attempts = first_attempt(deserializer.clone()) - .into_iter() - .chain(attempts); + let attempts = first_attempt.into_iter().chain(attempts); // TODO this message could be better by saving the errors from the failed // attempts. The heuristic used by TOML was to count the number of fields // processed before an error, and use the error that happened after the @@ -1728,6 +1719,7 @@ fn deserialize_untagged_enum_after( quote_block! { let __content = try!(<_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)); + let __deserializer = _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content); #( if let _serde::__private::Ok(__ok) = #attempts {