Skip to content

Commit daa2977

Browse files
committed
gccrs: implement the TuplePattern and use it for function patterns
In order to handle the tuple pattern of: fn test ((x _) : (i32, i32)) -> i32 { x } we need to recognize that ABI wise this function still takes a tuple as the parameter to this function its just how we can address the "pattern" of the tuple changes. So reall if this was C it would look like: void test (struct tuple_type __prameter) { return __parameter.0 } The code here reuses our existing pattern code so that we generate these implicit bindings of the paramter with a field access so any time x is referenced it's really just emplacing __parameter.0 for the field access into the struct which is a tuple. Fixes #2847 gcc/rust/ChangeLog: * backend/rust-compile-fnparam.cc (CompileFnParam::visit): compile tuple patterns (CompileSelfParam::compile): update return type (CompileFnParam::create_tmp_param_var): return Bvariable not tree to stop ICE * backend/rust-compile-fnparam.h: update prototype * backend/rust-compile-pattern.cc (CompilePatternBindings::visit): implement TuplePattern * backend/rust-compile-pattern.h: update prototype gcc/testsuite/ChangeLog: * rust/compile/issue-2847.rs: New test. Signed-off-by: Philip Herron <herron.philip@googlemail.com>
1 parent cc2445c commit daa2977

File tree

5 files changed

+117
-14
lines changed

5 files changed

+117
-14
lines changed

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

+20-11
Original file line numberDiff line numberDiff line change
@@ -68,25 +68,36 @@ CompileFnParam::visit (HIR::WildcardPattern &pattern)
6868
compiled_param = Backend::parameter_variable (fndecl, "_", decl_type, locus);
6969
}
7070

71+
void
72+
CompileFnParam::visit (HIR::TuplePattern &pattern)
73+
{
74+
compiled_param = create_tmp_param_var (decl_type);
75+
CompilePatternBindings::Compile (
76+
pattern, Backend::var_expression (compiled_param, locus), ctx);
77+
}
78+
7179
void
7280
CompileFnParam::visit (HIR::StructPattern &pattern)
7381
{
74-
tree tmp_param_var = create_tmp_param_var (decl_type);
75-
CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
82+
compiled_param = create_tmp_param_var (decl_type);
83+
CompilePatternBindings::Compile (
84+
pattern, Backend::var_expression (compiled_param, locus), ctx);
7685
}
7786

7887
void
7988
CompileFnParam::visit (HIR::TupleStructPattern &pattern)
8089
{
81-
tree tmp_param_var = create_tmp_param_var (decl_type);
82-
CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
90+
compiled_param = create_tmp_param_var (decl_type);
91+
CompilePatternBindings::Compile (
92+
pattern, Backend::var_expression (compiled_param, locus), ctx);
8393
}
8494

8595
void
8696
CompileFnParam::visit (HIR::ReferencePattern &pattern)
8797
{
88-
tree tmp_param_var = create_tmp_param_var (decl_type);
89-
CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
98+
compiled_param = create_tmp_param_var (decl_type);
99+
CompilePatternBindings::Compile (
100+
pattern, Backend::var_expression (compiled_param, locus), ctx);
90101
}
91102

92103
Bvariable *
@@ -102,18 +113,16 @@ CompileSelfParam::compile (Context *ctx, tree fndecl, HIR::SelfParam &self,
102113
return Backend::parameter_variable (fndecl, "self", decl_type, locus);
103114
}
104115

105-
tree
116+
Bvariable *
106117
CompileFnParam::create_tmp_param_var (tree decl_type)
107118
{
108119
// generate the anon param
109120
tree tmp_ident = create_tmp_var_name ("RSTPRM");
110121
std::string cpp_str_identifier = std::string (IDENTIFIER_POINTER (tmp_ident));
111122

112123
decl_type = Backend::immutable_type (decl_type);
113-
compiled_param = Backend::parameter_variable (fndecl, cpp_str_identifier,
114-
decl_type, locus);
115-
116-
return Backend::var_expression (compiled_param, locus);
124+
return Backend::parameter_variable (fndecl, cpp_str_identifier, decl_type,
125+
locus);
117126
}
118127

119128
} // namespace Compile

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ class CompileFnParam : private HIRCompileBase, protected HIR::HIRPatternVisitor
4747
void visit (HIR::QualifiedPathInExpression &) override {}
4848
void visit (HIR::RangePattern &) override {}
4949
void visit (HIR::SlicePattern &) override {}
50-
void visit (HIR::TuplePattern &) override {}
50+
void visit (HIR::TuplePattern &) override;
5151

