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

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

djkoloski

@djkoloski

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:

struct Foo<T: MyTrait>(T::MyType);

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

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.

@rustbot rustbot added S-waiting-on-review

Status: Awaiting review from the assignee but also interested parties.

T-compiler

Relevant to the compiler team, which will review and decide on the PR/issue.

labels

Apr 2, 2025

@rustbot rustbot added the T-types

Relevant to the types team, which will review and decide on the PR/issue.

label

May 1, 2025

bors added a commit to rust-lang-ci/rust that referenced this pull request

May 7, 2025

@bors

…pes, r=

Fix derive bounds for fully-qualified field types

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.

@oli-obk oli-obk added S-waiting-on-author

Status: This is awaiting some action (such as code changes or more information) from the author.

and removed S-waiting-on-review

Status: Awaiting review from the assignee but also interested parties.

labels

May 18, 2025