@@ -463,26 +463,27 @@ void
463
463
TypeCheckPattern::visit (HIR::TuplePattern &pattern)
464
464
{
465
465
std::unique_ptr<HIR::TuplePatternItems> items;
466
+
467
+ // Check whether parent is tuple
468
+ auto resolved_parent = parent->destructure ();
469
+ if (resolved_parent->get_kind () != TyTy::TUPLE)
470
+ {
471
+ rust_error_at (pattern.get_locus (), " expected %s, found tuple" ,
472
+ parent->as_string ().c_str ());
473
+ return ;
474
+ }
475
+ TyTy::TupleType &par = *static_cast <TyTy::TupleType *> (resolved_parent);
476
+
466
477
switch (pattern.get_items ().get_item_type ())
467
478
{
468
479
case HIR::TuplePatternItems::ItemType::MULTIPLE:
469
480
{
470
481
auto &ref = static_cast <HIR::TuplePatternItemsMultiple &> (
471
482
pattern.get_items ());
472
483
473
- auto resolved_parent = parent->destructure ();
474
- if (resolved_parent->get_kind () != TyTy::TUPLE)
475
- {
476
- rust_error_at (pattern.get_locus (), " expected %s, found tuple" ,
477
- parent->as_string ().c_str ());
478
- break ;
479
- }
480
-
481
484
const auto &patterns = ref.get_patterns ();
482
485
size_t nitems_to_resolve = patterns.size ();
483
486
484
- TyTy::TupleType &par
485
- = *static_cast <TyTy::TupleType *> (resolved_parent);
486
487
if (patterns.size () != par.get_fields ().size ())
487
488
{
488
489
emit_pattern_size_error (pattern, par.get_fields ().size (),
@@ -507,11 +508,53 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
507
508
508
509
case HIR::TuplePatternItems::ItemType::RANGED:
509
510
{
510
- // HIR::TuplePatternItemsRanged &ref
511
- // = *static_cast<HIR::TuplePatternItemsRanged *> (
512
- // pattern.get_items ().get ());
513
- // TODO
514
- rust_unreachable ();
511
+ HIR::TuplePatternItemsRanged &ref
512
+ = static_cast <HIR::TuplePatternItemsRanged &> (pattern.get_items ());
513
+
514
+ // Check whether size of lower and upper patterns <= parent size
515
+ const auto &lower = ref.get_lower_patterns ();
516
+ const auto &upper = ref.get_upper_patterns ();
517
+ size_t min_size_required = lower.size () + upper.size ();
518
+
519
+ if (par.get_fields ().size () > min_size_required)
520
+ {
521
+ emit_pattern_size_error (pattern, par.get_fields ().size (),
522
+ min_size_required);
523
+ // TODO attempt to continue to do typechecking even after wrong size
524
+ break ;
525
+ }
526
+
527
+ // Resolve lower patterns
528
+ std::vector<TyTy::TyVar> pattern_elems;
529
+ for (size_t i = 0 ; i < lower.size (); i++)
530
+ {
531
+ auto &p = lower[i];
532
+ TyTy::BaseType *par_type = par.get_field (i);
533
+
534
+ TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
535
+ pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
536
+ }
537
+
538
+ // Pad pattern_elems until needing to resolve upper patterns
539
+ size_t rest_end = par.get_fields ().size () - upper.size ();
540
+ for (size_t i = lower.size (); i < rest_end; i++)
541
+ {
542
+ TyTy::BaseType *par_type = par.get_field (i);
543
+ pattern_elems.push_back (TyTy::TyVar (par_type->get_ref ()));
544
+ }
545
+
546
+ // Resolve upper patterns
547
+ for (size_t i = 0 ; i < upper.size (); i++)
548
+ {
549
+ auto &p = upper[i];
550
+ TyTy::BaseType *par_type = par.get_field (rest_end + i);
551
+
552
+ TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
553
+ pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
554
+ }
555
+
556
+ infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
557
+ pattern.get_locus (), pattern_elems);
515
558
}
516
559
break ;
517
560
}
0 commit comments