From: Owen Avery Date: Sat, 4 Feb 2023 05:02:22 +0000 (-0500) Subject: gccrs: Add support for TuplePattern in let statements X-Git-Tag: upstream/13.1.0~164 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fa7b3a2f07f56ba7c36d854989b52183027db04e;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc index bad98be..cb4b082 100644 --- a/gcc/rust/backend/rust-compile-pattern.cc +++ b/gcc/rust/backend/rust-compile-pattern.cc @@ -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 (*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 (*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 ( + *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 diff --git a/gcc/rust/backend/rust-compile-pattern.h b/gcc/rust/backend/rust-compile-pattern.h index ddf5b14..8f44b7b 100644 --- a/gcc/rust/backend/rust-compile-pattern.h +++ b/gcc/rust/backend/rust-compile-pattern.h @@ -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 (), diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h index 83b041d..1b08ab8 100644 --- a/gcc/rust/hir/tree/rust-hir-pattern.h +++ b/gcc/rust/hir/tree/rust-hir-pattern.h @@ -1142,6 +1142,24 @@ public: return TuplePatternItemType::RANGED; } + std::vector > &get_lower_patterns () + { + return lower_patterns; + } + const std::vector > &get_lower_patterns () const + { + return lower_patterns; + } + + std::vector > &get_upper_patterns () + { + return upper_patterns; + } + const std::vector > &get_upper_patterns () const + { + return upper_patterns; + } + protected: /* Use covariance to implement clone function as returning this object rather * than base */ diff --git a/gcc/testsuite/rust/execute/torture/let-pattern-1.rs b/gcc/testsuite/rust/execute/torture/let-pattern-1.rs new file mode 100644 index 0000000..107d819 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/let-pattern-1.rs @@ -0,0 +1,4 @@ +fn main() -> i32 { + let (x, y, z) = (2, 3, 6); + x * y - z +}