-
Notifications
You must be signed in to change notification settings - Fork 170
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
Conversation
7243ef7
to
d50fc0c
Compare
b9c5bdf
to
741e633
Compare
gcc/rust/ast/rust-ast-builder.cc
Outdated
std::unique_ptr<Expr> | ||
Builder::literal_bool (bool b) const | ||
{ | ||
auto str = b ? "true" : "false"; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's important here as this is only used when generating code, which isn't done too often. we rarely repeat paths, and making individual segments available doesn't really help a lot I feel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also probably create two type paths here, one for creating eq_impl
and one for creating eq_generics
-- otherwise, two AST nodes sharing the same node id throws the 2.0 name resolver for a loop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking it might be best to just ignore duplicate map_usage
calls, as long as one usage is only ever mapped to one definition, in which case my previous suggestion can be ignored
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's probably cleaner to have different node IDs for different nodes even if it makes the derive code very slightly messier
gcc/rust/expand/rust-derive-eq.cc
Outdated
// nothing to do as they contain no inner types | ||
continue; | ||
case EnumItem::Kind::Tuple: { | ||
auto tuple = static_cast<EnumItemTuple &> (*variant); |
There was a problem hiding this comment.
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);
.
gcc/rust/expand/rust-derive-eq.cc
Outdated
break; | ||
} | ||
case EnumItem::Kind::Struct: { | ||
auto tuple = static_cast<EnumItemStruct &> (*variant); |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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
.
DeriveEq::assert_param_is_eq () | ||
{ | ||
auto eq_bound = std::unique_ptr<TypeParamBound> ( | ||
new TraitBound (builder.type_path ({"core", "cmp", "Eq"}, true), loc)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be a lang item path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, Eq
isn't a lang item in 1.49:
#[doc(alias = "==")]
#[doc(alias = "!=")]
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Eq: PartialEq<Self> {
// this method is used solely by #[deriving] to assert
// that every component of a type implements #[deriving]
// itself, the current deriving infrastructure means doing this
// assertion without using a method on this trait is nearly
// impossible.
//
// This should never be implemented by hand.
#[doc(hidden)]
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn assert_receiver_is_total_eq(&self) {}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dang
issue-3402-1.rs | ||
for-loop1.rs | ||
for-loop2.rs | ||
issue-3403.rs | ||
derive-default1.rs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unnecessary move
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, that's merge conflicts when rebasing - thanks for catching it, I'll fix it
741e633
to
58c9608
Compare
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.
gcc/rust/ChangeLog: * expand/rust-derive-eq.cc: Copy `Eq` typepath.
58c9608
to
1149921
Compare
Fixes #2992
This adds a base for deriving
PartialEq
andEq
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 asthis is now done in this PR.derive(Eq)
andderive(PartialEq)
should both create two impls: one of their trait, and one of the associatedStructural*
traitThis 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