@@ -162,19 +162,32 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
162162
163163 infered = pattern_ty;
164164 TyTy::ADTType *adt = static_cast <TyTy::ADTType *> (infered);
165- rust_assert (adt->number_of_variants () > 0 );
166165
167- TyTy::VariantDef *variant = adt-> get_variants (). at ( 0 ) ;
166+ TyTy::VariantDef *variant = nullptr ;
168167 if (adt->is_enum ())
169168 {
170169 HirId variant_id = UNKNOWN_HIRID;
171170 bool ok = context->lookup_variant_definition (
172171 pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
173- rust_assert (ok);
172+ if (!ok)
173+ {
174+ rust_error_at (
175+ pattern.get_locus (), ErrorCode::E0532 ,
176+ " expected tuple struct or tuple variant, found enum %qs" ,
177+ pattern_ty->get_name ().c_str ());
178+ return ;
179+ }
174180
175181 ok = adt->lookup_variant_by_id (variant_id, &variant);
176182 rust_assert (ok);
177183 }
184+ else
185+ {
186+ rust_assert (adt->number_of_variants () > 0 );
187+ variant = adt->get_variants ().at (0 );
188+ }
189+
190+ rust_assert (variant != nullptr );
178191
179192 // error[E0532]: expected tuple struct or tuple variant, found struct
180193 // variant `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
@@ -644,14 +657,14 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
644657 {
645658 emit_pattern_size_error (pattern, par.get_fields ().size (),
646659 min_size_required);
647- // TODO attempt to continue to do typechecking even after wrong
648- // size
649- break ;
660+ // continue and attempt to resolve individual items in the pattern
650661 }
651662
652663 // Resolve lower patterns
653664 std::vector<TyTy::TyVar> pattern_elems;
654- for (size_t i = 0 ; i < lower.size (); i++)
665+ size_t nlower_items_to_resolve
666+ = std::min (lower.size (), par.get_fields ().size ());
667+ for (size_t i = 0 ; i < nlower_items_to_resolve; i++)
655668 {
656669 auto &p = lower[i];
657670 TyTy::BaseType *par_type = par.get_field (i);
@@ -660,16 +673,23 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
660673 pattern_elems.emplace_back (elem->get_ref ());
661674 }
662675
676+ if (lower.size () > par.get_fields ().size ())
677+ break ;
678+
663679 // Pad pattern_elems until needing to resolve upper patterns
664- size_t rest_end = par.get_fields ().size () - upper.size ();
680+ size_t rest_end
681+ = std::max (par.get_fields ().size () - upper.size (), lower.size ());
665682 for (size_t i = lower.size (); i < rest_end; i++)
666683 {
667684 TyTy::BaseType *par_type = par.get_field (i);
668685 pattern_elems.emplace_back (par_type->get_ref ());
669686 }
670687
688+ size_t nupper_items_to_resolve
689+ = std::min (upper.size (),
690+ par.get_fields ().size () - pattern_elems.size ());
671691 // Resolve upper patterns
672- for (size_t i = 0 ; i < upper. size () ; i++)
692+ for (size_t i = 0 ; i < nupper_items_to_resolve ; i++)
673693 {
674694 auto &p = upper[i];
675695 TyTy::BaseType *par_type = par.get_field (rest_end + i);
0 commit comments