https://gcc.gnu.org/g:18d289ca2b1996aa76b902432941e88fa3497b6d

commit r15-8573-g18d289ca2b1996aa76b902432941e88fa3497b6d
Author: Philip Herron <herron.phi...@googlemail.com>
Date:   Fri Dec 13 15:51:55 2024 +0000

    gccrs: implement the TuplePattern and use it for function patterns
    
    In order to handle the tuple pattern of: fn test ((x _) : (i32, i32)) -> 
i32 { x }
    we need to recognize that ABI wise this function still takes a tuple as the 
parameter
    to this function its just how we can address the "pattern" of the tuple 
changes.
    
    So reall if this was C it would look like:
    
      void test (struct tuple_type __prameter)
      {
        return __parameter.0
      }
    
    The code here reuses our existing pattern code so that we generate these 
implicit
    bindings of the paramter with a field access so any time x is referenced 
it's really
    just emplacing __parameter.0 for the field access into the struct which is 
a tuple.
    
    Fixes Rust-GCC#2847
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-fnparam.cc (CompileFnParam::visit): compile 
tuple patterns
            (CompileSelfParam::compile): update return type
            (CompileFnParam::create_tmp_param_var): return Bvariable not tree 
to stop ICE
            * backend/rust-compile-fnparam.h: update prototype
            * backend/rust-compile-pattern.cc (CompilePatternBindings::visit): 
implement TuplePattern
            * backend/rust-compile-pattern.h: update prototype
    
    gcc/testsuite/ChangeLog:
    
            * rust/compile/issue-2847.rs: New test.
    
    Signed-off-by: Philip Herron <herron.phi...@googlemail.com>

Diff:
---
 gcc/rust/backend/rust-compile-fnparam.cc | 31 ++++++++----
 gcc/rust/backend/rust-compile-fnparam.h  |  4 +-
 gcc/rust/backend/rust-compile-pattern.cc | 86 ++++++++++++++++++++++++++++++++
 gcc/rust/backend/rust-compile-pattern.h  |  2 +-
 gcc/testsuite/rust/compile/issue-2847.rs |  8 +++
 5 files changed, 117 insertions(+), 14 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-fnparam.cc 
b/gcc/rust/backend/rust-compile-fnparam.cc
index c00092d219e2..b40065e110d1 100644
--- a/gcc/rust/backend/rust-compile-fnparam.cc
+++ b/gcc/rust/backend/rust-compile-fnparam.cc
@@ -68,25 +68,36 @@ CompileFnParam::visit (HIR::WildcardPattern &pattern)
   compiled_param = Backend::parameter_variable (fndecl, "_", decl_type, locus);
 }
 
+void
+CompileFnParam::visit (HIR::TuplePattern &pattern)
+{
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+    pattern, Backend::var_expression (compiled_param, locus), ctx);
+}
+
 void
 CompileFnParam::visit (HIR::StructPattern &pattern)
 {
-  tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+    pattern, Backend::var_expression (compiled_param, locus), ctx);
 }
 
 void
 CompileFnParam::visit (HIR::TupleStructPattern &pattern)
 {
-  tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+    pattern, Backend::var_expression (compiled_param, locus), ctx);
 }
 
 void
 CompileFnParam::visit (HIR::ReferencePattern &pattern)
 {
-  tree tmp_param_var = create_tmp_param_var (decl_type);
-  CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+  compiled_param = create_tmp_param_var (decl_type);
+  CompilePatternBindings::Compile (
+    pattern, Backend::var_expression (compiled_param, locus), ctx);
 }
 
 Bvariable *
@@ -102,7 +113,7 @@ CompileSelfParam::compile (Context *ctx, tree fndecl, 
HIR::SelfParam &self,
   return Backend::parameter_variable (fndecl, "self", decl_type, locus);
 }
 
-tree
+Bvariable *
 CompileFnParam::create_tmp_param_var (tree decl_type)
 {
   // generate the anon param
@@ -110,10 +121,8 @@ CompileFnParam::create_tmp_param_var (tree decl_type)
   std::string cpp_str_identifier = std::string (IDENTIFIER_POINTER 
(tmp_ident));
 
   decl_type = Backend::immutable_type (decl_type);
-  compiled_param = Backend::parameter_variable (fndecl, cpp_str_identifier,
-                                               decl_type, locus);
-
-  return Backend::var_expression (compiled_param, locus);
+  return Backend::parameter_variable (fndecl, cpp_str_identifier, decl_type,
+                                     locus);
 }
 
 } // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-fnparam.h 
b/gcc/rust/backend/rust-compile-fnparam.h
index 82a705fde7b9..189216c9ba49 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -47,12 +47,12 @@ public:
   void visit (HIR::QualifiedPathInExpression &) override {}
   void visit (HIR::RangePattern &) override {}
   void visit (HIR::SlicePattern &) override {}
