LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-hir-type-check-pattern.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.7 % 608 521
Test Date: 2026-07-11 15:47:05 Functions: 67.7 % 31 21
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.