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 QSelf
s in path types when looking for type parameters, rather than only looking at the outermost type.
Related issues:
- #[derive] fails to detect associated type when qualified path is used #50730
- Use T::Archived syntax instead of ::Archived rkyv/rkyv#602
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.