magiclen / educe

This crate offers procedural macros designed to facilitate the swift implementation of Rust's built-in traits.
MIT License
131 stars 11 forks source link

Precise bounds #19

Closed ijackson closed 5 months ago

ijackson commented 8 months ago

Fix the bounds for all generated trait impls.

Here, we change the default behaviour (without ...(bound(...))) to say something like: where FieldType: Clone, for each field.

For example, consider this:

#[derive(Educe)]
#[educe(Clone)]
struct Struct<T, U, V> {
    bare: T,
    boxed: Box<U>,
    marker: PhantomData<V>,
}

Before, we would get just where T: Clone, which is not sufficient, because the generated impl needs to clone boxed too.

With this MR, we get where T: Clone, Box<U>: Clone, PhantomData<V>: Clone. The latter is always satisfied since PhantomData is always Clone. The middle one is equivalent to U: Clone.

That the previous ident-hunting approach cannot be made to work can be seen by considering DebugAsDisplay (in the new debug_struct::bound_5 test case in this MR). struct S<T>(DebugAsDisplay<T>) can only be Debug if T: Display. There's no reasonable way to determine this condition and express it in those terms. But instead, if we write where DebugAsDisplay<T>: Debug, the compiler does the work for us.

Fixes #17, choosing option (3). I think this is not a semver break: the bounds we now require are precisely correct, so the effect is to make code compile (and work) which would previously not compile.

I have retained the existing behaviour for fields with method =. Those fields' bounds are not included. In some cases this means that the user needs to restate all of the bounds manually. That's not great but it's a thing we can improve later. Likewise my changes only affect autocomputed bounds.

I've added test cases, each of which fails when attempted without the functional changes.

I've left open the possibility of providing a syntax for #17 option 2. I'm hoping to make a followup MR for that; I think that's important to help migration from educe 0.4.x.

Also addresses the MyDebug part of #18, since I was reworking that part anyway.

magiclen commented 5 months ago

Thank you so much for your PR! Your contribution is greatly appreciated. I truly value your help and effort!