Note that "perfect derive" is a chimera. It is not actually possible in the general case, because it will overflow for recursive types. Fixing this would imply coinductive matching, which is unsound in general. Given all the things we are trying to achieve with the trait system, adding general purpose coinductive matching feels out of the question to me. (There are interesting papers on combining inductive/coinductive reasoning, but those same papers indicate that it is easy to get surprising, unsound results from such systems, and hence that they must be used with caution. I confess I don't fully understand the bounds here.) (Sorry this is kind of a jargon-y response, I can try to elaborate more later.)
I think for the purposes of derive, a more fruitful alternative is to allow people to annotate their type parameters to indicate what the requirements ought to be. For example, the derive for this type is too strict, because it requires that T: Copy
in order for Foo<T>: Copy
:
#[derive(Copy)]
struct Foo<'a, T: 'a> {
x: &'a T
}
We might therefore have some kind of annotation on T
to indicate that this is not needed. It's not ideal, but to be fair it also does seem like part of the public API for the type:
#[derive(Copy)]
struct Foo<'a, #[ignore(Copy)] T: 'a> {
x: &'a T
}
Shame it's so verbose though. =(