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: 83.9 % 310 260
Test Date: 2024-12-21 13:15:12 Functions: 64.5 % 31 20
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2024 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-type-check-expr.h"
      21                 :             : #include "rust-type-util.h"
      22                 :             : 
      23                 :             : namespace Rust {
      24                 :             : namespace Resolver {
      25                 :             : 
      26                 :       15743 : TypeCheckPattern::TypeCheckPattern (TyTy::BaseType *parent)
      27                 :       15743 :   : TypeCheckBase (), parent (parent), infered (new TyTy::ErrorType (0))
      28                 :       15743 : {}
      29                 :             : 
      30                 :             : TyTy::BaseType *
      31                 :       15743 : TypeCheckPattern::Resolve (HIR::Pattern *pattern, TyTy::BaseType *parent)
      32                 :             : {
      33                 :       15743 :   TypeCheckPattern resolver (parent);
      34                 :       15743 :   pattern->accept_vis (resolver);
      35                 :             : 
      36                 :       15743 :   if (resolver.infered == nullptr)
      37                 :           0 :     return new TyTy::ErrorType (pattern->get_mappings ().get_hirid ());
      38                 :             : 
      39                 :       15743 :   resolver.context->insert_type (pattern->get_mappings (), resolver.infered);
      40                 :       15743 :   return resolver.infered;
      41                 :       15743 : }
      42                 :             : 
      43                 :             : void
      44                 :         128 : TypeCheckPattern::visit (HIR::PathInExpression &pattern)
      45                 :             : {
      46                 :         128 :   infered = TypeCheckExpr::Resolve (&pattern);
      47                 :         128 : }
      48                 :             : 
      49                 :             : void
      50                 :         107 : TypeCheckPattern::visit (HIR::TupleStructPattern &pattern)
      51                 :             : {
      52                 :         107 :   TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern.get_path ());
      53                 :         107 :   if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
      54                 :             :     {
      55                 :           2 :       rust_error_at (
      56                 :           2 :         pattern.get_locus (), ErrorCode::E0532,
      57                 :             :         "expected tuple struct or tuple variant, found function %qs",
      58                 :           2 :         pattern_ty->get_name ().c_str ());
      59                 :           3 :       return;
      60                 :             :     }
      61                 :             : 
      62                 :         105 :   infered = pattern_ty;
      63                 :         105 :   TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
      64                 :         105 :   rust_assert (adt->number_of_variants () > 0);
      65                 :             : 
      66                 :         105 :   TyTy::VariantDef *variant = adt->get_variants ().at (0);
      67                 :         105 :   if (adt->is_enum ())
      68                 :             :     {
      69                 :          91 :       HirId variant_id = UNKNOWN_HIRID;
      70                 :          91 :       bool ok = context->lookup_variant_definition (
      71                 :          91 :         pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
      72                 :          91 :       rust_assert (ok);
      73                 :             : 
      74                 :          91 :       ok = adt->lookup_variant_by_id (variant_id, &variant);
      75                 :          91 :       rust_assert (ok);
      76                 :             :     }
      77                 :             : 
      78                 :             :   // error[E0532]: expected tuple struct or tuple variant, found struct variant
      79                 :             :   // `Foo::D`, E0532 by rustc 1.49.0 , E0164 by rustc 1.71.0
      80                 :         105 :   if (variant->get_variant_type () != TyTy::VariantDef::VariantType::TUPLE)
      81                 :             :     {
      82                 :           1 :       std::string variant_type
      83                 :           1 :         = TyTy::VariantDef::variant_type_string (variant->get_variant_type ());
      84                 :             : 
      85                 :           1 :       rich_location rich_locus (line_table, pattern.get_locus ());
      86                 :           1 :       rich_locus.add_fixit_replace ("not a tuple struct or tuple variant");
      87                 :           1 :       rust_error_at (
      88                 :             :         rich_locus, ErrorCode::E0164,
      89                 :             :         "expected tuple struct or tuple variant, found %s variant %<%s::%s%>",
      90                 :           2 :         variant_type.c_str (), adt->get_name ().c_str (),
      91                 :           1 :         variant->get_identifier ().c_str ());
      92                 :           1 :       return;
      93                 :           1 :     }
      94                 :             : 
      95                 :             :   // check the elements
      96                 :             :   // error[E0023]: this pattern has 2 fields, but the corresponding tuple
      97                 :             :   // variant has 1 field
      98                 :             :   // error[E0023]: this pattern has 0 fields, but the corresponding tuple
      99                 :             :   // variant has 1 field
     100                 :             : 
     101                 :         104 :   std::unique_ptr<HIR::TupleStructItems> &items = pattern.get_items ();
     102                 :         104 :   switch (items->get_item_type ())
     103                 :             :     {
     104                 :           0 :       case HIR::TupleStructItems::RANGED: {
     105                 :             :         // TODO
     106                 :           0 :         rust_unreachable ();
     107                 :             :       }
     108                 :         104 :       break;
     109                 :             : 
     110                 :         104 :       case HIR::TupleStructItems::MULTIPLE: {
     111                 :         104 :         HIR::TupleStructItemsNoRange &items_no_range
     112                 :         104 :           = static_cast<HIR::TupleStructItemsNoRange &> (*items.get ());
     113                 :             : 
     114                 :         104 :         if (items_no_range.get_patterns ().size () != variant->num_fields ())
     115                 :             :           {
     116                 :           1 :             rust_error_at (
     117                 :           1 :               pattern.get_locus (), ErrorCode::E0023,
     118                 :             :               "this pattern has %lu fields but the corresponding "
     119                 :             :               "tuple variant has %lu field",
     120                 :           1 :               (unsigned long) items_no_range.get_patterns ().size (),
     121                 :           1 :               (unsigned long) variant->num_fields ());
     122                 :             :             // we continue on to try and setup the types as best we can for
     123                 :             :             // type checking
     124                 :             :           }
     125                 :             : 
     126                 :             :         // iterate the fields and set them up, I wish we had ZIP
     127                 :         104 :         size_t i = 0;
     128                 :         215 :         for (auto &pattern : items_no_range.get_patterns ())
     129                 :             :           {
     130                 :         112 :             if (i >= variant->num_fields ())
     131                 :             :               break;
     132                 :             : 
     133                 :         111 :             TyTy::StructFieldType *field = variant->get_field_at_index (i++);
     134                 :         111 :             TyTy::BaseType *fty = field->get_field_type ();
     135                 :             : 
     136                 :             :             // setup the type on this pattern type
     137                 :         111 :             context->insert_type (pattern->get_mappings (), fty);
     138                 :             :           }
     139                 :             :       }
     140                 :             :       break;
     141                 :             :     }
     142                 :             : }
     143                 :             : 
     144                 :             : void
     145                 :           1 : emit_invalid_field_error (location_t loc, Rust::TyTy::VariantDef *variant,
     146                 :             :                           const std::string &name)
     147                 :             : {
     148                 :           1 :   rust_error_at (loc, ErrorCode::E0026,
     149                 :             :                  "variant %s does not have a field named %s",
     150                 :           1 :                  variant->get_identifier ().c_str (), name.c_str ());
     151                 :           1 : }
     152                 :             : 
     153                 :             : void
     154                 :          34 : TypeCheckPattern::visit (HIR::StructPattern &pattern)
     155                 :             : {
     156                 :          34 :   TyTy::BaseType *pattern_ty = TypeCheckExpr::Resolve (&pattern.get_path ());
     157                 :          34 :   if (pattern_ty->get_kind () != TyTy::TypeKind::ADT)
     158                 :             :     {
     159                 :           0 :       rust_error_at (pattern.get_locus (),
     160                 :             :                      "expected tuple struct/variant, found: %s",
     161                 :           0 :                      pattern_ty->get_name ().c_str ());
     162                 :           1 :       return;
     163                 :             :     }
     164                 :             : 
     165                 :          34 :   infered = pattern_ty;
     166                 :          34 :   TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered);
     167                 :          34 :   rust_assert (adt->number_of_variants () > 0);
     168                 :             : 
     169                 :          34 :   TyTy::VariantDef *variant = adt->get_variants ().at (0);
     170                 :          34 :   if (adt->is_enum ())
     171                 :             :     {
     172                 :          33 :       HirId variant_id = UNKNOWN_HIRID;
     173                 :          33 :       bool ok = context->lookup_variant_definition (
     174                 :          33 :         pattern.get_path ().get_mappings ().get_hirid (), &variant_id);
     175                 :          33 :       rust_assert (ok);
     176                 :             : 
     177                 :          33 :       ok = adt->lookup_variant_by_id (variant_id, &variant);
     178                 :          33 :       rust_assert (ok);
     179                 :             :     }
     180                 :             : 
     181                 :             :   // error[E0532]: expected tuple struct or tuple variant, found struct variant
     182                 :             :   // `Foo::D`
     183                 :          34 :   if (variant->get_variant_type () != TyTy::VariantDef::VariantType::STRUCT)
     184                 :             :     {
     185                 :           1 :       std::string variant_type
     186                 :           1 :         = TyTy::VariantDef::variant_type_string (variant->get_variant_type ());
     187                 :             : 
     188                 :           1 :       rich_location rich_locus (line_table, pattern.get_locus ());
     189                 :           1 :       std::string rich_msg = "use the tuple variant pattern syntax instead "
     190                 :           2 :                              + variant->get_identifier () + "(_)";
     191                 :           1 :       rich_locus.add_fixit_replace (rich_msg.c_str ());
     192                 :             : 
     193                 :           1 :       rust_error_at (rich_locus, ErrorCode::E0769,
     194                 :             :                      "%s variant %qs written as struct variant",
     195                 :             :                      variant_type.c_str (),
     196                 :           1 :                      variant->get_identifier ().c_str ());
     197                 :           1 :       return;
     198                 :           1 :     }
     199                 :             : 
     200                 :             :   // check the elements
     201                 :             :   // error[E0027]: pattern does not mention fields `x`, `y`
     202                 :             :   // error[E0026]: variant `Foo::D` does not have a field named `b`
     203                 :             : 
     204                 :          33 :   std::vector<std::string> named_fields;
     205                 :          33 :   auto &struct_pattern_elems = pattern.get_struct_pattern_elems ();
     206                 :          96 :   for (auto &field : struct_pattern_elems.get_struct_pattern_fields ())
     207                 :             :     {
     208                 :          63 :       switch (field->get_item_type ())
     209                 :             :         {
     210                 :           0 :           case HIR::StructPatternField::ItemType::TUPLE_PAT: {
     211                 :             :             // TODO
     212                 :           0 :             rust_unreachable ();
     213                 :             :           }
     214                 :           1 :           break;
     215                 :             : 
     216                 :           1 :           case HIR::StructPatternField::ItemType::IDENT_PAT: {
     217                 :           1 :             HIR::StructPatternFieldIdentPat &ident
     218                 :           1 :               = static_cast<HIR::StructPatternFieldIdentPat &> (*field.get ());
     219                 :             : 
     220                 :           1 :             TyTy::StructFieldType *field = nullptr;
     221                 :           1 :             if (!variant->lookup_field (ident.get_identifier ().as_string (),
     222                 :             :                                         &field, nullptr))
     223                 :             :               {
     224                 :           0 :                 emit_invalid_field_error (ident.get_locus (), variant,
     225                 :           0 :                                           ident.get_identifier ().as_string ());
     226                 :           0 :                 break;
     227                 :             :               }
     228                 :           1 :             named_fields.push_back (ident.get_identifier ().as_string ());
     229                 :             : 
     230                 :           1 :             TyTy::BaseType *fty = field->get_field_type ();
     231                 :           1 :             TypeCheckPattern::Resolve (ident.get_pattern ().get (), fty);
     232                 :             :           }
     233                 :           1 :           break;
     234                 :             : 
     235                 :          62 :           case HIR::StructPatternField::ItemType::IDENT: {
     236                 :          62 :             HIR::StructPatternFieldIdent &ident
     237                 :          62 :               = static_cast<HIR::StructPatternFieldIdent &> (*field.get ());
     238                 :             : 
     239                 :          62 :             TyTy::StructFieldType *field = nullptr;
     240                 :          62 :             if (!variant->lookup_field (ident.get_identifier ().as_string (),
     241                 :             :                                         &field, nullptr))
     242                 :             :               {
     243                 :           1 :                 emit_invalid_field_error (ident.get_locus (), variant,
     244                 :           1 :                                           ident.get_identifier ().as_string ());
     245                 :           1 :                 break;
     246                 :             :               }
     247                 :          61 :             named_fields.push_back (ident.get_identifier ().as_string ());
     248                 :             : 
     249                 :             :             // setup the type on this pattern
     250                 :          61 :             TyTy::BaseType *fty = field->get_field_type ();
     251                 :          61 :             context->insert_type (ident.get_mappings (), fty);
     252                 :             :           }
     253                 :          61 :           break;
     254                 :             :         }
     255                 :             :     }
     256                 :             : 
     257                 :          33 :   if (named_fields.size () != variant->num_fields ())
     258                 :             :     {
     259                 :           2 :       std::map<std::string, bool> missing_names;
     260                 :             : 
     261                 :             :       // populate with all fields
     262                 :           6 :       for (auto &field : variant->get_fields ())
     263                 :           4 :         missing_names[field->get_name ()] = true;
     264                 :             : 
     265                 :             :       // then eliminate with named_fields
     266                 :           3 :       for (auto &named : named_fields)
     267                 :           1 :         missing_names.erase (named);
     268                 :             : 
     269                 :             :       // then get the list of missing names
     270                 :           2 :       size_t i = 0;
     271                 :           2 :       std::string missing_fields_str;
     272                 :           5 :       for (auto it = missing_names.begin (); it != missing_names.end (); it++)
     273                 :             :         {
     274                 :           3 :           bool has_next = (i + 1) < missing_names.size ();
     275                 :           5 :           missing_fields_str += it->first + (has_next ? ", " : "");
     276                 :           3 :           i++;
     277                 :             :         }
     278                 :             : 
     279                 :           2 :       rust_error_at (pattern.get_locus (), ErrorCode::E0027,
     280                 :             :                      "pattern does not mention fields %s",
     281                 :             :                      missing_fields_str.c_str ());
     282                 :           2 :     }
     283                 :          33 : }
     284                 :             : 
     285                 :             : void
     286                 :         239 : TypeCheckPattern::visit (HIR::WildcardPattern &pattern)
     287                 :             : {
     288                 :             :   // wildcard patterns within the MatchArm's are simply just the same type as
     289                 :             :   // the parent
     290                 :         239 :   infered = parent->clone ();
     291                 :         239 :   infered->set_ref (pattern.get_mappings ().get_hirid ());
     292                 :         239 : }
     293                 :             : 
     294                 :             : void
     295                 :         147 : TypeCheckPattern::visit (HIR::TuplePattern &pattern)
     296                 :             : {
     297                 :         147 :   std::unique_ptr<HIR::TuplePatternItems> items;
     298                 :         147 :   switch (pattern.get_items ()->get_item_type ())
     299                 :             :     {
     300                 :         147 :       case HIR::TuplePatternItems::ItemType::MULTIPLE: {
     301                 :         147 :         HIR::TuplePatternItemsMultiple &ref
     302                 :             :           = *static_cast<HIR::TuplePatternItemsMultiple *> (
     303                 :         147 :             pattern.get_items ().get ());
     304                 :             : 
     305                 :         147 :         auto resolved_parent = parent->destructure ();
     306                 :         147 :         if (resolved_parent->get_kind () != TyTy::TUPLE)
     307                 :             :           {
     308                 :           1 :             rust_error_at (pattern.get_locus (), "expected %s, found tuple",
     309                 :           1 :                            parent->as_string ().c_str ());
     310                 :           1 :             break;
     311                 :             :           }
     312                 :             : 
     313                 :         146 :         const auto &patterns = ref.get_patterns ();
     314                 :         146 :         size_t nitems_to_resolve = patterns.size ();
     315                 :             : 
     316                 :         146 :         TyTy::TupleType &par
     317                 :             :           = *static_cast<TyTy::TupleType *> (resolved_parent);
     318                 :         146 :         if (patterns.size () != par.get_fields ().size ())
     319                 :             :           {
     320                 :           4 :             emit_pattern_size_error (pattern, par.get_fields ().size (),
     321                 :             :                                      patterns.size ());
     322                 :           4 :             nitems_to_resolve
     323                 :           4 :               = std::min (nitems_to_resolve, par.get_fields ().size ());
     324                 :             :           }
     325                 :             : 
     326                 :         146 :         std::vector<TyTy::TyVar> pattern_elems;
     327                 :         441 :         for (size_t i = 0; i < nitems_to_resolve; i++)
     328                 :             :           {
     329                 :         295 :             auto &p = patterns[i];
     330                 :         295 :             TyTy::BaseType *par_type = par.get_field (i);
     331                 :             : 
     332                 :         295 :             TyTy::BaseType *elem
     333                 :         295 :               = TypeCheckPattern::Resolve (p.get (), par_type);
     334                 :         295 :             pattern_elems.push_back (TyTy::TyVar (elem->get_ref ()));
     335                 :             :           }
     336                 :         292 :         infered = new TyTy::TupleType (pattern.get_mappings ().get_hirid (),
     337                 :         292 :                                        pattern.get_locus (), pattern_elems);
     338                 :         146 :       }
     339                 :         146 :       break;
     340                 :             : 
     341                 :           0 :       case HIR::TuplePatternItems::ItemType::RANGED: {
     342                 :             :         // HIR::TuplePatternItemsRanged &ref
     343                 :             :         //   = *static_cast<HIR::TuplePatternItemsRanged *> (
     344                 :             :         //     pattern.get_items ().get ());
     345                 :             :         // TODO
     346                 :           0 :         rust_unreachable ();
     347                 :             :       }
     348                 :         147 :       break;
     349                 :             :     }
     350                 :         147 : }
     351                 :             : 
     352                 :             : void
     353                 :         140 : TypeCheckPattern::visit (HIR::LiteralPattern &pattern)
     354                 :             : {
     355                 :         140 :   infered = resolve_literal (pattern.get_mappings (), pattern.get_literal (),
     356                 :         140 :                              pattern.get_locus ());
     357                 :         140 : }
     358                 :             : 
     359                 :             : void
     360                 :          21 : TypeCheckPattern::visit (HIR::RangePattern &pattern)
     361                 :             : {
     362                 :             :   // Resolve the upper and lower bounds, and ensure they are compatible types
     363                 :          21 :   TyTy::BaseType *upper = nullptr, *lower = nullptr;
     364                 :             : 
     365                 :          21 :   upper = typecheck_range_pattern_bound (pattern.get_upper_bound (),
     366                 :          21 :                                          pattern.get_mappings (),
     367                 :          21 :                                          pattern.get_locus ());
     368                 :             : 
     369                 :          63 :   lower = typecheck_range_pattern_bound (pattern.get_lower_bound (),
     370                 :          21 :                                          pattern.get_mappings (),
     371                 :          21 :                                          pattern.get_locus ());
     372                 :             : 
     373                 :          21 :   infered = unify_site (pattern.get_mappings ().get_hirid (),
     374                 :          21 :                         TyTy::TyWithLocation (upper),
     375                 :          21 :                         TyTy::TyWithLocation (lower), pattern.get_locus ());
     376                 :          21 : }
     377                 :             : 
     378                 :             : void
     379                 :       14890 : TypeCheckPattern::visit (HIR::IdentifierPattern &)
     380                 :             : {
     381                 :       14890 :   infered = parent;
     382                 :       14890 : }
     383                 :             : 
     384                 :             : void
     385                 :           0 : TypeCheckPattern::visit (HIR::QualifiedPathInExpression &pattern)
     386                 :             : {
     387                 :           0 :   rust_sorry_at (pattern.get_locus (),
     388                 :             :                  "type checking qualified path patterns not supported");
     389                 :           0 : }
     390                 :             : 
     391                 :             : void
     392                 :          36 : TypeCheckPattern::visit (HIR::ReferencePattern &pattern)
     393                 :             : {
     394                 :          36 :   if (parent->get_kind () != TyTy::TypeKind::REF)
     395                 :             :     {
     396                 :           1 :       rust_error_at (pattern.get_locus (), "expected %s, found reference",
     397                 :           1 :                      parent->as_string ().c_str ());
     398                 :           1 :       return;
     399                 :             :     }
     400                 :             : 
     401                 :          35 :   TyTy::ReferenceType *ref_ty_ty = static_cast<TyTy::ReferenceType *> (parent);
     402                 :          35 :   TyTy::BaseType *infered_base
     403                 :          35 :     = TypeCheckPattern::Resolve (pattern.get_referenced_pattern ().get (),
     404                 :             :                                  ref_ty_ty->get_base ());
     405                 :         105 :   infered = new TyTy::ReferenceType (pattern.get_mappings ().get_hirid (),
     406                 :          35 :                                      TyTy::TyVar (infered_base->get_ref ()),
     407                 :          35 :                                      pattern.is_mut () ? Mutability::Mut
     408                 :          70 :                                                        : Mutability::Imm);
     409                 :             : }
     410                 :             : 
     411                 :             : void
     412                 :           0 : TypeCheckPattern::visit (HIR::SlicePattern &pattern)
     413                 :             : {
     414                 :           0 :   rust_sorry_at (pattern.get_locus (),
     415                 :             :                  "type checking qualified path patterns not supported");
     416                 :           0 : }
     417                 :             : 
     418                 :             : void
     419                 :           4 : TypeCheckPattern::emit_pattern_size_error (const HIR::Pattern &pattern,
     420                 :             :                                            size_t expected_field_count,
     421                 :             :                                            size_t got_field_count)
     422                 :             : {
     423                 :           4 :   rich_location r (line_table, pattern.get_locus ());
     424                 :           4 :   r.add_range (mappings->lookup_location (parent->get_ref ()));
     425                 :          10 :   rust_error_at (r,
     426                 :             :                  "expected a tuple with %lu %s, found one "
     427                 :             :                  "with %lu %s",
     428                 :             :                  (unsigned long) expected_field_count,
     429                 :             :                  expected_field_count == 1 ? "element" : "elements",
     430                 :             :                  (unsigned long) got_field_count,
     431                 :             :                  got_field_count == 1 ? "element" : "elements");
     432                 :           4 : }
     433                 :             : 
     434                 :             : TyTy::BaseType *
     435                 :          42 : TypeCheckPattern::typecheck_range_pattern_bound (
     436                 :             :   std::unique_ptr<Rust::HIR::RangePatternBound> &bound,
     437                 :             :   Analysis::NodeMapping mappings, location_t locus)
     438                 :             : {
     439                 :          42 :   TyTy::BaseType *resolved_bound = nullptr;
     440                 :          42 :   switch (bound->get_bound_type ())
     441                 :             :     {
     442                 :          21 :       case HIR::RangePatternBound::RangePatternBoundType::LITERAL: {
     443                 :          21 :         HIR::RangePatternBoundLiteral &ref
     444                 :          21 :           = *static_cast<HIR::RangePatternBoundLiteral *> (bound.get ());
     445                 :             : 
     446                 :          21 :         HIR::Literal lit = ref.get_literal ();
     447                 :             : 
     448                 :          21 :         resolved_bound = resolve_literal (mappings, lit, locus);
     449                 :          21 :       }
     450                 :          21 :       break;
     451                 :             : 
     452                 :          21 :       case HIR::RangePatternBound::RangePatternBoundType::PATH: {
     453                 :          21 :         HIR::RangePatternBoundPath &ref
     454                 :          21 :           = *static_cast<HIR::RangePatternBoundPath *> (bound.get ());
     455                 :             : 
     456                 :          21 :         resolved_bound = TypeCheckExpr::Resolve (&ref.get_path ());
     457                 :             :       }
     458                 :          21 :       break;
     459                 :             : 
     460                 :           0 :       case HIR::RangePatternBound::RangePatternBoundType::QUALPATH: {
     461                 :           0 :         HIR::RangePatternBoundQualPath &ref
     462                 :           0 :           = *static_cast<HIR::RangePatternBoundQualPath *> (bound.get ());
     463                 :             : 
     464                 :           0 :         resolved_bound = TypeCheckExpr::Resolve (&ref.get_qualified_path ());
     465                 :             :       }
     466                 :           0 :       break;
     467                 :             :     }
     468                 :             : 
     469                 :          42 :   return resolved_bound;
     470                 :             : }
     471                 :             : 
     472                 :             : void
     473                 :           1 : TypeCheckPattern::visit (HIR::AltPattern &pattern)
     474                 :             : {
     475                 :           1 :   const auto &alts = pattern.get_alts ();
     476                 :             : 
     477                 :             :   // lub - taken from TypeCheckExpr::visit(ArrayExpr)
     478                 :           1 :   std::vector<TyTy::BaseType *> types;
     479                 :           4 :   for (auto &alt_pattern : alts)
     480                 :             :     {
     481                 :           3 :       types.push_back (TypeCheckPattern::Resolve (alt_pattern.get (), parent));
     482                 :             :     }
     483                 :             : 
     484                 :           1 :   TyTy::BaseType *alt_pattern_type
     485                 :           1 :     = TyTy::TyVar::get_implicit_infer_var (pattern.get_locus ()).get_tyty ();
     486                 :             : 
     487                 :           4 :   for (auto &type : types)
     488                 :             :     {
     489                 :           3 :       alt_pattern_type
     490                 :           3 :         = unify_site (pattern.get_mappings ().get_hirid (),
     491                 :           3 :                       TyTy::TyWithLocation (alt_pattern_type),
     492                 :           3 :                       TyTy::TyWithLocation (type, type->get_locus ()),
     493                 :           3 :                       pattern.get_locus ());
     494                 :             :     }
     495                 :             : 
     496                 :           1 :   infered = alt_pattern_type;
     497                 :           1 : }
     498                 :             : 
     499                 :             : TyTy::BaseType *
     500                 :           3 : ClosureParamInfer::Resolve (HIR::Pattern *pattern)
     501                 :             : {
     502                 :           3 :   ClosureParamInfer resolver;
     503                 :           3 :   pattern->accept_vis (resolver);
     504                 :             : 
     505                 :           3 :   if (resolver.infered->get_kind () != TyTy::TypeKind::ERROR)
     506                 :             :     {
     507                 :           3 :       resolver.context->insert_implicit_type (resolver.infered);
     508                 :           3 :       resolver.mappings->insert_location (resolver.infered->get_ref (),
     509                 :           3 :                                           pattern->get_locus ());
     510                 :             :     }
     511                 :           3 :   return resolver.infered;
     512                 :           3 : }
     513                 :             : 
     514                 :           3 : ClosureParamInfer::ClosureParamInfer ()
     515                 :           3 :   : TypeCheckBase (), infered (new TyTy::ErrorType (0))
     516                 :           3 : {}
     517                 :             : 
     518                 :             : void
     519                 :           1 : ClosureParamInfer::visit (HIR::WildcardPattern &pattern)
     520                 :             : {
     521                 :           1 :   HirId id = pattern.get_mappings ().get_hirid ();
     522                 :           1 :   infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
     523                 :             :                                  TyTy::InferType::TypeHint::Default (),
     524                 :           1 :                                  pattern.get_locus ());
     525                 :           1 : }
     526                 :             : 
     527                 :             : void
     528                 :           1 : ClosureParamInfer::visit (HIR::IdentifierPattern &pattern)
     529                 :             : {
     530                 :           1 :   HirId id = pattern.get_mappings ().get_hirid ();
     531                 :           1 :   infered = new TyTy::InferType (id, TyTy::InferType::InferTypeKind::GENERAL,
     532                 :             :                                  TyTy::InferType::TypeHint::Default (),
     533                 :           1 :                                  pattern.get_locus ());
     534                 :           1 : }
     535                 :             : 
     536                 :             : void
     537                 :           1 : ClosureParamInfer::visit (HIR::ReferencePattern &pattern)
     538                 :             : {
     539                 :           1 :   TyTy::BaseType *element
     540                 :           1 :     = ClosureParamInfer::Resolve (pattern.get_referenced_pattern ().get ());
     541                 :             : 
     542                 :           1 :   HirId id = pattern.get_mappings ().get_hirid ();
     543                 :           1 :   infered = new TyTy::ReferenceType (id, TyTy::TyVar (element->get_ref ()),
     544                 :           2 :                                      pattern.get_mutability ());
     545                 :           1 : }
     546                 :             : 
     547                 :             : void
     548                 :           0 : ClosureParamInfer::visit (HIR::PathInExpression &pattern)
     549                 :             : {
     550                 :           0 :   rust_sorry_at (pattern.get_locus (),
     551                 :             :                  "unable to infer this kind of parameter pattern");
     552                 :           0 : }
     553                 :             : 
     554                 :             : void
     555                 :           0 : ClosureParamInfer::visit (HIR::StructPattern &pattern)
     556                 :             : {
     557                 :           0 :   rust_sorry_at (pattern.get_locus (),
     558                 :             :                  "unable to infer this kind of parameter pattern");
     559                 :           0 : }
     560                 :             : 
     561                 :             : void
     562                 :           0 : ClosureParamInfer::visit (HIR::TupleStructPattern &pattern)
     563                 :             : {
     564                 :           0 :   rust_sorry_at (pattern.get_locus (),
     565                 :             :                  "unable to infer this kind of parameter pattern");
     566                 :           0 : }
     567                 :             : 
     568                 :             : void
     569                 :           0 : ClosureParamInfer::visit (HIR::TuplePattern &pattern)
     570                 :             : {
     571                 :           0 :   rust_sorry_at (pattern.get_locus (),
     572                 :             :                  "unable to infer this kind of parameter pattern");
     573                 :           0 : }
     574                 :             : 
     575                 :             : void
     576                 :           0 : ClosureParamInfer::visit (HIR::LiteralPattern &pattern)
     577                 :             : {
     578                 :           0 :   rust_sorry_at (pattern.get_locus (),
     579                 :             :                  "unable to infer this kind of parameter pattern");
     580                 :           0 : }
     581                 :             : 
     582                 :             : void
     583                 :           0 : ClosureParamInfer::visit (HIR::RangePattern &pattern)
     584                 :             : {
     585                 :           0 :   rust_sorry_at (pattern.get_locus (),
     586                 :             :                  "unable to infer this kind of parameter pattern");
     587                 :           0 : }
     588                 :             : 
     589                 :             : void
     590                 :           0 : ClosureParamInfer::visit (HIR::QualifiedPathInExpression &pattern)
     591                 :             : {
     592                 :           0 :   rust_sorry_at (pattern.get_locus (),
     593                 :             :                  "unable to infer this kind of parameter pattern");
     594                 :           0 : }
     595                 :             : 
     596                 :             : void
     597                 :           0 : ClosureParamInfer::visit (HIR::SlicePattern &pattern)
     598                 :             : {
     599                 :           0 :   rust_sorry_at (pattern.get_locus (),
     600                 :             :                  "unable to infer this kind of parameter pattern");
     601                 :           0 : }
     602                 :             : 
     603                 :             : void
     604                 :           0 : ClosureParamInfer::visit (HIR::AltPattern &pattern)
     605                 :             : {
     606                 :           0 :   rust_sorry_at (pattern.get_locus (),
     607                 :             :                  "unable to infer this kind of parameter pattern");
     608                 :           0 : }
     609                 :             : 
     610                 :             : } // namespace Resolver
     611                 :             : } // namespace Rust
        

Generated by: LCOV version 2.1-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.