aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <herron.philip@googlemail.com>2024-12-13 15:51:55 +0000
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-21 12:55:43 +0100
commit18d289ca2b1996aa76b902432941e88fa3497b6d (patch)
tree65f60208bf1641e919bc1a81ee0e5e0f126c7439 /gcc
parent7bf460b338845d1b9a581cca70a3191f76769816 (diff)
downloadgcc-18d289ca2b1996aa76b902432941e88fa3497b6d.zip
gcc-18d289ca2b1996aa76b902432941e88fa3497b6d.tar.gz
gcc-18d289ca2b1996aa76b902432941e88fa3497b6d.tar.bz2
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 Rust-GCC#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>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.cc31
-rw-r--r--gcc/rust/backend/rust-compile-fnparam.h4
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc86
-rw-r--r--gcc/rust/backend/rust-compile-pattern.h2
-rw-r--r--gcc/testsuite/rust/compile/issue-2847.rs8
5 files changed, 117 insertions, 14 deletions
diff --git a/gcc/rust/backend/rust-compile-fnparam.cc b/gcc/rust/backend/rust-compile-fnparam.cc
index c00092d..b40065e 100644
--- a/gcc/rust/backend/rust-compile-fnparam.cc
+++ b/gcc/rust/backend/rust-compile-fnparam.cc
@@ -69,24 +69,35 @@ CompileFnParam::visit (HIR::WildcardPattern &pattern)
}
void
+CompileFnParam::visit (HIR::TuplePattern &pattern)
+{
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
+}
+
+void
CompileFnParam::visit (HIR::StructPattern &pattern)
{
- tree tmp_param_var = create_tmp_param_var (decl_type);
- CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
}
void
CompileFnParam::visit (HIR::TupleStructPattern &pattern)
{
- tree tmp_param_var = create_tmp_param_var (decl_type);
- CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
}
void
CompileFnParam::visit (HIR::ReferencePattern &pattern)
{
- tree tmp_param_var = create_tmp_param_var (decl_type);
- CompilePatternBindings::Compile (pattern, tmp_param_var, ctx);
+ compiled_param = create_tmp_param_var (decl_type);
+ CompilePatternBindings::Compile (
+ pattern, Backend::var_expression (compiled_param, locus), ctx);
}
Bvariable *
@@ -102,7 +113,7 @@ CompileSelfParam::compile (Context *ctx, tree fndecl, HIR::SelfParam &self,
return Backend::parameter_variable (fndecl, "self", decl_type, locus);
}
-tree
+Bvariable *
CompileFnParam::create_tmp_param_var (tree decl_type)
{
// generate the anon param
@@ -110,10 +121,8 @@ CompileFnParam::create_tmp_param_var (tree decl_type)
std::string cpp_str_identifier = std::string (IDENTIFIER_POINTER (tmp_ident));
decl_type = Backend::immutable_type (decl_type);
- compiled_param = Backend::parameter_variable (fndecl, cpp_str_identifier,
- decl_type, locus);
-
- return Backend::var_expression (compiled_param, locus);
+ return Backend::parameter_variable (fndecl, cpp_str_identifier, decl_type,
+ locus);
}
} // namespace Compile
diff --git a/gcc/rust/backend/rust-compile-fnparam.h b/gcc/rust/backend/rust-compile-fnparam.h
index 82a705f..189216c 100644
--- a/gcc/rust/backend/rust-compile-fnparam.h
+++ b/gcc/rust/backend/rust-compile-fnparam.h
@@ -47,12 +47,12 @@ public:
void visit (HIR::QualifiedPathInExpression &) override {}
void visit (HIR::RangePattern &) override {}
void visit (HIR::SlicePattern &) override {}
- void visit (HIR::TuplePattern &) override {}
+ void visit (HIR::TuplePattern &) override;
private:
CompileFnParam (Context *ctx, tree fndecl, tree decl_type, location_t locus);
- tree create_tmp_param_var (tree decl_type);
+ Bvariable *create_tmp_param_var (tree decl_type);
tree fndecl;
tree decl_type;
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index d6161bd..b2e7c35 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -614,6 +614,92 @@ CompilePatternBindings::visit (HIR::IdentifierPattern &pattern)
}
void
+CompilePatternBindings::visit (HIR::TuplePattern &pattern)
+{
+ rust_assert (pattern.has_tuple_pattern_items ());
+
+ // lookup the type
+ TyTy::BaseType *ty = nullptr;
+ bool ok
+ = ctx->get_tyctx ()->lookup_type (pattern.get_mappings ().get_hirid (),
+ &ty);
+ rust_assert (ok);
+
+ switch (pattern.get_items ().get_item_type ())
+ {
+ case HIR::TuplePatternItems::ItemType::RANGED: {
+ size_t tuple_idx = 0;
+ auto &items
+ = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
+
+ auto &items_lower = items.get_lower_patterns ();
+ auto &items_upper = items.get_upper_patterns ();
+
+ for (auto &sub : items_lower)
+ {
+ TyTy::BaseType *ty_sub = nullptr;
+ HirId sub_id = sub->get_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_idx, sub->get_locus ());
+
+ CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+ tuple_idx++;
+ }
+
+ rust_assert (ty->get_kind () == TyTy::TypeKind::TUPLE);
+ tuple_idx = static_cast<TyTy::TupleType &> (*ty).num_fields ()
+ - items_upper.size ();
+
+ for (auto &sub : items_upper)
+ {
+ TyTy::BaseType *ty_sub = nullptr;
+ HirId sub_id = sub->get_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_idx, sub->get_locus ());
+ CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+ tuple_idx++;
+ }
+
+ return;
+ }
+ case HIR::TuplePatternItems::ItemType::MULTIPLE: {
+ size_t tuple_idx = 0;
+ auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
+ pattern.get_items ());
+
+ for (auto &sub : items.get_patterns ())
+ {
+ TyTy::BaseType *ty_sub = nullptr;
+ HirId sub_id = sub->get_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (sub_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init
+ = Backend::struct_field_expression (match_scrutinee_expr,
+ tuple_idx, sub->get_locus ());
+ CompilePatternBindings::Compile (*sub.get (), sub_init, ctx);
+ tuple_idx++;
+ }
+
+ return;
+ }
+ default: {
+ rust_unreachable ();
+ }
+ }
+}
+
+//
+
+void
CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
{
Bvariable *var = nullptr;
diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h
index 0b785c6..c7a62fc 100644
--- a/gcc/rust/backend/rust-compile-pattern.h
+++ b/gcc/rust/backend/rust-compile-pattern.h
@@ -82,6 +82,7 @@ public:
void visit (HIR::TupleStructPattern &pattern) override;
void visit (HIR::ReferencePattern &pattern) override;
void visit (HIR::IdentifierPattern &) override;
+ void visit (HIR::TuplePattern &pattern) override;
// Empty visit for unused Pattern HIR nodes.
void visit (HIR::AltPattern &) override {}
@@ -90,7 +91,6 @@ public:
void visit (HIR::QualifiedPathInExpression &) override {}
void visit (HIR::RangePattern &) override {}
void visit (HIR::SlicePattern &) override {}
- void visit (HIR::TuplePattern &) override {}
void visit (HIR::WildcardPattern &) override {}
protected:
diff --git a/gcc/testsuite/rust/compile/issue-2847.rs b/gcc/testsuite/rust/compile/issue-2847.rs
new file mode 100644
index 0000000..2bc5566
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-2847.rs
@@ -0,0 +1,8 @@
+pub fn myfun1((x, _): (i32, i32)) -> i32 {
+ x
+}
+
+pub fn myfun2() -> i32 {
+ let (x, _) = (1, 2);
+ x
+}