Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

derive(PartialEq): Add partial implementation (hehe) #3415

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

CohenArthur
Copy link
Member

@CohenArthur CohenArthur commented Feb 4, 2025

Fixes #2992

This adds a base for deriving PartialEq and Eq but misses some more complex stuff like struct enum items, as we need to add more to our nameres and codegen to handle these rebinding patterns.

We also need to rework this part of the expansion pass as derive(Eq) and derive(PartialEq) should both create two impls: one of their trait, and one of the associated Structural* trait this is now done in this PR.

This is ready for reviewing and merging IMO as a first basic implementation of derive(PartialEq) even if it does not support all types of Rust enums

@CohenArthur CohenArthur force-pushed the derive-partialeq-eq branch 4 times, most recently from 7243ef7 to d50fc0c Compare February 4, 2025 15:14
@P-E-P P-E-P self-requested a review February 5, 2025 14:11
gcc/rust/ChangeLog:

	* expand/rust-derive.cc (DeriveVisitor::derive): Call into DeriveEq.
	* expand/rust-derive-eq.cc: New file.
	* expand/rust-derive-eq.h: New file.
	* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

	* rust/compile/derive-eq-invalid.rs: New test.
gcc/rust/ChangeLog:

	* ast/rust-ast-builder.cc (Builder::block): Change return type.
	(Builder::loop): Use new APIs.
	* ast/rust-ast-builder.h: Change return type of block functions.
gcc/rust/ChangeLog:

	* ast/rust-ast-builder.cc (Builder::literal_bool): New method.
	(Builder::comparison_expr): Likewise.
	(Builder::boolean_operation): Likewise.
	* ast/rust-ast-builder.h: Declare them.
gcc/rust/ChangeLog:

	* expand/rust-derive-clone.cc: Cleanup implementation, avoid repetitions.
	* expand/rust-derive-clone.h: Likewise.
We are still missing some deriving for enums, as part of our codegen and nameres for rebinding struct
field patterns is missing.

gcc/rust/ChangeLog:

	* expand/rust-derive-partial-eq.cc: New file.
	* expand/rust-derive-partial-eq.h: New file.
	* expand/rust-derive.cc (DeriveVisitor::derive): Call them.
	* Make-lang.in: Compile them.

gcc/testsuite/ChangeLog:

	* rust/compile/derive-eq-invalid.rs: Mark PartialEq def as a lang item.
	* rust/compile/derive-partialeq1.rs: New test.
	* rust/execute/torture/derive-partialeq1.rs: New test.
	* rust/compile/nr2/exclude: Exclude all of them.
gcc/rust/ChangeLog:

	* expand/rust-derive.cc (DeriveVisitor::derive): Return a vector of items.
	* expand/rust-derive.h: Change return type.
	* expand/rust-expand-visitor.cc: Insert all generated items into the AST.
gcc/rust/ChangeLog:

	* expand/rust-derive-partial-eq.cc: Adapt signatures to generate two impls.
	* expand/rust-derive-partial-eq.h: Likewise.
	* expand/rust-derive.cc (DeriveVisitor::derive): Adapt to multiple item generation.

gcc/testsuite/ChangeLog:

	* rust/compile/derive-eq-invalid.rs: Declare StructuralPartialEq.
	* rust/compile/derive-partialeq1.rs: Likewise.
	* rust/execute/torture/derive-partialeq1.rs: Likewise.
gcc/rust/ChangeLog:

	* expand/rust-derive-eq.cc: Adapt functions to return two generated impls.
	* expand/rust-derive-eq.h: Likewise.
	* expand/rust-derive.cc (DeriveVisitor::derive): Likewise.
std::unique_ptr<Expr>
Builder::literal_bool (bool b) const
{
auto str = b ? "true" : "false";
Copy link
Member

Choose a reason for hiding this comment

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

We should probably use the keyword value from rust-keyword-values.h.

std::unique_ptr<AssociatedItem> &&fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
auto eq = builder.type_path ({"core", "cmp", "Eq"}, true);
Copy link
Member

Choose a reason for hiding this comment

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

Should we make this path (or individual segments) available globally like weak keywords ?

// nothing to do as they contain no inner types
continue;
case EnumItem::Kind::Tuple: {
auto tuple = static_cast<EnumItemTuple &> (*variant);
Copy link
Member

Choose a reason for hiding this comment

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

We want to avoid the copy here auto &tuple = static_cast<EnumItemTuple &> (*variant);.

break;
}
case EnumItem::Kind::Struct: {
auto tuple = static_cast<EnumItemStruct &> (*variant);
Copy link
Member

Choose a reason for hiding this comment

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

Likewise.

@@ -0,0 +1,313 @@
// Copyright (C) 2020-2024 Free Software Foundation, Inc.
Copy link
Member

Choose a reason for hiding this comment

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

Date range is incorrect, should be 2025 instead of 2020-2024.

auto block = builder.block (tl::nullopt, std::move (cmp_expression));

auto self_type
= std::unique_ptr<TypeNoBounds> (new TypePath (builder.type_path ("Self")));
Copy link
Member

Choose a reason for hiding this comment

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

We may use rust-keyword-values.h, unsure if it would make it more readable though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Eq
2 participants