https://gcc.gnu.org/g:866510c83a4e35473b1f4caf3b1258aa23fc742f

commit r16-2892-g866510c83a4e35473b1f4caf3b1258aa23fc742f
Author: Zhi Heng <yapz...@gmail.com>
Date:   Sun Jun 22 17:38:06 2025 +0800

    gccrs: Fix TupleStructPattern compilation throwing error
    
    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 <yapz...@gmail.com>

Diff:
---
 gcc/rust/backend/rust-compile-pattern.cc           | 62 +++++++++++++++-------
 .../rust/compile/match-tuplestructpattern.rs       |  9 ++++
 .../execute/torture/match-tuplestructpattern.rs    | 12 +++++
 3 files changed, 64 insertions(+), 19 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index bd3aea01b537..cd1c77be5eb7 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -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
index 000000000000..0dae71ea0051
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-tuplestructpattern.rs
@@ -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
index 000000000000..323109cd4963
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-tuplestructpattern.rs
@@ -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
+}

Reply via email to