Skip to content

Commit 3bb39a7

Browse files
committed
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>
1 parent 5dae614 commit 3bb39a7

4 files changed

Lines changed: 87 additions & 2 deletions

File tree

gcc/rust/backend/rust-compile-pattern.cc

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,8 +430,50 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
430430
{
431431
case HIR::TuplePatternItems::RANGED:
432432
{
433-
// TODO
434-
gcc_unreachable ();
433+
auto &items
434+
= static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
435+
size_t tuple_field_index = 0;
436+
437+
// lookup the type to find out number of fields
438+
TyTy::BaseType *ty = nullptr;
439+
bool ok = ctx->get_tyctx ()->lookup_type (
440+
pattern.get_mappings ().get_hirid (), &ty);
441+
rust_assert (ok);
442+
rust_assert (ty->get_kind () == TyTy::TypeKind::TUPLE);
443+
444+
// compile check expr for lower patterns
445+
for (auto &pat : items.get_lower_patterns ())
446+
{
447+
tree field_expr
448+
= Backend::struct_field_expression (match_scrutinee_expr,
449+
tuple_field_index++,
450+
pat->get_locus ());
451+
452+
tree check_expr_sub
453+
= CompilePatternCheckExpr::Compile (*pat, field_expr, ctx);
454+
check_expr = Backend::arithmetic_or_logical_expression (
455+
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
456+
check_expr_sub, pat->get_locus ());
457+
}
458+
459+
// skip the fields that are not checked
460+
tuple_field_index = static_cast<TyTy::TupleType &> (*ty).num_fields ()
461+
- items.get_upper_patterns ().size ();
462+
463+
// compile check expr for upper patterns
464+
for (auto &pat : items.get_upper_patterns ())
465+
{
466+
tree field_expr
467+
= Backend::struct_field_expression (match_scrutinee_expr,
468+
tuple_field_index++,
469+
pat->get_locus ());
470+
471+
tree check_expr_sub
472+
= CompilePatternCheckExpr::Compile (*pat, field_expr, ctx);
473+
check_expr = Backend::arithmetic_or_logical_expression (
474+
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
475+
check_expr_sub, pat->get_locus ());
476+
}
435477
}
436478
break;
437479

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let x = (1, 2, 3, 4);
3+
4+
match x {
5+
(1, .., 4) => {},
6+
_ => {}
7+
}
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fn main() {
2+
let x = (1, 2, 3, 4);
3+
4+
match x {
5+
(1, .., 2, 3, 4, 5) => {}, // { dg-error "expected a tuple with 4 elements, found one with 5 elements" }
6+
_ => {}
7+
}
8+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// { dg-output "correct\r*" }
2+
extern "C" {
3+
fn puts(s: *const i8);
4+
}
5+
6+
fn main() -> i32 {
7+
let x = (1, 2, 3, 4);
8+
let mut ret = 1;
9+
10+
match x {
11+
(1, .., 2, 4) => {
12+
/* should not take this path */
13+
unsafe { puts("wrong\0" as *const str as *const i8) }
14+
},
15+
(2, ..) => {
16+
/* should not take this path */
17+
unsafe { puts("wrong\0" as *const str as *const i8) }
18+
},
19+
(b, .., 4) => {
20+
ret -= b;
21+
unsafe { puts("correct\0" as *const str as *const i8) }
22+
},
23+
_ => {}
24+
}
25+
26+
ret
27+
}

0 commit comments

Comments
 (0)