https://gcc.gnu.org/g:59c81cdfeace0e2c7e5bcd6468e36764ede794a6
commit r16-2901-g59c81cdfeace0e2c7e5bcd6468e36764ede794a6 Author: Zhi Heng <yapz...@gmail.com> Date: Thu Jun 26 22:33:15 2025 +0800 gccrs: Implement type checking for ItemType::RANGED in TuplePattern This patch implements the previously unimplemented type checking for RANGED item type for TuplePattern, which serves as the start for implementing compilation of RestPattern. gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-pattern.cc (TypeCheckPattern::visit(TuplePattern)): Implement type checking for ItemType::RANGED. Signed-off-by: Yap Zhi Heng <yapz...@gmail.com> Diff: --- gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 73 ++++++++++++++++++----- 1 file changed, 58 insertions(+), 15 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index 15d8620dc2ad..d87916ec7985 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc @@ -463,6 +463,17 @@ void TypeCheckPattern::visit (HIR::TuplePattern &pattern) { std::unique_ptr<HIR::TuplePatternItems> items; + + // Check whether parent is tuple + auto resolved_parent = parent->destructure (); + if (resolved_parent->get_kind () != TyTy::TUPLE) + { + rust_error_at (pattern.get_locus (), "expected %s, found tuple", + parent->as_string ().c_str ()); + return; + } + TyTy::TupleType &par = *static_cast<TyTy::TupleType *> (resolved_parent); + switch (pattern.get_items ().get_item_type ()) { case HIR::TuplePatternItems::ItemType::MULTIPLE: @@ -470,19 +481,9 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern) auto &ref = static_cast<HIR::TuplePatternItemsMultiple &> ( pattern.get_items ()); - auto resolved_parent = parent->destructure (); - if (resolved_parent->get_kind () != TyTy::TUPLE) - { - rust_error_at (pattern.get_locus (), "expected %s, found tuple", - parent->as_string ().c_str ()); - break; - } - const auto &patterns = ref.get_patterns (); size_t nitems_to_resolve = patterns.size (); - TyTy::TupleType &par - = *static_cast<TyTy::TupleType *> (resolved_parent); if (patterns.size () != par.get_fields ().size ()) { emit_pattern_size_error (pattern, par.get_fields ().size (), @@ -507,11 +508,53 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern) case HIR::TuplePatternItems::ItemType::RANGED: { - // HIR::TuplePatternItemsRanged &ref - // = *static_cast<HIR::TuplePatternItemsRanged *> ( - // pattern.get_items ().get ()); - // TODO - rust_unreachable (); + HIR::TuplePatternItemsRanged &ref + = static_cast<HIR::TuplePatternItemsRanged &> (pattern.get_items ()); + + // Check whether size of lower and upper patterns <= parent size + const auto &lower = ref.get_lower_patterns (); + const auto &upper = ref.get_upper_patterns (); + size_t min_size_required = lower.size () + upper.size (); + + if (par.get_fields ().size () > min_size_required) + { + emit_pattern_size_error (pattern, par.get_fields ().size (), + min_size_required); + // TODO attempt to continue to do typechecking even after wrong size + break; + } + + // Resolve lower patterns + std::vector<TyTy::TyVar> pattern_elems; + for (size_t i = 0; i < lower.size (); i++) + { + auto &p = lower[i]; + TyTy::BaseType *par_type = par.get_field (i); + + TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type); + pattern_elems.push_back (TyTy::TyVar (elem->get_ref ())); + } + + // Pad pattern_elems until needing to resolve upper patterns + size_t rest_end = par.get_fields ().size () - upper.size (); + for (size_t i = lower.size (); i < rest_end; i++) + { + TyTy::BaseType *par_type = par.get_field (i); + pattern_elems.push_back (TyTy::TyVar (par_type->get_ref ())); + } + + // Resolve upper patterns + for (size_t i = 0; i < upper.size (); i++) + { + auto &p = upper[i]; + TyTy::BaseType *par_type = par.get_field (rest_end + i); + + TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type); + pattern_elems.push_back (TyTy::TyVar (elem->get_ref ())); + } + + infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (), + pattern.get_locus (), pattern_elems); } break; }