Branch data Line data Source code
1 : : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
2 : :
3 : : // This file is part of GCC.
4 : :
5 : : // GCC is free software; you can redistribute it and/or modify it under
6 : : // the terms of the GNU General Public License as published by the Free
7 : : // Software Foundation; either version 3, or (at your option) any later
8 : : // version.
9 : :
10 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 : : // for more details.
14 : :
15 : : // You should have received a copy of the GNU General Public License
16 : : // along with GCC; see the file COPYING3. If not see
17 : : // <http://www.gnu.org/licenses/>.
18 : :
19 : : #include "rust-hir-type-check-pattern.h"
20 : : #include "rust-hir-pattern.h"
21 : : #include "rust-hir-type-check-expr.h"
22 : : #include "rust-type-util.h"
23 : : #include "rust-immutable-name-resolution-context.h"
24 : : #include "rust-tyty.h"
25 : : #include "tree.h"
26 : :
27 : : namespace Rust {
28 : : namespace Resolver {
29 : :
30 : 43641 : TypeCheckPattern::TypeCheckPattern (TyTy::BaseType *parent)
31 : 43641 : : TypeCheckBase (), parent (parent), infered (new TyTy::ErrorType (0))
32 : 43641 : {}
33 : :
34 : : TyTy::BaseType *
35 : 43641 : TypeCheckPattern::Resolve (HIR::Pattern &pattern, TyTy::BaseType *parent)
36 : : {
37 : 43641 : TypeCheckPattern resolver (parent);
38 : 43641 : pattern.accept_vis (resolver);
39 : :
40 : 43641 : if (resolver.infered == nullptr)
41 : 0 : return new TyTy::ErrorType (pattern.get_mappings ().get_hirid ());
42 : :
43 : 43641 : resolver.context->insert_type (pattern.get_mappings (), resolver.infered);
44 : 43641 : return resolver.infered;
45 : 43641 : }
46 : :
47 : : void
48 : 1084 : TypeCheckPattern::visit (HIR::PathInExpression &pattern)
49 : : {
50 : : // Pattern must be enum variants, sturcts, constants, or associated constansts
51 : 1084 : TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern);
52 : :
53 : 1084 : NodeId ref_node_id = UNKNOWN_NODEID;
54 : 1084 : bool maybe_item = false;
55 : :
56 : 1084 : auto &nr_ctx
57 : 1084 : = Resolver2_0::ImmutableNameResolutionContext::get ().resolver ();
58 : :
59 : 1084 : if (auto id = nr_ctx.lookup (pattern.get_mappings ().get_nodeid ()))
60 : : {
61 : 1082 : ref_node_id = *id;
62 : 1082 : maybe_item = true;
63 : : }
64 : :
65 : 1084 : bool path_is_const_item = false;
66 : :
67 : 1084 : if (maybe_item)
68 : : {
69 : 1082 : tl::optional<HirId> definition_id
70 : 1082 : = mappings.lookup_node_to_hir (ref_node_id);
71 : 1082 : rust_assert (definition_id.has_value ());
72 : 1082 : HirId def_id = definition_id.value ();
73 : :
74 : 1082 : tl::optional<HIR::Item *> hir_item = mappings.lookup_hir_item (def_id);
75 : : // If the path refrerences an item, it must be constants or structs.
76 : 1082 : if (hir_item.has_value ())
77 : : {
78 : 5 : HIR::Item *item = hir_item.value ();
79 : 5 : if (item->get_item_kind () == HIR::Item::ItemKind::Constant)
80 : : {
81 : : path_is_const_item = true;
82 : : }
83 : 4 : else if (item->get_item_kind () != HIR::Item::ItemKind::Struct)
84 : : {
85 : 4 : HIR::Item *item = hir_item.value ();
86 : 4 : std::string item_kind
87 : 4 : = HIR::Item::item_kind_string (item->get_item_kind ());
88 : :
89 : 4 : std::string path_buf;
90 : 12 : for (size_t i = 0; i < pattern.get_segments ().size (); i++)
91 : : {
92 : 8 : HIR::PathExprSegment &seg = pattern.get_segments ().at (i);
93 : 16 : path_buf += seg.as_string ();
94 : 8 : if (i != pattern.get_segments ().size () - 1)
95 : 4 : path_buf += "::";
96 : : }
97 : :
98 : 4 : rich_location rich_locus (
99 : 4 : line_table, pattern.get_final_segment ().get_locus ());
100 : 4 : rich_locus.add_fixit_replace (
101 : : "not a unit struct, unit variant or constant");
102 : 4 : rust_error_at (rich_locus, ErrorCode::E0532,
103 : : "expected unit struct, unit variant or constant, "
104 : : "found %s %<%s%>",
105 : : item_kind.c_str (), path_buf.c_str ());
106 : 4 : return;
107 : 4 : }
108 : : }
109 : : }
110 : :
111 : : // If the path is a constructor, it must be a unit struct or unit variants.
112 : 1080 : if (!path_is_const_item && pattern_ty->get_kind () == TyTy::TypeKind::ADT)
113 : : {
114 : 1077 : TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (pattern_ty);
115 : 1077 : rust_assert (adt->get_variants ().size () > 0);
116 : :
117 : 1077 : TyTy::VariantDef *variant = adt->get_variants ().at (0);
118 : 1077 : if (adt->is_enum ())
119 : : {
120 : 1077 : HirId variant_id = UNKNOWN_HIRID;
121 : 1077 : bool ok = context->lookup_variant_definition (
122 : 1077 : pattern.get_mappings ().get_hirid (), &variant_id);
123 : 1077 : rust_assert (ok);
124 : :
125 : 1077 : ok = adt->lookup_variant_by_id (variant_id, &variant);
126 : 1077 : rust_assert (ok);
127 : : }
128 : :
129 : 1077 : if (variant->get_variant_type () != TyTy::VariantDef::VariantType::NUM)
130 : : {
131 : 3 : std::string variant_type = TyTy::VariantDef::variant_type_string (
132 : 3 : variant->get_variant_type ());
133 : :
134 : 3 : rich_location rich_locus (line_table,
135 : 3 : pattern.get_final_segment ().get_locus ());
136 : 3 : rich_locus.add_fixit_replace (
137 : : "not a unit struct, unit variant or constatnt");
138 : 3 : rust_error_at (rich_locus, ErrorCode::E0532,
139 : : "expected unit struct, unit variant or constant, "
140 : : "found %s variant %<%s::%s%>",
141 : 6 : variant_type.c_str (), adt->get_name ().c_str (),
142 : 3 : variant->get_identifier ().c_str ());
143 : 3 : return;
144 : 3 : }
145 : :
146 : 1074 : infered = pattern_ty;
147 : : }
148 : : }
149 : :
150 : : void
151 : 1003 : TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
152 : : {
153 : 1003 : TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern.get_path ());
154 : 1003 : if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
155 : : {
156 : 2 : rust_error_at (
157 : 2 : pattern.get_locus (), ErrorCode::E0532,
158 : : "expected tuple struct or tuple variant, found function %qs",
159 : 2 : pattern_ty->get_name ().c_str ());
160 : 6 : return;
161 : : }
162 : :
163 : 1001 : infered = pattern_ty;
164 : 1001 : TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
165 : :
166 : 1001 : TyTy::VariantDef *variant = nullptr;
167 : 1001 : if (adt->is_enum ())
168 : : {
169 : 939 : HirId variant_id = UNKNOWN_HIRID;
170 : 939 : bool ok = context->lookup_variant_definition (
171 : 939 : pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
172 : 939 : if (!ok)
173 : : {
174 : 3 : rust_error_at (
175 : 3 : pattern.get_locus (), ErrorCode::E0532,
176 : : "expected tuple struct or tuple variant, found enum %qs",
177 : 3 : pattern_ty->get_name ().c_str ());
178 : 3 : return;
179 : : }
180 : :
181 : 936 : ok = adt->lookup_variant_by_id (variant_id, &variant);
182 : 936 : rust_assert (ok);
183 : : }
184 : : else
185 : : {
186 : 62 : rust_assert (adt->number_of_variants () > 0);
187 : 62 : variant = adt->get_variants ().at (0);
188 : : }
189 : :
190 : 998 : rust_assert (variant != nullptr);
191 : :
192 : : // error[E0532]: expected tuple struct or tuple variant, found struct
193 : : // variant `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
194 : 998 : if (variant->get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
195 : : {
196 : 1 : std::string variant_type
197 : 1 : = TyTy::VariantDef::variant_type_string (variant->get_variant_type ());
198 : :
199 : 1 : rich_location rich_locus (line_table, pattern.get_locus ());
200 : 1 : rich_locus.add_fixit_replace ("not a tuple struct or tuple variant");
201 : 1 : rust_error_at (
202 : : rich_locus, ErrorCode::E0164,
203 : : "expected tuple struct or tuple variant, found %s variant %<%s::%s%>",
204 : 2 : variant_type.c_str (), adt->get_name ().c_str (),
205 : 1 : variant->get_identifier ().c_str ());
206 : 1 : return;
207 : 1 : }
208 : :
209 : : // check the elements
210 : : // error[E0023]: this pattern has 2 fields, but the corresponding tuple
211 : : // variant has 1 field
212 : : // error[E0023]: this pattern has 0 fields, but the corresponding tuple
213 : : // variant has 1 field
214 : :
215 : 997 : auto &items = pattern.get_items ();
216 : 997 : switch (items.get_item_type ())
217 : : {
218 : 38 : case HIR::TupleStructItems::HAS_REST:
219 : 38 : {
220 : 38 : HIR::TupleStructItemsHasRest &items_has_rest
221 : : = static_cast<HIR::TupleStructItemsHasRest &> (items);
222 : 38 : auto &lower_patterns = items_has_rest.get_lower_patterns ();
223 : 38 : auto &upper_patterns = items_has_rest.get_upper_patterns ();
224 : 38 : size_t pattern_min_cap
225 : 38 : = lower_patterns.size () + upper_patterns.size ();
226 : 38 : if (variant->num_fields () < pattern_min_cap)
227 : : {
228 : 2 : if (!lower_patterns.empty ())
229 : : {
230 : : // TODO initialize rich_locus with loc of ADT definition instead
231 : 1 : rich_location rich_locus (line_table,
232 : 1 : lower_patterns[0]->get_locus ());
233 : 3 : for (auto &pattern : lower_patterns)
234 : : {
235 : 2 : if (pattern == lower_patterns[0])
236 : 1 : continue;
237 : 1 : rich_locus.add_range (pattern->get_locus (),
238 : : SHOW_RANGE_WITH_CARET);
239 : : }
240 : 3 : for (auto &pattern : upper_patterns)
241 : : {
242 : 2 : rich_locus.add_range (pattern->get_locus (),
243 : : SHOW_RANGE_WITH_CARET);
244 : : }
245 : 3 : rust_error_at (rich_locus, ErrorCode::E0023,
246 : : "this pattern has %lu %s but the corresponding "
247 : : "tuple variant has %lu %s",
248 : : (unsigned long) (pattern_min_cap),
249 : : pattern_min_cap == 1 ? "field" : "fields",
250 : 1 : (unsigned long) variant->num_fields (),
251 : 1 : variant->num_fields () == 1 ? "field"
252 : : : "fields");
253 : 1 : }
254 : : else
255 : : {
256 : : // TODO initialize rich_locus with loc of ADT definition instead
257 : 1 : rich_location rich_locus (line_table,
258 : 1 : upper_patterns[0]->get_locus ());
259 : 4 : for (auto &pattern : upper_patterns)
260 : : {
261 : 3 : if (pattern == upper_patterns[0])
262 : 1 : continue;
263 : 2 : rich_locus.add_range (pattern->get_locus (),
264 : : SHOW_RANGE_WITH_CARET);
265 : : }
266 : 3 : rust_error_at (rich_locus, ErrorCode::E0023,
267 : : "this pattern has %lu %s but the corresponding "
268 : : "tuple variant has %lu %s",
269 : : (unsigned long) (pattern_min_cap),
270 : : pattern_min_cap == 1 ? "field" : "fields",
271 : 1 : (unsigned long) variant->num_fields (),
272 : 1 : variant->num_fields () == 1 ? "field"
273 : : : "fields");
274 : 1 : }
275 : : // we continue on to try and setup the types as best we can for
276 : : // type checking
277 : : }
278 : :
279 : : // iterate the fields manually to set them up
280 : 38 : size_t i = 0;
281 : 69 : for (auto &pattern : lower_patterns)
282 : : {
283 : 31 : if (i >= variant->num_fields ())
284 : : break;
285 : :
286 : 31 : TyTy::StructFieldType *field = variant->get_field_at_index (i++);
287 : 31 : TyTy::BaseType *fty = field->get_field_type ();
288 : :
289 : : // setup the type on this pattern type
290 : 31 : context->insert_type (pattern->get_mappings (), fty);
291 : 31 : TypeCheckPattern::Resolve (*pattern, fty);
292 : : }
293 : :
294 : 38 : i = variant->num_fields () - upper_patterns.size ();
295 : 54 : for (auto &pattern : upper_patterns)
296 : : {
297 : 17 : if (i >= variant->num_fields ())
298 : : break;
299 : :
300 : 16 : TyTy::StructFieldType *field = variant->get_field_at_index (i++);
301 : 16 : TyTy::BaseType *fty = field->get_field_type ();
302 : :
303 : : // setup the type on this pattern type
304 : 16 : context->insert_type (pattern->get_mappings (), fty);
305 : 16 : TypeCheckPattern::Resolve (*pattern, fty);
306 : : }
307 : : }
308 : : break;
309 : :
310 : 959 : case HIR::TupleStructItems::NO_REST:
311 : 959 : {
312 : 959 : HIR::TupleStructItemsNoRest &items_no_rest
313 : : = static_cast<HIR::TupleStructItemsNoRest &> (items);
314 : 959 : auto &patterns = items_no_rest.get_patterns ();
315 : :
316 : 959 : if (patterns.size () != variant->num_fields ())
317 : : {
318 : 2 : if (patterns.empty ())
319 : : {
320 : 0 : rust_error_at (pattern.get_locus (), ErrorCode::E0023,
321 : : "this pattern has %lu %s but the corresponding "
322 : : "tuple variant has %lu %s",
323 : 0 : (unsigned long) patterns.size (),
324 : 0 : patterns.size () == 1 ? "field" : "fields",
325 : 0 : (unsigned long) variant->num_fields (),
326 : 0 : variant->num_fields () == 1 ? "field"
327 : : : "fields");
328 : : }
329 : : else
330 : : {
331 : 2 : rich_location rich_locus (line_table,
332 : 2 : patterns[0]->get_locus ());
333 : 8 : for (auto &pattern : items_no_rest.get_patterns ())
334 : : {
335 : 6 : if (pattern == patterns[0])
336 : 2 : continue;
337 : 4 : rich_locus.add_range (pattern->get_locus (),
338 : : SHOW_RANGE_WITH_CARET);
339 : : }
340 : 2 : rust_error_at (rich_locus, ErrorCode::E0023,
341 : : "this pattern has %lu %s but the corresponding "
342 : : "tuple variant has %lu %s",
343 : 2 : (unsigned long) patterns.size (),
344 : 2 : patterns.size () == 1 ? "field" : "fields",
345 : 2 : (unsigned long) variant->num_fields (),
346 : 2 : variant->num_fields () == 1 ? "field"
347 : : : "fields");
348 : 2 : }
349 : : // we continue on to try and setup the types as best we can for
350 : : // type checking
351 : : }
352 : :
353 : : // iterate the fields and set them up, I wish we had ZIP
354 : 959 : size_t i = 0;
355 : 1993 : for (auto &pattern : items_no_rest.get_patterns ())
356 : : {
357 : 1036 : if (i >= variant->num_fields ())
358 : : break;
359 : :
360 : 1034 : TyTy::StructFieldType *field = variant->get_field_at_index (i++);
361 : 1034 : TyTy::BaseType *fty = field->get_field_type ();
362 : :
363 : : // setup the type on this pattern type
364 : 1034 : context->insert_type (pattern->get_mappings (), fty);
365 : 1034 : TypeCheckPattern::Resolve (*pattern, fty);
366 : : }
367 : : }
368 : : break;
369 : : }
370 : : }
371 : :
372 : : void
373 : 1 : emit_invalid_field_error (location_t loc, Rust::TyTy::VariantDef *variant,
374 : : const std::string &name)
375 : : {
376 : 1 : rust_error_at (loc, ErrorCode::E0026,
377 : : "variant %s does not have a field named %s",
378 : 1 : variant->get_identifier ().c_str (), name.c_str ());
379 : 1 : }
380 : :
381 : : void
382 : 149 : TypeCheckPattern::visit (HIR::StructPattern &pattern)
383 : : {
384 : 149 : TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (pattern.get_path ());
385 : 149 : if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
386 : : {
387 : 0 : rust_error_at (pattern.get_locus (),
388 : : "expected tuple struct/variant, found: %s",
389 : 0 : pattern_ty->get_name ().c_str ());
390 : 2 : return;
391 : : }
392 : :
393 : 149 : infered = pattern_ty;
394 : 149 : TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
395 : 149 : if (adt->number_of_variants () == 0)
396 : : {
397 : 0 : HIR::PathInExpression &path = pattern.get_path ();
398 : 0 : const AST::SimplePath &sp = path.as_simple_path ();
399 : 0 : rust_error_at (pattern.get_locus (), ErrorCode::E0574,
400 : : "expected struct, variant or union type, found enum %qs",
401 : 0 : sp.as_string ().c_str ());
402 : 0 : return;
403 : 0 : }
404 : :
405 : 149 : TyTy::VariantDef *variant = adt->get_variants ().at (0);
406 : 149 : if (adt->is_enum ())
407 : : {
408 : 118 : HirId variant_id = UNKNOWN_HIRID;
409 : 118 : bool ok = context->lookup_variant_definition (
410 : 118 : pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
411 : 118 : if (!ok)
412 : : {
413 : 1 : HIR::PathInExpression &path = pattern.get_path ();
414 : 1 : const AST::SimplePath &sp = path.as_simple_path ();
415 : 1 : rust_error_at (
416 : 1 : pattern.get_locus (), ErrorCode::E0574,
417 : : "expected struct, variant or union type, found enum %qs",
418 : 1 : sp.as_string ().c_str ());
419 : 1 : return;
420 : 1 : }
421 : :
422 : 117 : ok = adt->lookup_variant_by_id (variant_id, &variant);
423 : 117 : rust_assert (ok);
424 : : }
425 : :
426 : : // error[E0532]: expected tuple struct or tuple variant, found struct
427 : : // variant `Foo::D`
428 : 148 : bool error_E0532 = false;
429 : 148 : if (variant->get_variant_type () == TyTy::VariantDef::VariantType::TUPLE)
430 : : {
431 : : // Tuple structs can still be matched with struct patterns via index
432 : : // numbers e.g. Foo {0: a, .., 3: b}, so check whether the fields are of
433 : : // type TUPLE_PAT. Throw E0532 if not.
434 : 2 : auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
435 : 2 : for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
436 : : {
437 : 1 : if (field->get_item_type ()
438 : : != HIR::StructPatternField::ItemType::TUPLE_PAT)
439 : : {
440 : : error_E0532 = true;
441 : : break;
442 : : }
443 : : }
444 : : }
445 : 146 : else if (variant->get_variant_type ()
446 : : != TyTy::VariantDef::VariantType::STRUCT)
447 : : {
448 : : error_E0532 = true;
449 : : }
450 : :
451 : 2 : if (error_E0532)
452 : : {
453 : 1 : std::string variant_type
454 : 1 : = TyTy::VariantDef::variant_type_string (variant->get_variant_type ());
455 : :
456 : 1 : rich_location rich_locus (line_table, pattern.get_locus ());
457 : 1 : std::string rich_msg = "use the tuple variant pattern syntax instead "
458 : 2 : + variant->get_identifier () + "(_)";
459 : 1 : rich_locus.add_fixit_replace (rich_msg.c_str ());
460 : :
461 : 1 : rust_error_at (rich_locus, ErrorCode::E0769,
462 : : "%s variant %qs written as struct variant",
463 : : variant_type.c_str (),
464 : 1 : variant->get_identifier ().c_str ());
465 : 1 : return;
466 : 1 : }
467 : :
468 : 147 : std::vector<std::string> named_fields;
469 : 147 : auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
470 : 393 : for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
471 : : {
472 : 246 : switch (field->get_item_type ())
473 : : {
474 : 0 : case HIR::StructPatternField::ItemType::TUPLE_PAT:
475 : 0 : {
476 : : // TODO
477 : 0 : rust_unreachable ();
478 : : }
479 : 150 : break;
480 : :
481 : 150 : case HIR::StructPatternField::ItemType::IDENT_PAT:
482 : 150 : {
483 : 150 : HIR::StructPatternFieldIdentPat &ident
484 : 150 : = static_cast<HIR::StructPatternFieldIdentPat &> (*field);
485 : :
486 : 150 : TyTy::StructFieldType *field = nullptr;
487 : 150 : if (!variant->lookup_field (ident.get_identifier ().as_string (),
488 : : &field, nullptr))
489 : : {
490 : 0 : emit_invalid_field_error (ident.get_locus (), variant,
491 : 0 : ident.get_identifier ().as_string ());
492 : 0 : break;
493 : : }
494 : 150 : named_fields.push_back (ident.get_identifier ().as_string ());
495 : :
496 : 150 : TyTy::BaseType *fty = field->get_field_type ();
497 : 150 : TypeCheckPattern::Resolve (ident.get_pattern (), fty);
498 : : }
499 : 150 : break;
500 : :
501 : 96 : case HIR::StructPatternField::ItemType::IDENT:
502 : 96 : {
503 : 96 : HIR::StructPatternFieldIdent &ident
504 : 96 : = static_cast<HIR::StructPatternFieldIdent &> (*field);
505 : :
506 : 96 : TyTy::StructFieldType *field = nullptr;
507 : 96 : if (!variant->lookup_field (ident.get_identifier ().as_string (),
508 : : &field, nullptr))
509 : : {
510 : 1 : emit_invalid_field_error (ident.get_locus (), variant,
511 : 1 : ident.get_identifier ().as_string ());
512 : 1 : break;
513 : : }
514 : 95 : named_fields.push_back (ident.get_identifier ().as_string ());
515 : :
516 : : // setup the type on this pattern
517 : 95 : TyTy::BaseType *fty = field->get_field_type ();
518 : 95 : context->insert_type (ident.get_mappings (), fty);
519 : : }
520 : 95 : break;
521 : : }
522 : : }
523 : :
524 : : // check the elements
525 : 147 : if (adt->is_union ())
526 : : {
527 : 5 : auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
528 : 5 : if (struct_pattern_elems.get_struct_pattern_fields ().size () != 1)
529 : 2 : rust_error_at (pattern.get_locus (),
530 : : "union patterns should have exactly one field");
531 : :
532 : : else
533 : : {
534 : 6 : switch (struct_pattern_elems.get_struct_pattern_fields ()
535 : 3 : .at (0)
536 : 3 : ->get_item_type ())
537 : : {
538 : : case HIR::StructPatternField::ItemType::IDENT:
539 : : case HIR::StructPatternField::ItemType::IDENT_PAT:
540 : : break;
541 : 0 : default:
542 : 0 : {
543 : 0 : auto first_elem
544 : 0 : = struct_pattern_elems.get_struct_pattern_fields ()
545 : 0 : .at (0)
546 : 0 : ->as_string ();
547 : 0 : rust_error_at (pattern.get_locus (),
548 : : "%qs cannot be used in union patterns",
549 : : first_elem.c_str ());
550 : 0 : }
551 : : }
552 : : }
553 : : }
554 : : else
555 : : {
556 : : // Expects enum struct or struct struct.
557 : : // error[E0027]: pattern does not mention fields `x`, `y`
558 : : // error[E0026]: variant `Foo::D` does not have a field named `b`
559 : 142 : if (!pattern.get_struct_pattern_elems ().has_rest ()
560 : 282 : && named_fields.size () != variant->num_fields ())
561 : : {
562 : 2 : std::map<std::string, bool> missing_names;
563 : :
564 : : // populate with all fields
565 : 6 : for (auto &field : variant->get_fields ())
566 : 4 : missing_names[field->get_name ()] = true;
567 : :
568 : : // then eliminate with named_fields
569 : 3 : for (auto &named : named_fields)
570 : 1 : missing_names.erase (named);
571 : :
572 : : // then get the list of missing names
573 : 2 : size_t i = 0;
574 : 2 : std::string missing_fields_str;
575 : 5 : for (auto it = missing_names.begin (); it != missing_names.end ();
576 : 3 : it++)
577 : : {
578 : 3 : bool has_next = (i + 1) < missing_names.size ();
579 : 8 : missing_fields_str += it->first + (has_next ? ", " : "");
580 : 3 : i++;
581 : : }
582 : :
583 : 2 : rust_error_at (pattern.get_locus (), ErrorCode::E0027,
584 : : "pattern does not mention fields %s",
585 : : missing_fields_str.c_str ());
586 : 2 : }
587 : : }
588 : 147 : }
589 : :
590 : : void
591 : 1239 : TypeCheckPattern::visit (HIR::WildcardPattern &pattern)
592 : : {
593 : : // wildcard patterns within the MatchArm's are simply just the same type as
594 : : // the parent
595 : 1239 : infered = parent->clone ();
596 : 1239 : infered->set_ref (pattern.get_mappings ().get_hirid ());
597 : 1239 : }
598 : :
599 : : void
600 : 420 : TypeCheckPattern::visit (HIR::TuplePattern &pattern)
601 : : {
602 : 420 : std::unique_ptr<HIR::TuplePatternItems> items;
603 : :
604 : : // Check whether parent is tuple
605 : 420 : auto resolved_parent = parent->destructure ();
606 : 420 : if (resolved_parent->get_kind () != TyTy::TUPLE)
607 : : {
608 : 3 : rust_error_at (pattern.get_locus (), "expected %s, found tuple",
609 : 3 : parent->as_string ().c_str ());
610 : 3 : return;
611 : : }
612 : 417 : TyTy::TupleType &par = *static_cast<TyTy::TupleType *> (resolved_parent);
613 : :
614 : 417 : switch (pattern.get_items ().get_item_type ())
615 : : {
616 : 390 : case HIR::TuplePatternItems::ItemType::NO_REST:
617 : 390 : {
618 : 390 : auto &ref
619 : 390 : = static_cast<HIR::TuplePatternItemsNoRest &> (pattern.get_items ());
620 : :
621 : 390 : const auto &patterns = ref.get_patterns ();
622 : 390 : size_t nitems_to_resolve = patterns.size ();
623 : :
624 : 390 : if (patterns.size () != par.get_fields ().size ())
625 : : {
626 : 4 : emit_pattern_size_error (pattern, par.get_fields ().size (),
627 : : patterns.size ());
628 : 4 : nitems_to_resolve
629 : 4 : = std::min (nitems_to_resolve, par.get_fields ().size ());
630 : : }
631 : :
632 : 390 : std::vector<TyTy::TyVar> pattern_elems;
633 : 1187 : for (size_t i = 0; i < nitems_to_resolve; i++)
634 : : {
635 : 797 : auto &p = patterns[i];
636 : 797 : TyTy::BaseType *par_type = par.get_field (i);
637 : :
638 : 797 : TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
639 : 797 : pattern_elems.emplace_back (elem->get_ref ());
640 : : }
641 : 780 : infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
642 : 780 : pattern.get_locus (), pattern_elems);
643 : 390 : }
644 : 390 : break;
645 : :
646 : 27 : case HIR::TuplePatternItems::ItemType::HAS_REST:
647 : 27 : {
648 : 27 : HIR::TuplePatternItemsHasRest &ref
649 : 27 : = static_cast<HIR::TuplePatternItemsHasRest &> (pattern.get_items ());
650 : :
651 : 27 : const auto &lower = ref.get_lower_patterns ();
652 : 27 : const auto &upper = ref.get_upper_patterns ();
653 : 27 : size_t min_size_required = lower.size () + upper.size ();
654 : :
655 : : // Ensure that size of lower and upper patterns <= parent size
656 : 27 : if (min_size_required > par.get_fields ().size ())
657 : : {
658 : 3 : emit_pattern_size_error (pattern, par.get_fields ().size (),
659 : : min_size_required);
660 : : // continue and attempt to resolve individual items in the pattern
661 : : }
662 : :
663 : : // Resolve lower patterns
664 : 27 : std::vector<TyTy::TyVar> pattern_elems;
665 : 27 : size_t nlower_items_to_resolve
666 : 27 : = std::min (lower.size (), par.get_fields ().size ());
667 : 55 : for (size_t i = 0; i < nlower_items_to_resolve; i++)
668 : : {
669 : 28 : auto &p = lower[i];
670 : 28 : TyTy::BaseType *par_type = par.get_field (i);
671 : :
672 : 28 : TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
673 : 28 : pattern_elems.emplace_back (elem->get_ref ());
674 : : }
675 : :
676 : 27 : if (lower.size () > par.get_fields ().size ())
677 : : break;
678 : :
679 : : // Pad pattern_elems until needing to resolve upper patterns
680 : 27 : size_t rest_end
681 : 27 : = std::max (par.get_fields ().size () - upper.size (), lower.size ());
682 : 71 : for (size_t i = lower.size (); i < rest_end; i++)
683 : : {
684 : 44 : TyTy::BaseType *par_type = par.get_field (i);
685 : 44 : pattern_elems.emplace_back (par_type->get_ref ());
686 : : }
687 : :
688 : 27 : size_t nupper_items_to_resolve
689 : 27 : = std::min (upper.size (),
690 : 27 : par.get_fields ().size () - pattern_elems.size ());
691 : : // Resolve upper patterns
692 : 55 : for (size_t i = 0; i < nupper_items_to_resolve; i++)
693 : : {
694 : 28 : auto &p = upper[i];
695 : 28 : TyTy::BaseType *par_type = par.get_field (rest_end + i);
696 : :
697 : 28 : TyTy::BaseType *elem = TypeCheckPattern::Resolve (*p, par_type);
698 : 28 : pattern_elems.emplace_back (elem->get_ref ());
699 : : }
700 : :
701 : 54 : infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
702 : 54 : pattern.get_locus (), pattern_elems);
703 : 0 : }
704 : 27 : break;
705 : : }
706 : 420 : }
707 : :
708 : : void
709 : 409 : TypeCheckPattern::visit (HIR::LiteralPattern &pattern)
710 : : {
711 : 409 : TyTy::BaseType *resolved
712 : 409 : = resolve_literal (pattern.get_mappings (), pattern.get_literal (),
713 : 409 : pattern.get_locus ());
714 : 409 : if (resolved->get_kind () == TyTy::TypeKind::ERROR)
715 : : {
716 : 0 : infered = resolved;
717 : 0 : return;
718 : : }
719 : :
720 : 409 : infered = unify_site (pattern.get_mappings ().get_hirid (),
721 : 409 : TyTy::TyWithLocation (parent),
722 : 409 : TyTy::TyWithLocation (resolved), pattern.get_locus ());
723 : : }
724 : :
725 : : void
726 : 38 : TypeCheckPattern::visit (HIR::RangePattern &pattern)
727 : : {
728 : : // Resolve the upper and lower bounds, and ensure they are compatible types
729 : 38 : TyTy::BaseType *upper = nullptr, *lower = nullptr;
730 : :
731 : 38 : upper = typecheck_range_pattern_bound (pattern.get_upper_bound (),
732 : 38 : pattern.get_mappings (),
733 : 38 : pattern.get_locus ());
734 : :
735 : 114 : lower = typecheck_range_pattern_bound (pattern.get_lower_bound (),
736 : 38 : pattern.get_mappings (),
737 : 38 : pattern.get_locus ());
738 : :
739 : 38 : infered = unify_site (pattern.get_mappings ().get_hirid (),
740 : 38 : TyTy::TyWithLocation (upper),
741 : 38 : TyTy::TyWithLocation (lower), pattern.get_locus ());
742 : 38 : }
743 : :
744 : : void
745 : 38879 : TypeCheckPattern::visit (HIR::IdentifierPattern &pattern)
746 : : {
747 : 38879 : if (pattern.has_subpattern ())
748 : : {
749 : 17 : TypeCheckPattern::Resolve (pattern.get_subpattern (), parent);
750 : : }
751 : :
752 : 38879 : if (!pattern.get_is_ref ())
753 : : {
754 : 38876 : infered = parent;
755 : 38876 : return;
756 : : }
757 : :
758 : 9 : infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
759 : 3 : TyTy::TyVar (parent->get_ref ()),
760 : 3 : pattern.is_mut () ? Mutability::Mut
761 : 6 : : Mutability::Imm);
762 : : }
763 : :
764 : : void
765 : 0 : TypeCheckPattern::visit (HIR::QualifiedPathInExpression &pattern)
766 : : {
767 : 0 : rust_sorry_at (pattern.get_locus (),
768 : : "type checking qualified path patterns not supported");
769 : 0 : }
770 : :
771 : : void
772 : 199 : TypeCheckPattern::visit (HIR::ReferencePattern &pattern)
773 : : {
774 : 199 : if (parent->get_kind () != TyTy::TypeKind::REF)
775 : : {
776 : 1 : rust_error_at (pattern.get_locus (), "expected %s, found reference",
777 : 1 : parent->as_string ().c_str ());
778 : 1 : return;
779 : : }
780 : :
781 : 198 : auto &ref_ty_ty = static_cast<TyTy::ReferenceType &> (*parent);
782 : 198 : TyTy::BaseType *infered_base
783 : 198 : = TypeCheckPattern::Resolve (pattern.get_referenced_pattern (),
784 : : ref_ty_ty.get_base ());
785 : 594 : infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
786 : 198 : TyTy::TyVar (infered_base->get_ref ()),
787 : 198 : pattern.is_mut () ? Mutability::Mut
788 : 396 : : Mutability::Imm);
789 : : }
790 : :
791 : : void
792 : 76 : TypeCheckPattern::visit (HIR::SlicePattern &pattern)
793 : : {
794 : 76 : auto resolved_parent = parent->destructure ();
795 : 76 : TyTy::BaseType *parent_element_ty = nullptr;
796 : 76 : switch (resolved_parent->get_kind ())
797 : : {
798 : 37 : case TyTy::ARRAY:
799 : 37 : {
800 : 37 : auto &array_ty_ty = static_cast<TyTy::ArrayType &> (*parent);
801 : 37 : parent_element_ty = array_ty_ty.get_element_type ();
802 : 37 : auto capacity = array_ty_ty.get_capacity ();
803 : :
804 : 37 : tree cap = error_mark_node;
805 : 37 : if (capacity->get_kind () != TyTy::TypeKind::CONST)
806 : : {
807 : : // Error case - capacity is not a const type
808 : : break;
809 : : }
810 : :
811 : 37 : auto *capacity_const = capacity->as_const_type ();
812 : 37 : switch (capacity_const->const_kind ())
813 : : {
814 : 37 : case TyTy::BaseConstType::ConstKind::Value:
815 : 37 : {
816 : 37 : const auto &const_value
817 : : = *static_cast<TyTy::ConstValueType *> (capacity);
818 : 37 : cap = const_value.get_value ();
819 : : }
820 : 37 : break;
821 : :
822 : 0 : case TyTy::BaseConstType::ConstKind::Decl:
823 : 0 : case TyTy::BaseConstType::ConstKind::Infer:
824 : 0 : case TyTy::BaseConstType::ConstKind::Error:
825 : 0 : cap = error_mark_node;
826 : 0 : break;
827 : : }
828 : :
829 : 37 : if (error_operand_p (cap))
830 : : {
831 : 0 : rust_error_at (parent->get_locus (),
832 : : "capacity of array %qs is not known at compile time",
833 : 0 : array_ty_ty.get_name ().c_str ());
834 : 0 : break;
835 : : }
836 : 37 : auto cap_wi = wi::to_wide (cap).to_uhwi ();
837 : :
838 : : // size check during compile time
839 : 37 : switch (pattern.get_items ().get_item_type ())
840 : : {
841 : 16 : case HIR::SlicePatternItems::ItemType::NO_REST:
842 : 16 : {
843 : 16 : auto &ref = static_cast<HIR::SlicePatternItemsNoRest &> (
844 : 16 : pattern.get_items ());
845 : 16 : if (cap_wi != ref.get_patterns ().size ())
846 : : {
847 : 2 : rust_error_at (
848 : 1 : pattern.get_locus (), ErrorCode::E0527,
849 : : "pattern requires %lu elements but array has %lu",
850 : 1 : (unsigned long) ref.get_patterns ().size (),
851 : : (unsigned long) cap_wi);
852 : 1 : break;
853 : : }
854 : : }
855 : : break;
856 : 21 : case HIR::SlicePatternItems::ItemType::HAS_REST:
857 : 21 : {
858 : 21 : auto &ref = static_cast<HIR::SlicePatternItemsHasRest &> (
859 : 21 : pattern.get_items ());
860 : 21 : auto pattern_min_cap = ref.get_lower_patterns ().size ()
861 : 21 : + ref.get_upper_patterns ().size ();
862 : :
863 : 21 : if (cap_wi < pattern_min_cap)
864 : : {
865 : 0 : rust_error_at (pattern.get_locus (), ErrorCode::E0528,
866 : : "pattern requires at least %lu elements but "
867 : : "array has %lu",
868 : : (unsigned long) pattern_min_cap,
869 : : (unsigned long) cap_wi);
870 : 0 : break;
871 : : }
872 : : }
873 : : break;
874 : : }
875 : :
876 : : break;
877 : : }
878 : 0 : case TyTy::SLICE:
879 : 0 : {
880 : 0 : auto &slice_ty_ty = static_cast<TyTy::SliceType &> (*parent);
881 : 0 : parent_element_ty = slice_ty_ty.get_element_type ();
882 : 0 : break;
883 : : }
884 : 39 : case TyTy::REF:
885 : 39 : {
886 : 39 : auto &ref_ty_ty = static_cast<TyTy::ReferenceType &> (*parent);
887 : 39 : const TyTy::SliceType *slice = nullptr;
888 : 39 : if (!ref_ty_ty.is_dyn_slice_type (&slice))
889 : : {
890 : 0 : rust_error_at (pattern.get_locus (), "expected %s, found slice",
891 : 0 : parent->as_string ().c_str ());
892 : 0 : return;
893 : : }
894 : 39 : parent_element_ty = slice->get_element_type ();
895 : 39 : break;
896 : : }
897 : 0 : default:
898 : 0 : {
899 : 0 : rust_error_at (pattern.get_locus (), "expected %s, found slice",
900 : 0 : parent->as_string ().c_str ());
901 : 0 : return;
902 : : }
903 : : }
904 : :
905 : 76 : rust_assert (parent_element_ty != nullptr);
906 : : // infered inherits array/slice typing from parent
907 : 76 : infered = parent->clone ();
908 : 76 : infered->set_ref (pattern.get_mappings ().get_hirid ());
909 : :
910 : : // Type check every item in the SlicePattern against parent's element ty
911 : 76 : switch (pattern.get_items ().get_item_type ())
912 : : {
913 : 32 : case HIR::SlicePatternItems::ItemType::NO_REST:
914 : 32 : {
915 : 32 : auto &ref
916 : 32 : = static_cast<HIR::SlicePatternItemsNoRest &> (pattern.get_items ());
917 : 96 : for (const auto &pattern_member : ref.get_patterns ())
918 : : {
919 : 64 : TypeCheckPattern::Resolve (*pattern_member, parent_element_ty);
920 : : }
921 : : break;
922 : : }
923 : 44 : case HIR::SlicePatternItems::ItemType::HAS_REST:
924 : 44 : {
925 : 44 : auto &ref
926 : 44 : = static_cast<HIR::SlicePatternItemsHasRest &> (pattern.get_items ());
927 : 87 : for (const auto &pattern_member : ref.get_lower_patterns ())
928 : : {
929 : 43 : TypeCheckPattern::Resolve (*pattern_member, parent_element_ty);
930 : : }
931 : 87 : for (const auto &pattern_member : ref.get_upper_patterns ())
932 : : {
933 : 43 : TypeCheckPattern::Resolve (*pattern_member, parent_element_ty);
934 : : }
935 : : break;
936 : : }
937 : : }
938 : : }
939 : :
940 : : void
941 : 7 : TypeCheckPattern::emit_pattern_size_error (const HIR::Pattern &pattern,
942 : : size_t expected_field_count,
943 : : size_t got_field_count)
944 : : {
945 : 7 : rich_location r (line_table, pattern.get_locus ());
946 : 7 : r.add_range (mappings.lookup_location (parent->get_ref ()));
947 : 18 : rust_error_at (r,
948 : : "expected a tuple with %lu %s, found one "
949 : : "with %lu %s",
950 : : (unsigned long) expected_field_count,
951 : : expected_field_count == 1 ? "element" : "elements",
952 : : (unsigned long) got_field_count,
953 : : got_field_count == 1 ? "element" : "elements");
954 : 7 : }
955 : :
956 : : TyTy::BaseType *
957 : 76 : TypeCheckPattern::typecheck_range_pattern_bound (
958 : : Rust::HIR::RangePatternBound &bound, Analysis::NodeMapping mappings,
959 : : location_t locus)
960 : : {
961 : 76 : TyTy::BaseType *resolved_bound = nullptr;
962 : 76 : switch (bound.get_bound_type ())
963 : : {
964 : 55 : case HIR::RangePatternBound::RangePatternBoundType::LITERAL:
965 : 55 : {
966 : 55 : auto &ref = static_cast<HIR::RangePatternBoundLiteral &> (bound);
967 : :
968 : 55 : HIR::Literal lit = ref.get_literal ();
969 : :
970 : 55 : resolved_bound = resolve_literal (mappings, lit, locus);
971 : 55 : }
972 : 55 : break;
973 : :
974 : 21 : case HIR::RangePatternBound::RangePatternBoundType::PATH:
975 : 21 : {
976 : 21 : auto &ref = static_cast<HIR::RangePatternBoundPath &> (bound);
977 : :
978 : 21 : resolved_bound = TypeCheckExpr::Resolve (ref.get_path ());
979 : : }
980 : 21 : break;
981 : :
982 : 0 : case HIR::RangePatternBound::RangePatternBoundType::QUALPATH:
983 : 0 : {
984 : 0 : auto &ref = static_cast<HIR::RangePatternBoundQualPath &> (bound);
985 : :
986 : 0 : resolved_bound = TypeCheckExpr::Resolve (ref.get_qualified_path ());
987 : : }
988 : 0 : break;
989 : : }
990 : :
991 : 76 : return resolved_bound;
992 : : }
993 : :
994 : : void
995 : 145 : TypeCheckPattern::visit (HIR::AltPattern &pattern)
996 : : {
997 : 145 : const auto &alts = pattern.get_alts ();
998 : :
999 : : // lub - taken from TypeCheckExpr::visit(ArrayExpr)
1000 : 145 : std::vector<TyTy::BaseType *> types;
1001 : 436 : for (auto &alt_pattern : alts)
1002 : : {
1003 : 291 : types.push_back (TypeCheckPattern::Resolve (*alt_pattern, parent));
1004 : : }
1005 : :
1006 : 145 : TyTy::BaseType *alt_pattern_type
1007 : 145 : = TyTy::TyVar::get_implicit_infer_var (pattern.get_locus ()).get_tyty ();
1008 : :
1009 : 436 : for (auto &type : types)
1010 : : {
1011 : 291 : alt_pattern_type
1012 : 291 : = unify_site (pattern.get_mappings ().get_hirid (),
1013 : 291 : TyTy::TyWithLocation (alt_pattern_type),
1014 : 291 : TyTy::TyWithLocation (type, type->get_locus ()),
1015 : 291 : pattern.get_locus ());
1016 : : }
1017 : :
1018 : 145 : infered = alt_pattern_type;
1019 : 145 : }
1020 : :
1021 : : TyTy::BaseType *
1022 : 3 : ClosureParamInfer::Resolve (HIR::Pattern &pattern)
1023 : : {
1024 : 3 : ClosureParamInfer resolver;
1025 : 3 : pattern.accept_vis (resolver);
1026 : :
1027 : 3 : if (resolver.infered->get_kind () != TyTy::TypeKind::ERROR)
1028 : : {
1029 : 3 : resolver.context->insert_implicit_type (resolver.infered->get_ref (),
1030 : : resolver.infered);
1031 : 3 : resolver.mappings.insert_location (resolver.infered->get_ref (),
1032 : 3 : pattern.get_locus ());
1033 : : }
1034 : 3 : return resolver.infered;
1035 : 3 : }
1036 : :
1037 : 3 : ClosureParamInfer::ClosureParamInfer ()
1038 : 3 : : TypeCheckBase (), infered (new TyTy::ErrorType (0))
1039 : 3 : {}
1040 : :
1041 : : void
1042 : 1 : ClosureParamInfer::visit (HIR::WildcardPattern &pattern)
1043 : : {
1044 : 1 : HirId id = pattern.get_mappings ().get_hirid ();
1045 : 1 : infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
1046 : : TyTy::InferType::TypeHint::Default (),
1047 : 1 : pattern.get_locus ());
1048 : 1 : }
1049 : :
1050 : : void
1051 : 1 : ClosureParamInfer::visit (HIR::IdentifierPattern &pattern)
1052 : : {
1053 : 1 : if (pattern.has_subpattern ())
1054 : : {
1055 : 0 : ClosureParamInfer::Resolve (pattern.get_subpattern ());
1056 : : }
1057 : :
1058 : 1 : HirId id = pattern.get_mappings ().get_hirid ();
1059 : 1 : infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
1060 : : TyTy::InferType::TypeHint::Default (),
1061 : 1 : pattern.get_locus ());
1062 : 1 : }
1063 : :
1064 : : void
1065 : 1 : ClosureParamInfer::visit (HIR::ReferencePattern &pattern)
1066 : : {
1067 : 1 : TyTy::BaseType *element
1068 : 1 : = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ());
1069 : :
1070 : 1 : HirId id = pattern.get_mappings ().get_hirid ();
1071 : 1 : infered = new TyTy::ReferenceType (id, TyTy::TyVar (element->get_ref ()),
1072 : 2 : pattern.get_mutability ());
1073 : 1 : }
1074 : :
1075 : : void
1076 : 0 : ClosureParamInfer::visit (HIR::PathInExpression &pattern)
1077 : : {
1078 : 0 : rust_sorry_at (pattern.get_locus (),
1079 : : "unable to infer this kind of parameter pattern");
1080 : 0 : }
1081 : :
1082 : : void
1083 : 0 : ClosureParamInfer::visit (HIR::StructPattern &pattern)
1084 : : {
1085 : 0 : rust_sorry_at (pattern.get_locus (),
1086 : : "unable to infer this kind of parameter pattern");
1087 : 0 : }
1088 : :
1089 : : void
1090 : 0 : ClosureParamInfer::visit (HIR::TupleStructPattern &pattern)
1091 : : {
1092 : 0 : rust_sorry_at (pattern.get_locus (),
1093 : : "unable to infer this kind of parameter pattern");
1094 : 0 : }
1095 : :
1096 : : void
1097 : 0 : ClosureParamInfer::visit (HIR::TuplePattern &pattern)
1098 : : {
1099 : 0 : rust_sorry_at (pattern.get_locus (),
1100 : : "unable to infer this kind of parameter pattern");
1101 : 0 : }
1102 : :
1103 : : void
1104 : 0 : ClosureParamInfer::visit (HIR::LiteralPattern &pattern)
1105 : : {
1106 : 0 : rust_sorry_at (pattern.get_locus (),
1107 : : "unable to infer this kind of parameter pattern");
1108 : 0 : }
1109 : :
1110 : : void
1111 : 0 : ClosureParamInfer::visit (HIR::RangePattern &pattern)
1112 : : {
1113 : 0 : rust_sorry_at (pattern.get_locus (),
1114 : : "unable to infer this kind of parameter pattern");
1115 : 0 : }
1116 : :
1117 : : void
1118 : 0 : ClosureParamInfer::visit (HIR::QualifiedPathInExpression &pattern)
1119 : : {
1120 : 0 : rust_sorry_at (pattern.get_locus (),
1121 : : "unable to infer this kind of parameter pattern");
1122 : 0 : }
1123 : :
1124 : : void
1125 : 0 : ClosureParamInfer::visit (HIR::SlicePattern &pattern)
1126 : : {
1127 : 0 : rust_sorry_at (pattern.get_locus (),
1128 : : "unable to infer this kind of parameter pattern");
1129 : 0 : }
1130 : :
1131 : : void
1132 : 0 : ClosureParamInfer::visit (HIR::AltPattern &pattern)
1133 : : {
1134 : 0 : rust_sorry_at (pattern.get_locus (),
1135 : : "unable to infer this kind of parameter pattern");
1136 : 0 : }
1137 : :
1138 : : } // namespace Resolver
1139 : : } // namespace Rust
|