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;
     }

Reply via email to