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

commit r16-2912-gb42078879d758ff25daba406b7eaf9cc5812d0a3
Author: Zhi Heng <yapz...@gmail.com>
Date:   Sun Jun 29 10:44:31 2025 +0800

    gccrs: Implement compilation support for TuplePatternItems::RANGED
    
    Example GIMPLE output of the match statement for 
match-restpattern-tuple-1.rs:
    
    ...
    RUSTTMP.2 = x;
    _1 = RUSTTMP.2.__0;
    _2 = _1 == 1;
    _3 = RUSTTMP.2.__3;
    _4 = _3 == 4;
    _5 = _2 & _4;
    if (_5 != 0) goto <D.109>; else goto <D.110>;
    <D.109>:
    {
        {
    
        }
        goto <D.104>;
    }
    <D.110>:
    if (1 != 0) goto <D.111>; else goto <D.112>;
    <D.111>:
    {
        {
    
        }
        goto <D.104>;
    }
    <D.112>:
    <D.104>:
    ...
    
    gcc/rust/ChangeLog:
    
            * backend/rust-compile-pattern.cc 
(CompilePatternCheckExpr::visit(TuplePattern)):
                    Implement check expression compilation for 
TuplePatternItems::RANGED.
    
    Signed-off-by: Yap Zhi Heng <yapz...@gmail.com>

Diff:
---
 gcc/rust/backend/rust-compile-pattern.cc           | 46 +++++++++++++++++++++-
 .../rust/compile/match-restpattern-tuple-1.rs      |  8 ++++
 .../rust/compile/match-restpattern-tuple-2.rs      |  8 ++++
 .../execute/torture/match-restpattern-tuple.rs     | 27 +++++++++++++
 4 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-pattern.cc 
b/gcc/rust/backend/rust-compile-pattern.cc
index cd1c77be5eb7..3351becd1d99 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -430,8 +430,50 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
     {
     case HIR::TuplePatternItems::RANGED:
       {
-       // TODO
-       gcc_unreachable ();
+       auto &items
+         = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+       size_t tuple_field_index = 0;
+
+       // lookup the type to find out number of fields
+       TyTy::BaseType *ty = nullptr;
+       bool ok = ctx->get_tyctx ()->lookup_type (
+         pattern.get_mappings ().get_hirid (), &ty);
+       rust_assert (ok);
+       rust_assert (ty->get_kind () == TyTy::TypeKind::TUPLE);
+
+       // compile check expr for lower patterns
+       for (auto &pat : items.get_lower_patterns ())
+         {
+           tree field_expr
+             = Backend::struct_field_expression (match_scrutinee_expr,
+                                                 tuple_field_index++,
+                                                 pat->get_locus ());
+
+           tree check_expr_sub
+             = CompilePatternCheckExpr::Compile (*pat, field_expr, ctx);
+           check_expr = Backend::arithmetic_or_logical_expression (
+             ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+             check_expr_sub, pat->get_locus ());
+         }
+
+       // skip the fields that are not checked
+       tuple_field_index = static_cast<TyTy::TupleType &> (*ty).num_fields ()
+                           - items.get_upper_patterns ().size ();
+
+       // compile check expr for upper patterns
+       for (auto &pat : items.get_upper_patterns ())
+         {
+           tree field_expr
+             = Backend::struct_field_expression (match_scrutinee_expr,
+                                                 tuple_field_index++,
+                                                 pat->get_locus ());
+
+           tree check_expr_sub
+             = CompilePatternCheckExpr::Compile (*pat, field_expr, ctx);
+           check_expr = Backend::arithmetic_or_logical_expression (
+             ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+             check_expr_sub, pat->get_locus ());
+         }
       }
       break;
 
diff --git a/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs 
b/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs
new file mode 100644
index 000000000000..5cce3c409f0e
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let x = (1, 2, 3, 4);
+
+    match x {
+        (1, .., 4) => {},
+        _ => {}
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs 
b/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs
new file mode 100644
index 000000000000..40900a36bece
--- /dev/null
+++ b/gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs
@@ -0,0 +1,8 @@
+fn main() {
+    let x = (1, 2, 3, 4);
+
+    match x {
+        (1, .., 2, 3, 4, 5) => {}, // { dg-error "expected a tuple with 4 
elements, found one with 5 elements" }
+        _ => {}
+    }
+}
\ No newline at end of file
diff --git a/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs 
b/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs
new file mode 100644
index 000000000000..2c1418c551d0
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs
@@ -0,0 +1,27 @@
+// { dg-output "correct\r*" }
+extern "C" {
+    fn puts(s: *const i8);
+}
+
+fn main() -> i32 {
+    let x = (1, 2, 3, 4);
+    let mut ret = 1;
+
+    match x {
+        (1, .., 2, 4) => {
+            /* should not take this path */
+            unsafe { puts("wrong\0" as *const str as *const i8) }
+        },
+        (2, ..) => {
+            /* should not take this path */
+            unsafe { puts("wrong\0" as *const str as *const i8) }
+        },
+        (b, .., 4) => { 
+            ret -= b;
+            unsafe { puts("correct\0" as *const str as *const i8) }
+        },
+        _ => {}
+    }
+
+    ret
+}
\ No newline at end of file

Reply via email to