LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty-subst.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 86.0 % 522 449
Test Date: 2025-11-22 14:42:49 Functions: 87.3 % 79 69
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2020-2025 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #include "rust-tyty-subst.h"
      20                 :             : 
      21                 :             : #include "rust-hir-generic-param.h"
      22                 :             : #include "rust-system.h"
      23                 :             : #include "rust-tyty.h"
      24                 :             : #include "rust-hir-type-check.h"
      25                 :             : #include "rust-substitution-mapper.h"
      26                 :             : #include "rust-hir-type-check-type.h"
      27                 :             : #include "rust-hir-type-check-expr.h"
      28                 :             : #include "rust-compile-base.h"
      29                 :             : #include "rust-type-util.h"
      30                 :             : #include "tree.h"
      31                 :             : 
      32                 :             : namespace Rust {
      33                 :             : namespace TyTy {
      34                 :             : 
      35                 :    83592882 : SubstitutionParamMapping::SubstitutionParamMapping (HIR::GenericParam &generic,
      36                 :    83592882 :                                                     BaseGeneric *param)
      37                 :    83592882 :   : generic (generic), param (param)
      38                 :    83592882 : {}
      39                 :             : 
      40                 :    93348801 : SubstitutionParamMapping::SubstitutionParamMapping (
      41                 :    93348801 :   const SubstitutionParamMapping &other)
      42                 :    93348801 :   : generic (other.generic), param (other.param)
      43                 :    93348801 : {}
      44                 :             : 
      45                 :             : std::string
      46                 :      505431 : SubstitutionParamMapping::as_string () const
      47                 :             : {
      48                 :      505431 :   if (param == nullptr)
      49                 :           0 :     return "nullptr";
      50                 :             : 
      51                 :      505431 :   return param->get_name ();
      52                 :             : }
      53                 :             : 
      54                 :             : SubstitutionParamMapping
      55                 :    83579507 : SubstitutionParamMapping::clone () const
      56                 :             : {
      57                 :    83579507 :   return SubstitutionParamMapping (generic, static_cast<BaseGeneric *> (
      58                 :    83579507 :                                               param->clone ()));
      59                 :             : }
      60                 :             : 
      61                 :             : BaseGeneric *
      62                 :      201061 : SubstitutionParamMapping::get_param_ty ()
      63                 :             : {
      64                 :      201061 :   return param;
      65                 :             : }
      66                 :             : 
      67                 :             : const BaseGeneric *
      68                 :    75843285 : SubstitutionParamMapping::get_param_ty () const
      69                 :             : {
      70                 :    75843285 :   return param;
      71                 :             : }
      72                 :             : 
      73                 :             : HIR::GenericParam &
      74                 :       16883 : SubstitutionParamMapping::get_generic_param ()
      75                 :             : {
      76                 :       16883 :   return generic;
      77                 :             : }
      78                 :             : 
      79                 :             : const HIR::GenericParam &
      80                 :        9874 : SubstitutionParamMapping::get_generic_param () const
      81                 :             : {
      82                 :        9874 :   return generic;
      83                 :             : }
      84                 :             : 
      85                 :             : bool
      86                 :      110161 : SubstitutionParamMapping::needs_substitution () const
      87                 :             : {
      88                 :      110161 :   return !(get_param_ty ()->is_concrete ());
      89                 :             : }
      90                 :             : 
      91                 :             : Identifier
      92                 :        2366 : SubstitutionParamMapping::get_type_representation () const
      93                 :             : {
      94                 :        4732 :   return param->get_symbol ();
      95                 :             : }
      96                 :             : 
      97                 :             : location_t
      98                 :         993 : SubstitutionParamMapping::get_param_locus () const
      99                 :             : {
     100                 :         993 :   return generic.get_locus ();
     101                 :             : }
     102                 :             : 
     103                 :             : bool
     104                 :       23619 : SubstitutionParamMapping::param_has_default_ty () const
     105                 :             : {
     106                 :       23619 :   if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
     107                 :             :     {
     108                 :       23371 :       const auto &type_param = static_cast<const HIR::TypeParam &> (generic);
     109                 :       23371 :       return type_param.has_type ();
     110                 :             :     }
     111                 :             : 
     112                 :         248 :   rust_assert (generic.get_kind () == HIR::GenericParam::GenericKind::CONST);
     113                 :         248 :   const auto &const_param
     114                 :             :     = static_cast<const HIR::ConstGenericParam &> (generic);
     115                 :         248 :   return const_param.has_default_expression ();
     116                 :             : }
     117                 :             : 
     118                 :             : BaseType *
     119                 :        1137 : SubstitutionParamMapping::get_default_ty () const
     120                 :             : {
     121                 :        1137 :   if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
     122                 :             :     {
     123                 :        1132 :       const auto &type_param = static_cast<const HIR::TypeParam &> (generic);
     124                 :        1132 :       TyVar var (type_param.get_type_mappings ().get_hirid ());
     125                 :        1132 :       return var.get_tyty ();
     126                 :             :     }
     127                 :             : 
     128                 :           5 :   rust_assert (generic.get_kind () == HIR::GenericParam::GenericKind::CONST);
     129                 :           5 :   const auto &const_param
     130                 :             :     = static_cast<const HIR::ConstGenericParam &> (generic);
     131                 :           5 :   rust_assert (const_param.has_default_expression ());
     132                 :             : 
     133                 :           5 :   const auto &expr = const_param.get_default_expression ();
     134                 :           5 :   TyVar var (expr.get_mappings ().get_hirid ());
     135                 :           5 :   return var.get_tyty ();
     136                 :             : }
     137                 :             : 
     138                 :             : bool
     139                 :           0 : SubstitutionParamMapping::need_substitution () const
     140                 :             : {
     141                 :           0 :   if (!param->can_resolve ())
     142                 :             :     return true;
     143                 :             : 
     144                 :           0 :   auto resolved = param->resolve ();
     145                 :           0 :   return !resolved->is_concrete ();
     146                 :             : }
     147                 :             : 
     148                 :             : bool
     149                 :       37442 : SubstitutionParamMapping::fill_param_ty (
     150                 :             :   SubstitutionArgumentMappings &subst_mappings, location_t locus,
     151                 :             :   bool needs_bounds_check)
     152                 :             : {
     153                 :       37442 :   SubstitutionArg arg = SubstitutionArg::error ();
     154                 :       37442 :   bool ok = subst_mappings.get_argument_for_symbol (get_param_ty (), &arg);
     155                 :       37442 :   if (!ok)
     156                 :             :     return true;
     157                 :             : 
     158                 :       37442 :   TyTy::BaseType &type = *arg.get_tyty ();
     159                 :       37442 :   if (type.get_kind () == TyTy::TypeKind::INFER)
     160                 :             :     {
     161                 :       12107 :       type.inherit_bounds (*param);
     162                 :             :     }
     163                 :             : 
     164                 :       37442 :   if (type.get_kind () == TypeKind::PARAM)
     165                 :             :     {
     166                 :        7303 :       param = static_cast<BaseGeneric *> (type.clone ());
     167                 :             :     }
     168                 :       30139 :   else if (type.get_kind () == TyTy::TypeKind::CONST)
     169                 :             :     {
     170                 :         203 :       rust_assert (param->get_kind () == TyTy::TypeKind::CONST);
     171                 :         203 :       auto *const_type = type.as_const_type ();
     172                 :         203 :       if (const_type->const_kind () == TyTy::BaseConstType::ConstKind::Decl)
     173                 :          21 :         param = static_cast<BaseGeneric *> (type.clone ());
     174                 :             :       else
     175                 :         182 :         param->set_ty_ref (type.get_ref ());
     176                 :             :     }
     177                 :       29936 :   else if (param->get_kind () == TypeKind::PARAM)
     178                 :             :     {
     179                 :       29936 :       auto &p = *static_cast<TyTy::ParamType *> (param);
     180                 :             : 
     181                 :             :       // check the substitution is compatible with bounds
     182                 :       29936 :       rust_debug_loc (locus,
     183                 :             :                       "fill_param_ty bounds_compatible: param %s type %s",
     184                 :       59872 :                       param->get_name ().c_str (), type.get_name ().c_str ());
     185                 :       29936 :       if (needs_bounds_check && !p.is_implicit_self_trait ())
     186                 :             :         {
     187                 :       14885 :           if (!param->bounds_compatible (type, locus, true))
     188                 :             :             return false;
     189                 :             :         }
     190                 :             : 
     191                 :             :       // recursively pass this down to all HRTB's
     192                 :       66702 :       for (auto &bound : param->get_specified_bounds ())
     193                 :       36772 :         bound.handle_substitions (subst_mappings);
     194                 :             : 
     195                 :       29930 :       param->set_ty_ref (type.get_ref ());
     196                 :       29930 :       subst_mappings.on_param_subst (p, arg);
     197                 :             :     }
     198                 :             : 
     199                 :             :   return true;
     200                 :             : }
     201                 :             : 
     202                 :             : void
     203                 :        4487 : SubstitutionParamMapping::override_context ()
     204                 :             : {
     205                 :        4487 :   if (!param->can_resolve ())
     206                 :             :     return;
     207                 :             : 
     208                 :        4473 :   auto &mappings = Analysis::Mappings::get ();
     209                 :        4473 :   auto context = Resolver::TypeCheckContext::get ();
     210                 :             : 
     211                 :        4473 :   context->insert_type (Analysis::NodeMapping (mappings.get_current_crate (),
     212                 :             :                                                UNKNOWN_NODEID,
     213                 :        4473 :                                                param->get_ref (),
     214                 :        4473 :                                                UNKNOWN_LOCAL_DEFID),
     215                 :        4473 :                         param->resolve ());
     216                 :             : }
     217                 :             : 
     218                 :    75861848 : SubstitutionArg::SubstitutionArg (const SubstitutionParamMapping *param,
     219                 :    75861848 :                                   BaseType *argument)
     220                 :    75861848 :   : param (param), argument (argument)
     221                 :             : {
     222                 :    75861848 :   if (param != nullptr)
     223                 :    75692805 :     original_param = param->get_param_ty ();
     224                 :    75861848 : }
     225                 :             : 
     226                 :   306029576 : SubstitutionArg::SubstitutionArg (const SubstitutionArg &other)
     227                 :   306029576 :   : param (other.param), original_param (other.original_param),
     228                 :   306029576 :     argument (other.argument)
     229                 :   306029576 : {}
     230                 :             : 
     231                 :             : SubstitutionArg &
     232                 :      161655 : SubstitutionArg::operator= (const SubstitutionArg &other)
     233                 :             : {
     234                 :      161655 :   param = other.param;
     235                 :      161655 :   argument = other.argument;
     236                 :      161655 :   original_param = other.original_param;
     237                 :             : 
     238                 :      161655 :   return *this;
     239                 :             : }
     240                 :             : 
     241                 :             : BaseType *
     242                 :    78380860 : SubstitutionArg::get_tyty () const
     243                 :             : {
     244                 :    78380860 :   return argument;
     245                 :             : }
     246                 :             : 
     247                 :             : const SubstitutionParamMapping *
     248                 :        8343 : SubstitutionArg::get_param_mapping () const
     249                 :             : {
     250                 :        8343 :   return param;
     251                 :             : }
     252                 :             : 
     253                 :             : const BaseGeneric *
     254                 :      181293 : SubstitutionArg::get_param_ty () const
     255                 :             : {
     256                 :      181293 :   return original_param;
     257                 :             : }
     258                 :             : 
     259                 :             : SubstitutionArg
     260                 :      169043 : SubstitutionArg::error ()
     261                 :             : {
     262                 :      169043 :   return SubstitutionArg (nullptr, nullptr);
     263                 :             : }
     264                 :             : 
     265                 :             : bool
     266                 :       63425 : SubstitutionArg::is_error () const
     267                 :             : {
     268                 :       63425 :   return param == nullptr || argument == nullptr;
     269                 :             : }
     270                 :             : 
     271                 :             : bool
     272                 :           0 : SubstitutionArg::is_conrete () const
     273                 :             : {
     274                 :           0 :   if (argument == nullptr)
     275                 :             :     return false;
     276                 :             : 
     277                 :           0 :   if (argument->get_kind () == TyTy::TypeKind::PARAM)
     278                 :             :     return false;
     279                 :             : 
     280                 :           0 :   return argument->is_concrete ();
     281                 :             : }
     282                 :             : 
     283                 :             : std::string
     284                 :           0 : SubstitutionArg::as_string () const
     285                 :             : {
     286                 :           0 :   return original_param->as_string ()
     287                 :           0 :          + (argument != nullptr ? ":" + argument->as_string () : "");
     288                 :             : }
     289                 :             : 
     290                 :             : const RegionParamList &
     291                 :    73983681 : SubstitutionArgumentMappings::get_regions () const
     292                 :             : {
     293                 :    73983681 :   return regions;
     294                 :             : }
     295                 :             : 
     296                 :             : RegionParamList &
     297                 :        2046 : SubstitutionArgumentMappings::get_mut_regions ()
     298                 :             : {
     299                 :        2046 :   return regions;
     300                 :             : }
     301                 :             : 
     302                 :             : // SubstitutionArgumentMappings
     303                 :             : 
     304                 :   148148773 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
     305                 :             :   std::vector<SubstitutionArg> mappings,
     306                 :             :   std::map<std::string, BaseType *> binding_args, RegionParamList regions,
     307                 :             :   location_t locus, ParamSubstCb param_subst_cb, bool trait_item_flag,
     308                 :   148148773 :   bool error_flag)
     309                 :   148148773 :   : mappings (std::move (mappings)), binding_args (binding_args),
     310                 :   148148773 :     regions (regions), locus (locus), param_subst_cb (param_subst_cb),
     311                 :   148148773 :     trait_item_flag (trait_item_flag), error_flag (error_flag)
     312                 :   148148773 : {}
     313                 :             : 
     314                 :    74525711 : SubstitutionArgumentMappings::SubstitutionArgumentMappings (
     315                 :    74525711 :   const SubstitutionArgumentMappings &other)
     316                 :    74525711 :   : mappings (other.mappings), binding_args (other.binding_args),
     317                 :    74525711 :     regions (other.regions), locus (other.locus), param_subst_cb (nullptr),
     318                 :    74525711 :     trait_item_flag (other.trait_item_flag), error_flag (other.error_flag)
     319                 :    74525711 : {}
     320                 :             : 
     321                 :             : SubstitutionArgumentMappings &
     322                 :       41765 : SubstitutionArgumentMappings::operator= (
     323                 :             :   const SubstitutionArgumentMappings &other)
     324                 :             : {
     325                 :       41765 :   mappings = other.mappings;
     326                 :       41765 :   binding_args = other.binding_args;
     327                 :       41765 :   regions = other.regions;
     328                 :       41765 :   locus = other.locus;
     329                 :       41765 :   param_subst_cb = nullptr;
     330                 :       41765 :   trait_item_flag = other.trait_item_flag;
     331                 :       41765 :   error_flag = other.error_flag;
     332                 :             : 
     333                 :       41765 :   return *this;
     334                 :             : }
     335                 :             : 
     336                 :             : SubstitutionArgumentMappings
     337                 :       46308 : SubstitutionArgumentMappings::error ()
     338                 :             : {
     339                 :       92616 :   return SubstitutionArgumentMappings ({}, {}, 0, UNDEF_LOCATION, nullptr,
     340                 :       46308 :                                        false, true);
     341                 :             : }
     342                 :             : 
     343                 :             : SubstitutionArgumentMappings
     344                 :    74126340 : SubstitutionArgumentMappings::empty (size_t num_regions)
     345                 :             : {
     346                 :   148252680 :   return SubstitutionArgumentMappings ({}, {}, num_regions, UNDEF_LOCATION,
     347                 :    74126340 :                                        nullptr, false, false);
     348                 :             : }
     349                 :             : 
     350                 :             : bool
     351                 :       34245 : SubstitutionArgumentMappings::is_error () const
     352                 :             : {
     353                 :       34245 :   return error_flag;
     354                 :             : }
     355                 :             : 
     356                 :             : bool
     357                 :      153118 : SubstitutionArgumentMappings::get_argument_for_symbol (
     358                 :             :   const BaseGeneric *param_to_find, SubstitutionArg *argument) const
     359                 :             : {
     360                 :      196434 :   for (const auto &mapping : mappings)
     361                 :             :     {
     362                 :      181293 :       const auto *p = mapping.get_param_ty ();
     363                 :      181293 :       if (p->get_symbol () == param_to_find->get_symbol ())
     364                 :             :         {
     365                 :      137977 :           *argument = mapping;
     366                 :      137977 :           return true;
     367                 :             :         }
     368                 :             :     }
     369                 :             :   return false;
     370                 :             : }
     371                 :             : tl::optional<size_t>
     372                 :           0 : SubstitutionArgumentMappings::find_symbol (const ParamType &param_to_find) const
     373                 :             : {
     374                 :           0 :   auto it = std::find_if (mappings.begin (), mappings.end (),
     375                 :           0 :                           [param_to_find] (const SubstitutionArg &arg) {
     376                 :           0 :                             return arg.get_param_ty ()->get_symbol ()
     377                 :           0 :                                    == param_to_find.get_symbol ();
     378                 :             :                           });
     379                 :           0 :   if (it == mappings.end ())
     380                 :           0 :     return tl::nullopt;
     381                 :           0 :   return std::distance (mappings.begin (), it);
     382                 :             : }
     383                 :             : 
     384                 :             : bool
     385                 :       15925 : SubstitutionArgumentMappings::get_argument_at (size_t index,
     386                 :             :                                                SubstitutionArg *argument)
     387                 :             : {
     388                 :       15925 :   if (index > mappings.size ())
     389                 :             :     return false;
     390                 :             : 
     391                 :       15925 :   *argument = mappings.at (index);
     392                 :       15925 :   return true;
     393                 :             : }
     394                 :             : 
     395                 :             : bool
     396                 :           0 : SubstitutionArgumentMappings::is_concrete () const
     397                 :             : {
     398                 :           0 :   for (auto &mapping : mappings)
     399                 :             :     {
     400                 :           0 :       if (!mapping.is_conrete ())
     401                 :           0 :         return false;
     402                 :             :     }
     403                 :             :   return true;
     404                 :             : }
     405                 :             : 
     406                 :             : location_t
     407                 :    73991286 : SubstitutionArgumentMappings::get_locus () const
     408                 :             : {
     409                 :    73991286 :   return locus;
     410                 :             : }
     411                 :             : 
     412                 :             : size_t
     413                 :       43115 : SubstitutionArgumentMappings::size () const
     414                 :             : {
     415                 :       43115 :   return mappings.size ();
     416                 :             : }
     417                 :             : 
     418                 :             : bool
     419                 :       15632 : SubstitutionArgumentMappings::is_empty () const
     420                 :             : {
     421                 :       15632 :   return size () == 0;
     422                 :             : }
     423                 :             : 
     424                 :             : std::vector<SubstitutionArg> &
     425                 :       55718 : SubstitutionArgumentMappings::get_mappings ()
     426                 :             : {
     427                 :       55718 :   return mappings;
     428                 :             : }
     429                 :             : 
     430                 :             : const std::vector<SubstitutionArg> &
     431                 :   299123523 : SubstitutionArgumentMappings::get_mappings () const
     432                 :             : {
     433                 :   299123523 :   return mappings;
     434                 :             : }
     435                 :             : 
     436                 :             : std::map<std::string, BaseType *> &
     437                 :       61253 : SubstitutionArgumentMappings::get_binding_args ()
     438                 :             : {
     439                 :       61253 :   return binding_args;
     440                 :             : }
     441                 :             : 
     442                 :             : const std::map<std::string, BaseType *> &
     443                 :           0 : SubstitutionArgumentMappings::get_binding_args () const
     444                 :             : {
     445                 :           0 :   return binding_args;
     446                 :             : }
     447                 :             : 
     448                 :             : std::string
     449                 :           0 : SubstitutionArgumentMappings::as_string () const
     450                 :             : {
     451                 :           0 :   std::string buffer;
     452                 :           0 :   for (auto &mapping : mappings)
     453                 :             :     {
     454                 :           0 :       buffer += mapping.as_string () + ", ";
     455                 :             :     }
     456                 :           0 :   return "<" + buffer + ">";
     457                 :           0 : }
     458                 :             : 
     459                 :             : void
     460                 :       74841 : SubstitutionArgumentMappings::on_param_subst (const ParamType &p,
     461                 :             :                                               const SubstitutionArg &a) const
     462                 :             : {
     463                 :       74841 :   if (param_subst_cb == nullptr)
     464                 :             :     return;
     465                 :             : 
     466                 :         575 :   param_subst_cb (p, a);
     467                 :             : }
     468                 :             : 
     469                 :             : ParamSubstCb
     470                 :       19834 : SubstitutionArgumentMappings::get_subst_cb () const
     471                 :             : {
     472                 :       19834 :   return param_subst_cb;
     473                 :             : }
     474                 :             : 
     475                 :             : bool
     476                 :       14453 : SubstitutionArgumentMappings::trait_item_mode () const
     477                 :             : {
     478                 :       14453 :   return trait_item_flag;
     479                 :             : }
     480                 :             : 
     481                 :             : // SubstitutionRef
     482                 :             : 
     483                 :    74210952 : SubstitutionRef::SubstitutionRef (
     484                 :             :   std::vector<SubstitutionParamMapping> substitutions,
     485                 :    74210952 :   SubstitutionArgumentMappings arguments, RegionConstraints region_constraints)
     486                 :    74210952 :   : substitutions (substitutions), used_arguments (arguments),
     487                 :   148421904 :     region_constraints (region_constraints)
     488                 :    74210952 : {}
     489                 :             : 
     490                 :             : bool
     491                 :      184716 : SubstitutionRef::has_substitutions () const
     492                 :             : {
     493                 :      184716 :   return substitutions.size () > 0;
     494                 :             : }
     495                 :             : 
     496                 :             : std::string
     497                 :     1837831 : SubstitutionRef::subst_as_string () const
     498                 :             : {
     499                 :     1837831 :   std::string buffer;
     500                 :     2343262 :   for (size_t i = 0; i < substitutions.size (); i++)
     501                 :             :     {
     502                 :      505431 :       const SubstitutionParamMapping &sub = substitutions.at (i);
     503                 :     1010862 :       buffer += sub.as_string ();
     504                 :             : 
     505                 :      505431 :       if ((i + 1) < substitutions.size ())
     506                 :       58200 :         buffer += ", ";
     507                 :             :     }
     508                 :             : 
     509                 :     2285062 :   return buffer.empty () ? "" : "<" + buffer + ">";
     510                 :     1837831 : }
     511                 :             : 
     512                 :             : bool
     513                 :          73 : SubstitutionRef::supports_associated_bindings () const
     514                 :             : {
     515                 :          73 :   return get_num_associated_bindings () > 0;
     516                 :             : }
     517                 :             : 
     518                 :             : size_t
     519                 :           1 : SubstitutionRef::get_num_associated_bindings () const
     520                 :             : {
     521                 :           1 :   return 0;
     522                 :             : }
     523                 :             : 
     524                 :             : TypeBoundPredicateItem
     525                 :           0 : SubstitutionRef::lookup_associated_type (const std::string &search)
     526                 :             : {
     527                 :           0 :   return TypeBoundPredicateItem::error ();
     528                 :             : }
     529                 :             : 
     530                 :             : size_t
     531                 :       95052 : SubstitutionRef::get_num_substitutions () const
     532                 :             : {
     533                 :       95052 :   return substitutions.size ();
     534                 :             : }
     535                 :             : size_t
     536                 :         135 : SubstitutionRef::get_num_lifetime_params () const
     537                 :             : {
     538                 :         135 :   return used_arguments.get_regions ().size ();
     539                 :             : }
     540                 :             : size_t
     541                 :         538 : SubstitutionRef::get_num_type_params () const
     542                 :             : {
     543                 :         538 :   return get_num_substitutions ();
     544                 :             : }
     545                 :             : 
     546                 :             : std::vector<SubstitutionParamMapping> &
     547                 :      130342 : SubstitutionRef::get_substs ()
     548                 :             : {
     549                 :      130342 :   return substitutions;
     550                 :             : }
     551                 :             : 
     552                 :             : const std::vector<SubstitutionParamMapping> &
     553                 :    73961791 : SubstitutionRef::get_substs () const
     554                 :             : {
     555                 :    73961791 :   return substitutions;
     556                 :             : }
     557                 :             : 
     558                 :             : std::vector<SubstitutionParamMapping>
     559                 :      172094 : SubstitutionRef::clone_substs () const
     560                 :             : {
     561                 :      172094 :   std::vector<SubstitutionParamMapping> clone;
     562                 :      172094 :   clone.reserve (substitutions.size ());
     563                 :             : 
     564                 :      240542 :   for (auto &sub : substitutions)
     565                 :       68448 :     clone.push_back (sub.clone ());
     566                 :             : 
     567                 :      172094 :   return clone;
     568                 :             : }
     569                 :             : 
     570                 :             : void
     571                 :        3964 : SubstitutionRef::override_context ()
     572                 :             : {
     573                 :        8451 :   for (auto &sub : substitutions)
     574                 :             :     {
     575                 :        4487 :       sub.override_context ();
     576                 :             :     }
     577                 :        3964 : }
     578                 :             : 
     579                 :             : bool
     580                 :      156582 : SubstitutionRef::needs_substitution () const
     581                 :             : {
     582                 :      156582 :   return std::any_of (substitutions.begin (), substitutions.end (),
     583                 :             :                       std::mem_fn (
     584                 :      156582 :                         &SubstitutionParamMapping::needs_substitution));
     585                 :             : }
     586                 :             : 
     587                 :             : bool
     588                 :          63 : SubstitutionRef::was_substituted () const
     589                 :             : {
     590                 :          63 :   return !needs_substitution ();
     591                 :             : }
     592                 :             : 
     593                 :             : SubstitutionArgumentMappings &
     594                 :       54596 : SubstitutionRef::get_substitution_arguments ()
     595                 :             : {
     596                 :       54596 :   return used_arguments;
     597                 :             : }
     598                 :             : 
     599                 :             : const SubstitutionArgumentMappings &
     600                 :       24157 : SubstitutionRef::get_substitution_arguments () const
     601                 :             : {
     602                 :       24157 :   return used_arguments;
     603                 :             : }
     604                 :             : 
     605                 :             : size_t
     606                 :        9228 : SubstitutionRef::num_required_substitutions () const
     607                 :             : {
     608                 :        9228 :   size_t n = 0;
     609                 :       20789 :   for (auto &p : substitutions)
     610                 :             :     {
     611                 :       11561 :       if (p.needs_substitution ())
     612                 :       11234 :         n++;
     613                 :             :     }
     614                 :        9228 :   return n;
     615                 :             : }
     616                 :             : 
     617                 :             : size_t
     618                 :       18466 : SubstitutionRef::min_required_substitutions () const
     619                 :             : {
     620                 :       18466 :   size_t n = 0;
     621                 :       41602 :   for (auto &p : substitutions)
     622                 :             :     {
     623                 :       23136 :       if (p.needs_substitution () && !p.param_has_default_ty ())
     624                 :       19331 :         n++;
     625                 :             :     }
     626                 :       18466 :   return n;
     627                 :             : }
     628                 :             : 
     629                 :             : const SubstitutionArgumentMappings &
     630                 :       13999 : SubstitutionRef::get_used_arguments () const
     631                 :             : {
     632                 :       13999 :   return used_arguments;
     633                 :             : }
     634                 :             : 
     635                 :             : tl::optional<SubstitutionArg>
     636                 :         168 : SubstitutionRef::get_arg_at (size_t i) const
     637                 :             : {
     638                 :         168 :   auto param_ty = get_substs ().at (i).get_param_ty ();
     639                 :         168 :   SubstitutionArg arg = SubstitutionArg::error ();
     640                 :         168 :   get_used_arguments ().get_argument_for_symbol (param_ty, &arg);
     641                 :         168 :   if (arg.is_error ())
     642                 :           8 :     return tl::nullopt;
     643                 :         160 :   return arg;
     644                 :             : }
     645                 :             : 
     646                 :             : const RegionConstraints &
     647                 :      170818 : SubstitutionRef::get_region_constraints () const
     648                 :             : {
     649                 :      170818 :   return region_constraints;
     650                 :             : }
     651                 :             : 
     652                 :             : SubstitutionArgumentMappings
     653                 :        9239 : SubstitutionRef::get_mappings_from_generic_args (
     654                 :             :   HIR::GenericArgs &args, const std::vector<Region> &regions)
     655                 :             : {
     656                 :        9239 :   std::map<std::string, BaseType *> binding_arguments;
     657                 :        9239 :   if (args.get_binding_args ().size () > 0)
     658                 :             :     {
     659                 :          73 :       if (supports_associated_bindings ())
     660                 :             :         {
     661                 :          72 :           if (args.get_binding_args ().size () > get_num_associated_bindings ())
     662                 :             :             {
     663                 :           0 :               rich_location r (line_table, args.get_locus ());
     664                 :           0 :               rust_error_at (r,
     665                 :             :                              "generic item takes at most %lu type binding "
     666                 :             :                              "arguments but %lu were supplied",
     667                 :           0 :                              (unsigned long) get_num_associated_bindings (),
     668                 :           0 :                              (unsigned long) args.get_binding_args ().size ());
     669                 :           0 :               return SubstitutionArgumentMappings::error ();
     670                 :           0 :             }
     671                 :             : 
     672                 :         144 :           for (auto &binding : args.get_binding_args ())
     673                 :             :             {
     674                 :          72 :               BaseType *resolved
     675                 :          72 :                 = Resolver::TypeCheckType::Resolve (binding.get_type ());
     676                 :          72 :               if (resolved == nullptr
     677                 :          72 :                   || resolved->get_kind () == TyTy::TypeKind::ERROR)
     678                 :             :                 {
     679                 :           0 :                   return SubstitutionArgumentMappings::error ();
     680                 :             :                 }
     681                 :             : 
     682                 :             :               // resolve to relevant binding
     683                 :          72 :               auto binding_item = lookup_associated_type (
     684                 :          72 :                 binding.get_identifier ().as_string ());
     685                 :          72 :               if (binding_item.is_error ())
     686                 :             :                 {
     687                 :           0 :                   rust_error_at (
     688                 :             :                     binding.get_locus (), "unknown associated type binding: %s",
     689                 :           0 :                     binding.get_identifier ().as_string ().c_str ());
     690                 :           0 :                   return SubstitutionArgumentMappings::error ();
     691                 :             :                 }
     692                 :             : 
     693                 :          72 :               binding_arguments[binding.get_identifier ().as_string ()]
     694                 :          72 :                 = resolved;
     695                 :          72 :             }
     696                 :             :         }
     697                 :             :       else
     698                 :             :         {
     699                 :           1 :           rich_location r (line_table, args.get_locus ());
     700                 :           3 :           for (auto &binding : args.get_binding_args ())
     701                 :           2 :             r.add_range (binding.get_locus ());
     702                 :             : 
     703                 :           1 :           rust_error_at (r, ErrorCode::E0229,
     704                 :             :                          "associated type bindings are not allowed here");
     705                 :           1 :           return SubstitutionArgumentMappings::error ();
     706                 :           1 :         }
     707                 :             :     }
     708                 :             : 
     709                 :             :   // for inherited arguments
     710                 :        9238 :   size_t offs = used_arguments.size ();
     711                 :        9238 :   size_t total_arguments
     712                 :        9238 :     = args.get_type_args ().size () + args.get_const_args ().size () + offs;
     713                 :        9238 :   if (total_arguments > substitutions.size ())
     714                 :             :     {
     715                 :           3 :       rich_location r (line_table, args.get_locus ());
     716                 :           3 :       if (!substitutions.empty ())
     717                 :             :         {
     718                 :           2 :           const auto &subst = substitutions.front ();
     719                 :           2 :           const auto &generic = subst.get_generic_param ();
     720                 :           2 :           r.add_range (generic.get_locus ());
     721                 :             :         }
     722                 :             : 
     723                 :           6 :       rust_error_at (
     724                 :             :         r,
     725                 :             :         "generic item takes at most %lu type arguments but %lu were supplied",
     726                 :           3 :         (unsigned long) substitutions.size (),
     727                 :           3 :         (unsigned long) args.get_type_args ().size ());
     728                 :           3 :       return SubstitutionArgumentMappings::error ();
     729                 :           3 :     }
     730                 :             : 
     731                 :        9235 :   if (total_arguments < min_required_substitutions ())
     732                 :             :     {
     733                 :           3 :       rich_location r (line_table, args.get_locus ());
     734                 :           3 :       if (!substitutions.empty ())
     735                 :             :         {
     736                 :           3 :           const auto &subst = substitutions.front ();
     737                 :           3 :           const auto &generic = subst.get_generic_param ();
     738                 :           3 :           r.add_range (generic.get_locus ());
     739                 :             :         }
     740                 :             : 
     741                 :           6 :       rust_error_at (
     742                 :             :         r, ErrorCode::E0107,
     743                 :             :         "generic item takes at least %lu type arguments but %lu were supplied",
     744                 :           3 :         (unsigned long) (min_required_substitutions () - offs),
     745                 :           3 :         (unsigned long) args.get_type_args ().size ());
     746                 :           3 :       return SubstitutionArgumentMappings::error ();
     747                 :           3 :     }
     748                 :             : 
     749                 :        9232 :   std::vector<SubstitutionArg> mappings = used_arguments.get_mappings ();
     750                 :       18982 :   for (auto &arg : args.get_type_args ())
     751                 :             :     {
     752                 :        9754 :       BaseType *resolved = Resolver::TypeCheckType::Resolve (*arg);
     753                 :        9754 :       if (resolved == nullptr || resolved->get_kind () == TyTy::TypeKind::ERROR)
     754                 :             :         {
     755                 :           4 :           return SubstitutionArgumentMappings::error ();
     756                 :             :         }
     757                 :             : 
     758                 :        9754 :       const auto &param_mapping = substitutions.at (offs);
     759                 :        9754 :       const auto &generic = param_mapping.get_generic_param ();
     760                 :        9754 :       if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
     761                 :             :         {
     762                 :        9751 :           const auto &type_param
     763                 :             :             = static_cast<const HIR::TypeParam &> (generic);
     764                 :        9751 :           if (type_param.from_impl_trait ())
     765                 :             :             {
     766                 :           1 :               rich_location r (line_table, arg->get_locus ());
     767                 :           1 :               r.add_fixit_remove (arg->get_locus ());
     768                 :           1 :               rust_error_at (r, ErrorCode::E0632,
     769                 :             :                              "cannot provide explicit generic arguments when "
     770                 :             :                              "%<impl Trait%> is used in argument position");
     771                 :           1 :               return SubstitutionArgumentMappings::error ();
     772                 :           1 :             }
     773                 :             :         }
     774                 :           3 :       else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
     775                 :             :         {
     776                 :           3 :           if (resolved->get_kind () != TyTy::TypeKind::CONST)
     777                 :             :             {
     778                 :           3 :               rich_location r (line_table, arg->get_locus ());
     779                 :           3 :               r.add_fixit_remove (arg->get_locus ());
     780                 :           3 :               rust_error_at (r, ErrorCode::E0747,
     781                 :             :                              "type provided when a constant was expected");
     782                 :           3 :               return SubstitutionArgumentMappings::error ();
     783                 :           3 :             }
     784                 :             :         }
     785                 :             : 
     786                 :        9750 :       mappings.emplace_back (&param_mapping, resolved);
     787                 :        9750 :       offs++;
     788                 :             :     }
     789                 :             : 
     790                 :        9343 :   for (auto &arg : args.get_const_args ())
     791                 :             :     {
     792                 :         115 :       auto &expr = *arg.get_expression ().get ();
     793                 :         115 :       BaseType *expr_type = Resolver::TypeCheckExpr::Resolve (expr);
     794                 :         230 :       if (expr_type == nullptr || expr_type->is<ErrorType> ())
     795                 :           0 :         return SubstitutionArgumentMappings::error ();
     796                 :             : 
     797                 :             :       // validate this param is really a const generic
     798                 :         115 :       const auto &param_mapping = substitutions.at (offs);
     799                 :         115 :       const auto &generic = param_mapping.get_generic_param ();
     800                 :         115 :       if (generic.get_kind () != HIR::GenericParam::GenericKind::CONST)
     801                 :             :         {
     802                 :           0 :           rich_location r (line_table, arg.get_locus ());
     803                 :           0 :           r.add_fixit_remove (expr.get_locus ());
     804                 :           0 :           rust_error_at (r, "invalid position for a const generic argument");
     805                 :           0 :           return SubstitutionArgumentMappings::error ();
     806                 :           0 :         }
     807                 :             : 
     808                 :             :       // get the const generic specified type
     809                 :         115 :       const auto base_generic = param_mapping.get_param_ty ();
     810                 :         115 :       rust_assert (base_generic->get_kind () == TyTy::TypeKind::CONST);
     811                 :         115 :       const auto const_param
     812                 :         115 :         = static_cast<const TyTy::ConstParamType *> (base_generic);
     813                 :         115 :       auto specified_type = const_param->get_specified_type ();
     814                 :             : 
     815                 :             :       // validate this const generic is of the correct type
     816                 :         115 :       TyTy::BaseType *coereced_type = nullptr;
     817                 :         115 :       if (expr_type->get_kind () == TyTy::TypeKind::CONST)
     818                 :             :         {
     819                 :          21 :           auto const_expr_type = expr_type->as_const_type ();
     820                 :          21 :           auto const_value_type = const_expr_type->get_specified_type ();
     821                 :          21 :           coereced_type
     822                 :          21 :             = Resolver::coercion_site (expr.get_mappings ().get_hirid (),
     823                 :          21 :                                        TyTy::TyWithLocation (specified_type),
     824                 :             :                                        TyTy::TyWithLocation (const_value_type,
     825                 :          21 :                                                              expr.get_locus ()),
     826                 :             :                                        arg.get_locus ());
     827                 :             :         }
     828                 :             :       else
     829                 :             :         {
     830                 :          94 :           coereced_type
     831                 :          94 :             = Resolver::coercion_site (expr.get_mappings ().get_hirid (),
     832                 :          94 :                                        TyTy::TyWithLocation (specified_type),
     833                 :             :                                        TyTy::TyWithLocation (expr_type,
     834                 :          94 :                                                              expr.get_locus ()),
     835                 :             :                                        arg.get_locus ());
     836                 :             :         }
     837                 :             : 
     838                 :         230 :       if (coereced_type == nullptr || coereced_type->is<ErrorType> ())
     839                 :           0 :         return SubstitutionArgumentMappings::error ();
     840                 :             : 
     841                 :         115 :       TyTy::BaseType *const_value_ty = nullptr;
     842                 :         115 :       if (expr_type->get_kind () == TyTy::TypeKind::CONST)
     843                 :          21 :         const_value_ty = expr_type;
     844                 :             :       else
     845                 :             :         {
     846                 :             :           // const fold it if available
     847                 :          94 :           auto ctx = Compile::Context::get ();
     848                 :          94 :           tree folded
     849                 :          94 :             = Compile::HIRCompileBase::query_compile_const_expr (ctx,
     850                 :             :                                                                  coereced_type,
     851                 :             :                                                                  expr);
     852                 :             : 
     853                 :          94 :           if (folded == error_mark_node)
     854                 :             :             {
     855                 :           0 :               rich_location r (line_table, arg.get_locus ());
     856                 :           0 :               r.add_range (expr.get_locus ());
     857                 :           0 :               rust_error_at (r, "failed to resolve const expression");
     858                 :           0 :               return SubstitutionArgumentMappings::error ();
     859                 :           0 :             }
     860                 :             : 
     861                 :             :           // Use a fresh HirId to avoid conflicts with the expr's type
     862                 :          94 :           auto &global_mappings = Analysis::Mappings::get ();
     863                 :          94 :           HirId const_value_id = global_mappings.get_next_hir_id ();
     864                 :          94 :           const_value_ty
     865                 :          94 :             = new TyTy::ConstValueType (folded, coereced_type, const_value_id,
     866                 :          94 :                                         const_value_id, {});
     867                 :             : 
     868                 :             :           // Insert the ConstValueType into the context so it can be looked up
     869                 :          94 :           auto context = Resolver::TypeCheckContext::get ();
     870                 :          94 :           context->insert_type (
     871                 :          94 :             Analysis::NodeMapping (0, 0, const_value_ty->get_ref (), 0),
     872                 :             :             const_value_ty);
     873                 :             :         }
     874                 :             : 
     875                 :         115 :       mappings.emplace_back (&param_mapping, const_value_ty);
     876                 :         115 :       offs++;
     877                 :             :     }
     878                 :             : 
     879                 :             :   // we must need to fill out defaults
     880                 :        9228 :   size_t left_over
     881                 :        9228 :     = num_required_substitutions () - min_required_substitutions ();
     882                 :        9228 :   if (left_over > 0)
     883                 :             :     {
     884                 :        2712 :       for (size_t offs = mappings.size (); offs < substitutions.size (); offs++)
     885                 :             :         {
     886                 :        1137 :           SubstitutionParamMapping &param = substitutions.at (offs);
     887                 :        1137 :           rust_assert (param.param_has_default_ty ());
     888                 :             : 
     889                 :        1137 :           BaseType *resolved = param.get_default_ty ();
     890                 :        1137 :           if (resolved->get_kind () == TypeKind::ERROR)
     891                 :           0 :             return SubstitutionArgumentMappings::error ();
     892                 :             : 
     893                 :             :           // this resolved default might already contain default parameters
     894                 :        1137 :           if (!resolved->is_concrete ())
     895                 :             :             {
     896                 :        1118 :               SubstitutionArgumentMappings intermediate (
     897                 :             :                 mappings, binding_arguments,
     898                 :        1118 :                 {used_arguments.get_regions ().size ()}, args.get_locus ());
     899                 :        1118 :               resolved = Resolver::SubstMapperInternal::Resolve (resolved,
     900                 :             :                                                                  intermediate);
     901                 :             : 
     902                 :        1118 :               if (resolved->get_kind () == TypeKind::ERROR)
     903                 :           0 :                 return SubstitutionArgumentMappings::error ();
     904                 :        1118 :             }
     905                 :             : 
     906                 :        1137 :           mappings.emplace_back (&param, resolved);
     907                 :             :         }
     908                 :             :     }
     909                 :             : 
     910                 :        9228 :   return {mappings, binding_arguments,
     911                 :       18456 :           RegionParamList::from_subst (used_arguments.get_regions ().size (),
     912                 :             :                                        regions),
     913                 :       27684 :           args.get_locus ()};
     914                 :        9232 : }
     915                 :             : 
     916                 :             : BaseType *
     917                 :        6659 : SubstitutionRef::infer_substitions (location_t locus)
     918                 :             : {
     919                 :        6659 :   std::vector<SubstitutionArg> args;
     920                 :        6659 :   std::map<std::string, BaseType *> argument_mappings;
     921                 :       14845 :   for (auto &p : get_substs ())
     922                 :             :     {
     923                 :        8186 :       if (p.needs_substitution ())
     924                 :             :         {
     925                 :        8117 :           const HIR::GenericParam &generic = p.get_generic_param ();
     926                 :        8117 :           const std::string &symbol = p.get_param_ty ()->get_symbol ();
     927                 :        8117 :           auto it = argument_mappings.find (symbol);
     928                 :        8117 :           bool have_mapping = it != argument_mappings.end ();
     929                 :             : 
     930                 :        8117 :           if (have_mapping)
     931                 :             :             {
     932                 :         121 :               args.emplace_back (&p, it->second);
     933                 :             :             }
     934                 :        7996 :           else if (generic.get_kind () == HIR::GenericParam::GenericKind::TYPE)
     935                 :             :             {
     936                 :        7977 :               TyVar infer_var = TyVar::get_implicit_infer_var (locus);
     937                 :        7977 :               args.emplace_back (&p, infer_var.get_tyty ());
     938                 :        7977 :               argument_mappings[symbol] = infer_var.get_tyty ();
     939                 :             :             }
     940                 :          19 :           else if (generic.get_kind () == HIR::GenericParam::GenericKind::CONST)
     941                 :             :             {
     942                 :          19 :               TyVar infer_var = TyVar::get_implicit_const_infer_var (locus);
     943                 :          19 :               args.emplace_back (&p, infer_var.get_tyty ());
     944                 :          19 :               argument_mappings[symbol] = infer_var.get_tyty ();
     945                 :             :             }
     946                 :        8117 :         }
     947                 :             :       else
     948                 :             :         {
     949                 :          69 :           args.emplace_back (&p, p.get_param_ty ()->resolve ());
     950                 :             :         }
     951                 :             :     }
     952                 :             : 
     953                 :             :   // FIXME do we need to add inference variables to all the possible bindings?
     954                 :             :   // it might just lead to inference variable hell not 100% sure if rustc does
     955                 :             :   // this i think the language might needs this to be explicitly set
     956                 :             : 
     957                 :        6659 :   SubstitutionArgumentMappings infer_arguments (std::move (args),
     958                 :             :                                                 {} /* binding_arguments */,
     959                 :             :                                                 used_arguments.get_regions (),
     960                 :        6659 :                                                 locus);
     961                 :        6659 :   return handle_substitions (infer_arguments);
     962                 :        6659 : }
     963                 :             : 
     964                 :             : SubstitutionArgumentMappings
     965                 :       13964 : SubstitutionRef::adjust_mappings_for_this (
     966                 :             :   SubstitutionArgumentMappings &mappings, bool trait_mode)
     967                 :             : {
     968                 :       13964 :   std::vector<SubstitutionArg> resolved_mappings;
     969                 :       32146 :   for (size_t i = 0; i < substitutions.size (); i++)
     970                 :             :     {
     971                 :       18182 :       auto &subst = substitutions.at (i);
     972                 :             : 
     973                 :       18182 :       SubstitutionArg arg = SubstitutionArg::error ();
     974                 :       18182 :       if (mappings.size () == substitutions.size ())
     975                 :             :         {
     976                 :       15925 :           mappings.get_argument_at (i, &arg);
     977                 :             :         }
     978                 :             :       else
     979                 :             :         {
     980                 :        2257 :           if (subst.needs_substitution ())
     981                 :             :             {
     982                 :             :               // get from passed in mappings
     983                 :        2169 :               mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
     984                 :             :             }
     985                 :             :           else
     986                 :             :             {
     987                 :             :               // we should already have this somewhere
     988                 :          88 :               used_arguments.get_argument_for_symbol (subst.get_param_ty (),
     989                 :             :                                                       &arg);
     990                 :             :             }
     991                 :             :         }
     992                 :             : 
     993                 :       18182 :       bool ok = !arg.is_error ();
     994                 :       18182 :       if (ok || (trait_mode && i == 0))
     995                 :       17693 :         resolved_mappings.emplace_back (&subst, arg.get_tyty ());
     996                 :             :     }
     997                 :             : 
     998                 :       13964 :   if (resolved_mappings.empty ())
     999                 :           8 :     return SubstitutionArgumentMappings::error ();
    1000                 :             : 
    1001                 :       13956 :   return SubstitutionArgumentMappings (resolved_mappings,
    1002                 :       13956 :                                        mappings.get_binding_args (),
    1003                 :             :                                        mappings.get_regions (),
    1004                 :             :                                        mappings.get_locus (),
    1005                 :       13956 :                                        mappings.get_subst_cb (),
    1006                 :       27912 :                                        mappings.trait_item_mode ());
    1007                 :       13964 : }
    1008                 :             : 
    1009                 :             : bool
    1010                 :           0 : SubstitutionRef::are_mappings_bound (SubstitutionArgumentMappings &mappings)
    1011                 :             : {
    1012                 :           0 :   std::vector<SubstitutionArg> resolved_mappings;
    1013                 :           0 :   for (size_t i = 0; i < substitutions.size (); i++)
    1014                 :             :     {
    1015                 :           0 :       auto &subst = substitutions.at (i);
    1016                 :             : 
    1017                 :           0 :       SubstitutionArg arg = SubstitutionArg::error ();
    1018                 :           0 :       if (mappings.size () == substitutions.size ())
    1019                 :             :         {
    1020                 :           0 :           mappings.get_argument_at (i, &arg);
    1021                 :             :         }
    1022                 :             :       else
    1023                 :             :         {
    1024                 :           0 :           if (subst.needs_substitution ())
    1025                 :             :             {
    1026                 :             :               // get from passed in mappings
    1027                 :           0 :               mappings.get_argument_for_symbol (subst.get_param_ty (), &arg);
    1028                 :             :             }
    1029                 :             :           else
    1030                 :             :             {
    1031                 :             :               // we should already have this somewhere
    1032                 :           0 :               used_arguments.get_argument_for_symbol (subst.get_param_ty (),
    1033                 :             :                                                       &arg);
    1034                 :             :             }
    1035                 :             :         }
    1036                 :             : 
    1037                 :           0 :       bool ok = !arg.is_error ();
    1038                 :           0 :       if (ok)
    1039                 :           0 :         resolved_mappings.emplace_back (&subst, arg.get_tyty ());
    1040                 :             :     }
    1041                 :             : 
    1042                 :           0 :   return !resolved_mappings.empty ();
    1043                 :           0 : }
    1044                 :             : 
    1045                 :             : // this function assumes that the mappings being passed are for the same type as
    1046                 :             : // this new substitution reference so ordering matters here
    1047                 :             : SubstitutionArgumentMappings
    1048                 :          63 : SubstitutionRef::solve_mappings_from_receiver_for_self (
    1049                 :             :   SubstitutionArgumentMappings &mappings) const
    1050                 :             : {
    1051                 :          63 :   std::vector<SubstitutionArg> resolved_mappings;
    1052                 :             : 
    1053                 :          63 :   rust_assert (mappings.size () == get_num_substitutions ());
    1054                 :         126 :   for (size_t i = 0; i < get_num_substitutions (); i++)
    1055                 :             :     {
    1056                 :          63 :       const SubstitutionParamMapping &param_mapping = substitutions.at (i);
    1057                 :          63 :       SubstitutionArg &arg = mappings.get_mappings ().at (i);
    1058                 :             : 
    1059                 :          63 :       if (param_mapping.needs_substitution ())
    1060                 :          63 :         resolved_mappings.emplace_back (&param_mapping, arg.get_tyty ());
    1061                 :             :     }
    1062                 :             : 
    1063                 :          63 :   return SubstitutionArgumentMappings (resolved_mappings,
    1064                 :          63 :                                        mappings.get_binding_args (),
    1065                 :             :                                        mappings.get_regions (),
    1066                 :         126 :                                        mappings.get_locus ());
    1067                 :          63 : }
    1068                 :             : 
    1069                 :             : void
    1070                 :        4305 : SubstitutionRef::prepare_higher_ranked_bounds ()
    1071                 :             : {
    1072                 :        7210 :   for (const auto &subst : get_substs ())
    1073                 :             :     {
    1074                 :        2905 :       const auto pty = subst.get_param_ty ();
    1075                 :        6289 :       for (const auto &bound : pty->get_specified_bounds ())
    1076                 :             :         {
    1077                 :        3384 :           const auto ref = bound.get ();
    1078                 :        3384 :           ref->clear_associated_type_projections ();
    1079                 :             :         }
    1080                 :             :     }
    1081                 :        4305 : }
    1082                 :             : 
    1083                 :             : bool
    1084                 :       15384 : SubstitutionRef::monomorphize ()
    1085                 :             : {
    1086                 :       24962 :   for (const auto &subst : get_substs ())
    1087                 :             :     {
    1088                 :        9578 :       const auto pty = subst.get_param_ty ();
    1089                 :        9578 :       if (!pty->can_resolve ())
    1090                 :         100 :         continue;
    1091                 :             : 
    1092                 :        9478 :       TyTy::BaseType *binding = pty->resolve ();
    1093                 :        9478 :       if (binding->get_kind () == TyTy::TypeKind::PARAM)
    1094                 :        2256 :         continue;
    1095                 :             : 
    1096                 :       15566 :       for (const auto &bound : pty->get_specified_bounds ())
    1097                 :             :         {
    1098                 :        8344 :           bool ambigious = false;
    1099                 :        8344 :           auto associated
    1100                 :        8344 :             = Resolver::lookup_associated_impl_block (bound, binding,
    1101                 :             :                                                       &ambigious);
    1102                 :        8344 :           if (associated != nullptr)
    1103                 :        1946 :             associated->setup_associated_types (binding, bound);
    1104                 :             :         }
    1105                 :             :     }
    1106                 :             : 
    1107                 :       15384 :   return true;
    1108                 :             : }
    1109                 :             : 
    1110                 :             : } // namespace TyTy
    1111                 :             : } // 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.