diff --git a/serde/src/private/de.rs b/serde/src/private/de.rs index 51c7035a..4b0f2c4c 100644 --- a/serde/src/private/de.rs +++ b/serde/src/private/de.rs @@ -2916,18 +2916,17 @@ where where T: DeserializeSeed<'de>, { - match self.iter.next() { - Some(item) => { + while let Some(item) = self.iter.next() { + if let Some((ref key, ref content)) = *item { // Do not take(), instead borrow this entry. The internally tagged // enum does its own buffering so we can't tell whether this entry // is going to be consumed. Borrowing here leaves the entry // available for later flattened fields. - let (ref key, ref content) = *item.as_ref().unwrap(); self.pending = Some(content); - seed.deserialize(ContentRefDeserializer::new(key)).map(Some) + return seed.deserialize(ContentRefDeserializer::new(key)).map(Some); } - None => Ok(None), } + Ok(None) } fn next_value_seed(&mut self, seed: T) -> Result diff --git a/test_suite/tests/test_annotations.rs b/test_suite/tests/test_annotations.rs index 87eda501..bf8af805 100644 --- a/test_suite/tests/test_annotations.rs +++ b/test_suite/tests/test_annotations.rs @@ -12,9 +12,11 @@ extern crate serde_derive; extern crate serde; -use self::serde::de::{self, Unexpected}; +use self::serde::de::{self, Visitor, MapAccess, Unexpected}; use self::serde::{Deserialize, Deserializer, Serialize, Serializer}; + use std::collections::{BTreeMap, HashMap}; +use std::fmt; use std::marker::PhantomData; extern crate serde_test; @@ -2311,3 +2313,66 @@ fn test_flattened_internally_tagged_unit_enum_with_unknown_fields() { ], ); } + +#[test] +fn test_flatten_any_after_flatten_struct() { + #[derive(PartialEq, Debug)] + struct Any; + + impl<'de> Deserialize<'de> for Any { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AnyVisitor; + + impl<'de> Visitor<'de> for AnyVisitor { + type Value = Any; + + fn expecting(&self, _formatter: &mut fmt::Formatter) -> fmt::Result { + unimplemented!() + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'de>, + { + while let Some((Any, Any)) = map.next_entry()? {} + Ok(Any) + } + } + + deserializer.deserialize_any(AnyVisitor) + } + } + + #[derive(Deserialize, PartialEq, Debug)] + struct Outer { + #[serde(flatten)] + inner: Inner, + #[serde(flatten)] + extra: Any, + } + + #[derive(Deserialize, PartialEq, Debug)] + struct Inner { + inner: i32, + } + + let s = Outer { + inner: Inner { + inner: 0, + }, + extra: Any, + }; + + assert_de_tokens( + &s, + &[ + Token::Map { len: None }, + Token::Str("inner"), + Token::I32(0), + Token::MapEnd, + ], + ); +}