]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Implement missing var decl case for TuplePatternItemsHasRest
authorYap Zhi Heng <yapzhhg@gmail.com>
Wed, 27 Aug 2025 13:47:34 +0000 (21:47 +0800)
committerArthur Cohen <arthur.cohen@embecosm.com>
Thu, 30 Oct 2025 19:59:06 +0000 (20:59 +0100)
GIMPLE dump from compiling issue-3930.rs:

...
  const i32 b;
  const i32 a;

  D.114.__0 = 2;
  D.114.__1 = 3;
  RUSTTMP.1 = D.114;
  a = RUSTTMP.1.__0;
  b = RUSTTMP.1.__1;
...

gcc/rust/ChangeLog:

* backend/rust-compile-var-decl.h (CompileVarDecl::visit(TuplePattern)): Implement
variable declaration bindings for tuple patterns with rest pattern (i.e.
TuplePatternItemsHasRest).

Signed-off-by: Yap Zhi Heng <yapzhhg@gmail.com>
gcc/rust/backend/rust-compile-var-decl.h
gcc/testsuite/rust/compile/issue-3930.rs [new file with mode: 0644]

index 15f3ebb3a6a726d8a3f7e481046db1a7cd3dd790..1f306ade3f9e7d639a79c953dc155d8d39d4073f 100644 (file)
@@ -77,27 +77,66 @@ public:
 
   void visit (HIR::TuplePattern &pattern) override
   {
+    rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
     switch (pattern.get_items ().get_item_type ())
       {
       case HIR::TuplePatternItems::ItemType::NO_REST:
        {
-         rust_assert (TREE_CODE (translated_type) == RECORD_TYPE);
-         auto &items = static_cast<HIR::TuplePatternItemsNoRest &> (
+         auto &items_no_rest = static_cast<HIR::TuplePatternItemsNoRest &> (
            pattern.get_items ());
 
-         size_t offs = 0;
-         for (auto &sub : items.get_patterns ())
+         tree field = TYPE_FIELDS (translated_type);
+         for (auto &sub : items_no_rest.get_patterns ())
            {
-             tree sub_ty = error_mark_node;
-             tree field = TYPE_FIELDS (translated_type);
-             for (size_t i = 0; i < offs; i++)
+             gcc_assert (field != NULL_TREE);
+             tree sub_ty = TREE_TYPE (field);
+             CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
+             field = DECL_CHAIN (field);
+           }
+       }
+       break;
+
+      case HIR::TuplePatternItems::ItemType::HAS_REST:
+       {
+         auto &items_has_rest = static_cast<HIR::TuplePatternItemsHasRest &> (
+           pattern.get_items ());
+
+         // count total fields in translated_type
+         size_t total_fields = 0;
+         for (tree t = TYPE_FIELDS (translated_type); t; t = DECL_CHAIN (t))
+           {
+             total_fields++;
+           }
+
+         // process lower patterns
+         tree field = TYPE_FIELDS (translated_type);
+         for (auto &sub : items_has_rest.get_lower_patterns ())
+           {
+             gcc_assert (field != NULL_TREE);
+             tree sub_ty = TREE_TYPE (field);
+             CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
+             field = DECL_CHAIN (field);
+           }
+
+         // process upper patterns
+         if (!items_has_rest.get_upper_patterns ().empty ())
+           {
+             size_t upper_start
+               = total_fields - items_has_rest.get_upper_patterns ().size ();
+             field = TYPE_FIELDS (translated_type);
+             for (size_t i = 0; i < upper_start; i++)
                {
                  field = DECL_CHAIN (field);
                  gcc_assert (field != NULL_TREE);
                }
-             sub_ty = TREE_TYPE (field);
-             CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
-             offs++;
+
+             for (auto &sub : items_has_rest.get_upper_patterns ())
+               {
+                 gcc_assert (field != NULL_TREE);
+                 tree sub_ty = TREE_TYPE (field);
+                 CompileVarDecl::compile (fndecl, sub_ty, sub.get (), ctx);
+                 field = DECL_CHAIN (field);
+               }
            }
        }
        break;
diff --git a/gcc/testsuite/rust/compile/issue-3930.rs b/gcc/testsuite/rust/compile/issue-3930.rs
new file mode 100644 (file)
index 0000000..dfcd19a
--- /dev/null
@@ -0,0 +1,4 @@
+// { dg-additional-options "-w" }
+fn main() {
+    let (a, .., b) = (2, 3);
+}