diff --git a/serde_derive/src/de.rs b/serde_derive/src/de.rs index c9c93e19d..df3eced40 100644 --- a/serde_derive/src/de.rs +++ b/serde_derive/src/de.rs @@ -441,6 +441,43 @@ fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fra { _serde::__private::Ok(#this_value) } + + #[inline] + fn visit_seq<__A>(self, mut __seq: __A) -> _serde::__private::Result + where + __A: _serde::de::SeqAccess<'de>, + { + // Allow to deserialize unit from empty sequence + if _serde::de::SeqAccess::next_element::< + _serde::de::IgnoredAny, + >(&mut __seq)?.is_some() { + _serde::__private::Err(_serde::de::Error::invalid_type( + _serde::de::Unexpected::Seq, + &self + )) + } else { + _serde::__private::Ok(#this_value) + } + } + + #[inline] + fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result + where + __A: _serde::de::MapAccess<'de>, + { + // Allow to deserialize unit from empty map + if _serde::de::MapAccess::next_entry::< + _serde::de::IgnoredAny, + _serde::de::IgnoredAny, + >(&mut __map)?.is_some() { + _serde::__private::Err(_serde::de::Error::invalid_type( + _serde::de::Unexpected::Map, + &self + )) + } else { + _serde::__private::Ok(#this_value) + } + } } _serde::Deserializer::deserialize_unit_struct( diff --git a/test_suite/tests/test_de.rs b/test_suite/tests/test_de.rs index 31e726d4b..0aecb71c0 100644 --- a/test_suite/tests/test_de.rs +++ b/test_suite/tests/test_de.rs @@ -903,6 +903,20 @@ fn test_unit() { fn test_unit_struct() { test(UnitStruct, &[Token::Unit]); test(UnitStruct, &[Token::UnitStruct { name: "UnitStruct" }]); + test(UnitStruct, &[Token::Seq { len: Some(0) }, Token::SeqEnd]); + test(UnitStruct, &[Token::Seq { len: None }, Token::SeqEnd]); + test(UnitStruct, &[Token::Map { len: Some(0) }, Token::MapEnd]); + test(UnitStruct, &[Token::Map { len: None }, Token::MapEnd]); + test( + UnitStruct, + &[ + Token::Struct { + name: "ZeroStruct", + len: 0, + }, + Token::StructEnd, + ], + ); } #[test] diff --git a/test_suite/tests/test_de_error.rs b/test_suite/tests/test_de_error.rs index cae5eddab..0225df1b8 100644 --- a/test_suite/tests/test_de_error.rs +++ b/test_suite/tests/test_de_error.rs @@ -1446,14 +1446,6 @@ fn test_nan_no_decimal_point() { ); } -#[test] -fn test_unit_struct_from_seq() { - assert_de_tokens_error::( - &[Token::Seq { len: Some(0) }, Token::SeqEnd], - "invalid type: sequence, expected unit struct UnitStruct", - ); -} - #[test] fn test_wrapping_overflow() { assert_de_tokens_error::>(