public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-7640] gccrs: derive: Add proper derive(Clone) for unions
@ 2024-01-16 17:49 Arthur Cohen
  0 siblings, 0 replies; only message in thread
From: Arthur Cohen @ 2024-01-16 17:49 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:c566f9081067c9328a0f07bcc8bac46dc69d1599

commit r14-7640-gc566f9081067c9328a0f07bcc8bac46dc69d1599
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date:   Fri May 12 15:14:49 2023 +0200

    gccrs: derive: Add proper derive(Clone) for unions
    
    gcc/rust/ChangeLog:
    
            * ast/rust-ast-builder.cc (AstBuilder::struct_expr_struct): New function.
            (AstBuilder::let): Likewise.
            (AstBuilder::struct_expr): Likewise.
            (AstBuilder::struct_expr_field): Likewise.
            (AstBuilder::field_access): Likewise.
            (AstBuilder::wildcard): Likewise.
            * ast/rust-ast-builder.h: Likewise.
            * expand/rust-derive-clone.cc (DeriveClone::visit_union): Implement
            properly.
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/derive_macro4.rs: New test.
            * rust/compile/derive_macro6.rs: New test.

Diff:
---
 gcc/rust/ast/rust-ast-builder.cc            | 26 ++++++++++++++++----------
 gcc/rust/ast/rust-ast-builder.h             |  3 +++
 gcc/rust/expand/rust-derive-clone.cc        | 25 +++++++++++++++++++++++--
 gcc/testsuite/rust/compile/derive_macro4.rs | 16 ++++++++++++++++
 gcc/testsuite/rust/compile/derive_macro6.rs | 21 +++++++++++++++++++++
 5 files changed, 79 insertions(+), 12 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index d37f143ca34..b630cfa5392 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -81,13 +81,6 @@ AstBuilder::path_in_expression (std::vector<std::string> &&segments)
   return PathInExpression (std::move (path_segments), {}, loc);
 }
 
-std::unique_ptr<Expr>
-AstBuilder::struct_expr_struct (std::string struct_name)
-{
-  return std::unique_ptr<Expr> (
-    new StructExprStruct (path_in_expression ({struct_name}), {}, {}, loc));
-}
-
 std::unique_ptr<Expr>
 AstBuilder::block (std::vector<std::unique_ptr<Stmt>> &&stmts,
 		   std::unique_ptr<Expr> &&tail_expr)
@@ -100,9 +93,9 @@ std::unique_ptr<Stmt>
 AstBuilder::let (std::unique_ptr<Pattern> pattern, std::unique_ptr<Type> type,
 		 std::unique_ptr<Expr> init)
 {
-  return std::unique_ptr<Stmt> (
-    new LetStmt (/* needs a pattern here, not just a name */ nullptr,
-		 std::move (init), std::move (type), {}, loc));
+  return std::unique_ptr<Stmt> (new LetStmt (std::move (pattern),
+					     std::move (init), std::move (type),
+					     {}, loc));
 }
 
 std::unique_ptr<Expr>
@@ -118,6 +111,13 @@ AstBuilder::deref (std::unique_ptr<Expr> &&of)
   return std::unique_ptr<Expr> (new DereferenceExpr (std::move (of), {}, loc));
 }
 
+std::unique_ptr<Expr>
+AstBuilder::struct_expr_struct (std::string struct_name)
+{
+  return std::unique_ptr<Expr> (
+    new StructExprStruct (path_in_expression ({struct_name}), {}, {}, loc));
+}
+
 std::unique_ptr<Expr>
 AstBuilder::struct_expr (std::string struct_name,
 			 std::vector<std::unique_ptr<StructExprField>> &&fields)
@@ -142,5 +142,11 @@ AstBuilder::field_access (std::unique_ptr<Expr> &&instance, std::string field)
     new FieldAccessExpr (std::move (instance), field, {}, loc));
 }
 
