aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-compile-pattern.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/backend/rust-compile-pattern.cc')
-rw-r--r--gcc/rust/backend/rust-compile-pattern.cc383
1 files changed, 253 insertions, 130 deletions
diff --git a/gcc/rust/backend/rust-compile-pattern.cc b/gcc/rust/backend/rust-compile-pattern.cc
index 1a32f02..121749a 100644
--- a/gcc/rust/backend/rust-compile-pattern.cc
+++ b/gcc/rust/backend/rust-compile-pattern.cc
@@ -21,6 +21,12 @@
#include "rust-compile-resolve-path.h"
#include "rust-constexpr.h"
#include "rust-compile-type.h"
+#include "print-tree.h"
+#include "rust-diagnostics.h"
+#include "rust-hir-pattern-abstract.h"
+#include "rust-hir-pattern.h"
+#include "rust-system.h"
+#include "rust-tyty.h"
namespace Rust {
namespace Compile {
@@ -35,11 +41,16 @@ CompilePatternCheckExpr::visit (HIR::PathInExpression &pattern)
&lookup);
rust_assert (ok);
- // this must be an enum
- // TODO: might not be
+ // must be an ADT (?)
rust_assert (lookup->get_kind () == TyTy::TypeKind::ADT);
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup);
- rust_assert (adt->is_enum ());
+
+ // if this isn't an enum, always succeed
+ if (!adt->is_enum ())
+ {
+ check_expr = boolean_true_node;
+ return;
+ }
// lookup the variant
HirId variant_id;
@@ -52,17 +63,14 @@ CompilePatternCheckExpr::visit (HIR::PathInExpression &pattern)
rust_assert (ok);
// find discriminant field of scrutinee
- tree scrutinee_record_expr
- = Backend::struct_field_expression (match_scrutinee_expr, 0,
- pattern.get_locus ());
tree scrutinee_expr_qualifier_expr
- = Backend::struct_field_expression (scrutinee_record_expr, 0,
+ = Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_locus ());
// must be enum
match_scrutinee_expr = scrutinee_expr_qualifier_expr;
- HIR::Expr *discrim_expr = variant->get_discriminant ();
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
check_expr
@@ -75,10 +83,9 @@ void
CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
{
// Compile the literal
- HIR::LiteralExpr *litexpr
- = new HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
- pattern.get_locus (),
- std::vector<AST::Attribute> ());
+ auto litexpr = std::make_unique<HIR::LiteralExpr> (
+ HIR::LiteralExpr (pattern.get_mappings (), pattern.get_literal (),
+ pattern.get_locus (), std::vector<AST::Attribute> ()));
// Note: Floating point literals are currently accepted but will likely be
// forbidden in LiteralPatterns in a future version of Rust.
@@ -90,7 +97,7 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
rust_sorry_at (pattern.get_locus (), "floating-point literal in pattern");
}
- tree lit = CompileExpr::Compile (litexpr, ctx);
+ tree lit = CompileExpr::Compile (*litexpr, ctx);
check_expr = Backend::comparison_expression (ComparisonOperator::EQUAL,
match_scrutinee_expr, lit,
@@ -98,19 +105,17 @@ CompilePatternCheckExpr::visit (HIR::LiteralPattern &pattern)
}
static tree
-compile_range_pattern_bound (HIR::RangePatternBound *bound,
+compile_range_pattern_bound (HIR::RangePatternBound &bound,
Analysis::NodeMapping mappings, location_t locus,
Context *ctx)
{
tree result = NULL_TREE;
- switch (bound->get_bound_type ())
+ switch (bound.get_bound_type ())
{
case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
- HIR::RangePatternBoundLiteral &ref
- = *static_cast<HIR::RangePatternBoundLiteral *> (bound);
+ auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
- HIR::LiteralExpr *litexpr
- = new HIR::LiteralExpr (mappings, ref.get_literal (), locus,
+ HIR::LiteralExpr litexpr (mappings, ref.get_literal (), locus,
std::vector<AST::Attribute> ());
result = CompileExpr::Compile (litexpr, ctx);
@@ -118,8 +123,7 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
break;
case HIR::RangePatternBound::RangePatternBoundType::PATH: {
- HIR::RangePatternBoundPath &ref
- = *static_cast<HIR::RangePatternBoundPath *> (bound);
+ auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
result = ResolvePathRef::Compile (ref.get_path (), ctx);
@@ -129,8 +133,7 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
break;
case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
- HIR::RangePatternBoundQualPath &ref
- = *static_cast<HIR::RangePatternBoundQualPath *> (bound);
+ auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
result = ResolvePathRef::Compile (ref.get_qualified_path (), ctx);
@@ -145,10 +148,10 @@ compile_range_pattern_bound (HIR::RangePatternBound *bound,
void
CompilePatternCheckExpr::visit (HIR::RangePattern &pattern)
{
- tree upper = compile_range_pattern_bound (pattern.get_upper_bound ().get (),
+ tree upper = compile_range_pattern_bound (pattern.get_upper_bound (),
pattern.get_mappings (),
pattern.get_locus (), ctx);
- tree lower = compile_range_pattern_bound (pattern.get_lower_bound ().get (),
+ tree lower = compile_range_pattern_bound (pattern.get_lower_bound (),
pattern.get_mappings (),
pattern.get_locus (), ctx);
@@ -170,7 +173,7 @@ CompilePatternCheckExpr::visit (HIR::ReferencePattern &pattern)
{
match_scrutinee_expr
= indirect_expression (match_scrutinee_expr, pattern.get_locus ());
- pattern.get_referenced_pattern ()->accept_vis (*this);
+ pattern.get_referenced_pattern ().accept_vis (*this);
}
void
@@ -178,14 +181,13 @@ CompilePatternCheckExpr::visit (HIR::AltPattern &pattern)
{
auto &alts = pattern.get_alts ();
- check_expr = CompilePatternCheckExpr::Compile (alts.at (0).get (),
+ check_expr = CompilePatternCheckExpr::Compile (*alts.at (0),
match_scrutinee_expr, ctx);
auto end = alts.end ();
for (auto i = alts.begin () + 1; i != end; i++)
{
tree next_expr
- = CompilePatternCheckExpr::Compile (i->get (), match_scrutinee_expr,
- ctx);
+ = CompilePatternCheckExpr::Compile (**i, match_scrutinee_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_OR, check_expr, next_expr,
(*i)->get_locus ());
@@ -207,6 +209,7 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
rust_assert (adt->number_of_variants () > 0);
TyTy::VariantDef *variant = nullptr;
+ tree variant_accesser_expr = nullptr;
if (adt->is_enum ())
{
// lookup the variant
@@ -221,18 +224,21 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
// find expected discriminant
// // need to access qualifier the field, if we use QUAL_UNION_TYPE this
- // // would be DECL_QUALIFIER i think. For now this will just access the
- // // first record field and its respective qualifier because it will
- // // always be set because this is all a big special union
- HIR::Expr *discrim_expr = variant->get_discriminant ();
+ // // would be DECL_QUALIFIER i think.
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
// find discriminant field of scrutinee
- tree scrutinee_record_expr
- = Backend::struct_field_expression (match_scrutinee_expr, variant_index,
- pattern.get_path ().get_locus ());
tree scrutinee_expr_qualifier_expr
- = Backend::struct_field_expression (scrutinee_record_expr, 0,
+ = Backend::struct_field_expression (match_scrutinee_expr, 0,
+ pattern.get_path ().get_locus ());
+
+ // access variant data
+ tree scrutinee_union_expr
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern.get_path ().get_locus ());
+ variant_accesser_expr
+ = Backend::struct_field_expression (scrutinee_union_expr, variant_index,
pattern.get_path ().get_locus ());
check_expr
@@ -241,11 +247,12 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
discrim_expr_node,
pattern.get_path ().get_locus ());
- match_scrutinee_expr = scrutinee_record_expr;
+ match_scrutinee_expr = scrutinee_expr_qualifier_expr;
}
else
{
variant = adt->get_variants ().at (0);
+ variant_accesser_expr = match_scrutinee_expr;
check_expr = boolean_true_node;
}
@@ -269,19 +276,16 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
nullptr, &offs);
rust_assert (ok);
- // we may be offsetting by + 1 here since the first field in the
- // record is always the discriminator
- offs += adt->is_enum ();
tree field_expr
- = Backend::struct_field_expression (match_scrutinee_expr, offs,
+ = Backend::struct_field_expression (variant_accesser_expr, offs,
ident.get_locus ());
tree check_expr_sub
- = CompilePatternCheckExpr::Compile (ident.get_pattern ().get (),
+ = CompilePatternCheckExpr::Compile (ident.get_pattern (),
field_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
- check_expr_sub, ident.get_pattern ()->get_locus ());
+ check_expr_sub, ident.get_pattern ().get_locus ());
}
break;
@@ -296,8 +300,6 @@ CompilePatternCheckExpr::visit (HIR::StructPattern &pattern)
void
CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
{
- size_t tuple_field_index;
-
// lookup the type
TyTy::BaseType *lookup = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
@@ -308,6 +310,7 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
rust_assert (lookup->get_kind () == TyTy::TypeKind::ADT);
TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (lookup);
+ int variant_index = 0;
rust_assert (adt->number_of_variants () > 0);
TyTy::VariantDef *variant = nullptr;
if (adt->is_enum ())
@@ -318,20 +321,16 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
rust_assert (ok);
- int variant_index = 0;
ok = adt->lookup_variant_by_id (variant_id, &variant, &variant_index);
rust_assert (ok);
// find expected discriminant
- HIR::Expr *discrim_expr = variant->get_discriminant ();
+ HIR::Expr &discrim_expr = variant->get_discriminant ();
tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx);
// find discriminant field of scrutinee
- tree scrutinee_record_expr
- = Backend::struct_field_expression (match_scrutinee_expr, variant_index,
- pattern.get_path ().get_locus ());
tree scrutinee_expr_qualifier_expr
- = Backend::struct_field_expression (scrutinee_record_expr, 0,
+ = Backend::struct_field_expression (match_scrutinee_expr, 0,
pattern.get_path ().get_locus ());
check_expr
@@ -339,21 +338,15 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
scrutinee_expr_qualifier_expr,
discrim_expr_node,
pattern.get_path ().get_locus ());
-
- match_scrutinee_expr = scrutinee_record_expr;
- // we are offsetting by + 1 here since the first field in the record
- // is always the discriminator
- tuple_field_index = 1;
}
else
{
variant = adt->get_variants ().at (0);
check_expr = boolean_true_node;
- tuple_field_index = 0;
}
- std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
- switch (items->get_item_type ())
+ HIR::TupleStructItems &items = pattern.get_items ();
+ switch (items.get_item_type ())
{
case HIR::TupleStructItems::RANGED: {
// TODO
@@ -363,21 +356,30 @@ CompilePatternCheckExpr::visit (HIR::TupleStructPattern &pattern)
case HIR::TupleStructItems::MULTIPLE: {
HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+ = static_cast<HIR::TupleStructItemsNoRange &> (items);
rust_assert (items_no_range.get_patterns ().size ()
== variant->num_fields ());
+ size_t tuple_field_index = 0;
for (auto &pattern : items_no_range.get_patterns ())
{
+ // find payload union field of scrutinee
+ tree payload_ref
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern->get_locus ());
+
+ tree variant_ref
+ = Backend::struct_field_expression (payload_ref, variant_index,
+ pattern->get_locus ());
+
tree field_expr
- = Backend::struct_field_expression (match_scrutinee_expr,
+ = Backend::struct_field_expression (variant_ref,
tuple_field_index++,
pattern->get_locus ());
tree check_expr_sub
- = CompilePatternCheckExpr::Compile (pattern.get (), field_expr,
- ctx);
+ = CompilePatternCheckExpr::Compile (*pattern, field_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
check_expr_sub, pattern->get_locus ());
@@ -392,7 +394,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
{
check_expr = boolean_true_node;
- switch (pattern.get_items ()->get_item_type ())
+ switch (pattern.get_items ().get_item_type ())
{
case HIR::TuplePatternItems::RANGED: {
// TODO
@@ -402,7 +404,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
case HIR::TuplePatternItems::MULTIPLE: {
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- *pattern.get_items ());
+ pattern.get_items ());
size_t tuple_field_index = 0;
for (auto &pat : items.get_patterns ())
@@ -413,7 +415,7 @@ CompilePatternCheckExpr::visit (HIR::TuplePattern &pattern)
pat->get_locus ());
tree check_expr_sub
- = CompilePatternCheckExpr::Compile (pat.get (), field_expr, ctx);
+ = CompilePatternCheckExpr::Compile (*pat, field_expr, ctx);
check_expr = Backend::arithmetic_or_logical_expression (
ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
check_expr_sub, pat->get_locus ());
@@ -454,8 +456,8 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
rust_assert (variant->get_variant_type ()
== TyTy::VariantDef::VariantType::TUPLE);
- std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
- switch (items->get_item_type ())
+ HIR::TupleStructItems &items = pattern.get_items ();
+ switch (items.get_item_type ())
{
case HIR::TupleStructItems::RANGED: {
// TODO
@@ -465,20 +467,22 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
case HIR::TupleStructItems::MULTIPLE: {
HIR::TupleStructItemsNoRange &items_no_range
- = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
+ = static_cast<HIR::TupleStructItemsNoRange &> (items);
rust_assert (items_no_range.get_patterns ().size ()
== variant->num_fields ());
if (adt->is_enum ())
{
- // we are offsetting by + 1 here since the first field in the record
- // is always the discriminator
- size_t tuple_field_index = 1;
+ size_t tuple_field_index = 0;
for (auto &pattern : items_no_range.get_patterns ())
{
+ tree payload_accessor_union
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pattern->get_locus ());
+
tree variant_accessor
- = Backend::struct_field_expression (match_scrutinee_expr,
+ = Backend::struct_field_expression (payload_accessor_union,
variant_index,
pattern->get_locus ());
@@ -487,8 +491,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
tuple_field_index++,
pattern->get_locus ());
- ctx->insert_pattern_binding (
- pattern->get_mappings ().get_hirid (), binding);
+ CompilePatternBindings::Compile (*pattern, binding, ctx);
}
}
else
@@ -503,8 +506,7 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
tuple_field_index++,
pattern->get_locus ());
- ctx->insert_pattern_binding (
- pattern->get_mappings ().get_hirid (), binding);
+ CompilePatternBindings::Compile (*pattern, binding, ctx);
}
}
}
@@ -512,6 +514,71 @@ CompilePatternBindings::visit (HIR::TupleStructPattern &pattern)
}
}
+tree
+CompilePatternBindings::make_struct_access (TyTy::ADTType *adt,
+ TyTy::VariantDef *variant,
+ const Identifier &ident,
+ int variant_index)
+{
+ size_t offs = 0;
+ auto ok = variant->lookup_field (ident.as_string (), nullptr, &offs);
+ rust_assert (ok);
+
+ if (adt->is_enum ())
+ {
+ tree payload_accessor_union
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ ident.get_locus ());
+
+ tree variant_accessor
+ = Backend::struct_field_expression (payload_accessor_union,
+ variant_index, ident.get_locus ());
+
+ return Backend::struct_field_expression (variant_accessor, offs,
+ ident.get_locus ());
+ }
+ else
+ {
+ tree variant_accessor = match_scrutinee_expr;
+
+ return Backend::struct_field_expression (variant_accessor, offs,
+ ident.get_locus ());
+ }
+}
+
+void
+CompilePatternBindings::handle_struct_pattern_ident (
+ HIR::StructPatternField &pat, TyTy::ADTType *adt, TyTy::VariantDef *variant,
+ int variant_index)
+{
+ HIR::StructPatternFieldIdent &ident
+ = static_cast<HIR::StructPatternFieldIdent &> (pat);
+
+ auto identifier = ident.get_identifier ();
+ tree binding = make_struct_access (adt, variant, identifier, variant_index);
+
+ ctx->insert_pattern_binding (ident.get_mappings ().get_hirid (), binding);
+}
+
+void
+CompilePatternBindings::handle_struct_pattern_ident_pat (
+ HIR::StructPatternField &pat, TyTy::ADTType *adt, TyTy::VariantDef *variant,
+ int variant_index)
+{
+ auto &pattern = static_cast<HIR::StructPatternFieldIdentPat &> (pat);
+
+ tree binding = make_struct_access (adt, variant, pattern.get_identifier (),
+ variant_index);
+ CompilePatternBindings::Compile (pattern.get_pattern (), binding, ctx);
+}
+
+void
+CompilePatternBindings::handle_struct_pattern_tuple_pat (
+ HIR::StructPatternField &pat)
+{
+ rust_unreachable ();
+}
+
void
CompilePatternBindings::visit (HIR::StructPattern &pattern)
{
@@ -547,52 +614,14 @@ CompilePatternBindings::visit (HIR::StructPattern &pattern)
{
switch (field->get_item_type ())
{
- case HIR::StructPatternField::ItemType::TUPLE_PAT: {
- // TODO
- rust_unreachable ();
- }
+ case HIR::StructPatternField::ItemType::TUPLE_PAT:
+ handle_struct_pattern_tuple_pat (*field);
break;
-
- case HIR::StructPatternField::ItemType::IDENT_PAT: {
- // TODO
- rust_unreachable ();
- }
+ case HIR::StructPatternField::ItemType::IDENT_PAT:
+ handle_struct_pattern_ident_pat (*field, adt, variant, variant_index);
break;
-
- case HIR::StructPatternField::ItemType::IDENT: {
- HIR::StructPatternFieldIdent &ident
- = static_cast<HIR::StructPatternFieldIdent &> (*field.get ());
-
- size_t offs = 0;
- ok = variant->lookup_field (ident.get_identifier ().as_string (),
- nullptr, &offs);
- rust_assert (ok);
-
- tree binding = error_mark_node;
- if (adt->is_enum ())
- {
- tree variant_accessor
- = Backend::struct_field_expression (match_scrutinee_expr,
- variant_index,
- ident.get_locus ());
-
- // we are offsetting by + 1 here since the first field in the
- // record is always the discriminator
- binding = Backend::struct_field_expression (variant_accessor,
- offs + 1,
- ident.get_locus ());
- }
- else
- {
- tree variant_accessor = match_scrutinee_expr;
- binding
- = Backend::struct_field_expression (variant_accessor, offs,
- ident.get_locus ());
- }
-
- ctx->insert_pattern_binding (ident.get_mappings ().get_hirid (),
- binding);
- }
+ case HIR::StructPatternField::ItemType::IDENT:
+ handle_struct_pattern_ident (*field, adt, variant, variant_index);
break;
}
}
@@ -604,18 +633,112 @@ CompilePatternBindings::visit (HIR::ReferencePattern &pattern)
tree derefed
= indirect_expression (match_scrutinee_expr, pattern.get_locus ());
- CompilePatternBindings::Compile (pattern.get_referenced_pattern ().get (),
- derefed, ctx);
+ CompilePatternBindings::Compile (pattern.get_referenced_pattern (), derefed,
+ ctx);
}
void
CompilePatternBindings::visit (HIR::IdentifierPattern &pattern)
{
- ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
- match_scrutinee_expr);
+ if (!pattern.get_is_ref ())
+ {
+ ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (),
+ match_scrutinee_expr);
+ return;
+ }
+
+ tree ref = address_expression (match_scrutinee_expr,
+ EXPR_LOCATION (match_scrutinee_expr));
+ ctx->insert_pattern_binding (pattern.get_mappings ().get_hirid (), ref);
}
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;
@@ -627,7 +750,7 @@ CompilePatternLet::visit (HIR::IdentifierPattern &pattern)
{
ctx->add_statement (init_expr);
- auto unit_type_init_expr = unit_expression (ctx, rval_locus);
+ auto unit_type_init_expr = unit_expression (rval_locus);
auto s = Backend::init_statement (fnctx.fndecl, var, unit_type_init_expr);
ctx->add_statement (s);
}
@@ -665,12 +788,12 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
tree access_expr = Backend::var_expression (tmp_var, pattern.get_locus ());
ctx->add_statement (init_stmt);
- switch (pattern.get_items ()->get_item_type ())
+ 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 ());
+ = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ());
auto &items_lower = items.get_lower_patterns ();
auto &items_upper = items.get_upper_patterns ();
@@ -714,7 +837,7 @@ CompilePatternLet::visit (HIR::TuplePattern &pattern)
case HIR::TuplePatternItems::ItemType::MULTIPLE: {
size_t tuple_idx = 0;
auto &items = static_cast<HIR::TuplePatternItemsMultiple &> (
- *pattern.get_items ());
+ pattern.get_items ());
for (auto &sub : items.get_patterns ())
{