@@ -204,22 +204,66 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
204
204
{
205
205
HIR::TupleStructItemsHasRest &items_has_rest
206
206
= 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 ();
209
211
if (variant->num_fields () < pattern_min_cap)
210
212
{
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
+ }
216
260
// we continue on to try and setup the types as best we can for
217
261
// type checking
218
262
}
219
263
220
264
// iterate the fields manually to set them up
221
265
size_t i = 0 ;
222
- for (auto &pattern : items_has_rest. get_lower_patterns () )
266
+ for (auto &pattern : lower_patterns )
223
267
{
224
268
if (i >= variant->num_fields ())
225
269
break ;
@@ -232,9 +276,8 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
232
276
TypeCheckPattern::Resolve (*pattern, fty);
233
277
}
234
278
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)
238
281
{
239
282
if (i >= variant->num_fields ())
240
283
break ;
@@ -253,15 +296,41 @@ TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
253
296
{
254
297
HIR::TupleStructItemsNoRest &items_no_rest
255
298
= static_cast <HIR::TupleStructItemsNoRest &> (items);
299
+ auto &patterns = items_no_rest.get_patterns ();
256
300
257
- if (items_no_rest. get_patterns () .size () != variant->num_fields ())
301
+ if (patterns .size () != variant->num_fields ())
258
302
{
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
+ }
265
334
// we continue on to try and setup the types as best we can for
266
335
// type checking
267
336
}
0 commit comments