From: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/ChangeLog:
* hir/tree/rust-hir-pattern.h
(TuplePatternItemsRanged::get_lower_patterns): Add method.
(TuplePatternItemsRanged::get_upper_patterns): Add method.
* backend/rust-compile-pattern.cc
(CompilePatternLet::visit): Implement TuplePattern visitor.
* backend/rust-compile-pattern.h
(CompilePatternLet::visit): Move TuplePattern visitor out of header file.
gcc/testsuite/ChangeLog:
* rust/execute/torture/let-pattern-1.rs: New test.
Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
---
gcc/rust/backend/rust-compile-pattern.cc | 87 +++++++++++++++++++
gcc/rust/backend/rust-compile-pattern.h | 7 +-
gcc/rust/hir/tree/rust-hir-pattern.h | 18 ++++
.../rust/execute/torture/let-pattern-1.rs | 4 +
4 files changed, 110 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/rust/execute/torture/let-pattern-1.rs
@@ -387,5 +387,92 @@ CompilePatternLet::visit (HIR::WildcardPattern &pattern)
}
}
+void
+CompilePatternLet::visit (HIR::TuplePattern &pattern)
+{
+ rust_assert (pattern.has_tuple_pattern_items ());
+
+ tree tuple_type = TyTyResolveCompile::compile (ctx, ty);
+ tree init_stmt;
+ Bvariable *tmp_var
+ = ctx->get_backend ()->temporary_variable (ctx->peek_fn ().fndecl,
+ NULL_TREE, tuple_type, init_expr,
+ false, pattern.get_locus (),
+ &init_stmt);
+ tree access_expr
+ = ctx->get_backend ()->var_expression (tmp_var, pattern.get_locus ());
+ ctx->add_statement (init_stmt);
+
+ switch (pattern.get_items ()->get_pattern_type ())
+ {
+ case HIR::TuplePatternItems::TuplePatternItemType::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 pattern_id = pattern.get_pattern_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init = ctx->get_backend ()->struct_field_expression (
+ access_expr, tuple_idx, sub->get_locus ());
+ CompilePatternLet::Compile (sub.get (), sub_init, ty_sub,
+ rval_locus, 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 pattern_id = pattern.get_pattern_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init = ctx->get_backend ()->struct_field_expression (
+ access_expr, tuple_idx, sub->get_locus ());
+ CompilePatternLet::Compile (sub.get (), sub_init, ty_sub,
+ rval_locus, ctx);
+ tuple_idx++;
+ }
+
+ return;
+ }
+ case HIR::TuplePatternItems::TuplePatternItemType::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 pattern_id = pattern.get_pattern_mappings ().get_hirid ();
+ bool ok = ctx->get_tyctx ()->lookup_type (pattern_id, &ty_sub);
+ rust_assert (ok);
+
+ tree sub_init = ctx->get_backend ()->struct_field_expression (
+ access_expr, tuple_idx, sub->get_locus ());
+ CompilePatternLet::Compile (sub.get (), sub_init, ty_sub,
+ rval_locus, ctx);
+ tuple_idx++;
+ }
+
+ return;
+ }
+ default: {
+ gcc_unreachable ();
+ }
+ }
+}
+
} // namespace Compile
} // namespace Rust
@@ -101,6 +101,7 @@ public:
void visit (HIR::IdentifierPattern &) override;
void visit (HIR::WildcardPattern &) override;
+ void visit (HIR::TuplePattern &) override;
// check for unimplemented Pattern HIR nodes.
void visit (HIR::LiteralPattern &pattern) override
@@ -146,12 +147,6 @@ public:
"struct pattern let statements not supported");
}
- void visit (HIR::TuplePattern &pattern) override
- {
- rust_sorry_at (pattern.get_locus (),
- "tuple pattern let statements not supported");
- }
-
void visit (HIR::TupleStructPattern &pattern) override
{
rust_sorry_at (pattern.get_locus (),
@@ -1142,6 +1142,24 @@ public:
return TuplePatternItemType::RANGED;
}
+ std::vector<std::unique_ptr<Pattern> > &get_lower_patterns ()
+ {
+ return lower_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () const
+ {
+ return lower_patterns;
+ }
+
+ std::vector<std::unique_ptr<Pattern> > &get_upper_patterns ()
+ {
+ return upper_patterns;
+ }
+ const std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () const
+ {
+ return upper_patterns;
+ }
+
protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
new file mode 100644
@@ -0,0 +1,4 @@
+fn main() -> i32 {
+ let (x, y, z) = (2, 3, 6);
+ x * y - z
+}