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

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/expand/rust-derive.cc         | 16 ++++++++--------
 gcc/rust/expand/rust-derive.h          |  8 ++++++--
 gcc/rust/expand/rust-expand-visitor.cc | 13 ++++++++-----
 3 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/gcc/rust/expand/rust-derive.cc b/gcc/rust/expand/rust-derive.cc
index 1f89502f639..cd162247ec4 100644
--- a/gcc/rust/expand/rust-derive.cc
+++ b/gcc/rust/expand/rust-derive.cc
@@ -31,34 +31,34 @@ DeriveVisitor::DeriveVisitor (location_t loc)
   : loc (loc), builder (Builder (loc))
 {}
 
-std::unique_ptr<Item>
+std::vector<std::unique_ptr<Item>>
 DeriveVisitor::derive (Item &item, const Attribute &attr,
                       BuiltinMacro to_derive)
 {
   switch (to_derive)
     {
     case BuiltinMacro::Clone:
-      return DeriveClone (attr.get_locus ()).go (item);
+      return vec (DeriveClone (attr.get_locus ()).go (item));
     case BuiltinMacro::Copy:
-      return DeriveCopy (attr.get_locus ()).go (item);
+      return vec (DeriveCopy (attr.get_locus ()).go (item));
     case BuiltinMacro::Debug:
       rust_warning_at (
        attr.get_locus (), 0,
        "derive(Debug) is not fully implemented yet and has no effect - only a "
        "stub implementation will be generated");
-      return DeriveDebug (attr.get_locus ()).go (item);
+      return vec (DeriveDebug (attr.get_locus ()).go (item));
     case BuiltinMacro::Default:
-      return DeriveDefault (attr.get_locus ()).go (item);
+      return vec (DeriveDefault (attr.get_locus ()).go (item));
     case BuiltinMacro::Eq:
-      return DeriveEq (attr.get_locus ()).go (item);
+      return vec (DeriveEq (attr.get_locus ()).go (item));
     case BuiltinMacro::PartialEq:
-      return DerivePartialEq (attr.get_locus ()).go (item);
+      return vec (DerivePartialEq (attr.get_locus ()).go (item));
     case BuiltinMacro::Ord:
     case BuiltinMacro::PartialOrd:
     case BuiltinMacro::Hash:
     default:
       rust_sorry_at (attr.get_locus (), "unimplemented builtin derive macro");
-      return nullptr;
+      return {};
     };
 }
 
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index a494cc3c312..d8cc0a480ab 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -34,8 +34,12 @@ namespace AST {
 class DeriveVisitor : public AST::ASTVisitor
 {
 public:
-  static std::unique_ptr<Item> derive (Item &item, const Attribute &derive,
-                                      BuiltinMacro to_derive);
+  /**
+   * Expand a built-in derive macro on an item. This may generate multiple 
items
+   * which all need to be integrated to the existing AST
+   */
+  static std::vector<std::unique_ptr<Item>>
+  derive (Item &item, const Attribute &derive, BuiltinMacro to_derive);
 
 protected:
   DeriveVisitor (location_t loc);
diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index 6e06fa51609..8ba9a15fddf 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -43,7 +43,7 @@ ExpandVisitor::go (AST::Crate &crate)
   visit (crate);
 }
 
-static std::unique_ptr<AST::Item>
+static std::vector<std::unique_ptr<AST::Item>>
 builtin_derive_item (AST::Item &item, const AST::Attribute &derive,
                     BuiltinMacro to_derive)
 {
@@ -189,11 +189,12 @@ ExpandVisitor::expand_inner_items (
                        to_derive.get ().as_string ());
                      if (maybe_builtin.has_value ())
                        {
-                         auto new_item
+                         auto new_items
                            = builtin_derive_item (item, current,
                                                   maybe_builtin.value ());
 
-                         it = items.insert (it, std::move (new_item));
+                         for (auto &&new_item : new_items)
+                           it = items.insert (it, std::move (new_item));
                        }
                      else
                        {
@@ -276,12 +277,14 @@ ExpandVisitor::expand_inner_stmts (AST::BlockExpr &expr)
                        to_derive.get ().as_string ());
                      if (maybe_builtin.has_value ())
                        {
-                         auto new_item
+                         auto new_items
                            = builtin_derive_item (item, current,
                                                   maybe_builtin.value ());
+
                          // this inserts the derive *before* the item - is it a
                          // problem?
-                         it = stmts.insert (it, std::move (new_item));
+                         for (auto &&new_item : new_items)
+                           it = stmts.insert (it, std::move (new_item));
                        }
                      else
                        {
-- 
2.45.2

Reply via email to