proptest-rs / proptest

Hypothesis-like property testing for Rust
Apache License 2.0
1.67k stars 157 forks source link

proptest-derive fails to derive Arbitrary for a recusrive type #229

Open vi opened 3 years ago

vi commented 3 years ago
#[derive(Debug)]
#[cfg_attr(test,derive(proptest_derive::Arbitrary))]
struct Qqq(pub Option<Box<Qqq>>);

Expected: Arbitrary implementation that generates chains like Qqq(Some(Box(Qqq(Some(Box(Qqq(None))))))) and shrinks by Noneing some layers.

Actual: error[E0271]: type mismatch resolving<Option<Box> as Arbitrary>::Parameters == _,cyclic type of infinite size`

AltSysrq commented 3 years ago

Generating recursive types in general is fairly tricky, as anything that could hold more than one child at each level can easily blow up into immense sizes when using the naïve recursive approach (consider what would happen for struct Qqq(Option<Box<Qqq>>, Option<Box<Qqq>>)).

Basically, this is an expected limitation right now and unless someone comes up with a sensible way for recursive types to be handled in general the limitation won't be going away.

vi commented 3 years ago

Maybe some #[user] #[annotations] with probabilities for Option and other enums could help?

adaszko commented 1 year ago

Generating recursive types in general is fairly tricky, as anything that could hold more than one child at each level can easily blow up into immense sizes when using the naïve recursive approach (consider what would happen for struct Qqq(Option<Box<Qqq>>, Option<Box<Qqq>>)).

Basically, this is an expected limitation right now and unless someone comes up with a sensible way for recursive types to be handled in general the limitation won't be going away.

Would it be possible to simply limit the depth of such structures by a constant, taken as an argument by the derive macro (somehow)?

matthew-russo commented 9 months ago

Would it be possible to simply limit the depth of such structures by a constant, taken as an argument by the derive macro (somehow)?

I think this is a valid approach and at least deserves a look.