5252
private:
5353
CompileFnParam (Context *ctx, tree fndecl, tree decl_type, location_t locus);
5454

55-
tree create_tmp_param_var (tree decl_type);
55+
Bvariable *create_tmp_param_var (tree decl_type);
5656

5757
tree fndecl;
5858
tree decl_type;

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

+86
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,92 @@ CompilePatternBindings::visit (HIR::IdentifierPattern &pattern)
613613
match_scrutinee_expr);
614614
}
615615

616+
void
617+
CompilePatternBindings::visit (HIR::TuplePattern &pattern)
618+
{
619+
rust_assert (pattern.has_tuple_pattern_items ());
620+
621+
// lookup the type
622+
TyTy::BaseType *ty = nullptr;
623+
bool ok
624+
= ctx->get_tyctx ()->lookup_type (pattern.get_mappings ().get_hirid (),
625+
&ty);
626+
rust_assert (ok);
627+
628+
switch (pattern.get_items ().get_item_type ())
629+
{
630+
case HIR::TuplePatternItems::ItemType::RANGED: {
631+
size_t tuple_idx = 0;
632+
auto &items
633+
= static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
634+
635+
auto &items_lower = items.get_lower_patterns ();
636+
auto &items_upper = items.get_upper_patterns ();
637+
638+
for (auto &sub : items_lower)
639+
{
640+
TyTy::BaseType *ty_sub = nullptr;
641+
HirId sub_id = sub->get_mappings ().get_hirid ();
642+
bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
643+
rust_assert (ok);
644+
645+
tree sub_init
646+
= Backend::struct_field_expression (match_scrutinee_expr,
647+
tuple_idx, sub->get_locus ());
648+
649+
CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
650+
tuple_idx++;
651+
}
652+
653+
rust_assert (ty->get_kind () == TyTy::TypeKind::TUPLE);
654+
tuple_idx = static_cast<TyTy::TupleType &> (*ty).num_fields ()
655+
- items_upper.size ();
656+
657+
for (auto &sub : items_upper)
658+
{
659+
TyTy::BaseType *ty_sub = nullptr;
660+
HirId sub_id = sub->get_mappings ().get_hirid ();
661+
bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
662+
rust_assert (ok);
663+
664+
tree sub_init
665+
= Backend::struct_field_expression (match_scrutinee_expr,
666+
tuple_idx, sub->get_locus ());
667+
CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
668+
tuple_idx++;
669+
}
670+
671+
return;
672+
}
673+
case HIR::TuplePatternItems::ItemType::MULTIPLE: {
674+
size_t tuple_idx = 0;
675+
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
676+
pattern.get_items ());
677+
678+
for (auto &sub : items.get_patterns ())
679+
{
680+
TyTy::BaseType *ty_sub = nullptr;
681+
HirId sub_id = sub->get_mappings ().get_hirid ();
682+
bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
683+
rust_assert (ok);
684+
685+
tree sub_init
686+
= Backend::struct_field_expression (match_scrutinee_expr,
687+
tuple_idx, sub->get_locus ());
688+
CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
689+
tuple_idx++;
690+
}
691+
692+
return;
693+
}
694+
default: {
695+
rust_unreachable ();
696+
}
697+
}
698+
}
699+
700+
//
701+
616702
void
617703
CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
618704
{

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class CompilePatternBindings : public HIRCompileBase,
8282
void visit (HIR::TupleStructPattern &pattern) override;
8383
void visit (HIR::ReferencePattern &pattern) override;
8484
void visit (HIR::IdentifierPattern &) override;
85+
void visit (HIR::TuplePattern &pattern) override;
8586

8687
// Empty visit for unused Pattern HIR nodes.
8788
void visit (HIR::AltPattern &) override {}
@@ -90,7 +91,6 @@ class CompilePatternBindings : public HIRCompileBase,
9091
void visit (HIR::QualifiedPathInExpression &) override {}
9192
void visit (HIR::RangePattern &) override {}
9293
void visit (HIR::SlicePattern &) override {}
93-
void visit (HIR::TuplePattern &) override {}
9494
void visit (HIR::WildcardPattern &) override {}
9595

9696
protected:
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
pub fn myfun1((x, _): (i32, i32)) -> i32 {
2+
x
3+
}
4+
5+
pub fn myfun2() -> i32 {
6+
let (x, _) = (1, 2);
7+
x
8+
}

0 commit comments

Comments
 (0)