]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Fix TupleStructPattern compilation throwing error
authorZhi Heng <yapzhhg@gmail.com>
Sun, 22 Jun 2025 09:38:06 +0000 (17:38 +0800)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 5 Aug 2025 14:36:51 +0000 (16:36 +0200)
Code for TupleStructPattern compilation previously only assumes that it is derived from
an enum. This commit adds a check for that, and compiles non-enum TupleStructPatterns
similarly to TuplePatterns if it is not an enum.

gcc/rust/ChangeLog:

* backend/rust-compile-pattern.cc(CompilePatternCheckExpr::visit(TupleStructPattern)):
Fix error thrown when compiling non-enum TupleStructPattern.

Signed-off-by: Yap Zhi Heng <yapzhhg@gmail.com>
gcc/rust/backend/rust-compile-pattern.cc
gcc/testsuite/rust/compile/match-tuplestructpattern.rs [new file with mode: 0644]
gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs [new file with mode: 0644]

index bd3aea01b5379af3e1f4e87bac2c1a71b09d86e1..cd1c77be5eb755ee38202685c2b70623d2662f42 100644 (file)
@@ -369,31 +369,55 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
        rust_assert (items_no_range.get_patterns ().size ()
                     == variant->num_fields ());
 
-       size_t tuple_field_index = 0;
-       for (auto &pattern : items_no_range.get_patterns ())
+       if (adt->is_enum ())
          {
-           // find payload union field of scrutinee
-           tree payload_ref
-             = Backend::struct_field_expression (match_scrutinee_expr, 1,
-                                                 pattern->get_locus ());
+           size_t tuple_field_index = 0;
+           for (auto &pattern : items_no_range.get_patterns ())
+             {
+               // find payload union field of scrutinee
+               tree payload_ref
+                 = Backend::struct_field_expression (match_scrutinee_expr, 1,
+                                                     pattern->get_locus ());
 
-           tree variant_ref
-             = Backend::struct_field_expression (payload_ref, variant_index,
-                                                 pattern->get_locus ());
+               tree variant_ref
+                 = Backend::struct_field_expression (payload_ref,
+                                                     variant_index,
+                                                     pattern->get_locus ());
 
-           tree field_expr
-             = Backend::struct_field_expression (variant_ref,
-                                                 tuple_field_index++,
-                                                 pattern->get_locus ());
+               tree field_expr
+                 = Backend::struct_field_expression (variant_ref,
+                                                     tuple_field_index++,
+                                                     pattern->get_locus ());
 
-           tree check_expr_sub
-             = CompilePatternCheckExpr::Compile (*pattern, field_expr, ctx);
-           check_expr = Backend::arithmetic_or_logical_expression (
-             ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
-             check_expr_sub, pattern->get_locus ());
+               tree check_expr_sub
+                 = CompilePatternCheckExpr::Compile (*pattern, field_expr,
+                                                     ctx);
+               check_expr = Backend::arithmetic_or_logical_expression (
+                 ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+                 check_expr_sub, pattern->get_locus ());
+             }
+         }
+       else
+         {
+           // For non-enum TupleStructPatterns
+           size_t tuple_field_index = 0;
+           for (auto &pattern : items_no_range.get_patterns ())
+             {
+               tree field_expr
+                 = Backend::struct_field_expression (match_scrutinee_expr,
+                                                     tuple_field_index++,
+                                                     pattern->get_locus ());
+
+               tree check_expr_sub
+                 = CompilePatternCheckExpr::Compile (*pattern, field_expr,
+                                                     ctx);
+               check_expr = Backend::arithmetic_or_logical_expression (
+                 ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+                 check_expr_sub, pattern->get_locus ());
+             }
          }
+       break;
       }
-      break;
     }
 }
 
diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs
new file mode 100644 (file)
index 0000000..0dae71e
--- /dev/null
@@ -0,0 +1,9 @@
+fn main() {
+    struct A (i32, i32);
+    let a = A (0, 1);
+
+    match a {
+        A (0, 1) => {},
+        _ => {}
+    }
+}
diff --git a/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs
new file mode 100644 (file)
index 0000000..323109c
--- /dev/null
@@ -0,0 +1,12 @@
+fn main() -> i32 {
+    struct A (i32, i32);
+    let a = A (0, 1);
+    let mut ret = 1;
+
+    match a {
+        A (0, b) => { ret -= b },
+        _ => {}
+    }
+
+    ret
+}