https://gcc.gnu.org/g:50f8401aaf599a661c319ad04c3fd7953d723b27
commit r16-4896-g50f8401aaf599a661c319ad04c3fd7953d723b27 Author: Yap Zhi Heng <[email protected]> Date: Sat Oct 18 13:22:05 2025 +0800 gccrs: Attempt to resolve pattern items in tuple pattern with a rest pattern 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]> Diff: --- gcc/rust/typecheck/rust-hir-type-check-pattern.cc | 19 +++++++++++++------ .../compile/tuplepattern-restpattern-typecheck-err.rs | 8 ++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index dd9a49f49dc5..7dae303cd25a 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 000000000000..d9f7c18f3ac4 --- /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
