aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhi Heng <yapzhhg@gmail.com>2025-06-29 10:44:31 +0800
committerArthur Cohen <arthur.cohen@embecosm.com>2025-08-05 16:36:53 +0200
commitb42078879d758ff25daba406b7eaf9cc5812d0a3 (patch)
treeca7d93e791182079b2348366e4d070cfd1b6b615
parent0803c00cdddb88bf9cfca5ad1958105d66cf04c7 (diff)
downloadgcc-b42078879d758ff25daba406b7eaf9cc5812d0a3.zip
gcc-b42078879d758ff25daba406b7eaf9cc5812d0a3.tar.gz
gcc-b42078879d758ff25daba406b7eaf9cc5812d0a3.tar.bz2
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 <yapzhhg@gmail.com>
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc46
-rw-r--r--gcc/testsuite/rust/compile/match-restpattern-tuple-1.rs8
-rw-r--r--gcc/testsuite/rust/compile/match-restpattern-tuple-2.rs8
-rw-r--r--gcc/testsuite/rust/execute/torture/match-restpattern-tuple.rs27
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 cd1c77b..3351bec 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 0000000..5cce3c4
--- /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 0000000..40900a3
--- /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 0000000..2c1418c
--- /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