[gcc/devel/rust/master] Add support for TuplePattern in let statements

Thomas Schwinge tschwinge@gcc.gnu.org
Sat Feb 11 15:30:27 GMT 2023


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

commit d9eb2eb73c223d481dd0009d723bec0f57e1662a
Author: Owen Avery <powerboat9.gamer@gmail.com>
Date:   Sat Feb 4 00:02:22 2023 -0500

    Add support for TuplePattern in let statements
    
    gcc/rust/ChangeLog:
    
            * hir/tree/rust-hir-pattern.h
            (TuplePatternItemsRanged::get_lower_patterns): Add method.
            (TuplePatternItemsRanged::get_upper_patterns): Add method.
            * backend/rust-compile-pattern.cc
            (CompilePatternLet::visit): Implement TuplePattern visitor.
            * backend/rust-compile-pattern.h
            (CompilePatternLet::visit): Move TuplePattern visitor out of header file.
    
    gcc/testsuite/ChangeLog:
    
            * rust/execute/torture/let-pattern-1.rs: New test.
    
    Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>

Diff:
---
 gcc/rust/backend/rust-compile-pattern.cc           | 87 ++++++++++++++++++++++
 gcc/rust/backend/rust-compile-pattern.h            |  7 +-
 gcc/rust/hir/tree/rust-hir-pattern.h               | 18 +++++
 .../rust/execute/torture/let-pattern-1.rs          |  4 +
 4 files changed, 110 insertions(+), 6 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index 4c45a5377c0..c91dca195e2 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -387,5 +387,92 @@ CompilePatternLet::visit (HIR::WildcardPattern &pattern)
     }
 }
 
+void
+CompilePatternLet::visit (HIR::TuplePattern &pattern)
+{
+  rust_assert (pattern.has_tuple_pattern_items ());
+
+  tree tuple_type = TyTyResolveCompile::compile (ctx, ty);
+  tree init_stmt;
+  Bvariable *tmp_var
+    = ctx->get_backend ()->temporary_variable (ctx->peek_fn ().fndecl,
+					       NULL_TREE, tuple_type, init_expr,
+					       false, pattern.get_locus (),
+					       &init_stmt);
+  tree access_expr
+    = ctx->get_backend ()->var_expression (tmp_var, pattern.get_locus ());
+  ctx->add_statement (init_stmt);
+
+  switch (pattern.get_items ()->get_pattern_type ())
+    {
+      case HIR::TuplePatternItems::TuplePatternItemType::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 pattern_id = pattern.get_pattern_mappings ().get_hirid ();
+	    bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub);
+	    rust_assert (ok);
+
+	    tree sub_init = ctx->get_backend ()->struct_field_expression (
+	      access_expr, tuple_idx, sub->get_locus ());
+	    CompilePatternLet::Compile (sub.get (), sub_init, ty_sub,
+					rval_locus, 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 pattern_id = pattern.get_pattern_mappings ().get_hirid ();
+	    bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub);
+	    rust_assert (ok);
+
+	    tree sub_init = ctx->get_backend ()->struct_field_expression (
+	      access_expr, tuple_idx, sub->get_locus ());
+	    CompilePatternLet::Compile (sub.get (), sub_init, ty_sub,
+					rval_locus, ctx);
+	    tuple_idx++;
+	  }
+
+	return;
+      }
+      case HIR::TuplePatternItems::TuplePatternItemType::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 pattern_id = pattern.get_pattern_mappings ().get_hirid ();
+	    bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub);
+	    rust_assert (ok);
+
+	    tree sub_init = ctx->get_backend ()->struct_field_expression (
+	      access_expr, tuple_idx, sub->get_locus ());
+	    CompilePatternLet::Compile (sub.get (), sub_init, ty_sub,
+					rval_locus, ctx);
+	    tuple_idx++;
+	  }
+
+	return;
+      }
+      default: {
+	gcc_unreachable ();
+      }
+    }
+}
+
 } // namespace Compile
 } // namespace Rust
diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h
index fdaa51994f5..d2a5b33b83a 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -101,6 +101,7 @@ public:
 
   void visit (HIR::IdentifierPattern &) override;
   void visit (HIR::WildcardPattern &) override;
+  void visit (HIR::TuplePattern &) override;
 
   // check for unimplemented Pattern HIR nodes.
   void visit (HIR::LiteralPattern &pattern) override
@@ -146,12 +147,6 @@ public:
 		   "struct pattern let statements not supported");
   }
 
-  void visit (HIR::TuplePattern &pattern) override
-  {
-    rust_sorry_at (pattern.get_locus (),
-		   "tuple pattern let statements not supported");
-  }
-
   void visit (HIR::TupleStructPattern &pattern) override
   {
     rust_sorry_at (pattern.get_locus (),
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index c1c392f68d5..e7a298033d7 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -1142,6 +1142,24 @@ public:
     return TuplePatternItemType::RANGED;
   }
 
+  std::vector<std::unique_ptr<Pattern> > &get_lower_patterns ()
+  {
+    return lower_patterns;
+  }
+  const std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () const
+  {
+    return lower_patterns;
+  }
+
+  std::vector<std::unique_ptr<Pattern> > &get_upper_patterns ()
+  {
+    return upper_patterns;
+  }
+  const std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () const
+  {
+    return upper_patterns;
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object rather
    * than base */
diff --git a/gcc/testsuite/rust/execute/torture/let-pattern-1.rs b/gcc/testsuite/rust/execute/torture/let-pattern-1.rs
new file mode 100644
index 00000000000..107d819a69f
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/let-pattern-1.rs
@@ -0,0 +1,4 @@
+fn main() -> i32 {
+    let (x, y, z) = (2, 3, 6);
+    x * y - z
+}


More information about the Gcc-cvs mailing list