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.
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:
Before, we would get just
where T: Clone
, which is not sufficient, because the generated impl needs to cloneboxed
too.With this MR, we get
where T: Clone, Box<U>: Clone, PhantomData<V>: Clone
. The latter is always satisfied sincePhantomData
is alwaysClone
. The middle one is equivalent toU: Clone
.That the previous ident-hunting approach cannot be made to work can be seen by considering
DebugAsDisplay
(in the newdebug_struct::bound_5
test case in this MR).struct S<T>(DebugAsDisplay<T>)
can only beDebug
ifT: Display
. There's no reasonable way to determine this condition and express it in those terms. But instead, if we writewhere 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.