Skip to content

Commit 8779e12

Browse files
committed
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 <[email protected]>
1 parent 71b0bcd commit 8779e12

File tree

2 files changed

+101
-18
lines changed

2 files changed

+101
-18
lines changed

gcc/rust/typecheck/rust-hir-type-check-pattern.cc

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,22 +204,66 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
204204
{
205205
HIR::TupleStructItemsHasRest &items_has_rest
206206
= static_cast<HIR::TupleStructItemsHasRest &> (items);
207-
size_t pattern_min_cap = items_has_rest.get_lower_patterns ().size ()
208-
+ items_has_rest.get_upper_patterns ().size ();
207+
auto &lower_patterns = items_has_rest.get_lower_patterns ();
208+
auto &upper_patterns = items_has_rest.get_upper_patterns ();
209+
size_t pattern_min_cap
210+
= lower_patterns.size () + upper_patterns.size ();
209211
if (variant->num_fields () < pattern_min_cap)
210212
{
211-
rust_error_at (pattern.get_locus (), ErrorCode::E0023,
212-
"this pattern has %lu fields but the corresponding "
213-
"tuple variant has %lu field",
214-
(unsigned long) (pattern_min_cap),
215-
(unsigned long) variant->num_fields ());
213+
if (!lower_patterns.empty ())
214+
{
215+
// TODO initialize rich_locus with loc of ADT definition instead
216+
rich_location rich_locus (line_table,
217+
lower_patterns[0]->get_locus ());
218+
for (auto &pattern : lower_patterns)
219+
{
220+
if (pattern == lower_patterns[0])
221+
continue;
222+
rich_locus.add_range (pattern->get_locus (),
223+
SHOW_RANGE_WITH_CARET);
224+
}
225+
for (auto &pattern : upper_patterns)
226+
{
227+
rich_locus.add_range (pattern->get_locus (),
228+
SHOW_RANGE_WITH_CARET);
229+
}
230+
rust_error_at (rich_locus, ErrorCode::E0023,
231+
"this pattern has %lu %s but the corresponding "
232+
"tuple variant has %lu %s",
233+
(unsigned long) (pattern_min_cap),
234+
pattern_min_cap == 1 ? "field" : "fields",
235+
(unsigned long) variant->num_fields (),
236+
variant->num_fields () == 1 ? "field"
237+
: "fields");
238+
}
239+
else
240+
{
241+
// TODO initialize rich_locus with loc of ADT definition instead
242+
rich_location rich_locus (line_table,
243+
upper_patterns[0]->get_locus ());
244+
for (auto &pattern : upper_patterns)
245+
{
246+
if (pattern == upper_patterns[0])
247+
continue;
248+
rich_locus.add_range (pattern->get_locus (),
249+
SHOW_RANGE_WITH_CARET);
250+
}
251+
rust_error_at (rich_locus, ErrorCode::E0023,
252+
"this pattern has %lu %s but the corresponding "
253+
"tuple variant has %lu %s",
254+
(unsigned long) (pattern_min_cap),
255+
pattern_min_cap == 1 ? "field" : "fields",
256+
(unsigned long) variant->num_fields (),
257+
variant->num_fields () == 1 ? "field"
258+
: "fields");
259+
}
216260
// we continue on to try and setup the types as best we can for
217261
// type checking
218262
}
219263

220264
// iterate the fields manually to set them up
221265
size_t i = 0;
222-
for (auto &pattern : items_has_rest.get_lower_patterns ())
266+
for (auto &pattern : lower_patterns)
223267
{
224268
if (i >= variant->num_fields ())
225269
break;
@@ -232,9 +276,8 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
232276
TypeCheckPattern::Resolve (*pattern, fty);
233277
}
234278

235-
i = variant->num_fields ()
236-
- items_has_rest.get_upper_patterns ().size ();
237-
for (auto &pattern : items_has_rest.get_upper_patterns ())
279+
i = variant->num_fields () - upper_patterns.size ();
280+
for (auto &pattern : upper_patterns)
238281
{
239282
if (i >= variant->num_fields ())
240283
break;
@@ -253,15 +296,41 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
253296
{
254297
HIR::TupleStructItemsNoRest &items_no_rest
255298
= static_cast<HIR::TupleStructItemsNoRest &> (items);
299+
auto &patterns = items_no_rest.get_patterns ();
256300

257-
if (items_no_rest.get_patterns ().size () != variant->num_fields ())
301+
if (patterns.size () != variant->num_fields ())
258302
{
259-
rust_error_at (
260-
pattern.get_locus (), ErrorCode::E0023,
261-
"this pattern has %lu fields but the corresponding "
262-
"tuple variant has %lu field",
263-
(unsigned long) items_no_rest.get_patterns ().size (),
264-
(unsigned long) variant->num_fields ());
303+
if (patterns.empty ())
304+
{
305+
rust_error_at (pattern.get_locus (), ErrorCode::E0023,
306+
"this pattern has %lu %s but the corresponding "
307+
"tuple variant has %lu %s",
308+
(unsigned long) patterns.size (),
309+
patterns.size () == 1 ? "field" : "fields",
310+
(unsigned long) variant->num_fields (),
311+
variant->num_fields () == 1 ? "field"
312+
: "fields");
313+
}
314+
else
315+
{
316+
rich_location rich_locus (line_table,
317+
patterns[0]->get_locus ());
318+
for (auto &pattern : items_no_rest.get_patterns ())
319+
{
320+
if (pattern == patterns[0])
321+
continue;
322+
rich_locus.add_range (pattern->get_locus (),
323+
SHOW_RANGE_WITH_CARET);
324+
}
325+
rust_error_at (rich_locus, ErrorCode::E0023,
326+
"this pattern has %lu %s but the corresponding "
327+
"tuple variant has %lu %s",
328+
(unsigned long) patterns.size (),
329+
patterns.size () == 1 ? "field" : "fields",
330+
(unsigned long) variant->num_fields (),
331+
variant->num_fields () == 1 ? "field"
332+
: "fields");
333+
}
265334
// we continue on to try and setup the types as best we can for
266335
// type checking
267336
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
fn main() {
2+
struct A (i32, i32);
3+
let a = A (0, 1);
4+
5+
match a {
6+
A (1, 2, 3, 4) => {},
7+
// { dg-error "this pattern has 4 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 }
8+
A (1, 2, .., 3, 4) => {},
9+
// { dg-error "this pattern has 4 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 }
10+
A (.., 3, 4, 5) => {},
11+
// { dg-error "this pattern has 3 fields but the corresponding tuple variant has 2 fields .E0023." "" { target *-*-* } .-1 }
12+
_ => {}
13+
}
14+
}

0 commit comments

Comments
 (0)