Rust's standard derives are dumb

51 points platesturner 16 comments

The fact that this hasn't been brought up anywhere before makes me feel like I'm missing something.

Consider:

trait HasAssociatedType { type At; }

impl HasAssociatedType for String { type At = i32; }

#[derive(Copy, Clone)]
struct Foo<T : HasAssociatedType>(T::At);

Now tell me, under which circumstances would you expect Foo<T> to implement Copy?

Unfortunately, that's not how it works in reality.

fn dummy() where Foo<String> : Copy {}

fails to compile, since String does not implement Copy. But String doesn't need to implement Copy, <String as HasAssociatedType>::At does. Only all types used as fields for a type T, need to implement Copy for T to be able implement Copy. The same goes for: Clone, Default, Debug, etc.

I don't see any reason why this couldn't be implemented properly. A derive macro can always see the fields of the type it acts upon, so writing this derive macro properly is (tedious, yet) as simple as just textually going over each field type and stating field : Copy.

It seems too simple to miss. So perhaps it is me who is dumb...