Skip to content

Commit 73c03db

Browse files
committed
gccrs: Implement type check & codegen for HIR::StructPatternFieldTuplePat
006t.original dump of rust/compile/match-structpattern-tuplefield.rs: ... const struct match_structpattern_tuplefield::TupStruct t = {.0=1, .1=2}; struct () RUSTTMP.1; const struct match_structpattern_tuplefield::TupStruct RUSTTMP.2; RUSTTMP.2 = t; if (RUSTTMP.2.0 == 1 && RUSTTMP.2.1 == 2) { { struct () RUSTTMP.3; {} goto <D.100>; } } if (1) { { struct () RUSTTMP.4; {} goto <D.100>; } } if (RUSTTMP.2.0 == 1) { { struct () RUSTTMP.5; {} goto <D.100>; } } if (1) { { struct () RUSTTMP.6; {} goto <D.100>; } } <D.100>:; ... gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-pattern.cc (visit(StructPattern)): Implement type check case for HIR::StructPatternFieldTuplePat. * checks/errors/rust-hir-pattern-analysis.cc (lower_struct_pattern): Implement case for HIR::StructPatternField::ItemType::TUPLE_PAT. * backend/rust-compile-pattern.cc: * CompilePatternCheckExpr::visit (HIR::StructPattern): Implement code gen for HIR::StructPatternField::ItemType::TUPLE_PAT case. * CompilePatternBindings::handle_struct_pattern_tuple_pat: Implement bindings for HIR::StructPatternFieldTuplePat. * backend/rust-compile-pattern.h: Update function definition for handle_struct_pattern_tuple_pat. Signed-off-by: Yap Zhi Heng <[email protected]>
1 parent c57cf83 commit 73c03db

File tree

7 files changed

+109
-10
lines changed

7 files changed