+std::unique_ptr<Pattern>
+AstBuilder::wildcard ()
+{
+  return std::unique_ptr<Pattern> (new WildcardPattern (loc));
+}
+
 } // namespace AST
 } // namespace Rust
diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h
index 1c524b438d8..524b3905bbd 100644
--- a/gcc/rust/ast/rust-ast-builder.h
+++ b/gcc/rust/ast/rust-ast-builder.h
@@ -100,6 +100,9 @@ public:
   std::unique_ptr<Expr> field_access (std::unique_ptr<Expr> &&instance,
 				      std::string field);
 
+  /* Create a wildcard pattern (`_`) */
+  std::unique_ptr<Pattern> wildcard ();
+
 private:
   /**
    * Location of the generated AST nodes
diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc
index 176cee9b749..8529bac5019 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -155,8 +155,29 @@ DeriveClone::visit_enum (Enum &item)
 void
 DeriveClone::visit_union (Union &item)
 {
-  rust_sorry_at (item.get_locus (), "cannot derive %qs for these items yet",
-		 "Clone");
+  // FIXME: Should be $crate::core::clone::AssertParamIsCopy (or similar)
+
+  // <Self>
+  auto arg = GenericArg::create_type (builder.single_type_path ("Self"));
+
+  // AssertParamIsCopy::<Self>
+  auto type = std::unique_ptr<TypePathSegment> (
+    new TypePathSegmentGeneric (PathIdentSegment ("AssertParamIsCopy", loc),
+				false, GenericArgs ({}, {arg}, {}, loc), loc));
+  auto type_paths = std::vector<std::unique_ptr<TypePathSegment>> ();
+  type_paths.emplace_back (std::move (type));
+
+  auto full_path
+    = std::unique_ptr<Type> (new TypePath ({std::move (type_paths)}, loc));
+
+  auto stmts = std::vector<std::unique_ptr<Stmt>> ();
+  stmts.emplace_back (
+    builder.let (builder.wildcard (), std::move (full_path), nullptr));
+  auto tail_expr = builder.deref (builder.identifier ("self"));
+
+  auto block = builder.block (std::move (stmts), std::move (tail_expr));
+
+  expanded = clone_impl (clone_fn (std::move (block)), item.get_identifier ());
 }
 
 } // namespace AST
diff --git a/gcc/testsuite/rust/compile/derive_macro4.rs b/gcc/testsuite/rust/compile/derive_macro4.rs
new file mode 100644
index 00000000000..564555f896f
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive_macro4.rs
@@ -0,0 +1,16 @@
+pub trait Copy {}
+pub trait Clone {
+    fn clone(&self) -> Self;
+}
+
+struct PhantomData<T>;
+
+pub struct AssertParamIsCopy<T: Copy> {
+    _field: PhantomData<T>,
+}
+
+#[derive(Clone)] // { dg-error "bounds not satisfied for U .Copy. is not satisfied" }
+union U {
+    i: i32,
+    f: f64,
+}
diff --git a/gcc/testsuite/rust/compile/derive_macro6.rs b/gcc/testsuite/rust/compile/derive_macro6.rs
new file mode 100644
index 00000000000..0254754f7ae
--- /dev/null
+++ b/gcc/testsuite/rust/compile/derive_macro6.rs
@@ -0,0 +1,21 @@
+pub trait Copy {}
+pub trait Clone {
+    fn clone(&self) -> Self;
+}
+
+#[lang = "phantom_data"]
+pub struct PhantomData<T>;
+
+pub struct AssertParamIsCopy<T: Copy> {
+    pub _field: PhantomData<T>,
+}
+
+impl Copy for i32 {}
+impl Copy for i64 {}
+impl Copy for U {}
+
+#[derive(Clone)]
+union U {
+    i: i32,
+    f: f64,
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-01-16 17:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-16 17:49 [gcc r14-7640] gccrs: derive: Add proper derive(Clone) for unions Arthur Cohen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).