arbitrary
arbitrary copied to clipboard
Support arbitrary 🥁 collections
I would like to be able to derive(Arbitrary) on a custom struct that happens to contain various collections that aren't in std (e.g. DashMap, SmallVec). I could add optional dependencies on dashmap and smallvec directly to the arbitrary crate, but I'd prefer to do this more generically so that it works for any collection.
I tried to do that as follows:
impl<'a, T: Arbitrary<'a>, C: FromIterator<T>> Arbitrary<'a> for C {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter().collect()
}
}
which didn't work:
1 error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
--> /Users/jyn/src/arbitrary/src/lib.rs:1158:10
|
1158 | impl<'a, T: Arbitrary<'a>, C: FromIterator<T>> Arbitrary<'a> for C {
| ^ unconstrained type parameter
I have two questions:
- Before I spent more time on it, is this a feature you're interested in?
- Do you have suggestions for how to get it working?
ok, I think this idea cannot work.
impl<'a, T: Arbitrary<'a>, C: std::iter::FromIterator<T> + std::iter::IntoIterator<Item = T>> Arbitrary<'a> for C {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter().collect()
}
}
1 error[E0119]: conflicting implementations of trait `Arbitrary<'_>` for type `()`
--> /Users/jyn/src/arbitrary/src/lib.rs:1157:1
|
283 | impl<'a> Arbitrary<'a> for () {
| ----------------------------- first implementation here
...
1157 | impl<'a, T: Arbitrary<'a>, C: std::iter::FromIterator<T> + std::iter::IntoIterator<Item = T>> Arbitrary<'a> for C {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflict
|
= note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions
You can only commit to a single blanket impl per trait, and it severely restricts downstream impls, so I'm opposed to introducing any new blanket impl.
However, this may be possible by instead introducing a #[from_iterator] field attribute (perhaps with a T parameter though I suspect inference will usually work) that tweaks the methods used to construct the type.
i ended up not needing this (turns out smallvec already supports arbitrary and i needed custom logic for my dashmap struct anyway) but i don't mind keeping the issue open if you're interested in #[from_iterator].