From: Arthur Cohen <arthur.co...@embecosm.com>

gcc/rust/ChangeLog:

        * expand/rust-derive-ord.cc (DeriveOrd::make_cmp_arms): Use new 
make_equal function.
        (DeriveOrd::make_equal): New function.
        (DeriveOrd::recursive_match): Handle the unit struct/tuple case.
        * expand/rust-derive-ord.h: Declare make_equal.
---
 gcc/rust/expand/rust-derive-ord.cc | 31 +++++++++++++++++++++++++-----
 gcc/rust/expand/rust-derive-ord.h  |  6 ++++++
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/expand/rust-derive-ord.cc 
b/gcc/rust/expand/rust-derive-ord.cc
index 1623495b8b6..dfc014446fa 100644
--- a/gcc/rust/expand/rust-derive-ord.cc
+++ b/gcc/rust/expand/rust-derive-ord.cc
@@ -109,12 +109,9 @@ DeriveOrd::cmp_fn (std::unique_ptr<BlockExpr> &&block, 
Identifier type_name)
                           ptrify (return_type), std::move (block));
 }
 
-std::pair<MatchArm, MatchArm>
-DeriveOrd::make_cmp_arms ()
+std::unique_ptr<Pattern>
+DeriveOrd::make_equal ()
 {
-  // All comparison results other than Ordering::Equal
-  auto non_equal = builder.identifier_pattern (DeriveOrd::not_equal);
-
   std::unique_ptr<Pattern> equal = ptrify (
     builder.path_in_expression ({"core", "cmp", "Ordering", "Equal"}, true));
 
@@ -131,6 +128,16 @@ DeriveOrd::make_cmp_arms ()
                                                std::move (pattern_items));
     }
 
+  return equal;
+}
+
+std::pair<MatchArm, MatchArm>
+DeriveOrd::make_cmp_arms ()
+{
+  // All comparison results other than Ordering::Equal
+  auto non_equal = builder.identifier_pattern (DeriveOrd::not_equal);
+  auto equal = make_equal ();
+
   return {builder.match_arm (std::move (equal)),
          builder.match_arm (std::move (non_equal))};
 }
@@ -138,6 +145,20 @@ DeriveOrd::make_cmp_arms ()
 std::unique_ptr<Expr>
 DeriveOrd::recursive_match (std::vector<SelfOther> &&members)
 {
+  if (members.empty ())
+    {
+      std::unique_ptr<Expr> value = ptrify (
+       builder.path_in_expression ({"core", "cmp", "Ordering", "Equal"},
+                                   true));
+
+      if (ordering == Ordering::Partial)
+       value = builder.call (ptrify (builder.path_in_expression (
+                               LangItem::Kind::OPTION_SOME)),
+                             std::move (value));
+
+      return value;
+    }
+
   std::unique_ptr<Expr> final_expr = nullptr;
 
   for (auto it = members.rbegin (); it != members.rend (); it++)
diff --git a/gcc/rust/expand/rust-derive-ord.h 
b/gcc/rust/expand/rust-derive-ord.h
index 20086afe9b7..90ce9c8ca6f 100644
--- a/gcc/rust/expand/rust-derive-ord.h
+++ b/gcc/rust/expand/rust-derive-ord.h
@@ -79,6 +79,12 @@ private:
    */
   std::unique_ptr<Expr> recursive_match (std::vector<SelfOther> &&members);
 
+  /**
+   * Create a pattern for the `Ordering::Equal` case. In the case of partial
+   * ordering, `Option::Some(Ordering::Equal)`.
+   */
+  std::unique_ptr<Pattern> make_equal ();
+
   /**
    * Make the match arms for one inner match in a comparison function block.
    * This returns the "equal" match arm and the "rest" match arm, so something
-- 
2.49.0

Reply via email to