-
Notifications
You must be signed in to change notification settings - Fork 87
Open
Labels
Description
Current behavior
For a code like this:
#[derive(BorshDeserialize)]
enum I1<K, V, R> {
B {
#[borsh(skip)]
x: HashMap<K, V>,
y: String,
},
C(K, Vec<R>),
}the generated BorshDeserialize implementation looks like this (path prefixes removed for readability):
impl<K, V, R> BorshDeserialize for I1<K, V, R>
where
K: BorshDeserialize,
R: BorshDeserialize,
K: Default,
V: Default,
{
fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> Result<Self, borsh::io::Error> {
let tag = <u8 as BorshDeserialize>::deserialize_reader(reader)?;
<Self as borsh::de::EnumExt>::deserialize_variant(reader, tag)
}
}
impl<K, V, R> borsh::de::EnumExt for I1<K, V, R>
where
K: BorshDeserialize,
R: BorshDeserialize,
K: Default,
V: Default,
{
fn deserialize_variant<R: borsh::io::Read>(reader: &mut R, variant_tag: u8) -> Result<Self, borsh::io::Error> {
let mut return_value = if variant_tag == 0u8 {
I1::B {
x: Default::default(),
y: BorshDeserialize::deserialize_reader(reader)?,
}
} else if variant_tag == 1u8 {
I1::C(
BorshDeserialize::deserialize_reader(reader)?,
BorshDeserialize::deserialize_reader(reader)?
)
} else {
return Err(borsh::io::Error::new(
borsh::io::ErrorKind::InvalidData,
format!("Unexpected variant tag: {:?}", variant_tag)
))
};
Ok(return_value)
}
}Meanwhile, HashMap<K, V> does not require the Default implementation for its type parameters, and yet, the implementation for BorshDeserialize does.
So rather than generating
K: Default,
V: Default,bound, it should generate
HashMap<K, V>: Defaultbound. Same goes if the field would be of any other type, e.g. Option<T> or Vec<T>, as those types do not require Default to be implemented for their type parameters
This can be fixed and released as a patch, because the existing API would not be reduced, but broadened in applicability.