-  void visit (HIR::TuplePattern &) override {}
+  void visit (HIR::TuplePattern &) override;
 
 private:
   CompileFnParam (Context *ctx, tree fndecl, tree decl_type, location_t locus);
 
-  tree create_tmp_param_var (tree decl_type);
+  Bvariable *create_tmp_param_var (tree decl_type);
 
   tree fndecl;
   tree decl_type;
diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index d6161bd5e831..b2e7c351f952 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -613,6 +613,92 @@ CompilePatternBindings::visit (HIR::IdentifierPattern 
&pattern)
                               match_scrutinee_expr);
 }
 
+void
+CompilePatternBindings::visit (HIR::TuplePattern &pattern)
+{
+  rust_assert (pattern.has_tuple_pattern_items ());
+
+  // lookup the type
+  TyTy::BaseType *ty = nullptr;
+  bool ok
+    = ctx->get_tyctx ()->lookup_type (pattern.get_mappings ().get_hirid (),
+                                     &ty);
+  rust_assert (ok);
+
+  switch (pattern.get_items ().get_item_type ())
+    {
+      case HIR::TuplePatternItems::ItemType::RANGED: {
+       size_t tuple_idx = 0;
+       auto &items
+         = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+
+       auto &items_lower = items.get_lower_patterns ();
+       auto &items_upper = items.get_upper_patterns ();
+
+       for (auto &sub : items_lower)
+         {
+           TyTy::BaseType *ty_sub = nullptr;
+           HirId sub_id = sub->get_mappings ().get_hirid ();
+           bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+           rust_assert (ok);
+
+           tree sub_init
+             = Backend::struct_field_expression (match_scrutinee_expr,
+                                                 tuple_idx, sub->get_locus ());
+
+           CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+           tuple_idx++;
+         }
+
+       rust_assert (ty->get_kind () == TyTy::TypeKind::TUPLE);
+       tuple_idx = static_cast<TyTy::TupleType &> (*ty).num_fields ()
+                   - items_upper.size ();
+
+       for (auto &sub : items_upper)
+         {
+           TyTy::BaseType *ty_sub = nullptr;
+           HirId sub_id = sub->get_mappings ().get_hirid ();
+           bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+           rust_assert (ok);
+
+           tree sub_init
+             = Backend::struct_field_expression (match_scrutinee_expr,
+                                                 tuple_idx, sub->get_locus ());
+           CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+           tuple_idx++;
+         }
+
+       return;
+      }
+      case HIR::TuplePatternItems::ItemType::MULTIPLE: {
+       size_t tuple_idx = 0;
+       auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
+         pattern.get_items ());
+
+       for (auto &sub : items.get_patterns ())
+         {
+           TyTy::BaseType *ty_sub = nullptr;
+           HirId sub_id = sub->get_mappings ().get_hirid ();
+           bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+           rust_assert (ok);
+
+           tree sub_init
+             = Backend::struct_field_expression (match_scrutinee_expr,
+                                                 tuple_idx, sub->get_locus ());
+           CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+           tuple_idx++;
+         }
+
+       return;
+      }
+      default: {
+       rust_unreachable ();
+      }
+    }
+}
+
+//
+
 void
 CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
 {
diff --git a/gcc/rust/backend/rust-compile-pattern.h 
b/gcc/rust/backend/rust-compile-pattern.h
index 0b785c6ce8c9..c7a62fcbc532 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -82,6 +82,7 @@ public:
   void visit (HIR::TupleStructPattern &pattern) override;
   void visit (HIR::ReferencePattern &pattern) override;
   void visit (HIR::IdentifierPattern &) override;
+  void visit (HIR::TuplePattern &pattern) override;
 
   // Empty visit for unused Pattern HIR nodes.
   void visit (HIR::AltPattern &) override {}
@@ -90,7 +91,6 @@ public:
   void visit (HIR::QualifiedPathInExpression &) override {}
   void visit (HIR::RangePattern &) override {}
   void visit (HIR::SlicePattern &) override {}
-  void visit (HIR::TuplePattern &) override {}
   void visit (HIR::WildcardPattern &) override {}
 
 protected:
diff --git a/gcc/testsuite/rust/compile/issue-2847.rs 
b/gcc/testsuite/rust/compile/issue-2847.rs
new file mode 100644
index 000000000000..2bc556666c19
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2847.rs
@@ -0,0 +1,8 @@
+pub fn myfun1((x, _): (i32, i32)) -> i32 {
+    x
+}
+
+pub fn myfun2() -> i32 {
+    let (x, _) = (1, 2);
+    x
+}

Reply via email to