It's overriding bounds for BorshSerialize and BorshDeserialize in order to allow not to keep
bounds on type parameters in struct definition itself and fix complex cases, when derive hasn't figured
the right bounds on type parameters automatically, while still not having to implement the traits manually.
/// `T: PartialOrd` is injected here via field bound to avoid having this restriction on
/// the struct itself
#[cfg(hash_collections)]
#[derive(BorshSerialize)]
struct C1<T, U> {
a: String,
#[borsh(bound(serialize =
"T: borsh::ser::BorshSerialize + PartialOrd,
U: borsh::ser::BorshSerialize"))]
b: HashMap<T, U>,
}
/// `T: PartialOrd + Hash + Eq` is injected here via field bound to avoid having this restriction on
/// the struct itself
#[allow(unused)]
#[cfg(hash_collections)]
#[derive(BorshDeserialize)]
struct C2<T, U> {
a: String,
#[borsh(bound(
deserialize =
"T: PartialOrd + Hash + Eq + borsh::de::BorshDeserialize,
U: borsh::de::BorshDeserialize"
))]
b: HashMap<T, U>,
}
/// implicit derived `core::default::Default` bounds on `K` and `V` are dropped by empty bound
/// specified, as `HashMap` has its own `Default` implementation
#[cfg(hash_collections)]
#[derive(BorshDeserialize)]
struct G3<K, V, U>(
#[borsh_skip]
#[borsh(bound(deserialize = ""))]
HashMap<K, V>,
U,
);
// derive here figures the bound erroneously as `T: borsh::ser::BorshSerialize`
#[derive(BorshSerialize)]
struct ParametrizedWronDerive<T, V>
where
T: TraitName,
{
#[borsh(bound(serialize = "<T as TraitName>::Associated: borsh::ser::BorshSerialize"))]
field: <T as TraitName>::Associated,
another: V,
}
This is logical continuation/conclusion of #178 .
It's overriding bounds for BorshSerialize and BorshDeserialize in order to allow not to keep bounds on type parameters in struct definition itself and fix complex cases, when derive hasn't figured the right bounds on type parameters automatically, while still not having to implement the traits manually.