Fix derive bounds for fully-qualified field types by djkoloski · Pull Request #139272 · rust-lang/rust (original) (raw)

Builtin traits like Clone, Debug, and PartialEq which can be derived look for uses of generics when adding type bounds. However, the procedure for adding these trait bounds did not account for fully-qualified type paths. This causes code which does not fully-qualify paths to generate correct derive bounds, while fully-qualified paths do not receive correct bounds. For example:

#[derive(Clone)]
struct Foo<T: MyTrait>(T::MyType);

Will receive the correct T::MyType: Clone bound, but:

#[derive(Clone)]
struct Foo<T: MyTrait>(<T>::MyType);

Does not. This change modifies generic parameter detection to walk up the chain of QSelfs in path types when looking for type parameters, rather than only looking at the outermost type.

Related issues:

Note that there are existing tests for this behavior. However, the existing tests accidentally include fields with the working syntax (T::MyType) alongside fields with the broken syntax (<T>::MyType) and so this issue has gone undiscovered.

This is a conservative fix; it aims only to make previously-invalid code valid. It does not attempt to move the builtin derive macros closer to a perfect derive.