{
case HIR::StructPatternField::ItemType::TUPLE_PAT:
{
- // TODO
- rust_unreachable ();
+ HIR::StructPatternFieldTuplePat &tuple_pat
+ = static_cast<HIR::StructPatternFieldTuplePat &> (*field.get ());
+ size_t tuple_pat_index = tuple_pat.get_index ();
+ tree field_expr
+ = Backend::struct_field_expression (variant_accesser_expr,
+ tuple_pat_index,
+ tuple_pat.get_locus ());
+ tree check_expr_sub = CompilePatternCheckExpr::Compile (
+ tuple_pat.get_tuple_pattern (), field_expr, ctx);
+ check_expr = Backend::arithmetic_or_logical_expression (
+ ArithmeticOrLogicalOperator::BITWISE_AND, check_expr,
+ check_expr_sub, tuple_pat.get_locus ());
}
break;
void
CompilePatternBindings::handle_struct_pattern_tuple_pat (
- HIR::StructPatternField &pat)
+ HIR::StructPatternField &pat, TyTy::ADTType *adt, TyTy::VariantDef *variant,
+ int variant_index)
{
- rust_unreachable ();
+ HIR::StructPatternFieldTuplePat &tuple_pat
+ = static_cast<HIR::StructPatternFieldTuplePat &> (pat);
+
+ size_t tuple_pat_index = tuple_pat.get_index ();
+ tree binding;
+
+ if (adt->is_enum ())
+ {
+ tree payload_accessor_union
+ = Backend::struct_field_expression (match_scrutinee_expr, 1,
+ pat.get_locus ());
+
+ tree variant_accessor
+ = Backend::struct_field_expression (payload_accessor_union,
+ variant_index, pat.get_locus ());
+
+ binding
+ = Backend::struct_field_expression (variant_accessor, tuple_pat_index,
+ pat.get_locus ());
+ }
+ else
+ {
+ tree variant_accessor = match_scrutinee_expr;
+
+ binding
+ = Backend::struct_field_expression (variant_accessor, tuple_pat_index,
+ pat.get_locus ());
+ }
+
+ CompilePatternBindings::Compile (tuple_pat.get_tuple_pattern (), binding,
+ ctx);
}
void
switch (field->get_item_type ())
{
case HIR::StructPatternField::ItemType::TUPLE_PAT:
- handle_struct_pattern_tuple_pat (*field);
+ handle_struct_pattern_tuple_pat (*field, adt, variant, variant_index);
break;
case HIR::StructPatternField::ItemType::IDENT_PAT:
handle_struct_pattern_ident_pat (*field, adt, variant, variant_index);
TyTy::ADTType *adt,
TyTy::VariantDef *variant,
int variant_index);
- void handle_struct_pattern_tuple_pat (HIR::StructPatternField &pat);
+ void handle_struct_pattern_tuple_pat (HIR::StructPatternField &pat,
+ TyTy::ADTType *adt,
+ TyTy::VariantDef *variant,
+ int variant_index);
void visit (HIR::StructPattern &pattern) override;
void visit (HIR::TupleStructPattern &pattern) override;
break;
case HIR::StructPatternField::ItemType::TUPLE_PAT:
{
- // TODO: tuple: pat
- rust_unreachable ();
+ HIR::StructPatternFieldTuplePat *tuple_pat
+ = static_cast<HIR::StructPatternFieldTuplePat *> (elem.get ());
+ int field_idx = tuple_pat->get_index ();
+ fields.at (field_idx) = lower_pattern (
+ ctx, tuple_pat->get_tuple_pattern (),
+ variant->get_fields ().at (field_idx)->get_field_type ());
}
break;
default:
{
case HIR::StructPatternField::ItemType::TUPLE_PAT:
{
- // TODO
- rust_unreachable ();
+ HIR::StructPatternFieldTuplePat &tuple_pat
+ = static_cast<HIR::StructPatternFieldTuplePat &> (*field.get ());
+
+ if ((size_t) tuple_pat.get_index () >= variant->num_fields ())
+ {
+ emit_invalid_field_error (tuple_pat.get_locus (), variant,
+ std::to_string (
+ tuple_pat.get_index ()));
+ break;
+ }
+ named_fields.push_back (std::to_string (tuple_pat.get_index ()));
+ TyTy::StructFieldType *field
+ = variant->get_field_at_index (tuple_pat.get_index ());
+ TyTy::BaseType *fty = field->get_field_type ();
+ TypeCheckPattern::Resolve (tuple_pat.get_tuple_pattern (), fty);
}
break;
--- /dev/null
+pub struct TupStruct (i32, i32);
+
+pub fn main() {
+ let t = TupStruct (1, 2);
+ match t {
+ TupStruct { 0: 1, 1: 2, 2: 3 } => {}
+ // { dg-error "variant TupStruct does not have a field named 2 .E0026." "" { target *-*-* } .-1 }
+ TupStruct { 3: 3 } => {}
+ // { dg-error "pattern does not mention fields 0, 1 .E0027." "" { target *-*-* } .-1 }
+ // { dg-error "variant TupStruct does not have a field named 3 .E0026." "" { target *-*-* } .-2 }
+ TupStruct { a: 3 } => {}
+ // { dg-error "tuple variant .TupStruct. written as struct variant .E0769." "" { target *-*-* } .-1 }
+ TupStruct { 0: 0.1f32, .. } => {}
+ // { dg-error "mismatched types, expected .i32. but got .f32. .E0308." "" { target *-*-* } .-1 }
+ _ => {}
+ }
+}
--- /dev/null
+pub struct TupStruct (i32, i32);
+
+pub fn main() {
+ let t = TupStruct (1, 2);
+ match t {
+ TupStruct { 0: 1, 1: 2 } => {}
+ TupStruct { 1: b, .. } => {}
+ TupStruct { 0: 1, .. } => {}
+ _ => {}
+ }
+}
--- /dev/null
+pub struct TupStruct (i32, i32);
+
+pub fn main() -> i32 {
+ let mut t = TupStruct (1, 1);
+ match t {
+ TupStruct { 0: 1, 1: b } => { b -= 1 }
+ _ => {}
+ }
+ b
+}