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