Skip to content

Change derive macro for Eq to not impl Eq trait fn#153125

Open
KiChjang wants to merge 8 commits intorust-lang:mainfrom
KiChjang:derive-eq-const-assertion
Open

Change derive macro for Eq to not impl Eq trait fn#153125
KiChjang wants to merge 8 commits intorust-lang:mainfrom
KiChjang:derive-eq-const-assertion

Conversation

@KiChjang
Copy link
Contributor

@KiChjang KiChjang commented Feb 26, 2026

Fixes #152504.

r? @cyrgani

@rustbot
Copy link
Collaborator

rustbot commented Feb 26, 2026

Changes to the code generated for builtin derived traits.

cc @nnethercote

@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 Feb 26, 2026
@rust-log-analyzer

This comment has been minimized.

@theemathas
Copy link
Contributor

A test case that seems like might break with this:

trait Trait<T> {}

#[derive(PartialEq, Eq)]
struct Thing<T: Trait<Self>>(T);

@theemathas
Copy link
Contributor

A less exotic test case:

#[derive(PartialEq, Eq)]
struct Thing(Option<Box<Self>>);

@Kivooeo
Copy link
Member

Kivooeo commented Feb 26, 2026

Nick, I would reassign to you (feel free to reroll) since @cyrgani is a triage member and can't approve compiler changes

r? nnethercote

@rustbot rustbot assigned nnethercote and unassigned cyrgani Feb 26, 2026
@KiChjang
Copy link
Contributor Author

KiChjang commented Feb 26, 2026

A less exotic test case:

#[derive(PartialEq, Eq)]
struct Thing(Option<Box<Self>>);

Gah, because we're now generating a const item instead of a trait impl block, we'd need to rewrite the Self reference to its concrete type, but this is a bit tough as it would require us to supply the correct generic params to the Self concrete type if it has any.

A better solution now would be to emit the following:

impl<...> Type<...> {
    const fn assert_fields_are_eq() {
        let _: ::core::cmp::AssertParamIsEq<Option<Box<Self>>>;
    }
}

This would side-step the issue of rewriting Self into its concrete type.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

//~^ ERROR: struct takes 0 generic arguments
//~| ERROR: struct takes 0 generic arguments
//~| ERROR: struct takes 0 generic arguments
//~| ERROR: struct takes 0 generic arguments
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is expected since the Eq derive macro now respans generics in the where clause, which causes the same E0107 error to be reported in 2 different contexts instead of simply the original one (i.e. in the derived trait impl for Eq)

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@KiChjang
Copy link
Contributor Author

Looks like CI is passing now, r? @nnethercote

@rustbot
Copy link
Collaborator

rustbot commented Feb 28, 2026

Requested reviewer is already assigned to this pull request.

Please choose another assignee.

@KiChjang KiChjang requested a review from nnethercote February 28, 2026 00:45
@cyrgani
Copy link
Contributor

cyrgani commented Feb 28, 2026

You should be able to delete the fn assert_fields_are_eq(&self) {} method from the Eq trait again now.

@cyrgani
Copy link
Contributor

cyrgani commented Feb 28, 2026

Could you also add a test that something like

fn main() {
    X::assert_fields_are_eq();
}
#[derive(PartialEq, Eq)]
struct X(u8);

will not compile?

id: ast::DUMMY_NODE_ID,
attrs: thin_vec![
cx.attr_nested_word(sym::doc, sym::hidden, span),
cx.attr_nested_word(sym::coverage, sym::off, span),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this will also need #[inline] like #153157?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

update #[derive(Eq)] to not need assert_receiver_is_total_eq

7 participants