arbitrary icon indicating copy to clipboard operation
arbitrary copied to clipboard

Arbitrary derive fails with lifetimes in some cases

Open LegNeato opened this issue 3 years ago • 3 comments

Hello! Bear with me as I am new to Arbitrary.

I have this type from juniper:

pub struct Arguments<'a, S> {
    pub items: Vec<(Spanning<&'a str>, Spanning<InputValue<S>>)>,
}

Spanning and InputValue successfully derive(arbitrary::Arbitrary)). When I try to derive on Arguments, I get the following error:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
  --> juniper/src/ast.rs:59:42
   |
59 | #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
   |                                          ^^^^^^^^^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the lifetime `'a` as defined here...
  --> juniper/src/ast.rs:60:22
   |
60 | pub struct Arguments<'a, S> {
   |                      ^^
note: ...so that the types are compatible
  --> juniper/src/ast.rs:59:42
   |
59 | #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
   |                                          ^^^^^^^^^^^^^^^^^^^^
   = note: expected `<&'a str as Arbitrary<'_>>`
              found `<&str as Arbitrary<'_>>`
note: but, the lifetime must be valid for the lifetime `'arbitrary` as defined here...
  --> juniper/src/ast.rs:59:42
   |
59 | #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
   |                                          ^^^^^^^^^^^^^^^^^^^^
note: ...so that the types are compatible

Manually implenting it works:

impl<'a, S> arbitrary::Arbitrary<'a> for Arguments<'a, S>
where
    S: arbitrary::Arbitrary<'a>,
{
    fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
        let items: Vec<(Spanning<&'a str>, Spanning<InputValue<S>>)> = u.arbitrary()?;
        Ok(Self { items })
    }
}

Even though I am unblocked, I figured I'd file as one would expect the derive to work in this case.

LegNeato avatar Feb 28 '22 23:02 LegNeato

You can see the various types that the derive didn't work for in https://github.com/graphql-rust/juniper/pull/1032.

LegNeato avatar Mar 01 '22 07:03 LegNeato

Can you confirm that you're using the latest version of arbitrary and arbitrary-derive?

It sort of looks like this might be an old version of the derive that tried to use 'a as the derived lifetime, which conflicted with already-existing 'a lifetimes.

If you can provide a complete test case that doesn't rely on any external code, that would be useful as well.

fitzgen avatar Mar 01 '22 18:03 fitzgen

I'm using:

arbitrary = { version = "1.1", optional = true, features = ["derive"] }

I'll work on getting a standalone complete test case.

LegNeato avatar Mar 01 '22 20:03 LegNeato