From: Yap Zhi Heng Date: Tue, 2 Sep 2025 13:44:19 +0000 (+0800) Subject: gccrs: Use rich_location for TupleStructPattern type check num field error X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=10c3682a55c61e48be4b30e52f8df9b4242b886e;p=thirdparty%2Fgcc.git gccrs: Use rich_location for TupleStructPattern type check num field error gcc/rust/ChangeLog: * typecheck/rust-hir-type-check-pattern.cc (visit(TupleStructPattern)): Update error for mismatched number of fields to use rich_location. Signed-off-by: Yap Zhi Heng --- diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index 751456ccc77..4d9d60ca5bd 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc @@ -204,22 +204,66 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern) { HIR::TupleStructItemsHasRest &items_has_rest = static_cast (items); - size_t pattern_min_cap = items_has_rest.get_lower_patterns ().size () - + items_has_rest.get_upper_patterns ().size (); + auto &lower_patterns = items_has_rest.get_lower_patterns (); + auto &upper_patterns = items_has_rest.get_upper_patterns (); + size_t pattern_min_cap + = lower_patterns.size () + upper_patterns.size (); if (variant->num_fields () < pattern_min_cap) { - rust_error_at (pattern.get_locus (), ErrorCode::E0023, - "this pattern has %lu fields but the corresponding " - "tuple variant has %lu field", - (unsigned long) (pattern_min_cap), - (unsigned long) variant->num_fields ()); + if (!lower_patterns.empty ()) + { + // TODO initialize rich_locus with loc of ADT definition instead + rich_location rich_locus (line_table, + lower_patterns[0]->get_locus ()); + for (auto &pattern : lower_patterns) + { + if (pattern == lower_patterns[0]) + continue; + rich_locus.add_range (pattern->get_locus (), + SHOW_RANGE_WITH_CARET); + } + for (auto &pattern : upper_patterns) + { + rich_locus.add_range (pattern->get_locus (), + SHOW_RANGE_WITH_CARET); + } + rust_error_at (rich_locus, ErrorCode::E0023, + "this pattern has %lu %s but the corresponding " + "tuple variant has %lu %s", + (unsigned long) (pattern_min_cap), + pattern_min_cap == 1 ? "field" : "fields", + (unsigned long) variant->num_fields (), + variant->num_fields () == 1 ? "field" + : "fields"); + } + else + { + // TODO initialize rich_locus with loc of ADT definition instead + rich_location rich_locus (line_table, + upper_patterns[0]->get_locus ()); + for (auto &pattern : upper_patterns) + { + if (pattern == upper_patterns[0]) + continue; + rich_locus.add_range (pattern->get_locus (), + SHOW_RANGE_WITH_CARET); + } + rust_error_at (rich_locus, ErrorCode::E0023, + "this pattern has %lu %s but the corresponding " + "tuple variant has %lu %s", + (unsigned long) (pattern_min_cap), + pattern_min_cap == 1 ? "field" : "fields", + (unsigned long) variant->num_fields (), + variant->num_fields () == 1 ? "field" + : "fields"); + } // we continue on to try and setup the types as best we can for // type checking } // iterate the fields manually to set them up size_t i = 0; - for (auto &pattern : items_has_rest.get_lower_patterns ()) + for (auto &pattern : lower_patterns) { if (i >= variant->num_fields ()) break; @@ -232,9 +276,8 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern) TypeCheckPattern::Resolve (*pattern, fty); } - i = variant->num_fields () - - items_has_rest.get_upper_patterns ().size (); - for (auto &pattern : items_has_rest.get_upper_patterns ()) + i = variant->num_fields () - upper_patterns.size (); + for (auto &pattern : upper_patterns) { if (i >= variant->num_fields ()) break; @@ -253,15 +296,41 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern) { HIR::TupleStructItemsNoRest &items_no_rest = static_cast (items); + auto &patterns = items_no_rest.get_patterns (); - if (items_no_rest.get_patterns ().size () != variant->num_fields ()) + if (patterns.size () != variant->num_fields ()) { - rust_error_at ( - pattern.get_locus (), ErrorCode::E0023, - "this pattern has %lu fields but the corresponding " - "tuple variant has %lu field", - (unsigned long) items_no_rest.get_patterns ().size (), - (unsigned long) variant->num_fields ()); + if (patterns.empty ()) + { + rust_error_at (pattern.get_locus (), ErrorCode::E0023, + "this pattern has %lu %s but the corresponding " + "tuple variant has %lu %s", + (unsigned long) patterns.size (), + patterns.size () == 1 ? "field" : "fields", + (unsigned long) variant->num_fields (), + variant->num_fields () == 1 ? "field" + : "fields"); + } + else + { + rich_location rich_locus (line_table, + patterns[0]->get_locus ()); + for (auto &pattern : items_no_rest.get_patterns ()) + { + if (pattern == patterns[0]) + continue; + rich_locus.add_range (pattern->get_locus (), + SHOW_RANGE_WITH_CARET); + } + rust_error_at (rich_locus, ErrorCode::E0023, + "this pattern has %lu %s but the corresponding " + "tuple variant has %lu %s", + (unsigned long) patterns.size (), + patterns.size () == 1 ? "field" : "fields", + (unsigned long) variant->num_fields (), + variant->num_fields () == 1 ? "field" + : "fields"); + } // we continue on to try and setup the types as best we can for // type checking } diff --git a/gcc/testsuite/rust/compile/match-tuplestructpattern-err.rs b/gcc/testsuite/rust/compile/match-tuplestructpattern-err.rs new file mode 100644 index 00000000000..efd1a896941 --- /dev/null +++ b/gcc/testsuite/rust/compile/match-tuplestructpattern-err.rs @@ -0,0 +1,14 @@ +fn main() { + struct A (i32, i32); + let a = A (0, 1); + + match a { + A (1, 2, 3, 4) => {}, + // { dg-error "this pattern has 4 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 } + A (1, 2, .., 3, 4) => {}, + // { dg-error "this pattern has 4 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 } + A (.., 3, 4, 5) => {}, + // { dg-error "this pattern has 3 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 } + _ => {} + } +} \ No newline at end of file