LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty-subst.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 81.2 % 430 349
Test Date: 2024-12-21 13:15:12 Functions: 84.6 % 78 66
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-tyty-subst.h"
      20                 :             : 
      21                 :             : #include "rust-system.h"
      22                 :             : #include "rust-tyty.h"
      23                 :             : #include "rust-hir-type-check.h"
      24                 :             : #include "rust-substitution-mapper.h"
      25                 :             : #include "rust-hir-type-check-type.h"
      26                 :             : #include "rust-type-util.h"
      27                 :             : 
      28                 :             : namespace Rust {
      29                 :             : namespace TyTy {
      30                 :             : 
      31                 :    12158284 : SubstitutionParamMapping::SubstitutionParamMapping (
      32                 :    12158284 :   const HIR::TypeParam &generic, ParamType *param)
      33                 :    12158284 :   : generic (generic), param (param)
      34                 :    12158284 : {}
      35                 :             : 
      36                 :    12505344 : SubstitutionParamMapping::SubstitutionParamMapping (
      37                 :    12505344 :   const SubstitutionParamMapping &other)
      38                 :    12505344 :   : generic (other.generic), param (other.param)
      39                 :    12505344 : {}
      40                 :             : 
      41                 :             : std::string
      42                 :       70747 : SubstitutionParamMapping::as_string () const
      43                 :             : {
      44                 :       70747 :   if (param == nullptr)
      45                 :           0 :     return "nullptr";
      46                 :             : 
      47                 :       70747 :   return param->get_name ();
      48                 :             : }
      49                 :             : 
      50                 :             : SubstitutionParamMapping
      51                 :    12149589 : SubstitutionParamMapping::clone () const
      52                 :             : {
      53                 :    12149589 :   return SubstitutionParamMapping (generic,
      54                 :    12149589 :                                    static_cast<ParamType *> (param->clone ()));
      55                 :             : }
      56                 :             : 
      57                 :             : ParamType *
      58                 :       66099 : SubstitutionParamMapping::get_param_ty ()
      59                 :             : {
      60                 :       66099 :   return param;
      61                 :             : }
      62                 :             : 
      63                 :             : const ParamType *
      64                 :    11999383 : SubstitutionParamMapping::get_param_ty () const
      65                 :             : {
      66                 :    11999383 :   return param;
      67                 :             : }
      68                 :             : 
      69                 :             : const HIR::TypeParam &
      70                 :        1470 : SubstitutionParamMapping::get_generic_param () const
      71                 :             : {
      72                 :        1470 :   return generic;
      73                 :             : }
      74                 :             : 
      75                 :             : bool
      76                 :       27043 : SubstitutionParamMapping::needs_substitution () const
      77                 :             : {
      78                 :       27043 :   return !(get_param_ty ()->is_concrete ());
      79                 :             : }
      80                 :             : 
      81                 :             : location_t
      82                 :         707 : SubstitutionParamMapping::get_param_locus () const
      83                 :             : {
      84                 :         707 :   return generic.get_locus ();
      85                 :             : }
      86                 :             : 
      87                 :             : bool
      88                 :       11101 : SubstitutionParamMapping::param_has_default_ty () const
      89                 :             : {
      90                 :       11101 :   return generic.has_type ();
      91                 :             : }
      92                 :             : 
      93                 :             : BaseType *
      94                 :         243 : SubstitutionParamMapping::get_default_ty () const
      95                 :             : {
      96                 :         243 :   TyVar var (generic.get_type_mappings ().get_hirid ());
      97                 :         243 :   return var.get_tyty ();
      98                 :             : }
      99                 :             : 
     100                 :             : bool
     101                 :           0 : SubstitutionParamMapping::need_substitution () const
     102                 :             : {
     103                 :           0 :   if (!param->can_resolve ())
     104                 :             :     return true;
     105                 :             : 
     106                 :           0 :   auto resolved = param->resolve ();
     107                 :           0 :   return !resolved->is_concrete ();
     108                 :             : }
     109                 :             : 
     110                 :             : bool
     111                 :       14127 : SubstitutionParamMapping::fill_param_ty (
     112                 :             :   SubstitutionArgumentMappings &subst_mappings, location_t locus)
     113                 :             : {
     114                 :       14127 :   SubstitutionArg arg = SubstitutionArg::error ();
     115                 :       14127 :   bool ok = subst_mappings.get_argument_for_symbol (get_param_ty (), &arg);
     116                 :       14127 :   if (!ok)
     117                 :             :     return true;
     118                 :             : 
     119                 :       14127 :   TyTy::BaseType &type = *arg.get_tyty ();
     120                 :       14127 :   if (type.get_kind () == TyTy::TypeKind::INFER)
     121                 :             :     {
     122                 :        4991 :       type.inherit_bounds (*param);
     123                 :             :     }
     124                 :             : 
     125                 :       14127 :   if (type.get_kind () == TypeKind::PARAM)
     126                 :             :     {
     127                 :             :       // delete param;
     128                 :        1844 :       param = static_cast<ParamType *> (type.clone ());
     129                 :             :     }
     130                 :             :   else
     131                 :             :     {
     132                 :             :       // check the substitution is compatible with bounds
     133                 :       12283 :       rust_debug_loc (locus,
     134                 :             :                       "fill_param_ty bounds_compatible: param %s type %s",
     135                 :       24566 :                       param->get_name ().c_str (), type.get_name ().c_str ());
     136                 :             : 
     137                 :       12283 :       if (!param->is_implicit_self_trait ())
     138                 :             :         {
     139                 :        7449 :           if (!param->bounds_compatible (type, locus, true))
     140                 :             :             return false;
     141                 :             :         }
     142                 :             : 
     143                 :             :       // recursively pass this down to all HRTB's
     144                 :       27117 :       for (auto &bound : param->get_specified_bounds ())
     145                 :       14838 :         bound.handle_substitions (subst_mappings);
     146                 :             : 
     147                 :       12279 :       param->set_ty_ref (type.get_ref ());
     148                 :       12279 :       subst_mappings.on_param_subst (*param, arg);
     149                 :             :     }
     150                 :             : 
     151                 :             :   return true;
     152                 :             : }
     153                 :             : 
     154                 :             : void
     155                 :        3134 : SubstitutionParamMapping::override_context ()
     156                 :             : {
     157                 :        3134 :   if (!param->can_resolve ())
     158                 :             :     return;
     159                 :             : 
     160                 :        3111 :   auto mappings = Analysis::Mappings::get ();
     161                 :        3111 :   auto context = Resolver::TypeCheckContext::get ();
     162                 :             : 
     163                 :        3111 :   context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
     164                 :             :                                                UNKNOWN_NODEID,
     165                 :        3111 :                                                param->get_ref (),
     166                 :        3111 :                                                UNKNOWN_LOCAL_DEFID),
     167                 :        3111 :                         param->resolve ());
     168                 :             : }
     169                 :             : 
     170                 :    12019260 : SubstitutionArg::SubstitutionArg (const SubstitutionParamMapping *param,
     171                 :    12019260 :                                   BaseType *argument)
     172                 :    12019260 :   : param (param), argument (argument)
     173                 :             : {
     174                 :    12019260 :   if (param != nullptr)
     175                 :    11955441 :     original_param = param->get_param_ty ();
     176                 :    12019260 : }
     177                 :             : 
     178                 :    47975454 : SubstitutionArg::SubstitutionArg (const SubstitutionArg &other)
     179                 :    47975454 :   : param (other.param), original_param (other.original_param),
     180                 :    47975454 :     argument (other.argument)
     181                 :    47975454 : {}
     182                 :             : 
     183                 :             : SubstitutionArg &
     184                 :       58804 : SubstitutionArg::operator= (const SubstitutionArg &other)
     185                 :             : {
     186                 :       58804 :   param = other.param;
     187                 :       58804 :   argument = other.argument;
     188                 :       58804 :   original_param = other.original_param;
     189                 :             : 
     190                 :       58804 :   return *this;
     191                 :             : }
     192                 :             : 
     193                 :             : BaseType *
     194                 :       62644 : SubstitutionArg::get_tyty ()
     195                 :             : {
     196                 :       62644 :   return argument;
     197                 :             : }
     198                 :             : 
     199                 :             : const BaseType *
     200                 :    12162252 : SubstitutionArg::get_tyty () const
     201                 :             : {
     202                 :    12162252 :   return argument;
     203                 :             : }
     204                 :             : 
     205                 :             : const SubstitutionParamMapping *
     206                 :        3290 : SubstitutionArg::get_param_mapping () const
     207                 :             : {
     208                 :        3290 :   return param;
     209                 :             : }
     210                 :             : 
     211                 :             : const ParamType *
     212                 :       67731 : SubstitutionArg::get_param_ty () const
     213                 :             : {
     214                 :       67731 :   return original_param;
     215                 :             : }
     216                 :             : 
     217                 :             : SubstitutionArg
     218                 :       63819 : SubstitutionArg::error ()
     219                 :             : {
     220                 :       63819 :   return SubstitutionArg (nullptr, nullptr);
     221                 :             : }
     222                 :             : 
     223                 :             : bool
     224                 :       20896 : SubstitutionArg::is_error () const
     225                 :             : {
     226                 :       20896 :   return param == nullptr || argument == nullptr;
     227                 :             : }
     228                 :             : 
     229                 :             : bool
     230                 :           0 : SubstitutionArg::is_conrete () const
     231                 :             : {
     232                 :           0 :   if (argument == nullptr)
     233                 :             :     return false;
     234                 :             : 
     235                 :           0 :   if (argument->get_kind () == TyTy::TypeKind::PARAM)
     236                 :             :     return false;
     237                 :             : 
     238                 :           0 :   return argument->is_concrete ();
     239                 :             : }
     240                 :             : 
     241                 :             : std::string
     242                 :           0 : SubstitutionArg::as_string () const
     243                 :             : {
     244                 :           0 :   return original_param->as_string ()
     245                 :           0 :          + (argument != nullptr ? ":" + argument->as_string () : "");
     246                 :             : }
     247                 :             : 
     248                 :             : const RegionParamList &
     249                 :    11870680 : SubstitutionArgumentMappings::get_regions () const
     250                 :             : {
     251                 :    11870680 :   return regions;
     252                 :             : }
     253                 :             : 
     254                 :             : RegionParamList &
     255                 :         735 : SubstitutionArgumentMappings::get_mut_regions ()
     256                 :             : {
     257                 :         735 :   return regions;
     258                 :             : }
     259                 :             : 
     260                 :             : // SubstitutionArgumentMappings
     261                 :             : 
     262                 :    23808041 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
     263                 :             :   std::vector<SubstitutionArg> mappings,
     264                 :             :   std::map<std::string, BaseType *> binding_args, RegionParamList regions,
     265                 :             :   location_t locus, ParamSubstCb param_subst_cb, bool trait_item_flag,
     266                 :    23808041 :   bool error_flag)
     267                 :    23808041 :   : mappings (std::move (mappings)), binding_args (binding_args),
     268                 :    23808041 :     regions (regions), locus (locus), param_subst_cb (param_subst_cb),
     269                 :    23808041 :     trait_item_flag (trait_item_flag), error_flag (error_flag)
     270                 :    23808041 : {}
     271                 :             : 
     272                 :    12053444 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
     273                 :    12053444 :   const SubstitutionArgumentMappings &other)
     274                 :    12053444 :   : mappings (other.mappings), binding_args (other.binding_args),
     275                 :    12053444 :     regions (other.regions), locus (other.locus), param_subst_cb (nullptr),
     276                 :    12053444 :     trait_item_flag (other.trait_item_flag), error_flag (other.error_flag)
     277                 :    12053444 : {}
     278                 :             : 
     279                 :             : SubstitutionArgumentMappings &
     280                 :       13562 : SubstitutionArgumentMappings::operator= (
     281                 :             :   const SubstitutionArgumentMappings &other)
     282                 :             : {
     283                 :       13562 :   mappings = other.mappings;
     284                 :       13562 :   binding_args = other.binding_args;
     285                 :       13562 :   regions = other.regions;
     286                 :       13562 :   locus = other.locus;
     287                 :       13562 :   param_subst_cb = nullptr;
     288                 :       13562 :   trait_item_flag = other.trait_item_flag;
     289                 :       13562 :   error_flag = other.error_flag;
     290                 :             : 
     291                 :       13562 :   return *this;
     292                 :             : }
     293                 :             : 
     294                 :             : SubstitutionArgumentMappings
     295                 :       14808 : SubstitutionArgumentMappings::error ()
     296                 :             : {
     297                 :       14808 :   return SubstitutionArgumentMappings ({}, {}, 0, UNDEF_LOCATION, nullptr,
     298                 :       14808 :                                        false, true);
     299                 :             : }
     300                 :             : 
     301                 :             : SubstitutionArgumentMappings
     302                 :    11927469 : SubstitutionArgumentMappings::empty (size_t num_regions)
     303                 :             : {
     304                 :    11927469 :   return SubstitutionArgumentMappings ({}, {}, num_regions, UNDEF_LOCATION,
     305                 :    11927469 :                                        nullptr, false, false);
     306                 :             : }
     307                 :             : 
     308                 :             : bool
     309                 :        9845 : SubstitutionArgumentMappings::is_error () const
     310                 :             : {
     311                 :        9845 :   return error_flag;
     312                 :             : }
     313                 :             : 
     314                 :             : bool
     315                 :       58667 : SubstitutionArgumentMappings::get_argument_for_symbol (
     316                 :             :   const ParamType *param_to_find, SubstitutionArg *argument) const
     317                 :             : {
     318                 :       74423 :   for (const auto &mapping : mappings)
     319                 :             :     {
     320                 :       67731 :       const ParamType *p = mapping.get_param_ty ();
     321                 :       67731 :       if (p->get_symbol () == param_to_find->get_symbol ())
     322                 :             :         {
     323                 :       51975 :           *argument = mapping;
     324                 :       51975 :           return true;
     325                 :             :         }
     326                 :             :     }
     327                 :             :   return false;
     328                 :             : }
     329                 :             : tl::optional<size_t>
     330                 :           0 : SubstitutionArgumentMappings::find_symbol (const ParamType &param_to_find) const
     331                 :             : {
     332                 :           0 :   auto it = std::find_if (mappings.begin (), mappings.end (),
     333                 :           0 :                           [param_to_find] (const SubstitutionArg &arg) {
     334                 :           0 :                             return arg.get_param_ty ()->get_symbol ()
     335                 :           0 :                                    == param_to_find.get_symbol ();
     336                 :             :                           });
     337                 :           0 :   if (it == mappings.end ())
     338                 :           0 :     return tl::nullopt;
     339                 :           0 :   return std::distance (mappings.begin (), it);
     340                 :             : }
     341                 :             : 
     342                 :             : bool
     343                 :        5152 : SubstitutionArgumentMappings::get_argument_at (size_t index,
     344                 :             :                                                SubstitutionArg *argument)
     345                 :             : {
     346                 :        5152 :   if (index > mappings.size ())
     347                 :             :     return false;
     348                 :             : 
     349                 :        5152 :   *argument = mappings.at (index);
     350                 :        5152 :   return true;
     351                 :             : }
     352                 :             : 
     353                 :             : bool
     354                 :           0 : SubstitutionArgumentMappings::is_concrete () const
     355                 :             : {
     356                 :           0 :   for (auto &mapping : mappings)
     357                 :             :     {
     358                 :           0 :       if (!mapping.is_conrete ())
     359                 :           0 :         return false;
     360                 :             :     }
     361                 :             :   return true;
     362                 :             : }
     363                 :             : 
     364                 :             : location_t
     365                 :    11869772 : SubstitutionArgumentMappings::get_locus () const
     366                 :             : {
     367                 :    11869772 :   return locus;
     368                 :             : }
     369                 :             : 
     370                 :             : size_t
     371                 :       17603 : SubstitutionArgumentMappings::size () const
     372                 :             : {
     373                 :       17603 :   return mappings.size ();
     374                 :             : }
     375                 :             : 
     376                 :             : bool
     377                 :        7512 : SubstitutionArgumentMappings::is_empty () const
     378                 :             : {
     379                 :        7512 :   return size () == 0;
     380                 :             : }
     381                 :             : 
     382                 :             : std::vector<SubstitutionArg> &
     383                 :       27579 : SubstitutionArgumentMappings::get_mappings ()
     384                 :             : {
     385                 :       27579 :   return mappings;
     386                 :             : }
     387                 :             : 
     388                 :             : const std::vector<SubstitutionArg> &
     389                 :    47550090 : SubstitutionArgumentMappings::get_mappings () const
     390                 :             : {
     391                 :    47550090 :   return mappings;
     392                 :             : }
     393                 :             : 
     394                 :             : std::map<std::string, BaseType *> &
     395                 :       22359 : SubstitutionArgumentMappings::get_binding_args ()
     396                 :             : {
     397                 :       22359 :   return binding_args;
     398                 :             : }
     399                 :             : 
     400                 :             : const std::map<std::string, BaseType *> &
     401                 :           0 : SubstitutionArgumentMappings::get_binding_args () const
     402                 :             : {
     403                 :           0 :   return binding_args;
     404                 :             : }
     405                 :             : 
     406                 :             : std::string
     407                 :           0 : SubstitutionArgumentMappings::as_string () const
     408                 :             : {
     409                 :           0 :   std::string buffer;
     410                 :           0 :   for (auto &mapping : mappings)
     411                 :             :     {
     412                 :           0 :       buffer += mapping.as_string () + ", ";
     413                 :             :     }
     414                 :           0 :   return "<" + buffer + ">";
     415                 :           0 : }
     416                 :             : 
     417                 :             : void
     418                 :       27559 : SubstitutionArgumentMappings::on_param_subst (const ParamType &p,
     419                 :             :                                               const SubstitutionArg &a) const
     420                 :             : {
     421                 :       27559 :   if (param_subst_cb == nullptr)
     422                 :             :     return;
     423                 :             : 
     424                 :         394 :   param_subst_cb (p, a);
     425                 :             : }
     426                 :             : 
     427                 :             : ParamSubstCb
     428                 :        6959 : SubstitutionArgumentMappings::get_subst_cb () const
     429                 :             : {
     430                 :        6959 :   return param_subst_cb;
     431                 :             : }
     432                 :             : 
     433                 :             : bool
     434                 :        4843 : SubstitutionArgumentMappings::trait_item_mode () const
     435                 :             : {
     436                 :        4843 :   return trait_item_flag;
     437                 :             : }
     438                 :             : 
     439                 :             : // SubstitutionRef
     440                 :             : 
     441                 :    11949713 : SubstitutionRef::SubstitutionRef (
     442                 :             :   std::vector<SubstitutionParamMapping> substitutions,
     443                 :    11949713 :   SubstitutionArgumentMappings arguments, RegionConstraints region_constraints)
     444                 :    11949713 :   : substitutions (substitutions), used_arguments (arguments),
     445                 :    23899426 :     region_constraints (region_constraints)
     446                 :    11949713 : {}
     447                 :             : 
     448                 :             : bool
     449                 :       63231 : SubstitutionRef::has_substitutions () const
     450                 :             : {
     451                 :       63231 :   return substitutions.size () > 0;
     452                 :             : }
     453                 :             : 
     454                 :             : std::string
     455                 :      145232 : SubstitutionRef::subst_as_string () const
     456                 :             : {
     457                 :      145232 :   std::string buffer;
     458                 :      215979 :   for (size_t i = 0; i < substitutions.size (); i++)
     459                 :             :     {
     460                 :       70747 :       const SubstitutionParamMapping &sub = substitutions.at (i);
     461                 :       70747 :       buffer += sub.as_string ();
     462                 :             : 
     463                 :       70747 :       if ((i + 1) < substitutions.size ())
     464                 :        7111 :         buffer += ", ";
     465                 :             :     }
     466                 :             : 
     467                 :      208868 :   return buffer.empty () ? "" : "<" + buffer + ">";
     468                 :      145232 : }
     469                 :             : 
     470                 :             : bool
     471                 :          44 : SubstitutionRef::supports_associated_bindings () const
     472                 :             : {
     473                 :          44 :   return get_num_associated_bindings () > 0;
     474                 :             : }
     475                 :             : 
     476                 :             : size_t
     477                 :           1 : SubstitutionRef::get_num_associated_bindings () const
     478                 :             : {
     479                 :           1 :   return 0;
     480                 :             : }
     481                 :             : 
     482                 :             : TypeBoundPredicateItem
     483                 :           0 : SubstitutionRef::lookup_associated_type (const std::string &search)
     484                 :             : {
     485                 :           0 :   return TypeBoundPredicateItem::error ();
     486                 :             : }
     487                 :             : 
     488                 :             : size_t
     489                 :       21697 : SubstitutionRef::get_num_substitutions () const
     490                 :             : {
     491                 :       21697 :   return substitutions.size ();
     492                 :             : }
     493                 :             : size_t
     494                 :           0 : SubstitutionRef::get_num_lifetime_params () const
     495                 :             : {
     496                 :           0 :   return used_arguments.get_regions ().size ();
     497                 :             : }
     498                 :             : size_t
     499                 :           0 : SubstitutionRef::get_num_type_params () const
     500                 :             : {
     501                 :           0 :   return get_num_substitutions ();
     502                 :             : }
     503                 :             : 
     504                 :             : std::vector<SubstitutionParamMapping> &
     505                 :       58765 : SubstitutionRef::get_substs ()
     506                 :             : {
     507                 :       58765 :   return substitutions;
     508                 :             : }
     509                 :             : 
     510                 :             : const std::vector<SubstitutionParamMapping> &
     511                 :    11862694 : SubstitutionRef::get_substs () const
     512                 :             : {
     513                 :    11862694 :   return substitutions;
     514                 :             : }
     515                 :             : 
     516                 :             : std::vector<SubstitutionParamMapping>
     517                 :       50407 : SubstitutionRef::clone_substs () const
     518                 :             : {
     519                 :       50407 :   std::vector<SubstitutionParamMapping> clone;
     520                 :             : 
     521                 :       81839 :   for (auto &sub : substitutions)
     522                 :       31432 :     clone.push_back (sub.clone ());
     523                 :             : 
     524                 :       50407 :   return clone;
     525                 :             : }
     526                 :             : 
     527                 :             : void
     528                 :        2856 : SubstitutionRef::override_context ()
     529                 :             : {
     530                 :        5990 :   for (auto &sub : substitutions)
     531                 :             :     {
     532                 :        3134 :       sub.override_context ();
     533                 :             :     }
     534                 :        2856 : }
     535                 :             : 
     536                 :             : bool
     537                 :       17605 : SubstitutionRef::needs_substitution () const
     538                 :             : {
     539                 :       17605 :   return std::any_of (substitutions.begin (), substitutions.end (),
     540                 :             :                       std::mem_fn (
     541                 :       17605 :                         &SubstitutionParamMapping::needs_substitution));
     542                 :             : }
     543                 :             : 
     544                 :             : bool
     545                 :          63 : SubstitutionRef::was_substituted () const
     546                 :             : {
     547                 :          63 :   return !needs_substitution ();
     548                 :             : }
     549                 :             : 
     550                 :             : SubstitutionArgumentMappings &
     551                 :       12060 : SubstitutionRef::get_substitution_arguments ()
     552                 :             : {
     553                 :       12060 :   return used_arguments;
     554                 :             : }
     555                 :             : 
     556                 :             : const SubstitutionArgumentMappings &
     557                 :       18233 : SubstitutionRef::get_substitution_arguments () const
     558                 :             : {
     559                 :       18233 :   return used_arguments;
     560                 :             : }
     561                 :             : 
     562                 :             : size_t
     563                 :        4570 : SubstitutionRef::num_required_substitutions () const
     564                 :             : {
     565                 :        4570 :   size_t n = 0;
     566                 :       10037 :   for (auto &p : substitutions)
     567                 :             :     {
     568                 :        5467 :       if (p.needs_substitution ())
     569                 :        5425 :         n++;
     570                 :             :     }
     571                 :        4570 :   return n;
     572                 :             : }
     573                 :             : 
     574                 :             : size_t
     575                 :        9146 : SubstitutionRef::min_required_substitutions () const
     576                 :             : {
     577                 :        9146 :   size_t n = 0;
     578                 :       20088 :   for (auto &p : substitutions)
     579                 :             :     {
     580                 :       10942 :       if (p.needs_substitution () && !p.param_has_default_ty ())
     581                 :       10094 :         n++;
     582                 :             :     }
     583                 :        9146 :   return n;
     584                 :             : }
     585                 :             : 
     586                 :             : const SubstitutionArgumentMappings &
     587                 :        6971 : SubstitutionRef::get_used_arguments () const
     588                 :             : {
     589                 :        6971 :   return used_arguments;
     590                 :             : }
     591                 :             : 
     592                 :             : tl::optional<SubstitutionArg>
     593                 :          96 : SubstitutionRef::get_arg_at (size_t i) const
     594                 :             : {
     595                 :          96 :   auto param_ty = get_substs ().at (i).get_param_ty ();
     596                 :          96 :   SubstitutionArg arg = SubstitutionArg::error ();
     597                 :          96 :   get_used_arguments ().get_argument_for_symbol (param_ty, &arg);
     598                 :          96 :   if (arg.is_error ())
     599                 :           1 :     return tl::nullopt;
     600                 :          95 :   return arg;
     601                 :             : }
     602                 :             : 
     603                 :             : const RegionConstraints &
     604                 :       49279 : SubstitutionRef::get_region_constraints () const
     605                 :             : {
     606                 :       49279 :   return region_constraints;
     607                 :             : }
     608                 :             : 
     609                 :             : SubstitutionArgumentMappings
     610                 :        4576 : SubstitutionRef::get_mappings_from_generic_args (
     611                 :             :   HIR::GenericArgs &args, const std::vector<Region> &regions)
     612                 :             : {
     613                 :        4576 :   std::map<std::string, BaseType *> binding_arguments;
     614                 :        4576 :   if (args.get_binding_args ().size () > 0)
     615                 :             :     {
     616                 :          44 :       if (supports_associated_bindings ())
     617                 :             :         {
     618                 :          43 :           if (args.get_binding_args ().size () > get_num_associated_bindings ())
     619                 :             :             {
     620                 :           0 :               rich_location r (line_table, args.get_locus ());
     621                 :             : 
     622                 :           0 :               rust_error_at (r,
     623                 :             :                              "generic item takes at most %lu type binding "
     624                 :             :                              "arguments but %lu were supplied",
     625                 :           0 :                              (unsigned long) get_num_associated_bindings (),
     626                 :           0 :                              (unsigned long) args.get_binding_args ().size ());
     627                 :           0 :               return SubstitutionArgumentMappings::error ();
     628                 :           0 :             }
     629                 :             : 
     630                 :          86 :           for (auto &binding : args.get_binding_args ())
     631                 :             :             {
     632                 :          43 :               BaseType *resolved
     633                 :          43 :                 = Resolver::TypeCheckType::Resolve (binding.get_type ().get ());
     634                 :          43 :               if (resolved == nullptr
     635                 :          43 :                   || resolved->get_kind () == TyTy::TypeKind::ERROR)
     636                 :             :                 {
     637                 :           0 :                   rust_error_at (binding.get_locus (),
     638                 :             :                                  "failed to resolve type arguments");
     639                 :           0 :                   return SubstitutionArgumentMappings::error ();
     640                 :             :                 }
     641                 :             : 
     642                 :             :               // resolve to relevant binding
     643                 :          43 :               auto binding_item = lookup_associated_type (
     644                 :          43 :                 binding.get_identifier ().as_string ());
     645                 :          43 :               if (binding_item.is_error ())
     646                 :             :                 {
     647                 :           0 :                   rust_error_at (
     648                 :             :                     binding.get_locus (), "unknown associated type binding: %s",
     649                 :           0 :                     binding.get_identifier ().as_string ().c_str ());
     650                 :           0 :                   return SubstitutionArgumentMappings::error ();
     651                 :             :                 }
     652                 :             : 
     653                 :          43 :               binding_arguments[binding.get_identifier ().as_string ()]
     654                 :          43 :                 = resolved;
     655                 :             :             }
     656                 :             :         }
     657                 :             :       else
     658                 :             :         {
     659                 :           1 :           rich_location r (line_table, args.get_locus ());
     660                 :           3 :           for (auto &binding : args.get_binding_args ())
     661                 :           2 :             r.add_range (binding.get_locus ());
     662                 :             : 
     663                 :           1 :           rust_error_at (r, ErrorCode::E0229,
     664                 :             :                          "associated type bindings are not allowed here");
     665                 :           1 :           return SubstitutionArgumentMappings::error ();
     666                 :           1 :         }
     667                 :             :     }
     668                 :             : 
     669                 :             :   // for inherited arguments
     670                 :        4575 :   size_t offs = used_arguments.size ();
     671                 :        4575 :   if (args.get_type_args ().size () + offs > substitutions.size ())
     672                 :             :     {
     673                 :           2 :       rich_location r (line_table, args.get_locus ());
     674                 :           2 :       if (!substitutions.empty ())
     675                 :           1 :         r.add_range (substitutions.front ().get_param_locus ());
     676                 :             : 
     677                 :           2 :       rust_error_at (
     678                 :             :         r,
     679                 :             :         "generic item takes at most %lu type arguments but %lu were supplied",
     680                 :           2 :         (unsigned long) substitutions.size (),
     681                 :           2 :         (unsigned long) args.get_type_args ().size ());
     682                 :           2 :       return SubstitutionArgumentMappings::error ();
     683                 :           2 :     }
     684                 :             : 
     685                 :        4573 :   if (args.get_type_args ().size () + offs < min_required_substitutions ())
     686                 :             :     {
     687                 :           3 :       rich_location r (line_table, args.get_locus ());
     688                 :           3 :       r.add_range (substitutions.front ().get_param_locus ());
     689                 :             : 
     690                 :           6 :       rust_error_at (
     691                 :             :         r, ErrorCode::E0107,
     692                 :             :         "generic item takes at least %lu type arguments but %lu were supplied",
     693                 :           3 :         (unsigned long) (min_required_substitutions () - offs),
     694                 :           3 :         (unsigned long) args.get_type_args ().size ());
     695                 :           3 :       return SubstitutionArgumentMappings::error ();
     696                 :           3 :     }
     697                 :             : 
     698                 :        4570 :   std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
     699                 :        9558 :   for (auto &arg : args.get_type_args ())
     700                 :             :     {
     701                 :        4988 :       BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ());
     702                 :        4988 :       if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
     703                 :             :         {
     704                 :           0 :           rust_error_at (args.get_locus (), "failed to resolve type arguments");
     705                 :           0 :           return SubstitutionArgumentMappings::error ();
     706                 :             :         }
     707                 :             : 
     708                 :        4988 :       SubstitutionArg subst_arg (&substitutions.at (offs), resolved);
     709                 :        4988 :       offs++;
     710                 :        4988 :       mappings.push_back (std::move (subst_arg));
     711                 :             :     }
     712                 :             : 
     713                 :             :   // we must need to fill out defaults
     714                 :        4570 :   size_t left_over
     715                 :        4570 :     = num_required_substitutions () - min_required_substitutions ();
     716                 :        4570 :   if (left_over > 0)
     717                 :             :     {
     718                 :         625 :       for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
     719                 :             :         {
     720                 :         243 :           SubstitutionParamMapping &param = substitutions.at (offs);
     721                 :         243 :           rust_assert (param.param_has_default_ty ());
     722                 :             : 
     723                 :         243 :           BaseType *resolved = param.get_default_ty ();
     724                 :         243 :           if (resolved->get_kind () == TypeKind::ERROR)
     725                 :           0 :             return SubstitutionArgumentMappings::error ();
     726                 :             : 
     727                 :             :           // this resolved default might already contain default parameters
     728                 :         243 :           if (!resolved->is_concrete ())
     729                 :             :             {
     730                 :         229 :               SubstitutionArgumentMappings intermediate (
     731                 :             :                 mappings, binding_arguments,
     732                 :         229 :                 {used_arguments.get_regions ().size ()}, args.get_locus ());
     733                 :         229 :               resolved = Resolver::SubstMapperInternal::Resolve (resolved,
     734                 :             :                                                                  intermediate);
     735                 :             : 
     736                 :         229 :               if (resolved->get_kind () == TypeKind::ERROR)
     737                 :           0 :                 return SubstitutionArgumentMappings::error ();
     738                 :         229 :             }
     739                 :             : 
     740                 :         243 :           SubstitutionArg subst_arg (&param, resolved);
     741                 :         243 :           mappings.push_back (std::move (subst_arg));
     742                 :             :         }
     743                 :             :     }
     744                 :             : 
     745                 :        4570 :   return {mappings, binding_arguments,
     746                 :        9140 :           RegionParamList::from_subst (used_arguments.get_regions ().size (),
     747                 :             :                                        regions),
     748                 :       13710 :           args.get_locus ()};
     749                 :        4570 : }
     750                 :             : 
     751                 :             : BaseType *
     752                 :        2648 : SubstitutionRef::infer_substitions (location_t locus)
     753                 :             : {
     754                 :        2648 :   std::vector<SubstitutionArg> args;
     755                 :        2648 :   std::map<std::string, BaseType *> argument_mappings;
     756                 :        5693 :   for (auto &p : get_substs ())
     757                 :             :     {
     758                 :        3045 :       if (p.needs_substitution ())
     759                 :             :         {
     760                 :        2989 :           const std::string &symbol = p.get_param_ty ()->get_symbol ();
     761                 :        2989 :           auto it = argument_mappings.find (symbol);
     762                 :        2989 :           bool have_mapping = it != argument_mappings.end ();
     763                 :             : 
     764                 :        2989 :           if (have_mapping)
     765                 :             :             {
     766                 :           7 :               args.push_back (SubstitutionArg (&p, it->second));
     767                 :             :             }
     768                 :             :           else
     769                 :             :             {
     770                 :        2982 :               TyVar infer_var = TyVar::get_implicit_infer_var (locus);
     771                 :        2982 :               args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
     772                 :        2982 :               argument_mappings[symbol] = infer_var.get_tyty ();
     773                 :             :             }
     774                 :        2989 :         }
     775                 :             :       else
     776                 :             :         {
     777                 :          56 :           args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
     778                 :             :         }
     779                 :             :     }
     780                 :             : 
     781                 :             :   // FIXME do we need to add inference variables to all the possible bindings?
     782                 :             :   // it might just lead to inference variable hell not 100% sure if rustc does
     783                 :             :   // this i think the language might needs this to be explicitly set
     784                 :             : 
     785                 :        2648 :   SubstitutionArgumentMappings infer_arguments (std::move (args),
     786                 :             :                                                 {} /* binding_arguments */,
     787                 :             :                                                 used_arguments.get_regions (),
     788                 :        2648 :                                                 locus);
     789                 :        2648 :   return handle_substitions (infer_arguments);
     790                 :        2648 : }
     791                 :             : 
     792                 :             : SubstitutionArgumentMappings
     793                 :        4439 : SubstitutionRef::adjust_mappings_for_this (
     794                 :             :   SubstitutionArgumentMappings &mappings)
     795                 :             : {
     796                 :        4439 :   std::vector<SubstitutionArg> resolved_mappings;
     797                 :        9892 :   for (size_t i = 0; i < substitutions.size (); i++)
     798                 :             :     {
     799                 :        5453 :       auto &subst = substitutions.at (i);
     800                 :             : 
     801                 :        5453 :       SubstitutionArg arg = SubstitutionArg::error ();
     802                 :        5453 :       if (mappings.size () == substitutions.size ())
     803                 :             :         {
     804                 :        5152 :           mappings.get_argument_at (i, &arg);
     805                 :             :         }
     806                 :             :       else
     807                 :             :         {
     808                 :         301 :           if (subst.needs_substitution ())
     809                 :             :             {
     810                 :             :               // get from passed in mappings
     811                 :         231 :               mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
     812                 :             :             }
     813                 :             :           else
     814                 :             :             {
     815                 :             :               // we should already have this somewhere
     816                 :          70 :               used_arguments.get_argument_for_symbol (subst.get_param_ty (),
     817                 :             :                                                       &arg);
     818                 :             :             }
     819                 :             :         }
     820                 :             : 
     821                 :        5453 :       bool ok = !arg.is_error ();
     822                 :        5453 :       if (ok)
     823                 :             :         {
     824                 :        5404 :           SubstitutionArg adjusted (&subst, arg.get_tyty ());
     825                 :        5404 :           resolved_mappings.push_back (std::move (adjusted));
     826                 :             :         }
     827                 :             :     }
     828                 :             : 
     829                 :        4439 :   if (resolved_mappings.empty ())
     830                 :           0 :     return SubstitutionArgumentMappings::error ();
     831                 :             : 
     832                 :        4439 :   return SubstitutionArgumentMappings (resolved_mappings,
     833                 :        4439 :                                        mappings.get_binding_args (),
     834                 :             :                                        mappings.get_regions (),
     835                 :             :                                        mappings.get_locus (),
     836                 :        4439 :                                        mappings.get_subst_cb (),
     837                 :        8878 :                                        mappings.trait_item_mode ());
     838                 :        4439 : }
     839                 :             : 
     840                 :             : bool
     841                 :           0 : SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
     842                 :             : {
     843                 :           0 :   std::vector<SubstitutionArg> resolved_mappings;
     844                 :           0 :   for (size_t i = 0; i < substitutions.size (); i++)
     845                 :             :     {
     846                 :           0 :       auto &subst = substitutions.at (i);
     847                 :             : 
     848                 :           0 :       SubstitutionArg arg = SubstitutionArg::error ();
     849                 :           0 :       if (mappings.size () == substitutions.size ())
     850                 :             :         {
     851                 :           0 :           mappings.get_argument_at (i, &arg);
     852                 :             :         }
     853                 :             :       else
     854                 :             :         {
     855                 :           0 :           if (subst.needs_substitution ())
     856                 :             :             {
     857                 :             :               // get from passed in mappings
     858                 :           0 :               mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
     859                 :             :             }
     860                 :             :           else
     861                 :             :             {
     862                 :             :               // we should already have this somewhere
     863                 :           0 :               used_arguments.get_argument_for_symbol (subst.get_param_ty (),
     864                 :             :                                                       &arg);
     865                 :             :             }
     866                 :             :         }
     867                 :             : 
     868                 :           0 :       bool ok = !arg.is_error ();
     869                 :           0 :       if (ok)
     870                 :             :         {
     871                 :           0 :           SubstitutionArg adjusted (&subst, arg.get_tyty ());
     872                 :           0 :           resolved_mappings.push_back (std::move (adjusted));
     873                 :             :         }
     874                 :             :     }
     875                 :             : 
     876                 :           0 :   return !resolved_mappings.empty ();
     877                 :           0 : }
     878                 :             : 
     879                 :             : // this function assumes that the mappings being passed are for the same type as
     880                 :             : // this new substitution reference so ordering matters here
     881                 :             : SubstitutionArgumentMappings
     882                 :          63 : SubstitutionRef::solve_mappings_from_receiver_for_self (
     883                 :             :   SubstitutionArgumentMappings &mappings) const
     884                 :             : {
     885                 :          63 :   std::vector<SubstitutionArg> resolved_mappings;
     886                 :             : 
     887                 :          63 :   rust_assert (mappings.size () == get_num_substitutions ());
     888                 :         126 :   for (size_t i = 0; i < get_num_substitutions (); i++)
     889                 :             :     {
     890                 :          63 :       const SubstitutionParamMapping &param_mapping = substitutions.at (i);
     891                 :          63 :       SubstitutionArg &arg = mappings.get_mappings ().at (i);
     892                 :             : 
     893                 :          63 :       if (param_mapping.needs_substitution ())
     894                 :             :         {
     895                 :          63 :           SubstitutionArg adjusted (&param_mapping, arg.get_tyty ());
     896                 :          63 :           resolved_mappings.push_back (std::move (adjusted));
     897                 :             :         }
     898                 :             :     }
     899                 :             : 
     900                 :          63 :   return SubstitutionArgumentMappings (resolved_mappings,
     901                 :          63 :                                        mappings.get_binding_args (),
     902                 :             :                                        mappings.get_regions (),
     903                 :         126 :                                        mappings.get_locus ());
     904                 :          63 : }
     905                 :             : 
     906                 :             : void
     907                 :        1325 : SubstitutionRef::prepare_higher_ranked_bounds ()
     908                 :             : {
     909                 :        2444 :   for (const auto &subst : get_substs ())
     910                 :             :     {
     911                 :        1119 :       const TyTy::ParamType *pty = subst.get_param_ty ();
     912                 :        2529 :       for (const auto &bound : pty->get_specified_bounds ())
     913                 :             :         {
     914                 :        1410 :           const auto ref = bound.get ();
     915                 :        1410 :           ref->clear_associated_type_projections ();
     916                 :             :         }
     917                 :             :     }
     918                 :        1325 : }
     919                 :             : 
     920                 :             : bool
     921                 :        8320 : SubstitutionRef::monomorphize ()
     922                 :             : {
     923                 :       13071 :   for (const auto &subst : get_substs ())
     924                 :             :     {
     925                 :        4751 :       const TyTy::ParamType *pty = subst.get_param_ty ();
     926                 :             : 
     927                 :        4751 :       if (!pty->can_resolve ())
     928                 :          64 :         continue;
     929                 :             : 
     930                 :        4687 :       const TyTy::BaseType *binding = pty->resolve ();
     931                 :        4687 :       if (binding->get_kind () == TyTy::TypeKind::PARAM)
     932                 :         801 :         continue;
     933                 :             : 
     934                 :        8321 :       for (const auto &bound : pty->get_specified_bounds ())
     935                 :             :         {
     936                 :        4435 :           bool ambigious = false;
     937                 :        4435 :           auto associated
     938                 :        4435 :             = Resolver::lookup_associated_impl_block (bound, binding,
     939                 :             :                                                       &ambigious);
     940                 :        4435 :           if (associated == nullptr && ambigious)
     941                 :             :             {
     942                 :             :               // go for the first one? or error out?
     943                 :           0 :               auto &mappings = *Analysis::Mappings::get ();
     944                 :           0 :               const auto &type_param = subst.get_generic_param ();
     945                 :           0 :               const auto *trait_ref = bound.get ();
     946                 :             : 
     947                 :           0 :               rich_location r (line_table, type_param.get_locus ());
     948                 :           0 :               r.add_range (bound.get_locus ());
     949                 :           0 :               r.add_range (mappings.lookup_location (binding->get_ref ()));
     950                 :             : 
     951                 :           0 :               rust_error_at (r, "ambiguous type bound for trait %s and type %s",
     952                 :           0 :                              trait_ref->get_name ().c_str (),
     953                 :           0 :                              binding->get_name ().c_str ());
     954                 :           0 :               return false;
     955                 :           0 :             }
     956                 :             : 
     957                 :             :           if (associated != nullptr)
     958                 :             :             {
     959                 :         771 :               associated->setup_associated_types (binding, bound);
     960                 :             :             }
     961                 :             :         }
     962                 :             :     }
     963                 :             : 
     964                 :             :   return true;
     965                 :             : }
     966                 :             : 
     967                 :             : } // namespace TyTy
     968                 :             : } // 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.