mirror of
https://gcc.gnu.org/git/gcc.git
synced 2026-02-22 20:01:22 -05:00
gccrs: Add support for TuplePattern in let statements
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>
This commit is contained in:
@@ -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 */
|
||||
|
||||
4
gcc/testsuite/rust/execute/torture/let-pattern-1.rs
Normal file
4
gcc/testsuite/rust/execute/torture/let-pattern-1.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
fn main() -> i32 {
|
||||
let (x, y, z) = (2, 3, 6);
|
||||
x * y - z
|
||||
}
|
||||
Reference in New Issue
Block a user