+109
-10
lines changed

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

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,18 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
297297
{
298298
case HIR::StructPatternField::ItemType::TUPLE_PAT:
299299
{
300-
// TODO
301-
rust_unreachable ();
300+
HIR::StructPatternFieldTuplePat &tuple_pat
301+
= static_cast<HIR::StructPatternFieldTuplePat &> (*field.get ());
302+
size_t tuple_pat_index = tuple_pat.get_index ();
303+
tree field_expr
304+
= Backend::struct_field_expression (variant_accesser_expr,
305+
tuple_pat_index,
306+
tuple_pat.get_locus ());
307+
tree check_expr_sub = CompilePatternCheckExpr::Compile (
308+
tuple_pat.get_tuple_pattern (), field_expr, ctx);
309+
check_expr = Backend::arithmetic_or_logical_expression (
310+
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
311+
check_expr_sub, tuple_pat.get_locus ());
302312
}
303313
break;
304314

@@ -954,9 +964,40 @@ CompilePatternBindings::handle_struct_pattern_ident_pat (
954964

955965
void
956966
CompilePatternBindings::handle_struct_pattern_tuple_pat (
957-
HIR::StructPatternField &pat)
967+
HIR::StructPatternField &pat, TyTy::ADTType *adt, TyTy::VariantDef *variant,
968+
int variant_index)
958969
{
959-
rust_unreachable ();
970+
HIR::StructPatternFieldTuplePat &tuple_pat
971+
= static_cast<HIR::StructPatternFieldTuplePat &> (pat);
972+
973+
size_t tuple_pat_index = tuple_pat.get_index ();
974+
tree binding;
975+
976+
if (adt->is_enum ())
977+
{
978+
tree payload_accessor_union
979+
= Backend::struct_field_expression (match_scrutinee_expr, 1,
980+
pat.get_locus ());
981+
982+
tree variant_accessor
983+
= Backend::struct_field_expression (payload_accessor_union,
984+
variant_index, pat.get_locus ());
985+
986+
binding
987+
= Backend::struct_field_expression (variant_accessor, tuple_pat_index,
988+
pat.get_locus ());
989+
}
990+
else
991+
{
992+
tree variant_accessor = match_scrutinee_expr;
993+
994+
binding
995+
= Backend::struct_field_expression (variant_accessor, tuple_pat_index,
996+
pat.get_locus ());
997+
}
998+
999+
CompilePatternBindings::Compile (tuple_pat.get_tuple_pattern (), binding,
1000+
ctx);
9601001
}
9611002

9621003
void
@@ -996,7 +1037,7 @@ CompilePatternBindings::visit (HIR::StructPattern &pattern)
9961037
switch (field->get_item_type ())
9971038
{
9981039
case HIR::StructPatternField::ItemType::TUPLE_PAT:
999-
handle_struct_pattern_tuple_pat (*field);
1040+
handle_struct_pattern_tuple_pat (*field, adt, variant, variant_index);
10001041
break;
10011042
case HIR::StructPatternField::ItemType::IDENT_PAT:
10021043
handle_struct_pattern_ident_pat (*field, adt, variant, variant_index);

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,10 @@ class CompilePatternBindings : public HIRCompileBase,
8888
TyTy::ADTType *adt,
8989
TyTy::VariantDef *variant,
9090
int variant_index);
91-
void handle_struct_pattern_tuple_pat (HIR::StructPatternField &pat);
91+
void handle_struct_pattern_tuple_pat (HIR::StructPatternField &pat,
92+
TyTy::ADTType *adt,
93+
TyTy::VariantDef *variant,
94+
int variant_index);
9295

9396
void visit (HIR::StructPattern &pattern) override;
9497
void visit (HIR::TupleStructPattern &pattern) override;

gcc/rust/checks/errors/rust-hir-pattern-analysis.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,8 +1315,12 @@ lower_struct_pattern (Resolver::TypeCheckContext *ctx,
13151315
break;
13161316
case HIR::StructPatternField::ItemType::TUPLE_PAT:
13171317
{
1318-
// TODO: tuple: pat
1319-
rust_unreachable ();
1318+
HIR::StructPatternFieldTuplePat *tuple_pat
1319+
= static_cast<HIR::StructPatternFieldTuplePat *> (elem.get ());
1320+
int field_idx = tuple_pat->get_index ();
1321+
fields.at (field_idx) = lower_pattern (
1322+
ctx, tuple_pat->get_tuple_pattern (),
1323+
variant->get_fields ().at (field_idx)->get_field_type ());
13201324
}
13211325
break;
13221326
default:

gcc/rust/typecheck/rust-hir-type-check-pattern.cc

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -474,8 +474,21 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern)
474474
{
475475
case HIR::StructPatternField::ItemType::TUPLE_PAT:
476476
{
477-
// TODO
478-
rust_unreachable ();
477+
HIR::StructPatternFieldTuplePat &tuple_pat
478+
= static_cast<HIR::StructPatternFieldTuplePat &> (*field.get ());
479+
480+
if ((size_t) tuple_pat.get_index () >= variant->num_fields ())
481+
{
482+
emit_invalid_field_error (tuple_pat.get_locus (), variant,
483+
std::to_string (
484+
tuple_pat.get_index ()));
485+
break;
486+
}
487+
named_fields.push_back (std::to_string (tuple_pat.get_index ()));
488+
TyTy::StructFieldType *field
489+
= variant->get_field_at_index (tuple_pat.get_index ());
490+
TyTy::BaseType *fty = field->get_field_type ();
491+
TypeCheckPattern::Resolve (tuple_pat.get_tuple_pattern (), fty);
479492
}
480493
break;
481494

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
pub struct TupStruct (i32, i32);
2+
3+
pub fn main() {
4+
let t = TupStruct (1, 2);
5+
match t {
6+
TupStruct { 0: 1, 1: 2, 2: 3 } => {}
7+
// { dg-error "variant TupStruct does not have a field named 2 .E0026." "" { target *-*-* } .-1 }
8+
TupStruct { 3: 3 } => {}
9+
// { dg-error "pattern does not mention fields 0, 1 .E0027." "" { target *-*-* } .-1 }
10+
// { dg-error "variant TupStruct does not have a field named 3 .E0026." "" { target *-*-* } .-2 }
11+
TupStruct { a: 3 } => {}
12+
// { dg-error "tuple variant .TupStruct. written as struct variant .E0769." "" { target *-*-* } .-1 }
13+
TupStruct { 0: 0.1f32, .. } => {}
14+
// { dg-error "mismatched types, expected .i32. but got .f32. .E0308." "" { target *-*-* } .-1 }
15+
_ => {}
16+
}
17+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pub struct TupStruct (i32, i32);
2+
3+
pub fn main() {
4+
let t = TupStruct (1, 2);
5+
match t {
6+
TupStruct { 0: 1, 1: 2 } => {}
7+
TupStruct { 1: b, .. } => {}
8+
TupStruct { 0: 1, .. } => {}
9+
_ => {}
10+
}
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
pub struct TupStruct (i32, i32);
2+
3+
pub fn main() -> i32 {
4+
let mut t = TupStruct (1, 1);
5+
match t {
6+
TupStruct { 0: 1, 1: b } => { b -= 1 }
7+
_ => {}
8+
}
9+
b
10+
}

0 commit comments

Comments
 (0)