LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty-subst.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 80.3 % 422 339
Test Date: 2024-03-23 14:05:01 Functions: 83.1 % 77 64
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 <utility>
      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                 :    12157837 : SubstitutionParamMapping::SubstitutionParamMapping (
      32                 :    12157837 :   const HIR::TypeParam &generic, ParamType *param)
      33                 :    12157837 :   : generic (generic), param (param)
      34                 :    12157837 : {}
      35                 :             : 
      36                 :    12504873 : SubstitutionParamMapping::SubstitutionParamMapping (
      37                 :    12504873 :   const SubstitutionParamMapping &other)
      38                 :    12504873 :   : generic (other.generic), param (other.param)
      39                 :    12504873 : {}
      40                 :             : 
      41                 :             : std::string
      42                 :       69807 : SubstitutionParamMapping::as_string () const
      43                 :             : {
      44                 :       69807 :   if (param == nullptr)
      45                 :           0 :     return "nullptr";
      46                 :             : 
      47                 :       69807 :   return param->get_name ();
      48                 :             : }
      49                 :             : 
      50                 :             : SubstitutionParamMapping
      51                 :    12149145 : SubstitutionParamMapping::clone () const
      52                 :             : {
      53                 :    12149145 :   return SubstitutionParamMapping (generic,
      54                 :    12149145 :                                    static_cast<ParamType *> (param->clone ()));
      55                 :             : }
      56                 :             : 
      57                 :             : ParamType *
      58                 :       66081 : SubstitutionParamMapping::get_param_ty ()
      59                 :             : {
      60                 :       66081 :   return param;
      61                 :             : }
      62                 :             : 
      63                 :             : const ParamType *
      64                 :    11998841 : SubstitutionParamMapping::get_param_ty () const
      65                 :             : {
      66                 :    11998841 :   return param;
      67                 :             : }
      68                 :             : 
      69                 :             : const HIR::TypeParam &
      70                 :           0 : SubstitutionParamMapping::get_generic_param () const
      71                 :             : {
      72                 :           0 :   return generic;
      73                 :             : }
      74                 :             : 
      75                 :             : bool
      76                 :       27034 : SubstitutionParamMapping::needs_substitution () const
      77                 :             : {
      78                 :       27034 :   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                 :       11099 : SubstitutionParamMapping::param_has_default_ty () const
      89                 :             : {
      90                 :       11099 :   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                 :       14123 : SubstitutionParamMapping::fill_param_ty (
     112                 :             :   SubstitutionArgumentMappings &subst_mappings, location_t locus)
     113                 :             : {
     114                 :       14123 :   SubstitutionArg arg = SubstitutionArg::error ();
     115                 :       14123 :   bool ok = subst_mappings.get_argument_for_symbol (get_param_ty (), &arg);
     116                 :       14123 :   if (!ok)
     117                 :             :     return true;
     118                 :             : 
     119                 :       14123 :   TyTy::BaseType &type = *arg.get_tyty ();
     120                 :       14123 :   if (type.get_kind () == TyTy::TypeKind::INFER)
     121                 :             :     {
     122                 :        4989 :       type.inherit_bounds (*param);
     123                 :             :     }
     124                 :             : 
     125                 :       14123 :   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                 :       12279 :       rust_debug_loc (locus,
     134                 :             :                       "fill_param_ty bounds_compatible: param %s type %s",
     135                 :       24558 :                       param->get_name ().c_str (), type.get_name ().c_str ());
     136                 :             : 
     137                 :       12279 :       if (!param->is_implicit_self_trait ())
     138                 :             :         {
     139                 :        7448 :           if (!param->bounds_compatible (type, locus, true))
     140                 :             :             return false;
     141                 :             :         }
     142                 :             : 
     143                 :             :       // recursively pass this down to all HRTB's
     144                 :       27109 :       for (auto &bound : param->get_specified_bounds ())
     145                 :       14834 :         bound.handle_substitions (subst_mappings);
     146                 :             : 
     147                 :       12275 :       param->set_ty_ref (type.get_ref ());
     148                 :       12275 :       subst_mappings.on_param_subst (*param, arg);
     149                 :             :     }
     150                 :             : 
     151                 :             :   return true;
     152                 :             : }
     153                 :             : 
     154                 :             : void
     155                 :        3133 : SubstitutionParamMapping::override_context ()
     156                 :             : {
     157                 :        3133 :   if (!param->can_resolve ())
     158                 :             :     return;
     159                 :             : 
     160                 :        3110 :   auto mappings = Analysis::Mappings::get ();
     161                 :        3110 :   auto context = Resolver::TypeCheckContext::get ();
     162                 :             : 
     163                 :        3110 :   context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
     164                 :             :                                                UNKNOWN_NODEID,
     165                 :        3110 :                                                param->get_ref (),
     166                 :             :                                                UNKNOWN_LOCAL_DEFID),
     167                 :        3110 :                         param->resolve ());
     168                 :             : }
     169                 :             : 
     170                 :    12018713 : SubstitutionArg::SubstitutionArg (const SubstitutionParamMapping *param,
     171                 :    12018713 :                                   BaseType *argument)
     172                 :    12018713 :   : param (param), argument (argument)
     173                 :             : {
     174                 :    12018713 :   if (param != nullptr)
     175                 :    11955006 :     original_param = param->get_param_ty ();
     176                 :    12018713 : }
     177                 :             : 
     178                 :    47973644 : SubstitutionArg::SubstitutionArg (const SubstitutionArg &other)
     179                 :    47973644 :   : param (other.param), original_param (other.original_param),
     180                 :    47973644 :     argument (other.argument)
     181                 :    47973644 : {}
     182                 :             : 
     183                 :             : SubstitutionArg &
     184                 :       58694 : SubstitutionArg::operator= (const SubstitutionArg &other)
     185                 :             : {
     186                 :       58694 :   param = other.param;
     187                 :       58694 :   argument = other.argument;
     188                 :       58694 :   original_param = other.original_param;
     189                 :             : 
     190                 :       58694 :   return *this;
     191                 :             : }
     192                 :             : 
     193                 :             : BaseType *
     194                 :       62531 : SubstitutionArg::get_tyty ()
     195                 :             : {
     196                 :       62531 :   return argument;
     197                 :             : }
     198                 :             : 
     199                 :             : const BaseType *
     200                 :    12161813 : SubstitutionArg::get_tyty () const
     201                 :             : {
     202                 :    12161813 :   return argument;
     203                 :             : }
     204                 :             : 
     205                 :             : const SubstitutionParamMapping *
     206                 :        3289 : SubstitutionArg::get_param_mapping () const
     207                 :             : {
     208                 :        3289 :   return param;
     209                 :             : }
     210                 :             : 
     211                 :             : const ParamType *
     212                 :       67620 : SubstitutionArg::get_param_ty () const
     213                 :             : {
     214                 :       67620 :   return original_param;
     215                 :             : }
     216                 :             : 
     217                 :             : SubstitutionArg
     218                 :       63707 : SubstitutionArg::error ()
     219                 :             : {
     220                 :       63707 :   return SubstitutionArg (nullptr, nullptr);
     221                 :             : }
     222                 :             : 
     223                 :             : bool
     224                 :       20793 : SubstitutionArg::is_error () const
     225                 :             : {
     226                 :       20793 :   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                 :    11864184 : SubstitutionArgumentMappings::get_regions () const
     250                 :             : {
     251                 :    11864184 :   return regions;
     252                 :             : }
     253                 :             : 
     254                 :             : RegionParamList &
     255                 :         734 : SubstitutionArgumentMappings::get_mut_regions ()
     256                 :             : {
     257                 :         734 :   return regions;
     258                 :             : }
     259                 :             : 
     260                 :             : // SubstitutionArgumentMappings
     261                 :             : 
     262                 :    23807086 : 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                 :    23807086 :   bool error_flag)
     267                 :    23807086 :   : mappings (std::move (mappings)), binding_args (binding_args),
     268                 :    23807086 :     regions (regions), locus (locus), param_subst_cb (param_subst_cb),
     269                 :    23807086 :     trait_item_flag (trait_item_flag), error_flag (error_flag)
     270                 :    23807086 : {}
     271                 :             : 
     272                 :    12052773 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
     273                 :    12052773 :   const SubstitutionArgumentMappings &other)
     274                 :    12052773 :   : mappings (other.mappings), binding_args (other.binding_args),
     275                 :    12052773 :     regions (other.regions), locus (other.locus), param_subst_cb (nullptr),
     276                 :    12052773 :     trait_item_flag (other.trait_item_flag), error_flag (other.error_flag)
     277                 :    12052773 : {}
     278                 :             : 
     279                 :             : SubstitutionArgumentMappings &
     280                 :       13548 : SubstitutionArgumentMappings::operator= (
     281                 :             :   const SubstitutionArgumentMappings &other)
     282                 :             : {
     283                 :       13548 :   mappings = other.mappings;
     284                 :       13548 :   binding_args = other.binding_args;
     285                 :       13548 :   regions = other.regions;
     286                 :       13548 :   locus = other.locus;
     287                 :       13548 :   param_subst_cb = nullptr;
     288                 :       13548 :   trait_item_flag = other.trait_item_flag;
     289                 :       13548 :   error_flag = other.error_flag;
     290                 :             : 
     291                 :       13548 :   return *this;
     292                 :             : }
     293                 :             : 
     294                 :             : SubstitutionArgumentMappings
     295                 :       14794 : SubstitutionArgumentMappings::error ()
     296                 :             : {
     297                 :       14794 :   return SubstitutionArgumentMappings ({}, {}, 0, UNDEF_LOCATION, nullptr,
     298                 :       14794 :                                        false, true);
     299                 :             : }
     300                 :             : 
     301                 :             : SubstitutionArgumentMappings
     302                 :    11926960 : SubstitutionArgumentMappings::empty (size_t num_regions)
     303                 :             : {
     304                 :    11926960 :   return SubstitutionArgumentMappings ({}, {}, num_regions, UNDEF_LOCATION,
     305                 :    11926960 :                                        nullptr, false, false);
     306                 :             : }
     307                 :             : 
     308                 :             : bool
     309                 :        9836 : SubstitutionArgumentMappings::is_error () const
     310                 :             : {
     311                 :        9836 :   return error_flag;
     312                 :             : }
     313                 :             : 
     314                 :             : bool
     315                 :       58556 : SubstitutionArgumentMappings::get_argument_for_symbol (
     316                 :             :   const ParamType *param_to_find, SubstitutionArg *argument) const
     317                 :             : {
     318                 :       74310 :   for (const auto &mapping : mappings)
     319                 :             :     {
     320                 :       67620 :       const ParamType *p = mapping.get_param_ty ();
     321                 :       67620 :       if (p->get_symbol () == param_to_find->get_symbol ())
     322                 :             :         {
     323                 :       51866 :           *argument = mapping;
     324                 :       51866 :           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                 :        5151 : SubstitutionArgumentMappings::get_argument_at (size_t index,
     344                 :             :                                                SubstitutionArg *argument)
     345                 :             : {
     346                 :        5151 :   if (index > mappings.size ())
     347                 :             :     return false;
     348                 :             : 
     349                 :        5151 :   *argument = mappings.at (index);
     350                 :        5151 :   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                 :    11869343 : SubstitutionArgumentMappings::get_locus () const
     366                 :             : {
     367                 :    11869343 :   return locus;
     368                 :             : }
     369                 :             : 
     370                 :             : size_t
     371                 :       17595 : SubstitutionArgumentMappings::size () const
     372                 :             : {
     373                 :       17595 :   return mappings.size ();
     374                 :             : }
     375                 :             : 
     376                 :             : bool
     377                 :        7510 : SubstitutionArgumentMappings::is_empty () const
     378                 :             : {
     379                 :        7510 :   return size () == 0;
     380                 :             : }
     381                 :             : 
     382                 :             : std::vector<SubstitutionArg> &
     383                 :       27564 : SubstitutionArgumentMappings::get_mappings ()
     384                 :             : {
     385                 :       27564 :   return mappings;
     386                 :             : }
     387                 :             : 
     388                 :             : const std::vector<SubstitutionArg> &
     389                 :    47548388 : SubstitutionArgumentMappings::get_mappings () const
     390                 :             : {
     391                 :    47548388 :   return mappings;
     392                 :             : }
     393                 :             : 
     394                 :             : std::map<std::string, BaseType *> &
     395                 :       22353 : SubstitutionArgumentMappings::get_binding_args ()
     396                 :             : {
     397                 :       22353 :   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                 :       27549 : SubstitutionArgumentMappings::on_param_subst (const ParamType &p,
     419                 :             :                                               const SubstitutionArg &a) const
     420                 :             : {
     421                 :       27549 :   if (param_subst_cb == nullptr)
     422                 :             :     return;
     423                 :             : 
     424                 :         394 :   param_subst_cb (p, a);
     425                 :             : }
     426                 :             : 
     427                 :             : ParamSubstCb
     428                 :        6957 : SubstitutionArgumentMappings::get_subst_cb () const
     429                 :             : {
     430                 :        6957 :   return param_subst_cb;
     431                 :             : }
     432                 :             : 
     433                 :             : bool
     434                 :        4842 : SubstitutionArgumentMappings::trait_item_mode () const
     435                 :             : {
     436                 :        4842 :   return trait_item_flag;
     437                 :             : }
     438                 :             : 
     439                 :             : // SubstitutionRef
     440                 :             : 
     441                 :    11949154 : SubstitutionRef::SubstitutionRef (
     442                 :             :   std::vector<SubstitutionParamMapping> substitutions,
     443                 :    11949154 :   SubstitutionArgumentMappings arguments, RegionConstraints region_constraints)
     444                 :    11949154 :   : substitutions (substitutions), used_arguments (arguments),
     445                 :    23898308 :     region_constraints (region_constraints)
     446                 :    11949154 : {}
     447                 :             : 
     448                 :             : bool
     449                 :       63064 : SubstitutionRef::has_substitutions () const
     450                 :             : {
     451                 :       63064 :   return substitutions.size () > 0;
     452                 :             : }
     453                 :             : 
     454                 :             : std::string
     455                 :      142530 : SubstitutionRef::subst_as_string () const
     456                 :             : {
     457                 :      142530 :   std::string buffer;
     458                 :      212337 :   for (size_t i = 0; i < substitutions.size (); i++)
     459                 :             :     {
     460                 :       69807 :       const SubstitutionParamMapping &sub = substitutions.at (i);
     461                 :       69807 :       buffer += sub.as_string ();
     462                 :             : 
     463                 :       69807 :       if ((i + 1) < substitutions.size ())
     464                 :        7029 :         buffer += ", ";
     465                 :             :     }
     466                 :             : 
     467                 :      205308 :   return buffer.empty () ? "" : "<" + buffer + ">";
     468                 :      142530 : }
     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                 :       19655 : SubstitutionRef::get_num_substitutions () const
     490                 :             : {
     491                 :       19655 :   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                 :       54664 : SubstitutionRef::get_substs ()
     506                 :             : {
     507                 :       54664 :   return substitutions;
     508                 :             : }
     509                 :             : 
     510                 :             : const std::vector<SubstitutionParamMapping> &
     511                 :    11862166 : SubstitutionRef::get_substs () const
     512                 :             : {
     513                 :    11862166 :   return substitutions;
     514                 :             : }
     515                 :             : 
     516                 :             : std::vector<SubstitutionParamMapping>
     517                 :       50347 : SubstitutionRef::clone_substs () const
     518                 :             : {
     519                 :       50347 :   std::vector<SubstitutionParamMapping> clone;
     520                 :             : 
     521                 :       81775 :   for (auto &sub : substitutions)
     522                 :       31428 :     clone.push_back (sub.clone ());
     523                 :             : 
     524                 :       50347 :   return clone;
     525                 :             : }
     526                 :             : 
     527                 :             : void
     528                 :        2855 : SubstitutionRef::override_context ()
     529                 :             : {
     530                 :        5988 :   for (auto &sub : substitutions)
     531                 :             :     {
     532                 :        3133 :       sub.override_context ();
     533                 :             :     }
     534                 :        2855 : }
     535                 :             : 
     536                 :             : bool
     537                 :       17502 : SubstitutionRef::needs_substitution () const
     538                 :             : {
     539                 :       17502 :   return std::any_of (substitutions.begin (), substitutions.end (),
     540                 :             :                       std::mem_fn (
     541                 :       17502 :                         &SubstitutionParamMapping::needs_substitution));
     542                 :             : }
     543                 :             : 
     544                 :             : bool
     545                 :          63 : SubstitutionRef::was_substituted () const
     546                 :             : {
     547                 :          63 :   return !needs_substitution ();
     548                 :             : }
     549                 :             : 
     550                 :             : SubstitutionArgumentMappings &
     551                 :       12051 : SubstitutionRef::get_substitution_arguments ()
     552                 :             : {
     553                 :       12051 :   return used_arguments;
     554                 :             : }
     555                 :             : 
     556                 :             : const SubstitutionArgumentMappings &
     557                 :       18220 : SubstitutionRef::get_substitution_arguments () const
     558                 :             : {
     559                 :       18220 :   return used_arguments;
     560                 :             : }
     561                 :             : 
     562                 :             : size_t
     563                 :        4565 : SubstitutionRef::num_required_substitutions () const
     564                 :             : {
     565                 :        4565 :   size_t n = 0;
     566                 :       10031 :   for (auto &p : substitutions)
     567                 :             :     {
     568                 :        5466 :       if (p.needs_substitution ())
     569                 :        5424 :         n++;
     570                 :             :     }
     571                 :        4565 :   return n;
     572                 :             : }
     573                 :             : 
     574                 :             : size_t
     575                 :        9136 : SubstitutionRef::min_required_substitutions () const
     576                 :             : {
     577                 :        9136 :   size_t n = 0;
     578                 :       20076 :   for (auto &p : substitutions)
     579                 :             :     {
     580                 :       10940 :       if (p.needs_substitution () && !p.param_has_default_ty ())
     581                 :       10092 :         n++;
     582                 :             :     }
     583                 :        9136 :   return n;
     584                 :             : }
     585                 :             : 
     586                 :             : const SubstitutionArgumentMappings &
     587                 :         811 : SubstitutionRef::get_used_arguments () const
     588                 :             : {
     589                 :         811 :   return used_arguments;
     590                 :             : }
     591                 :             : 
     592                 :             : const RegionConstraints &
     593                 :       49219 : SubstitutionRef::get_region_constraints () const
     594                 :             : {
     595                 :       49219 :   return region_constraints;
     596                 :             : }
     597                 :             : 
     598                 :             : SubstitutionArgumentMappings
     599                 :        4571 : SubstitutionRef::get_mappings_from_generic_args (
     600                 :             :   HIR::GenericArgs &args, const std::vector<Region> &regions)
     601                 :             : {
     602                 :        4571 :   std::map<std::string, BaseType *> binding_arguments;
     603                 :        4571 :   if (args.get_binding_args ().size () > 0)
     604                 :             :     {
     605                 :          44 :       if (supports_associated_bindings ())
     606                 :             :         {
     607                 :          43 :           if (args.get_binding_args ().size () > get_num_associated_bindings ())
     608                 :             :             {
     609                 :           0 :               rich_location r (line_table, args.get_locus ());
     610                 :             : 
     611                 :           0 :               rust_error_at (r,
     612                 :             :                              "generic item takes at most %lu type binding "
     613                 :             :                              "arguments but %lu were supplied",
     614                 :           0 :                              (unsigned long) get_num_associated_bindings (),
     615                 :           0 :                              (unsigned long) args.get_binding_args ().size ());
     616                 :           0 :               return SubstitutionArgumentMappings::error ();
     617                 :           0 :             }
     618                 :             : 
     619                 :          86 :           for (auto &binding : args.get_binding_args ())
     620                 :             :             {
     621                 :          43 :               BaseType *resolved
     622                 :          43 :                 = Resolver::TypeCheckType::Resolve (binding.get_type ().get ());
     623                 :          43 :               if (resolved == nullptr
     624                 :          43 :                   || resolved->get_kind () == TyTy::TypeKind::ERROR)
     625                 :             :                 {
     626                 :           0 :                   rust_error_at (binding.get_locus (),
     627                 :             :                                  "failed to resolve type arguments");
     628                 :           0 :                   return SubstitutionArgumentMappings::error ();
     629                 :             :                 }
     630                 :             : 
     631                 :             :               // resolve to relevant binding
     632                 :          43 :               auto binding_item = lookup_associated_type (
     633                 :          43 :                 binding.get_identifier ().as_string ());
     634                 :          43 :               if (binding_item.is_error ())
     635                 :             :                 {
     636                 :           0 :                   rust_error_at (
     637                 :             :                     binding.get_locus (), "unknown associated type binding: %s",
     638                 :           0 :                     binding.get_identifier ().as_string ().c_str ());
     639                 :           0 :                   return SubstitutionArgumentMappings::error ();
     640                 :             :                 }
     641                 :             : 
     642                 :          43 :               binding_arguments[binding.get_identifier ().as_string ()]
     643                 :          43 :                 = resolved;
     644                 :             :             }
     645                 :             :         }
     646                 :             :       else
     647                 :             :         {
     648                 :           1 :           rich_location r (line_table, args.get_locus ());
     649                 :           3 :           for (auto &binding : args.get_binding_args ())
     650                 :           2 :             r.add_range (binding.get_locus ());
     651                 :             : 
     652                 :           1 :           rust_error_at (r, ErrorCode::E0229,
     653                 :             :                          "associated type bindings are not allowed here");
     654                 :           1 :           return SubstitutionArgumentMappings::error ();
     655                 :           1 :         }
     656                 :             :     }
     657                 :             : 
     658                 :             :   // for inherited arguments
     659                 :        4570 :   size_t offs = used_arguments.size ();
     660                 :        4570 :   if (args.get_type_args ().size () + offs > substitutions.size ())
     661                 :             :     {
     662                 :           2 :       rich_location r (line_table, args.get_locus ());
     663                 :           2 :       if (!substitutions.empty ())
     664                 :           1 :         r.add_range (substitutions.front ().get_param_locus ());
     665                 :             : 
     666                 :           2 :       rust_error_at (
     667                 :             :         r,
     668                 :             :         "generic item takes at most %lu type arguments but %lu were supplied",
     669                 :           2 :         (unsigned long) substitutions.size (),
     670                 :           2 :         (unsigned long) args.get_type_args ().size ());
     671                 :           2 :       return SubstitutionArgumentMappings::error ();
     672                 :           2 :     }
     673                 :             : 
     674                 :        4568 :   if (args.get_type_args ().size () + offs < min_required_substitutions ())
     675                 :             :     {
     676                 :           3 :       rich_location r (line_table, args.get_locus ());
     677                 :           3 :       r.add_range (substitutions.front ().get_param_locus ());
     678                 :             : 
     679                 :           3 :       rust_error_at (
     680                 :             :         r, ErrorCode::E0107,
     681                 :             :         "generic item takes at least %lu type arguments but %lu were supplied",
     682                 :           3 :         (unsigned long) (min_required_substitutions () - offs),
     683                 :           3 :         (unsigned long) args.get_type_args ().size ());
     684                 :           3 :       return SubstitutionArgumentMappings::error ();
     685                 :           3 :     }
     686                 :             : 
     687                 :        4565 :   std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
     688                 :        9552 :   for (auto &arg : args.get_type_args ())
     689                 :             :     {
     690                 :        4987 :       BaseType *resolved = Resolver::TypeCheckType::Resolve (arg.get ());
     691                 :        4987 :       if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
     692                 :             :         {
     693                 :           0 :           rust_error_at (args.get_locus (), "failed to resolve type arguments");
     694                 :           0 :           return SubstitutionArgumentMappings::error ();
     695                 :             :         }
     696                 :             : 
     697                 :        4987 :       SubstitutionArg subst_arg (&substitutions.at (offs), resolved);
     698                 :        4987 :       offs++;
     699                 :        4987 :       mappings.push_back (std::move (subst_arg));
     700                 :             :     }
     701                 :             : 
     702                 :             :   // we must need to fill out defaults
     703                 :        4565 :   size_t left_over
     704                 :        4565 :     = num_required_substitutions () - min_required_substitutions ();
     705                 :        4565 :   if (left_over > 0)
     706                 :             :     {
     707                 :         625 :       for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
     708                 :             :         {
     709                 :         243 :           SubstitutionParamMapping &param = substitutions.at (offs);
     710                 :         243 :           rust_assert (param.param_has_default_ty ());
     711                 :             : 
     712                 :         243 :           BaseType *resolved = param.get_default_ty ();
     713                 :         243 :           if (resolved->get_kind () == TypeKind::ERROR)
     714                 :           0 :             return SubstitutionArgumentMappings::error ();
     715                 :             : 
     716                 :             :           // this resolved default might already contain default parameters
     717                 :         243 :           if (!resolved->is_concrete ())
     718                 :             :             {
     719                 :         229 :               SubstitutionArgumentMappings intermediate (
     720                 :             :                 mappings, binding_arguments,
     721                 :         229 :                 {used_arguments.get_regions ().size ()}, args.get_locus ());
     722                 :         229 :               resolved = Resolver::SubstMapperInternal::Resolve (resolved,
     723                 :             :                                                                  intermediate);
     724                 :             : 
     725                 :         229 :               if (resolved->get_kind () == TypeKind::ERROR)
     726                 :           0 :                 return SubstitutionArgumentMappings::error ();
     727                 :         229 :             }
     728                 :             : 
     729                 :         243 :           SubstitutionArg subst_arg (&param, resolved);
     730                 :         243 :           mappings.push_back (std::move (subst_arg));
     731                 :             :         }
     732                 :             :     }
     733                 :             : 
     734                 :        4565 :   return {mappings, binding_arguments,
     735                 :        9130 :           RegionParamList::from_subst (used_arguments.get_regions ().size (),
     736                 :             :                                        regions),
     737                 :       13695 :           args.get_locus ()};
     738                 :        4565 : }
     739                 :             : 
     740                 :             : BaseType *
     741                 :        2646 : SubstitutionRef::infer_substitions (location_t locus)
     742                 :             : {
     743                 :        2646 :   std::vector<SubstitutionArg> args;
     744                 :        2646 :   std::map<std::string, BaseType *> argument_mappings;
     745                 :        5689 :   for (auto &p : get_substs ())
     746                 :             :     {
     747                 :        3043 :       if (p.needs_substitution ())
     748                 :             :         {
     749                 :        2987 :           const std::string &symbol = p.get_param_ty ()->get_symbol ();
     750                 :        2987 :           auto it = argument_mappings.find (symbol);
     751                 :        2987 :           bool have_mapping = it != argument_mappings.end ();
     752                 :             : 
     753                 :        2987 :           if (have_mapping)
     754                 :             :             {
     755                 :           7 :               args.push_back (SubstitutionArg (&p, it->second));
     756                 :             :             }
     757                 :             :           else
     758                 :             :             {
     759                 :        2980 :               TyVar infer_var = TyVar::get_implicit_infer_var (locus);
     760                 :        2980 :               args.push_back (SubstitutionArg (&p, infer_var.get_tyty ()));
     761                 :        2980 :               argument_mappings[symbol] = infer_var.get_tyty ();
     762                 :             :             }
     763                 :        2987 :         }
     764                 :             :       else
     765                 :             :         {
     766                 :          56 :           args.push_back (SubstitutionArg (&p, p.get_param_ty ()->resolve ()));
     767                 :             :         }
     768                 :             :     }
     769                 :             : 
     770                 :             :   // FIXME do we need to add inference variables to all the possible bindings?
     771                 :             :   // it might just lead to inference variable hell not 100% sure if rustc does
     772                 :             :   // this i think the language might needs this to be explicitly set
     773                 :             : 
     774                 :        2646 :   SubstitutionArgumentMappings infer_arguments (std::move (args),
     775                 :             :                                                 {} /* binding_arguments */,
     776                 :             :                                                 used_arguments.get_regions (),
     777                 :        2646 :                                                 locus);
     778                 :        2646 :   return handle_substitions (infer_arguments);
     779                 :        2646 : }
     780                 :             : 
     781                 :             : SubstitutionArgumentMappings
     782                 :        4438 : SubstitutionRef::adjust_mappings_for_this (
     783                 :             :   SubstitutionArgumentMappings &mappings)
     784                 :             : {
     785                 :        4438 :   std::vector<SubstitutionArg> resolved_mappings;
     786                 :        9890 :   for (size_t i = 0; i < substitutions.size (); i++)
     787                 :             :     {
     788                 :        5452 :       auto &subst = substitutions.at (i);
     789                 :             : 
     790                 :        5452 :       SubstitutionArg arg = SubstitutionArg::error ();
     791                 :        5452 :       if (mappings.size () == substitutions.size ())
     792                 :             :         {
     793                 :        5151 :           mappings.get_argument_at (i, &arg);
     794                 :             :         }
     795                 :             :       else
     796                 :             :         {
     797                 :         301 :           if (subst.needs_substitution ())
     798                 :             :             {
     799                 :             :               // get from passed in mappings
     800                 :         231 :               mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
     801                 :             :             }
     802                 :             :           else
     803                 :             :             {
     804                 :             :               // we should already have this somewhere
     805                 :          70 :               used_arguments.get_argument_for_symbol (subst.get_param_ty (),
     806                 :             :                                                       &arg);
     807                 :             :             }
     808                 :             :         }
     809                 :             : 
     810                 :        5452 :       bool ok = !arg.is_error ();
     811                 :        5452 :       if (ok)
     812                 :             :         {
     813                 :        5403 :           SubstitutionArg adjusted (&subst, arg.get_tyty ());
     814                 :        5403 :           resolved_mappings.push_back (std::move (adjusted));
     815                 :             :         }
     816                 :             :     }
     817                 :             : 
     818                 :        4438 :   if (resolved_mappings.empty ())
     819                 :           0 :     return SubstitutionArgumentMappings::error ();
     820                 :             : 
     821                 :        4438 :   return SubstitutionArgumentMappings (resolved_mappings,
     822                 :        4438 :                                        mappings.get_binding_args (),
     823                 :             :                                        mappings.get_regions (),
     824                 :             :                                        mappings.get_locus (),
     825                 :        4438 :                                        mappings.get_subst_cb (),
     826                 :        8876 :                                        mappings.trait_item_mode ());
     827                 :        4438 : }
     828                 :             : 
     829                 :             : bool
     830                 :           0 : SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
     831                 :             : {
     832                 :           0 :   std::vector<SubstitutionArg> resolved_mappings;
     833                 :           0 :   for (size_t i = 0; i < substitutions.size (); i++)
     834                 :             :     {
     835                 :           0 :       auto &subst = substitutions.at (i);
     836                 :             : 
     837                 :           0 :       SubstitutionArg arg = SubstitutionArg::error ();
     838                 :           0 :       if (mappings.size () == substitutions.size ())
     839                 :             :         {
     840                 :           0 :           mappings.get_argument_at (i, &arg);
     841                 :             :         }
     842                 :             :       else
     843                 :             :         {
     844                 :           0 :           if (subst.needs_substitution ())
     845                 :             :             {
     846                 :             :               // get from passed in mappings
     847                 :           0 :               mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
     848                 :             :             }
     849                 :             :           else
     850                 :             :             {
     851                 :             :               // we should already have this somewhere
     852                 :           0 :               used_arguments.get_argument_for_symbol (subst.get_param_ty (),
     853                 :             :                                                       &arg);
     854                 :             :             }
     855                 :             :         }
     856                 :             : 
     857                 :           0 :       bool ok = !arg.is_error ();
     858                 :           0 :       if (ok)
     859                 :             :         {
     860                 :           0 :           SubstitutionArg adjusted (&subst, arg.get_tyty ());
     861                 :           0 :           resolved_mappings.push_back (std::move (adjusted));
     862                 :             :         }
     863                 :             :     }
     864                 :             : 
     865                 :           0 :   return !resolved_mappings.empty ();
     866                 :           0 : }
     867                 :             : 
     868                 :             : // this function assumes that the mappings being passed are for the same type as
     869                 :             : // this new substitution reference so ordering matters here
     870                 :             : SubstitutionArgumentMappings
     871                 :          63 : SubstitutionRef::solve_mappings_from_receiver_for_self (
     872                 :             :   SubstitutionArgumentMappings &mappings) const
     873                 :             : {
     874                 :          63 :   std::vector<SubstitutionArg> resolved_mappings;
     875                 :             : 
     876                 :          63 :   rust_assert (mappings.size () == get_num_substitutions ());
     877                 :         126 :   for (size_t i = 0; i < get_num_substitutions (); i++)
     878                 :             :     {
     879                 :          63 :       const SubstitutionParamMapping &param_mapping = substitutions.at (i);
     880                 :          63 :       SubstitutionArg &arg = mappings.get_mappings ().at (i);
     881                 :             : 
     882                 :          63 :       if (param_mapping.needs_substitution ())
     883                 :             :         {
     884                 :          63 :           SubstitutionArg adjusted (&param_mapping, arg.get_tyty ());
     885                 :          63 :           resolved_mappings.push_back (std::move (adjusted));
     886                 :             :         }
     887                 :             :     }
     888                 :             : 
     889                 :          63 :   return SubstitutionArgumentMappings (resolved_mappings,
     890                 :          63 :                                        mappings.get_binding_args (),
     891                 :             :                                        mappings.get_regions (),
     892                 :         126 :                                        mappings.get_locus ());
     893                 :          63 : }
     894                 :             : 
     895                 :             : void
     896                 :        1325 : SubstitutionRef::prepare_higher_ranked_bounds ()
     897                 :             : {
     898                 :        2444 :   for (const auto &subst : get_substs ())
     899                 :             :     {
     900                 :        1119 :       const TyTy::ParamType *pty = subst.get_param_ty ();
     901                 :        2529 :       for (const auto &bound : pty->get_specified_bounds ())
     902                 :             :         {
     903                 :        1410 :           const auto ref = bound.get ();
     904                 :        1410 :           ref->clear_associated_type_projections ();
     905                 :             :         }
     906                 :             :     }
     907                 :        1325 : }
     908                 :             : 
     909                 :             : bool
     910                 :        8310 : SubstitutionRef::monomorphize ()
     911                 :             : {
     912                 :       13059 :   for (const auto &subst : get_substs ())
     913                 :             :     {
     914                 :        4749 :       const TyTy::ParamType *pty = subst.get_param_ty ();
     915                 :             : 
     916                 :        4749 :       if (!pty->can_resolve ())
     917                 :          64 :         continue;
     918                 :             : 
     919                 :        4685 :       const TyTy::BaseType *binding = pty->resolve ();
     920                 :        4685 :       if (binding->get_kind () == TyTy::TypeKind::PARAM)
     921                 :         801 :         continue;
     922                 :             : 
     923                 :        8317 :       for (const auto &bound : pty->get_specified_bounds ())
     924                 :             :         {
     925                 :        4433 :           bool ambigious = false;
     926                 :        4433 :           auto associated
     927                 :        4433 :             = Resolver::lookup_associated_impl_block (bound, binding,
     928                 :             :                                                       &ambigious);
     929                 :        4433 :           if (associated == nullptr && ambigious)
     930                 :             :             {
     931                 :             :               // go for the first one? or error out?
     932                 :           0 :               auto &mappings = *Analysis::Mappings::get ();
     933                 :           0 :               const auto &type_param = subst.get_generic_param ();
     934                 :           0 :               const auto *trait_ref = bound.get ();
     935                 :             : 
     936                 :           0 :               rich_location r (line_table, type_param.get_locus ());
     937                 :           0 :               r.add_range (bound.get_locus ());
     938                 :           0 :               r.add_range (mappings.lookup_location (binding->get_ref ()));
     939                 :             : 
     940                 :           0 :               rust_error_at (r, "ambiguous type bound for trait %s and type %s",
     941                 :           0 :                              trait_ref->get_name ().c_str (),
     942                 :           0 :                              binding->get_name ().c_str ());
     943                 :           0 :               return false;
     944                 :           0 :             }
     945                 :             : 
     946                 :             :           if (associated != nullptr)
     947                 :             :             {
     948                 :         771 :               associated->setup_associated_types (binding, bound);
     949                 :             :             }
     950                 :             :         }
     951                 :             :     }
     952                 :             : 
     953                 :             :   return true;
     954                 :             : }
     955                 :             : 
     956                 :             : } // namespace TyTy
     957                 :             : } // namespace Rust
        

Generated by: LCOV version 2.0-1

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.