rust-fuzz / arbitrary

Generating structured data from arbitrary, unstructured input.

Home Page:https://docs.rs/arbitrary/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Arbitrary derive doesn't play nicely with cfg_attr

silvergasp opened this issue · comments

So I'm trying to keep the arbitrary crate as an optional dependency for a project. So I'd like to conditionally derive the arbitrary implementation e.g.

#[derive(Clone, Debug, Deserialize)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Number {
        Int(i64),
        Float(f64),
        Decimal(BigDecimal),
}

This works fine when every var/enum variant also implements derive (or I can implement it manually). However in this case bigdecimal::BigDecimal is in an external crate that I don't have control over so I'd like to be able to do something like this;

#[derive(Clone, Debug, Deserialize)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub enum Number {
        Int(i64),
        Float(f64),
        #[cfg_attr(feature = "arbitrary", arbitrary(with = |u: &mut Unstructured| BigDecimal::from(u64::arbitrary(&mut u))))]
        Decimal(BigDecimal),
}

Where I conditionally enable lambda implementation for that variant type. However for whatever reason this doesn't actually work and I get an error like;

27 | #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
   |                                          ^^^^^^^^^^^^^^^^^^^^ the trait `Arbitrary<'_>` is not implemented for `BigDecimal`

Hm, that's strange, cfg_attr is handled by the compiler and the proc macro has no visibility of that in the first place.

The cfg_attr is a red herring, the with is simply not working. I don't know why.

Oh weird, perhaps it's just because it's an enum variant. To be honest I haven't tried using that attribute with an enum before, only structs. I'll investigate a little further.

Oh!

The attribute needs to be on the field, not the variant.

That explains that.

We should perhaps throw an error if you use #[arbitrary(with)] on a variant.

Closing as works-as-intended, but filed #150 for the diagnostics (and potentially making the case you laid out automatic)

Thanks for reporting!

No worries thanks for being so responsive!