From: Yap Zhi Heng <[email protected]>

gcc/rust/ChangeLog:

        * typecheck/rust-hir-type-check-pattern.cc (visit(TuplePattern)): 
Update HAS_REST
        case to continue to attempt to resolve pattern items after emitting 
size error.

Signed-off-by: Yap Zhi Heng <[email protected]>
---
 .../typecheck/rust-hir-type-check-pattern.cc  | 19 +++++++++++++------
 .../tuplepattern-restpattern-typecheck-err.rs |  8 ++++++++
 2 files changed, 21 insertions(+), 6 deletions(-)
 create mode 100644 
gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc 
b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index dd9a49f49dc..7dae303cd25 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -657,14 +657,14 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
          {
            emit_pattern_size_error (pattern, par.get_fields ().size (),
                                     min_size_required);
-           // TODO attempt to continue to do typechecking even after wrong
-           // size
-           break;
+           // continue and attempt to resolve individual items in the pattern
          }
 
        // Resolve lower patterns
        std::vector<TyTy::TyVar> pattern_elems;
-       for (size_t i = 0; i < lower.size (); i++)
+       size_t nlower_items_to_resolve
+         = std::min (lower.size (), par.get_fields ().size ());
+       for (size_t i = 0; i < nlower_items_to_resolve; i++)
          {
            auto &p = lower[i];
            TyTy::BaseType *par_type = par.get_field (i);
@@ -673,16 +673,23 @@ TypeCheckPattern::visit (HIR::TuplePattern &pattern)
            pattern_elems.emplace_back (elem->get_ref ());
          }
 
+       if (lower.size () > par.get_fields ().size ())
+         break;
+
        // Pad pattern_elems until needing to resolve upper patterns
-       size_t rest_end = par.get_fields ().size () - upper.size ();
+       size_t rest_end
+         = std::max (par.get_fields ().size () - upper.size (), lower.size ());
        for (size_t i = lower.size (); i < rest_end; i++)
          {
            TyTy::BaseType *par_type = par.get_field (i);
            pattern_elems.emplace_back (par_type->get_ref ());
          }
 
+       size_t nupper_items_to_resolve
+         = std::min (upper.size (),
+                     par.get_fields ().size () - pattern_elems.size ());
        // Resolve upper patterns
-       for (size_t i = 0; i < upper.size (); i++)
+       for (size_t i = 0; i < nupper_items_to_resolve; i++)
          {
            auto &p = upper[i];
            TyTy::BaseType *par_type = par.get_field (rest_end + i);
diff --git 
a/gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs 
b/gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs
new file mode 100644
index 00000000000..d9f7c18f3ac
--- /dev/null
+++ b/gcc/testsuite/rust/compile/tuplepattern-restpattern-typecheck-err.rs
@@ -0,0 +1,8 @@
+fn main() {
+    match (1, 2.2, "not 3") {
+        // { dg-error "expected a tuple with 3 elements, found one with 5 
elements" "" { target *-*-* } .+1 }
+        (a, b, .., c, d, e) => {
+            let _ = b + c; // { dg-error "cannot apply operator .+. to types 
<float> and & str" }
+        }
+    }
+}
\ No newline at end of file
-- 
2.50.1

Reply via email to