LCOV - code coverage report
Current view: top level - gcc/rust/typecheck - rust-tyty-bounds.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.3 % 424 400
Test Date: 2024-03-23 14:05:01 Functions: 91.8 % 49 45
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : // Copyright (C) 2021-2024 Free Software Foundation, Inc.
       2                 :             : 
       3                 :             : // This file is part of GCC.
       4                 :             : 
       5                 :             : // GCC is free software; you can redistribute it and/or modify it under
       6                 :             : // the terms of the GNU General Public License as published by the Free
       7                 :             : // Software Foundation; either version 3, or (at your option) any later
       8                 :             : // version.
       9                 :             : 
      10                 :             : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11                 :             : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12                 :             : // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13                 :             : // for more details.
      14                 :             : 
      15                 :             : // You should have received a copy of the GNU General Public License
      16                 :             : // along with GCC; see the file COPYING3.  If not see
      17                 :             : // <http://www.gnu.org/licenses/>.
      18                 :             : 
      19                 :             : #include "rust-hir-type-bounds.h"
      20                 :             : #include "rust-hir-trait-resolve.h"
      21                 :             : #include "rust-substitution-mapper.h"
      22                 :             : #include "rust-type-util.h"
      23                 :             : 
      24                 :             : namespace Rust {
      25                 :             : namespace Resolver {
      26                 :             : 
      27                 :       12388 : TypeBoundsProbe::TypeBoundsProbe (const TyTy::BaseType *receiver)
      28                 :       12388 :   : TypeCheckBase (), receiver (receiver)
      29                 :       12388 : {}
      30                 :             : 
      31                 :             : std::vector<std::pair<TraitReference *, HIR::ImplBlock *>>
      32                 :       12388 : TypeBoundsProbe::Probe (const TyTy::BaseType *receiver)
      33                 :             : {
      34                 :       12388 :   TypeBoundsProbe probe (receiver);
      35                 :       12388 :   probe.scan ();
      36                 :       12388 :   return probe.trait_references;
      37                 :       12388 : }
      38                 :             : 
      39                 :             : bool
      40                 :         222 : TypeBoundsProbe::is_bound_satisfied_for_type (TyTy::BaseType *receiver,
      41                 :             :                                               TraitReference *ref)
      42                 :             : {
      43                 :         236 :   for (auto &bound : receiver->get_specified_bounds ())
      44                 :             :     {
      45                 :          49 :       const TraitReference *b = bound.get ();
      46                 :          49 :       if (b->is_equal (*ref))
      47                 :         222 :         return true;
      48                 :             :     }
      49                 :             : 
      50                 :         187 :   std::vector<std::pair<TraitReference *, HIR::ImplBlock *>> bounds
      51                 :         187 :     = Probe (receiver);
      52                 :         199 :   for (auto &bound : bounds)
      53                 :             :     {
      54                 :         199 :       const TraitReference *b = bound.first;
      55                 :         199 :       if (b->is_equal (*ref))
      56                 :         187 :         return true;
      57                 :             :     }
      58                 :             : 
      59                 :             :   return false;
      60                 :         187 : }
      61                 :             : 
      62                 :             : void
      63                 :       12388 : TypeBoundsProbe::scan ()
      64                 :             : {
      65                 :       12388 :   std::vector<std::pair<HIR::TypePath *, HIR::ImplBlock *>>
      66                 :       12388 :     possible_trait_paths;
      67                 :       12388 :   mappings->iterate_impl_blocks (
      68                 :       12388 :     [&] (HirId id, HIR::ImplBlock *impl) mutable -> bool {
      69                 :             :       // we are filtering for trait-impl-blocks
      70                 :      181155 :       if (!impl->has_trait_ref ())
      71                 :             :         return true;
      72                 :             : 
      73                 :      155338 :       HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
      74                 :      155338 :       TyTy::BaseType *impl_type = nullptr;
      75                 :      155338 :       if (!query_type (impl_ty_id, &impl_type))
      76                 :             :         return true;
      77                 :             : 
      78                 :      154378 :       if (!receiver->can_eq (impl_type, false))
      79                 :             :         {
      80                 :      135809 :           if (!impl_type->can_eq (receiver, false))
      81                 :             :             return true;
      82                 :             :         }
      83                 :             : 
      84                 :       25943 :       possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl});
      85                 :       25943 :       return true;
      86                 :             :     });
      87                 :             : 
      88                 :       38331 :   for (auto &path : possible_trait_paths)
      89                 :             :     {
      90                 :       25943 :       HIR::TypePath *trait_path = path.first;
      91                 :       25943 :       TraitReference *trait_ref = TraitResolver::Resolve (*trait_path);
      92                 :             : 
      93                 :       25943 :       if (!trait_ref->is_error ())
      94                 :       25943 :         trait_references.push_back ({trait_ref, path.second});
      95                 :             :     }
      96                 :             : 
      97                 :             :   // marker traits...
      98                 :       12388 :   assemble_sized_builtin ();
      99                 :       12388 : }
     100                 :             : 
     101                 :             : void
     102                 :       12388 : TypeBoundsProbe::assemble_sized_builtin ()
     103                 :             : {
     104                 :       12388 :   const TyTy::BaseType *raw = receiver->destructure ();
     105                 :             : 
     106                 :             :   // https://runrust.miraheze.org/wiki/Dynamically_Sized_Type
     107                 :             :   // everything is sized except for:
     108                 :             :   //
     109                 :             :   //   1. dyn traits
     110                 :             :   //   2. slices
     111                 :             :   //   3. str
     112                 :             :   //   4. ADT's which contain any of the above
     113                 :             :   //   t. tuples which contain any of the above
     114                 :       12388 :   switch (raw->get_kind ())
     115                 :             :     {
     116                 :        8861 :     case TyTy::ARRAY:
     117                 :        8861 :     case TyTy::REF:
     118                 :        8861 :     case TyTy::POINTER:
     119                 :        8861 :     case TyTy::PARAM:
     120                 :        8861 :     case TyTy::FNDEF:
     121                 :        8861 :     case TyTy::FNPTR:
     122                 :        8861 :     case TyTy::BOOL:
     123                 :        8861 :     case TyTy::CHAR:
     124                 :        8861 :     case TyTy::INT:
     125                 :        8861 :     case TyTy::UINT:
     126                 :        8861 :     case TyTy::FLOAT:
     127                 :        8861 :     case TyTy::USIZE:
     128                 :        8861 :     case TyTy::ISIZE:
     129                 :        8861 :     case TyTy::CLOSURE:
     130                 :        8861 :     case TyTy::INFER:
     131                 :        8861 :     case TyTy::NEVER:
     132                 :        8861 :     case TyTy::PLACEHOLDER:
     133                 :        8861 :     case TyTy::PROJECTION:
     134                 :        8861 :       assemble_builtin_candidate (Analysis::RustLangItem::SIZED);
     135                 :        8861 :       break;
     136                 :             : 
     137                 :             :       // FIXME str and slice need to be moved and test cases updated
     138                 :        3448 :     case TyTy::SLICE:
     139                 :        3448 :     case TyTy::STR:
     140                 :        3448 :     case TyTy::ADT:
     141                 :        3448 :     case TyTy::TUPLE:
     142                 :             :       // FIXME add extra checks
     143                 :        3448 :       assemble_builtin_candidate (Analysis::RustLangItem::SIZED);
     144                 :        3448 :       break;
     145                 :             : 
     146                 :             :     case TyTy::DYNAMIC:
     147                 :             :     case TyTy::ERROR:
     148                 :             :       break;
     149                 :             :     }
     150                 :       12388 : }
     151                 :             : 
     152                 :             : void
     153                 :       12309 : TypeBoundsProbe::assemble_builtin_candidate (
     154                 :             :   Analysis::RustLangItem::ItemType lang_item)
     155                 :             : {
     156                 :       12309 :   DefId id;
     157                 :       12309 :   bool found_lang_item = mappings->lookup_lang_item (lang_item, &id);
     158                 :       12309 :   if (!found_lang_item)
     159                 :           0 :     return;
     160                 :             : 
     161                 :       12309 :   HIR::Item *item = mappings->lookup_defid (id);
     162                 :       12309 :   if (item == nullptr)
     163                 :             :     return;
     164                 :             : 
     165                 :       12309 :   rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
     166                 :       12309 :   HIR::Trait *trait = static_cast<HIR::Trait *> (item);
     167                 :       12309 :   const TyTy::BaseType *raw = receiver->destructure ();
     168                 :             : 
     169                 :             :   // assemble the reference
     170                 :       12309 :   TraitReference *trait_ref = TraitResolver::Resolve (*trait);
     171                 :       12309 :   trait_references.push_back ({trait_ref, mappings->lookup_builtin_marker ()});
     172                 :             : 
     173                 :       12309 :   rust_debug ("Added builtin lang_item: %s for %s",
     174                 :             :               Analysis::RustLangItem::ToString (lang_item).c_str (),
     175                 :             :               raw->get_name ().c_str ());
     176                 :             : }
     177                 :             : 
     178                 :             : TraitReference *
     179                 :        3122 : TypeCheckBase::resolve_trait_path (HIR::TypePath &path)
     180                 :             : {
     181                 :        3122 :   return TraitResolver::Resolve (path);
     182                 :             : }
     183                 :             : 
     184                 :             : TyTy::TypeBoundPredicate
     185                 :       12033 : TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
     186                 :             :                                          HIR::Type *associated_self,
     187                 :             :                                          BoundPolarity polarity)
     188                 :             : {
     189                 :       12033 :   TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
     190                 :       12033 :   bool already_resolved
     191                 :       12033 :     = context->lookup_predicate (type_path.get_mappings ().get_hirid (),
     192                 :             :                                  &lookup);
     193                 :       12033 :   if (already_resolved)
     194                 :        8911 :     return lookup;
     195                 :             : 
     196                 :        3122 :   TraitReference *trait = resolve_trait_path (type_path);
     197                 :        3122 :   if (trait->is_error ())
     198                 :           8 :     return TyTy::TypeBoundPredicate::error ();
     199                 :             : 
     200                 :        3114 :   TyTy::TypeBoundPredicate predicate (*trait, polarity, type_path.get_locus ());
     201                 :        3114 :   HIR::GenericArgs args
     202                 :        3114 :     = HIR::GenericArgs::create_empty (type_path.get_locus ());
     203                 :             : 
     204                 :        3114 :   auto &final_seg = type_path.get_final_segment ();
     205                 :        3114 :   switch (final_seg->get_type ())
     206                 :             :     {
     207                 :         426 :       case HIR::TypePathSegment::SegmentType::GENERIC: {
     208                 :         426 :         auto final_generic_seg
     209                 :         426 :           = static_cast<HIR::TypePathSegmentGeneric *> (final_seg.get ());
     210                 :         426 :         if (final_generic_seg->has_generic_args ())
     211                 :             :           {
     212                 :         426 :             args = final_generic_seg->get_generic_args ();
     213                 :             :           }
     214                 :             :       }
     215                 :             :       break;
     216                 :             : 
     217                 :          17 :       case HIR::TypePathSegment::SegmentType::FUNCTION: {
     218                 :          17 :         auto final_function_seg
     219                 :          17 :           = static_cast<HIR::TypePathSegmentFunction *> (final_seg.get ());
     220                 :          17 :         auto &fn = final_function_seg->get_function_path ();
     221                 :             : 
     222                 :             :         // we need to make implicit generic args which must be an implicit
     223                 :             :         // Tuple
     224                 :          17 :         auto crate_num = mappings->get_current_crate ();
     225                 :          17 :         HirId implicit_args_id = mappings->get_next_hir_id ();
     226                 :          17 :         Analysis::NodeMapping mapping (crate_num,
     227                 :          17 :                                        final_seg->get_mappings ().get_nodeid (),
     228                 :          17 :                                        implicit_args_id, UNKNOWN_LOCAL_DEFID);
     229                 :             : 
     230                 :          17 :         std::vector<std::unique_ptr<HIR::Type>> params_copy;
     231                 :          34 :         for (auto &p : fn.get_params ())
     232                 :             :           {
     233                 :          17 :             params_copy.push_back (p->clone_type ());
     234                 :             :           }
     235                 :             : 
     236                 :          17 :         HIR::TupleType *implicit_tuple
     237                 :             :           = new HIR::TupleType (mapping, std::move (params_copy),
     238                 :          17 :                                 final_seg->get_locus ());
     239                 :             : 
     240                 :          17 :         std::vector<std::unique_ptr<HIR::Type>> inputs;
     241                 :          17 :         inputs.push_back (std::unique_ptr<HIR::Type> (implicit_tuple));
     242                 :             : 
     243                 :             :         // resolve the fn_once_output type which assumes there must be an output
     244                 :             :         // set
     245                 :          17 :         rust_assert (fn.has_return_type ());
     246                 :          17 :         TypeCheckType::Resolve (fn.get_return_type ().get ());
     247                 :             : 
     248                 :          17 :         HIR::TraitItem *trait_item = mappings->lookup_trait_item_lang_item (
     249                 :             :           Analysis::RustLangItem::ItemType::FN_ONCE_OUTPUT,
     250                 :             :           final_seg->get_locus ());
     251                 :             : 
     252                 :          17 :         std::vector<HIR::GenericArgsBinding> bindings;
     253                 :          17 :         location_t output_locus = fn.get_return_type ()->get_locus ();
     254                 :          51 :         HIR::GenericArgsBinding binding (Identifier (
     255                 :          17 :                                            trait_item->trait_identifier ()),
     256                 :          34 :                                          fn.get_return_type ()->clone_type (),
     257                 :          17 :                                          output_locus);
     258                 :          17 :         bindings.push_back (std::move (binding));
     259                 :             : 
     260                 :          34 :         args = HIR::GenericArgs ({} /* lifetimes */,
     261                 :             :                                  std::move (inputs) /* type_args*/,
     262                 :             :                                  std::move (bindings) /* binding_args*/,
     263                 :          17 :                                  {} /* const_args */, final_seg->get_locus ());
     264                 :          17 :       }
     265                 :          17 :       break;
     266                 :             : 
     267                 :             :     default:
     268                 :             :       /* nothing to do */
     269                 :             :       break;
     270                 :             :     }
     271                 :             : 
     272                 :        3114 :   if (associated_self != nullptr)
     273                 :             :     {
     274                 :        2861 :       std::vector<std::unique_ptr<HIR::Type>> type_args;
     275                 :        2861 :       type_args.push_back (
     276                 :        2861 :         std::unique_ptr<HIR::Type> (associated_self->clone_type ()));
     277                 :        3305 :       for (auto &arg : args.get_type_args ())
     278                 :             :         {
     279                 :         444 :           type_args.push_back (std::unique_ptr<HIR::Type> (arg->clone_type ()));
     280                 :             :         }
     281                 :             : 
     282                 :        5722 :       args = HIR::GenericArgs (args.get_lifetime_args (), std::move (type_args),
     283                 :        2861 :                                args.get_binding_args (), args.get_const_args (),
     284                 :        2861 :                                args.get_locus ());
     285                 :        2861 :     }
     286                 :             : 
     287                 :             :   // we try to apply generic arguments when they are non empty and or when the
     288                 :             :   // predicate requires them so that we get the relevant Foo expects x number
     289                 :             :   // arguments but got zero see test case rust/compile/traits12.rs
     290                 :        3359 :   if (!args.is_empty () || predicate.requires_generic_args ())
     291                 :             :     {
     292                 :             :       // this is applying generic arguments to a trait reference
     293                 :        2869 :       predicate.apply_generic_arguments (&args, associated_self != nullptr);
     294                 :             :     }
     295                 :             : 
     296                 :        3114 :   context->insert_resolved_predicate (type_path.get_mappings ().get_hirid (),
     297                 :             :                                       predicate);
     298                 :             : 
     299                 :        3114 :   return predicate;
     300                 :        3114 : }
     301                 :             : 
     302                 :             : } // namespace Resolver
     303                 :             : 
     304                 :             : namespace TyTy {
     305                 :             : 
     306                 :       11753 : TypeBoundPredicate::TypeBoundPredicate (
     307                 :             :   const Resolver::TraitReference &trait_reference, BoundPolarity polarity,
     308                 :       11753 :   location_t locus)
     309                 :       23506 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     310                 :       11753 :     reference (trait_reference.get_mappings ().get_defid ()), locus (locus),
     311                 :       23506 :     error_flag (false), polarity (polarity)
     312                 :             : {
     313                 :       11753 :   rust_assert (!trait_reference.get_trait_substs ().empty ());
     314                 :             : 
     315                 :       11753 :   substitutions.clear ();
     316                 :       24588 :   for (const auto &p : trait_reference.get_trait_substs ())
     317                 :       24588 :     substitutions.push_back (p.clone ());
     318                 :             : 
     319                 :             :   // we setup a dummy implict self argument
     320                 :       11753 :   SubstitutionArg placeholder_self (&get_substs ().front (), nullptr);
     321                 :       11753 :   used_arguments.get_mappings ().push_back (placeholder_self);
     322                 :       11753 : }
     323                 :             : 
     324                 :        2080 : TypeBoundPredicate::TypeBoundPredicate (
     325                 :             :   DefId reference, std::vector<SubstitutionParamMapping> subst,
     326                 :        2080 :   BoundPolarity polarity, location_t locus)
     327                 :        4160 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     328                 :        2080 :     reference (reference), locus (locus), error_flag (false),
     329                 :        2080 :     polarity (polarity)
     330                 :             : {
     331                 :        2080 :   rust_assert (!subst.empty ());
     332                 :             : 
     333                 :        2080 :   substitutions.clear ();
     334                 :        4459 :   for (const auto &p : subst)
     335                 :        2379 :     substitutions.push_back (p.clone ());
     336                 :             : 
     337                 :             :   // we setup a dummy implict self argument
     338                 :        2080 :   SubstitutionArg placeholder_self (&get_substs ().front (), nullptr);
     339                 :        2080 :   used_arguments.get_mappings ().push_back (placeholder_self);
     340                 :        2080 : }
     341                 :             : 
     342                 :       38638 : TypeBoundPredicate::TypeBoundPredicate (mark_is_error)
     343                 :       77276 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     344                 :       38638 :     reference (UNKNOWN_DEFID), locus (UNDEF_LOCATION), error_flag (true),
     345                 :       38638 :     polarity (BoundPolarity::RegularBound)
     346                 :       38638 : {}
     347                 :             : 
     348                 :    11828459 : TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
     349                 :    23656918 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     350                 :    11828459 :     reference (other.reference), locus (other.locus),
     351                 :    11828459 :     error_flag (other.error_flag), polarity (other.polarity)
     352                 :             : {
     353                 :    11828459 :   substitutions.clear ();
     354                 :    23884935 :   for (const auto &p : other.get_substs ())
     355                 :    12056476 :     substitutions.push_back (p.clone ());
     356                 :             : 
     357                 :    11828459 :   std::vector<SubstitutionArg> mappings;
     358                 :    23723888 :   for (size_t i = 0; i < other.used_arguments.get_mappings ().size (); i++)
     359                 :             :     {
     360                 :    11895429 :       const SubstitutionArg &oa = other.used_arguments.get_mappings ().at (i);
     361                 :    11895429 :       SubstitutionArg arg (oa);
     362                 :    11895429 :       mappings.push_back (std::move (arg));
     363                 :             :     }
     364                 :             : 
     365                 :             :   // we need to remap the argument mappings based on this copied constructor
     366                 :    11828459 :   std::vector<SubstitutionArg> copied_arg_mappings;
     367                 :    11828459 :   size_t i = 0;
     368                 :    23723888 :   for (const auto &m : other.used_arguments.get_mappings ())
     369                 :             :     {
     370                 :    11895429 :       TyTy::BaseType *argument
     371                 :    11895429 :         = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone ();
     372                 :    11895429 :       SubstitutionArg c (&substitutions.at (i++), argument);
     373                 :    11895429 :       copied_arg_mappings.push_back (std::move (c));
     374                 :             :     }
     375                 :             : 
     376                 :    11828459 :   used_arguments
     377                 :    23656918 :     = SubstitutionArgumentMappings (copied_arg_mappings, {},
     378                 :             :                                     other.used_arguments.get_regions (),
     379                 :    11828459 :                                     other.used_arguments.get_locus ());
     380                 :    11828459 : }
     381                 :             : 
     382                 :             : TypeBoundPredicate &
     383                 :       25521 : TypeBoundPredicate::operator= (const TypeBoundPredicate &other)
     384                 :             : {
     385                 :       25521 :   reference = other.reference;
     386                 :       25521 :   locus = other.locus;
     387                 :       25521 :   error_flag = other.error_flag;
     388                 :       25521 :   polarity = other.polarity;
     389                 :       25521 :   used_arguments = SubstitutionArgumentMappings::empty ();
     390                 :             : 
     391                 :       25521 :   substitutions.clear ();
     392                 :       53041 :   for (const auto &p : other.get_substs ())
     393                 :       27520 :     substitutions.push_back (p.clone ());
     394                 :             : 
     395                 :       25521 :   if (other.is_error ())
     396                 :             :     return *this;
     397                 :             : 
     398                 :       19741 :   std::vector<SubstitutionArg> mappings;
     399                 :       47255 :   for (size_t i = 0; i < other.used_arguments.get_mappings ().size (); i++)
     400                 :             :     {
     401                 :       27514 :       const SubstitutionArg &oa = other.used_arguments.get_mappings ().at (i);
     402                 :       27514 :       SubstitutionArg arg (oa);
     403                 :       27514 :       mappings.push_back (std::move (arg));
     404                 :             :     }
     405                 :             : 
     406                 :             :   // we need to remap the argument mappings based on this copied constructor
     407                 :       19741 :   std::vector<SubstitutionArg> copied_arg_mappings;
     408                 :       19741 :   size_t i = 0;
     409                 :       47255 :   for (const auto &m : other.used_arguments.get_mappings ())
     410                 :             :     {
     411                 :       27514 :       TyTy::BaseType *argument
     412                 :       27514 :         = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone ();
     413                 :       27514 :       SubstitutionArg c (&substitutions.at (i++), argument);
     414                 :       27514 :       copied_arg_mappings.push_back (std::move (c));
     415                 :             :     }
     416                 :             : 
     417                 :       19741 :   used_arguments
     418                 :       39482 :     = SubstitutionArgumentMappings (copied_arg_mappings, {},
     419                 :             :                                     other.used_arguments.get_regions (),
     420                 :       19741 :                                     other.used_arguments.get_locus ());
     421                 :             : 
     422                 :       19741 :   return *this;
     423                 :       19741 : }
     424                 :             : 
     425                 :             : TypeBoundPredicate
     426                 :       38638 : TypeBoundPredicate::error ()
     427                 :             : {
     428                 :       38638 :   return TypeBoundPredicate (mark_is_error ());
     429                 :             : }
     430                 :             : 
     431                 :             : std::string
     432                 :        1558 : TypeBoundPredicate::as_string () const
     433                 :             : {
     434                 :        1558 :   return get ()->as_string () + subst_as_string ();
     435                 :             : }
     436                 :             : 
     437                 :             : std::string
     438                 :        4267 : TypeBoundPredicate::as_name () const
     439                 :             : {
     440                 :        4267 :   return get ()->get_name () + subst_as_string ();
     441                 :             : }
     442                 :             : 
     443                 :             : const Resolver::TraitReference *
     444                 :       46238 : TypeBoundPredicate::get () const
     445                 :             : {
     446                 :       46238 :   auto context = Resolver::TypeCheckContext::get ();
     447                 :             : 
     448                 :       46238 :   Resolver::TraitReference *ref = nullptr;
     449                 :       46238 :   bool ok = context->lookup_trait_reference (reference, &ref);
     450                 :       46238 :   rust_assert (ok);
     451                 :             : 
     452                 :       46238 :   return ref;
     453                 :             : }
     454                 :             : 
     455                 :             : std::string
     456                 :         660 : TypeBoundPredicate::get_name () const
     457                 :             : {
     458                 :         660 :   return get ()->get_name ();
     459                 :             : }
     460                 :             : 
     461                 :             : bool
     462                 :         110 : TypeBoundPredicate::is_object_safe (bool emit_error, location_t locus) const
     463                 :             : {
     464                 :         110 :   const Resolver::TraitReference *trait = get ();
     465                 :         110 :   rust_assert (trait != nullptr);
     466                 :         110 :   return trait->is_object_safe (emit_error, locus);
     467                 :             : }
     468                 :             : 
     469                 :             : void
     470                 :        2922 : TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args,
     471                 :             :                                              bool has_associated_self)
     472                 :             : {
     473                 :        2922 :   rust_assert (!substitutions.empty ());
     474                 :        2922 :   if (has_associated_self)
     475                 :             :     {
     476                 :        2861 :       used_arguments = SubstitutionArgumentMappings::empty ();
     477                 :             :     }
     478                 :             :   else
     479                 :             :     {
     480                 :             :       // we need to get the substitutions argument mappings but also remember
     481                 :             :       // that we have an implicit Self argument which we must be careful to
     482                 :             :       // respect
     483                 :          61 :       rust_assert (!used_arguments.is_empty ());
     484                 :             :     }
     485                 :             : 
     486                 :             :   // now actually perform a substitution
     487                 :        5844 :   used_arguments = get_mappings_from_generic_args (
     488                 :             :     *generic_args,
     489                 :        5844 :     Resolver::TypeCheckContext::get ()->regions_from_generic_args (
     490                 :        2922 :       *generic_args));
     491                 :             : 
     492                 :        2922 :   error_flag |= used_arguments.is_error ();
     493                 :        2922 :   auto &subst_mappings = used_arguments;
     494                 :        6572 :   for (auto &sub : get_substs ())
     495                 :             :     {
     496                 :        3650 :       SubstitutionArg arg = SubstitutionArg::error ();
     497                 :        3650 :       bool ok
     498                 :        3650 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
     499                 :        3650 :       if (ok && arg.get_tyty () != nullptr)
     500                 :        3587 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
     501                 :             :     }
     502                 :             : 
     503                 :             :   // associated argument mappings
     504                 :        2965 :   for (auto &it : subst_mappings.get_binding_args ())
     505                 :             :     {
     506                 :          43 :       std::string identifier = it.first;
     507                 :          43 :       TyTy::BaseType *type = it.second;
     508                 :             : 
     509                 :          43 :       TypeBoundPredicateItem item = lookup_associated_item (identifier);
     510                 :          43 :       rust_assert (!item.is_error ());
     511                 :             : 
     512                 :          43 :       const auto item_ref = item.get_raw_item ();
     513                 :          43 :       item_ref->associated_type_set (type);
     514                 :          43 :     }
     515                 :        2922 : }
     516                 :             : 
     517                 :             : bool
     518                 :           0 : TypeBoundPredicate::contains_item (const std::string &search) const
     519                 :             : {
     520                 :           0 :   auto trait_ref = get ();
     521                 :           0 :   const Resolver::TraitItemReference *trait_item_ref = nullptr;
     522                 :           0 :   return trait_ref->lookup_trait_item (search, &trait_item_ref);
     523                 :             : }
     524                 :             : 
     525                 :             : TypeBoundPredicateItem
     526                 :        5971 : TypeBoundPredicate::lookup_associated_item (const std::string &search) const
     527                 :             : {
     528                 :        5971 :   auto trait_ref = get ();
     529                 :        5971 :   const Resolver::TraitItemReference *trait_item_ref = nullptr;
     530                 :        5971 :   if (!trait_ref->lookup_trait_item (search, &trait_item_ref))
     531                 :         498 :     return TypeBoundPredicateItem::error ();
     532                 :             : 
     533                 :        5473 :   return TypeBoundPredicateItem (this, trait_item_ref);
     534                 :             : }
     535                 :             : 
     536                 :        8557 : TypeBoundPredicateItem::TypeBoundPredicateItem (
     537                 :             :   const TypeBoundPredicate *parent,
     538                 :        8557 :   const Resolver::TraitItemReference *trait_item_ref)
     539                 :        8557 :   : parent (parent), trait_item_ref (trait_item_ref)
     540                 :        8557 : {}
     541                 :             : 
     542                 :             : TypeBoundPredicateItem
     543                 :        3014 : TypeBoundPredicateItem::error ()
     544                 :             : {
     545                 :        3014 :   return TypeBoundPredicateItem (nullptr, nullptr);
     546                 :             : }
     547                 :             : 
     548                 :             : bool
     549                 :        8478 : TypeBoundPredicateItem::is_error () const
     550                 :             : {
     551                 :        8478 :   return parent == nullptr || trait_item_ref == nullptr;
     552                 :             : }
     553                 :             : 
     554                 :             : const TypeBoundPredicate *
     555                 :         506 : TypeBoundPredicateItem::get_parent () const
     556                 :             : {
     557                 :         506 :   return parent;
     558                 :             : }
     559                 :             : 
     560                 :             : TypeBoundPredicateItem
     561                 :        2461 : TypeBoundPredicate::lookup_associated_item (
     562                 :             :   const Resolver::TraitItemReference *ref) const
     563                 :             : {
     564                 :        2461 :   return lookup_associated_item (ref->get_identifier ());
     565                 :             : }
     566                 :             : 
     567                 :             : BaseType *
     568                 :        3996 : TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
     569                 :             : {
     570                 :        3996 :   TyTy::BaseType *trait_item_tyty = get_raw_item ()->get_tyty ();
     571                 :        3996 :   if (parent->get_substitution_arguments ().is_empty ())
     572                 :             :     return trait_item_tyty;
     573                 :             : 
     574                 :        3996 :   const Resolver::TraitItemReference *tref = get_raw_item ();
     575                 :        3996 :   bool is_associated_type = tref->get_trait_item_type ();
     576                 :        3996 :   if (is_associated_type)
     577                 :             :     return trait_item_tyty;
     578                 :             : 
     579                 :             :   // set up the self mapping
     580                 :        2519 :   SubstitutionArgumentMappings gargs = parent->get_substitution_arguments ();
     581                 :        2519 :   rust_assert (!gargs.is_empty ());
     582                 :             : 
     583                 :             :   // setup the adjusted mappings
     584                 :        2519 :   std::vector<SubstitutionArg> adjusted_mappings;
     585                 :        5808 :   for (size_t i = 0; i < gargs.get_mappings ().size (); i++)
     586                 :             :     {
     587                 :        3289 :       auto &mapping = gargs.get_mappings ().at (i);
     588                 :             : 
     589                 :        3289 :       bool is_implicit_self = i == 0;
     590                 :        3289 :       TyTy::BaseType *argument
     591                 :        3289 :         = is_implicit_self ? receiver->clone () : mapping.get_tyty ();
     592                 :             : 
     593                 :        3289 :       SubstitutionArg arg (mapping.get_param_mapping (), argument);
     594                 :        3289 :       adjusted_mappings.push_back (std::move (arg));
     595                 :             :     }
     596                 :             : 
     597                 :        2519 :   SubstitutionArgumentMappings adjusted (adjusted_mappings, {},
     598                 :             :                                          gargs.get_regions (),
     599                 :             :                                          gargs.get_locus (),
     600                 :        2519 :                                          gargs.get_subst_cb (),
     601                 :        2519 :                                          true /* trait-mode-flag */);
     602                 :        2519 :   return Resolver::SubstMapperInternal::Resolve (trait_item_tyty, adjusted);
     603                 :        2519 : }
     604                 :             : bool
     605                 :       49765 : TypeBoundPredicate::is_error () const
     606                 :             : {
     607                 :       49765 :   auto context = Resolver::TypeCheckContext::get ();
     608                 :             : 
     609                 :       49765 :   Resolver::TraitReference *ref = nullptr;
     610                 :       49765 :   bool ok = context->lookup_trait_reference (reference, &ref);
     611                 :             : 
     612                 :       49765 :   return !ok || error_flag;
     613                 :             : }
     614                 :             : 
     615                 :             : BaseType *
     616                 :       14930 : TypeBoundPredicate::handle_substitions (
     617                 :             :   SubstitutionArgumentMappings &subst_mappings)
     618                 :             : {
     619                 :       31335 :   for (auto &sub : get_substs ())
     620                 :             :     {
     621                 :       16405 :       if (sub.get_param_ty () == nullptr)
     622                 :           0 :         continue;
     623                 :             : 
     624                 :       16405 :       ParamType *p = sub.get_param_ty ();
     625                 :       16405 :       BaseType *r = p->resolve ();
     626                 :       16405 :       BaseType *s = Resolver::SubstMapperInternal::Resolve (r, subst_mappings);
     627                 :             : 
     628                 :       16405 :       p->set_ty_ref (s->get_ty_ref ());
     629                 :             :     }
     630                 :             : 
     631                 :             :   // associated argument mappings
     632                 :       14947 :   for (auto &it : subst_mappings.get_binding_args ())
     633                 :             :     {
     634                 :          17 :       std::string identifier = it.first;
     635                 :          17 :       TyTy::BaseType *type = it.second;
     636                 :             : 
     637                 :          17 :       TypeBoundPredicateItem item = lookup_associated_item (identifier);
     638                 :          17 :       if (!item.is_error ())
     639                 :             :         {
     640                 :           0 :           const auto item_ref = item.get_raw_item ();
     641                 :           0 :           item_ref->associated_type_set (type);
     642                 :             :         }
     643                 :          17 :     }
     644                 :             : 
     645                 :             :   // FIXME more error handling at some point
     646                 :             :   // used_arguments = subst_mappings;
     647                 :             :   // error_flag |= used_arguments.is_error ();
     648                 :             : 
     649                 :       14930 :   return nullptr;
     650                 :             : }
     651                 :             : 
     652                 :             : bool
     653                 :         245 : TypeBoundPredicate::requires_generic_args () const
     654                 :             : {
     655                 :         245 :   if (is_error ())
     656                 :             :     return false;
     657                 :             : 
     658                 :         245 :   return substitutions.size () > 1;
     659                 :             : }
     660                 :             : 
     661                 :             : bool
     662                 :           0 : TypeBoundPredicate::contains_associated_types () const
     663                 :             : {
     664                 :           0 :   return get_num_associated_bindings () > 0;
     665                 :             : }
     666                 :             : 
     667                 :             : size_t
     668                 :          86 : TypeBoundPredicate::get_num_associated_bindings () const
     669                 :             : {
     670                 :          86 :   size_t count = 0;
     671                 :          86 :   auto trait_ref = get ();
     672                 :         258 :   for (const auto &trait_item : trait_ref->get_trait_items ())
     673                 :             :     {
     674                 :         172 :       bool is_associated_type
     675                 :         172 :         = trait_item.get_trait_item_type ()
     676                 :         172 :           == Resolver::TraitItemReference::TraitItemType::TYPE;
     677                 :         172 :       if (is_associated_type)
     678                 :          86 :         count++;
     679                 :             :     }
     680                 :          86 :   return count;
     681                 :             : }
     682                 :             : 
     683                 :             : TypeBoundPredicateItem
     684                 :          43 : TypeBoundPredicate::lookup_associated_type (const std::string &search)
     685                 :             : {
     686                 :          43 :   TypeBoundPredicateItem item = lookup_associated_item (search);
     687                 :             : 
     688                 :             :   // only need to check that it is infact an associated type because other
     689                 :             :   // wise if it was not found it will just be an error node anyway
     690                 :          43 :   if (!item.is_error ())
     691                 :             :     {
     692                 :          43 :       const auto raw = item.get_raw_item ();
     693                 :          43 :       if (raw->get_trait_item_type ()
     694                 :             :           != Resolver::TraitItemReference::TraitItemType::TYPE)
     695                 :           0 :         return TypeBoundPredicateItem::error ();
     696                 :             :     }
     697                 :          43 :   return item;
     698                 :             : }
     699                 :             : 
     700                 :             : std::vector<TypeBoundPredicateItem>
     701                 :           0 : TypeBoundPredicate::get_associated_type_items ()
     702                 :             : {
     703                 :           0 :   std::vector<TypeBoundPredicateItem> items;
     704                 :           0 :   auto trait_ref = get ();
     705                 :           0 :   for (const auto &trait_item : trait_ref->get_trait_items ())
     706                 :             :     {
     707                 :           0 :       bool is_associated_type
     708                 :           0 :         = trait_item.get_trait_item_type ()
     709                 :           0 :           == Resolver::TraitItemReference::TraitItemType::TYPE;
     710                 :           0 :       if (is_associated_type)
     711                 :             :         {
     712                 :           0 :           TypeBoundPredicateItem item (this, &trait_item);
     713                 :           0 :           items.push_back (std::move (item));
     714                 :             :         }
     715                 :             :     }
     716                 :           0 :   return items;
     717                 :             : }
     718                 :             : 
     719                 :             : bool
     720                 :        6981 : TypeBoundPredicate::is_equal (const TypeBoundPredicate &other) const
     721                 :             : {
     722                 :             :   // check they match the same trait reference
     723                 :       13052 :   if (reference != other.reference)
     724                 :             :     return false;
     725                 :             : 
     726                 :             :   // check that the generics match
     727                 :         923 :   if (get_num_substitutions () != other.get_num_substitutions ())
     728                 :             :     return false;
     729                 :             : 
     730                 :             :   // then match the generics applied
     731                 :        2180 :   for (size_t i = 0; i < get_num_substitutions (); i++)
     732                 :             :     {
     733                 :        1270 :       const SubstitutionParamMapping &a = substitutions.at (i);
     734                 :        1270 :       const SubstitutionParamMapping &b = other.substitutions.at (i);
     735                 :             : 
     736                 :        1270 :       const ParamType *ap = a.get_param_ty ();
     737                 :        1270 :       const ParamType *bp = b.get_param_ty ();
     738                 :             : 
     739                 :        1270 :       const BaseType *apd = ap->destructure ();
     740                 :        1270 :       const BaseType *bpd = bp->destructure ();
     741                 :             : 
     742                 :             :       // FIXME use the unify_and infer inteface or try coerce
     743                 :        1270 :       if (!apd->can_eq (bpd, false /*emit_errors*/))
     744                 :             :         {
     745                 :         316 :           if (!bpd->can_eq (apd, false /*emit_errors*/))
     746                 :             :             return false;
     747                 :             :         }
     748                 :             :     }
     749                 :             : 
     750                 :             :   return true;
     751                 :             : }
     752                 :             : 
     753                 :             : // trait item reference
     754                 :             : 
     755                 :             : const Resolver::TraitItemReference *
     756                 :       16494 : TypeBoundPredicateItem::get_raw_item () const
     757                 :             : {
     758                 :       16494 :   return trait_item_ref;
     759                 :             : }
     760                 :             : 
     761                 :             : bool
     762                 :           0 : TypeBoundPredicateItem::needs_implementation () const
     763                 :             : {
     764                 :           0 :   return !get_raw_item ()->is_optional ();
     765                 :             : }
     766                 :             : 
     767                 :             : location_t
     768                 :           3 : TypeBoundPredicateItem::get_locus () const
     769                 :             : {
     770                 :           3 :   return get_raw_item ()->get_locus ();
     771                 :             : }
     772                 :             : 
     773                 :             : // TypeBoundsMappings
     774                 :             : 
     775                 :    13104876 : TypeBoundsMappings::TypeBoundsMappings (
     776                 :    13104876 :   std::vector<TypeBoundPredicate> specified_bounds)
     777                 :    13104876 :   : specified_bounds (specified_bounds)
     778                 :    13104876 : {}
     779                 :             : 
     780                 :             : std::vector<TypeBoundPredicate> &
     781                 :       20829 : TypeBoundsMappings::get_specified_bounds ()
     782                 :             : {
     783                 :       20829 :   return specified_bounds;
     784                 :             : }
     785                 :             : 
     786                 :             : const std::vector<TypeBoundPredicate> &
     787                 :    12388998 : TypeBoundsMappings::get_specified_bounds () const
     788                 :             : {
     789                 :    12388998 :   return specified_bounds;
     790                 :             : }
     791                 :             : 
     792                 :             : TypeBoundPredicate
     793                 :        1157 : TypeBoundsMappings::lookup_predicate (DefId id)
     794                 :             : {
     795                 :        1211 :   for (auto &b : specified_bounds)
     796                 :             :     {
     797                 :        1250 :       if (b.get_id () == id)
     798                 :        1142 :         return b;
     799                 :             :     }
     800                 :          15 :   return TypeBoundPredicate::error ();
     801                 :             : }
     802                 :             : 
     803                 :             : size_t
     804                 :      117087 : TypeBoundsMappings::num_specified_bounds () const
     805                 :             : {
     806                 :      117087 :   return specified_bounds.size ();
     807                 :             : }
     808                 :             : 
     809                 :             : std::string
     810                 :       17526 : TypeBoundsMappings::raw_bounds_as_string () const
     811                 :             : {
     812                 :       17526 :   std::string buf;
     813                 :       18058 :   for (size_t i = 0; i < specified_bounds.size (); i++)
     814                 :             :     {
     815                 :         532 :       const TypeBoundPredicate &b = specified_bounds.at (i);
     816                 :         532 :       bool has_next = (i + 1) < specified_bounds.size ();
     817                 :        1596 :       buf += b.as_string () + (has_next ? " + " : "");
     818                 :             :     }
     819                 :       17526 :   return buf;
     820                 :             : }
     821                 :             : 
     822                 :             : std::string
     823                 :       17045 : TypeBoundsMappings::bounds_as_string () const
     824                 :             : {
     825                 :       34090 :   return "bounds:[" + raw_bounds_as_string () + "]";
     826                 :             : }
     827                 :             : 
     828                 :             : std::string
     829                 :        4287 : TypeBoundsMappings::raw_bounds_as_name () const
     830                 :             : {
     831                 :        4287 :   std::string buf;
     832                 :        8554 :   for (size_t i = 0; i < specified_bounds.size (); i++)
     833                 :             :     {
     834                 :        4267 :       const TypeBoundPredicate &b = specified_bounds.at (i);
     835                 :        4267 :       bool has_next = (i + 1) < specified_bounds.size ();
     836                 :       12801 :       buf += b.as_name () + (has_next ? " + " : "");
     837                 :             :     }
     838                 :             : 
     839                 :        4287 :   return buf;
     840                 :             : }
     841                 :             : 
     842                 :             : void
     843                 :       17760 : TypeBoundsMappings::add_bound (TypeBoundPredicate predicate)
     844                 :             : {
     845                 :       19653 :   for (auto &bound : specified_bounds)
     846                 :             :     {
     847                 :        9625 :       bool same_trait_ref_p = bound.get_id () == predicate.get_id ();
     848                 :        1893 :       if (same_trait_ref_p)
     849                 :       17760 :         return;
     850                 :             :     }
     851                 :             : 
     852                 :       10028 :   specified_bounds.push_back (predicate);
     853                 :             : }
     854                 :             : 
     855                 :             : } // namespace TyTy
     856                 :             : } // 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.