aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2025-02-04 16:06:33 +0100
committerCohenArthur <arthur.cohen@embecosm.com>2025-02-20 09:37:09 +0000
commiteca22285618fd9ac63ae95030d24af78a08475e1 (patch)
tree8f88d62ca9879c9aa1a0e48d30378a28f89dc62b
parentbad70abc60e4a6d466bfbdfccb424b7d127c57b8 (diff)
downloadgcc-eca22285618fd9ac63ae95030d24af78a08475e1.zip
gcc-eca22285618fd9ac63ae95030d24af78a08475e1.tar.gz
gcc-eca22285618fd9ac63ae95030d24af78a08475e1.tar.bz2
derive(PartialEq): Also derive StructuralPartialEq
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.
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.cc43
-rw-r--r--gcc/rust/expand/rust-derive-partial-eq.h10
-rw-r--r--gcc/rust/expand/rust-derive.cc2
-rw-r--r--gcc/testsuite/rust/compile/derive-eq-invalid.rs6
-rw-r--r--gcc/testsuite/rust/compile/derive-partialeq1.rs3
-rw-r--r--gcc/testsuite/rust/execute/torture/derive-partialeq1.rs3
6 files changed, 44 insertions, 23 deletions
diff --git a/gcc/rust/expand/rust-derive-partial-eq.cc b/gcc/rust/expand/rust-derive-partial-eq.cc
index 6f7ef7d..ff66faa 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.cc
+++ b/gcc/rust/expand/rust-derive-partial-eq.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2020-2024 Free Software Foundation, Inc.
+// Copyright (C) 2025 Free Software Foundation, Inc.
// This file is part of GCC.
@@ -27,35 +27,40 @@
namespace Rust {
namespace AST {
-DerivePartialEq::DerivePartialEq (location_t loc)
- : DeriveVisitor (loc), expanded (nullptr)
-{}
+DerivePartialEq::DerivePartialEq (location_t loc) : DeriveVisitor (loc) {}
-std::unique_ptr<AST::Item>
+std::vector<std::unique_ptr<AST::Item>>
DerivePartialEq::go (Item &item)
{
item.accept_vis (*this);
- rust_assert (expanded);
-
return std::move (expanded);
}
-std::unique_ptr<Item>
-DerivePartialEq::partial_eq_impl (
+std::vector<std::unique_ptr<Item>>
+DerivePartialEq::partialeq_impls (
std::unique_ptr<AssociatedItem> &&eq_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics)
{
auto eq = builder.type_path (LangItem::Kind::EQ);
+ auto speq = builder.type_path (LangItem::Kind::STRUCTURAL_PEQ);
auto trait_items = vec (std::move (eq_fn));
- auto generics
+ // no extra bound on StructuralPeq
+ auto peq_generics
= setup_impl_generics (name, type_generics, builder.trait_bound (eq));
+ auto speq_generics = setup_impl_generics (name, type_generics);
+
+ auto peq = builder.trait_impl (eq, std::move (peq_generics.self_type),
+ std::move (trait_items),
+ std::move (peq_generics.impl));
+
+ auto structural_peq
+ = builder.trait_impl (speq, std::move (speq_generics.self_type), {},
+ std::move (speq_generics.impl));
- return builder.trait_impl (eq, std::move (generics.self_type),
- std::move (trait_items),
- std::move (generics.impl));
+ return vec (std::move (peq), std::move (structural_peq));
}
std::unique_ptr<AssociatedItem>
@@ -137,7 +142,7 @@ DerivePartialEq::visit_tuple (TupleStruct &item)
auto fn = eq_fn (build_eq_expression (std::move (fields)), type_name);
expanded
- = partial_eq_impl (std::move (fn), type_name, item.get_generic_params ());
+ = partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
}
void
@@ -153,7 +158,7 @@ DerivePartialEq::visit_struct (StructStruct &item)
auto fn = eq_fn (build_eq_expression (std::move (fields)), type_name);
expanded
- = partial_eq_impl (std::move (fn), type_name, item.get_generic_params ());
+ = partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
}
MatchCase
@@ -250,11 +255,12 @@ void
DerivePartialEq::visit_enum (Enum &item)
{
auto cases = std::vector<MatchCase> ();
+ auto type_name = item.get_identifier ().as_string ();
for (auto &variant : item.get_variants ())
{
auto variant_path
- = builder.variant_path (item.get_identifier ().as_string (),
+ = builder.variant_path (type_name,
variant->get_identifier ().as_string ());
switch (variant->get_enum_item_kind ())
@@ -290,11 +296,10 @@ DerivePartialEq::visit_enum (Enum &item)
builder.identifier ("other"))),
std::move (cases));
- auto fn = eq_fn (std::move (match), item.get_identifier ().as_string ());
+ auto fn = eq_fn (std::move (match), type_name);
expanded
- = partial_eq_impl (std::move (fn), item.get_identifier ().as_string (),
- item.get_generic_params ());
+ = partialeq_impls (std::move (fn), type_name, item.get_generic_params ());
}
void
diff --git a/gcc/rust/expand/rust-derive-partial-eq.h b/gcc/rust/expand/rust-derive-partial-eq.h
index 2bc18d2..ac963a6 100644
--- a/gcc/rust/expand/rust-derive-partial-eq.h
+++ b/gcc/rust/expand/rust-derive-partial-eq.h
@@ -30,12 +30,16 @@ class DerivePartialEq : DeriveVisitor
public:
DerivePartialEq (location_t loc);
- std::unique_ptr<AST::Item> go (Item &item);
+ std::vector<std::unique_ptr<AST::Item>> go (Item &item);
private:
- std::unique_ptr<Item> expanded;
+ std::vector<std::unique_ptr<Item>> expanded;
- std::unique_ptr<Item> partial_eq_impl (
+ /**
+ * Generate both an implementation of `PartialEq` and `StructuralPartialEq`
+ * for the given type
+ */
+ std::vector<std::unique_ptr<Item>> partialeq_impls (
std::unique_ptr<AssociatedItem> &&eq_fn, std::string name,
const std::vector<std::unique_ptr<GenericParam>> &type_generics);
diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index bfcfd8f..56e0e94 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -52,7 +52,7 @@ DeriveVisitor::derive (Item &item, const Attribute &attr,
case BuiltinMacro::Eq:
return vec (DeriveEq (attr.get_locus ()).go (item));
case BuiltinMacro::PartialEq:
- return vec (DerivePartialEq (attr.get_locus ()).go (item));
+ return DerivePartialEq (attr.get_locus ()).go (item);
case BuiltinMacro::Ord:
case BuiltinMacro::PartialOrd:
case BuiltinMacro::Hash:
diff --git a/gcc/testsuite/rust/compile/derive-eq-invalid.rs b/gcc/testsuite/rust/compile/derive-eq-invalid.rs
index 0c4d48e..b0bf856 100644
--- a/gcc/testsuite/rust/compile/derive-eq-invalid.rs
+++ b/gcc/testsuite/rust/compile/derive-eq-invalid.rs
@@ -21,6 +21,12 @@ struct PhantomData<T>;
#[lang = "sized"]
trait Sized {}
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
+#[lang = "structural_teq"]
+trait StructuralEq {}
+
#[derive(PartialEq)]
struct NotEq;
diff --git a/gcc/testsuite/rust/compile/derive-partialeq1.rs b/gcc/testsuite/rust/compile/derive-partialeq1.rs
index 7151324..35e33fb 100644
--- a/gcc/testsuite/rust/compile/derive-partialeq1.rs
+++ b/gcc/testsuite/rust/compile/derive-partialeq1.rs
@@ -6,6 +6,9 @@ trait Sized {}
#[lang = "copy"]
trait Copy {}
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
#[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> {
/// This method tests for `self` and `other` values to be equal, and is used
diff --git a/gcc/testsuite/rust/execute/torture/derive-partialeq1.rs b/gcc/testsuite/rust/execute/torture/derive-partialeq1.rs
index 4d5124e..67b2773 100644
--- a/gcc/testsuite/rust/execute/torture/derive-partialeq1.rs
+++ b/gcc/testsuite/rust/execute/torture/derive-partialeq1.rs
@@ -25,6 +25,9 @@ pub trait PartialEq<Rhs: ?Sized = Self> {
}
}
+#[lang = "structural_peq"]
+trait StructuralPartialEq {}
+
#[derive(PartialEq, Copy)] // { dg-warning "unused name" }
struct Foo;