Skip to content

Commit da7fc79

Browse files
committed
Fix deserialization of empty struct variant in untagged enums
SeqRefDeserializer::deserialize_any has a special condition for empty sequence, which emits visit_unit. That condition assumes that type would be able to deserialized from unit, but: 1) struct variants was never able to deserialize from it (they expect only visit_map or visit_seq) 2) tuple variants even with zero fields expect visit_seq only. The suggestion to accept visit_unit instead was rejected in #2520 Fixes (2): newtype_enum::tuple0 newtype_enum::empty_struct_from_seq
1 parent 4c5fec1 commit da7fc79

File tree

1 file changed

+2
-81
lines changed

1 file changed

+2
-81
lines changed

serde/src/private/de.rs

Lines changed: 2 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -2190,9 +2190,7 @@ mod content {
21902190
// Covered by tests/test_enum_untagged.rs
21912191
// newtype_enum::tuple0
21922192
// newtype_enum::tuple2
2193-
Some(Content::Seq(v)) => {
2194-
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
2195-
}
2193+
Some(Content::Seq(v)) => visit_content_seq_ref(v, visitor),
21962194
Some(other) => Err(de::Error::invalid_type(
21972195
other.unexpected(),
21982196
&"tuple variant",
@@ -2221,9 +2219,7 @@ mod content {
22212219
// Covered by tests/test_enum_untagged.rs
22222220
// newtype_enum::struct_from_seq
22232221
// newtype_enum::empty_struct_from_seq
2224-
Some(Content::Seq(v)) => {
2225-
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
2226-
}
2222+
Some(Content::Seq(v)) => visit_content_seq_ref(v, visitor),
22272223
Some(other) => Err(de::Error::invalid_type(
22282224
other.unexpected(),
22292225
&"struct variant",
@@ -2236,81 +2232,6 @@ mod content {
22362232
}
22372233
}
22382234

2239-
struct SeqRefDeserializer<'a, 'de: 'a, E>
2240-
where
2241-
E: de::Error,
2242-
{
2243-
iter: <&'a [Content<'de>] as IntoIterator>::IntoIter,
2244-
err: PhantomData<E>,
2245-
}
2246-
2247-
impl<'a, 'de, E> SeqRefDeserializer<'a, 'de, E>
2248-
where
2249-
E: de::Error,
2250-
{
2251-
fn new(slice: &'a [Content<'de>]) -> Self {
2252-
SeqRefDeserializer {
2253-
iter: slice.iter(),
2254-
err: PhantomData,
2255-
}
2256-
}
2257-
}
2258-
2259-
impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, 'de, E>
2260-
where
2261-
E: de::Error,
2262-
{
2263-
type Error = E;
2264-
2265-
#[inline]
2266-
fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
2267-
where
2268-
V: de::Visitor<'de>,
2269-
{
2270-
let len = self.iter.len();
2271-
if len == 0 {
2272-
visitor.visit_unit()
2273-
} else {
2274-
let ret = tri!(visitor.visit_seq(&mut self));
2275-
let remaining = self.iter.len();
2276-
if remaining == 0 {
2277-
Ok(ret)
2278-
} else {
2279-
Err(de::Error::invalid_length(len, &"fewer elements in array"))
2280-
}
2281-
}
2282-
}
2283-
2284-
forward_to_deserialize_any! {
2285-
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
2286-
bytes byte_buf option unit unit_struct newtype_struct seq tuple
2287-
tuple_struct map struct enum identifier ignored_any
2288-
}
2289-
}
2290-
2291-
impl<'de, 'a, E> de::SeqAccess<'de> for SeqRefDeserializer<'a, 'de, E>
2292-
where
2293-
E: de::Error,
2294-
{
2295-
type Error = E;
2296-
2297-
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
2298-
where
2299-
T: de::DeserializeSeed<'de>,
2300-
{
2301-
match self.iter.next() {
2302-
Some(value) => seed
2303-
.deserialize(ContentRefDeserializer::new(value))
2304-
.map(Some),
2305-
None => Ok(None),
2306-
}
2307-
}
2308-
2309-
fn size_hint(&self) -> Option<usize> {
2310-
size_hint::from_bounds(&self.iter)
2311-
}
2312-
}
2313-
23142235
struct MapRefDeserializer<'a, 'de: 'a, E>
23152236
where
23162237
E: de::Error,

0 commit comments

Comments
 (0)