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: 2025-03-08 13:07:09 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-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-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                 :       12390 : TypeBoundsProbe::TypeBoundsProbe (const TyTy::BaseType *receiver)
      28                 :       12390 :   : TypeCheckBase (), receiver (receiver)
      29                 :       12390 : {}
      30                 :             : 
      31                 :             : std::vector<std::pair<TraitReference *, HIR::ImplBlock *>>
      32                 :       12390 : TypeBoundsProbe::Probe (const TyTy::BaseType *receiver)
      33                 :             : {
      34                 :       12390 :   TypeBoundsProbe probe (receiver);
      35                 :       12390 :   probe.scan ();
      36                 :       12390 :   return probe.trait_references;
      37                 :       12390 : }
      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                 :       12390 : TypeBoundsProbe::scan ()
      64                 :             : {
      65                 :       12390 :   std::vector<std::pair<HIR::TypePath *, HIR::ImplBlock *>>
      66                 :       12390 :     possible_trait_paths;
      67                 :       12390 :   mappings->iterate_impl_blocks (
      68                 :       12390 :     [&] (HirId id, HIR::ImplBlock *impl) mutable -> bool {
      69                 :             :       // we are filtering for trait-impl-blocks
      70                 :      181161 :       if (!impl->has_trait_ref ())
      71                 :             :         return true;
      72                 :             : 
      73                 :      155340 :       HirId impl_ty_id = impl->get_type ()->get_mappings ().get_hirid ();
      74                 :      155340 :       TyTy::BaseType *impl_type = nullptr;
      75                 :      155340 :       if (!query_type (impl_ty_id, &impl_type))
      76                 :             :         return true;
      77                 :             : 
      78                 :      154380 :       if (!receiver->can_eq (impl_type, false))
      79                 :             :         {
      80                 :      135809 :           if (!impl_type->can_eq (receiver, false))
      81                 :             :             return true;
      82                 :             :         }
      83                 :             : 
      84                 :       25945 :       possible_trait_paths.push_back ({impl->get_trait_ref ().get (), impl});
      85                 :       25945 :       return true;
      86                 :             :     });
      87                 :             : 
      88                 :       38335 :   for (auto &path : possible_trait_paths)
      89                 :             :     {
      90                 :       25945 :       HIR::TypePath *trait_path = path.first;
      91                 :       25945 :       TraitReference *trait_ref = TraitResolver::Resolve (*trait_path);
      92                 :             : 
      93                 :       25945 :       if (!trait_ref->is_error ())
      94                 :       25945 :         trait_references.push_back ({trait_ref, path.second});
      95                 :             :     }
      96                 :             : 
      97                 :             :   // marker traits...
      98                 :       12390 :   assemble_sized_builtin ();
      99                 :       12390 : }
     100                 :             : 
     101                 :             : void
     102                 :       12390 : TypeBoundsProbe::assemble_sized_builtin ()
     103                 :             : {
     104                 :       12390 :   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                 :       12390 :   switch (raw->get_kind ())
     115                 :             :     {
     116                 :        8863 :     case TyTy::ARRAY:
     117                 :        8863 :     case TyTy::REF:
     118                 :        8863 :     case TyTy::POINTER:
     119                 :        8863 :     case TyTy::PARAM:
     120                 :        8863 :     case TyTy::FNDEF:
     121                 :        8863 :     case TyTy::FNPTR:
     122                 :        8863 :     case TyTy::BOOL:
     123                 :        8863 :     case TyTy::CHAR:
     124                 :        8863 :     case TyTy::INT:
     125                 :        8863 :     case TyTy::UINT:
     126                 :        8863 :     case TyTy::FLOAT:
     127                 :        8863 :     case TyTy::USIZE:
     128                 :        8863 :     case TyTy::ISIZE:
     129                 :        8863 :     case TyTy::CLOSURE:
     130                 :        8863 :     case TyTy::INFER:
     131                 :        8863 :     case TyTy::NEVER:
     132                 :        8863 :     case TyTy::PLACEHOLDER:
     133                 :        8863 :     case TyTy::PROJECTION:
     134                 :        8863 :       assemble_builtin_candidate (LangItem::Kind::SIZED);
     135                 :        8863 :       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 (LangItem::Kind::SIZED);
     144                 :        3448 :       break;
     145                 :             : 
     146                 :             :     case TyTy::DYNAMIC:
     147                 :             :     case TyTy::ERROR:
     148                 :             :       break;
     149                 :             :     }
     150                 :       12390 : }
     151                 :             : 
     152                 :             : void
     153                 :       12311 : TypeBoundsProbe::assemble_builtin_candidate (LangItem::Kind lang_item)
     154                 :             : {
     155                 :       12311 :   DefId id;
     156                 :       12311 :   bool found_lang_item = mappings->lookup_lang_item (lang_item, &id);
     157                 :       12311 :   if (!found_lang_item)
     158                 :           0 :     return;
     159                 :             : 
     160                 :       12311 :   HIR::Item *item = mappings->lookup_defid (id);
     161                 :       12311 :   if (item == nullptr)
     162                 :             :     return;
     163                 :             : 
     164                 :       12311 :   rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
     165                 :       12311 :   HIR::Trait *trait = static_cast<HIR::Trait *> (item);
     166                 :       12311 :   const TyTy::BaseType *raw = receiver->destructure ();
     167                 :             : 
     168                 :             :   // assemble the reference
     169                 :       12311 :   TraitReference *trait_ref = TraitResolver::Resolve (*trait);
     170                 :       12311 :   trait_references.push_back ({trait_ref, mappings->lookup_builtin_marker ()});
     171                 :             : 
     172                 :       12311 :   rust_debug ("Added builtin lang_item: %s for %s",
     173                 :             :               LangItem::ToString (lang_item).c_str (),
     174                 :             :               raw->get_name ().c_str ());
     175                 :             : }
     176                 :             : 
     177                 :             : TraitReference *
     178                 :        3123 : TypeCheckBase::resolve_trait_path (HIR::TypePath &path)
     179                 :             : {
     180                 :        3123 :   return TraitResolver::Resolve (path);
     181                 :             : }
     182                 :             : 
     183                 :             : TyTy::TypeBoundPredicate
     184                 :       12035 : TypeCheckBase::get_predicate_from_bound (HIR::TypePath &type_path,
     185                 :             :                                          HIR::Type *associated_self,
     186                 :             :                                          BoundPolarity polarity)
     187                 :             : {
     188                 :       12035 :   TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
     189                 :       12035 :   bool already_resolved
     190                 :       12035 :     = context->lookup_predicate (type_path.get_mappings ().get_hirid (),
     191                 :             :                                  &lookup);
     192                 :       12035 :   if (already_resolved)
     193                 :        8912 :     return lookup;
     194                 :             : 
     195                 :        3123 :   TraitReference *trait = resolve_trait_path (type_path);
     196                 :        3123 :   if (trait->is_error ())
     197                 :           8 :     return TyTy::TypeBoundPredicate::error ();
     198                 :             : 
     199                 :        3115 :   TyTy::TypeBoundPredicate predicate (*trait, polarity, type_path.get_locus ());
     200                 :        3115 :   HIR::GenericArgs args
     201                 :        3115 :     = HIR::GenericArgs::create_empty (type_path.get_locus ());
     202                 :             : 
     203                 :        3115 :   auto &final_seg = type_path.get_final_segment ();
     204                 :        3115 :   switch (final_seg->get_type ())
     205                 :             :     {
     206                 :         426 :       case HIR::TypePathSegment::SegmentType::GENERIC: {
     207                 :         426 :         auto final_generic_seg
     208                 :         426 :           = static_cast<HIR::TypePathSegmentGeneric *> (final_seg.get ());
     209                 :         426 :         if (final_generic_seg->has_generic_args ())
     210                 :             :           {
     211                 :         426 :             args = final_generic_seg->get_generic_args ();
     212                 :             :           }
     213                 :             :       }
     214                 :             :       break;
     215                 :             : 
     216                 :          17 :       case HIR::TypePathSegment::SegmentType::FUNCTION: {
     217                 :          17 :         auto final_function_seg
     218                 :          17 :           = static_cast<HIR::TypePathSegmentFunction *> (final_seg.get ());
     219                 :          17 :         auto &fn = final_function_seg->get_function_path ();
     220                 :             : 
     221                 :             :         // we need to make implicit generic args which must be an implicit
     222                 :             :         // Tuple
     223                 :          17 :         auto crate_num = mappings->get_current_crate ();
     224                 :          17 :         HirId implicit_args_id = mappings->get_next_hir_id ();
     225                 :          17 :         Analysis::NodeMapping mapping (crate_num,
     226                 :          17 :                                        final_seg->get_mappings ().get_nodeid (),
     227                 :          17 :                                        implicit_args_id, UNKNOWN_LOCAL_DEFID);
     228                 :             : 
     229                 :          17 :         std::vector<std::unique_ptr<HIR::Type>> params_copy;
     230                 :          34 :         for (auto &p : fn.get_params ())
     231                 :             :           {
     232                 :          17 :             params_copy.push_back (p->clone_type ());
     233                 :             :           }
     234                 :             : 
     235                 :          17 :         HIR::TupleType *implicit_tuple
     236                 :             :           = new HIR::TupleType (mapping, std::move (params_copy),
     237                 :          17 :                                 final_seg->get_locus ());
     238                 :             : 
     239                 :          17 :         std::vector<std::unique_ptr<HIR::Type>> inputs;
     240                 :          17 :         inputs.push_back (std::unique_ptr<HIR::Type> (implicit_tuple));
     241                 :             : 
     242                 :             :         // resolve the fn_once_output type which assumes there must be an output
     243                 :             :         // set
     244                 :          17 :         rust_assert (fn.has_return_type ());
     245                 :          17 :         TypeCheckType::Resolve (fn.get_return_type ().get ());
     246                 :             : 
     247                 :          17 :         HIR::TraitItem *trait_item = mappings->lookup_trait_item_lang_item (
     248                 :             :           LangItem::Kind::FN_ONCE_OUTPUT, final_seg->get_locus ());
     249                 :             : 
     250                 :          17 :         std::vector<HIR::GenericArgsBinding> bindings;
     251                 :          17 :         location_t output_locus = fn.get_return_type ()->get_locus ();
     252                 :          34 :         HIR::GenericArgsBinding binding (Identifier (
     253                 :          17 :                                            trait_item->trait_identifier ()),
     254                 :          34 :                                          fn.get_return_type ()->clone_type (),
     255                 :          17 :                                          output_locus);
     256                 :          17 :         bindings.push_back (std::move (binding));
     257                 :             : 
     258                 :          34 :         args = HIR::GenericArgs ({} /* lifetimes */,
     259                 :             :                                  std::move (inputs) /* type_args*/,
     260                 :             :                                  std::move (bindings) /* binding_args*/,
     261                 :          34 :                                  {} /* const_args */, final_seg->get_locus ());
     262                 :          17 :       }
     263                 :          17 :       break;
     264                 :             : 
     265                 :             :     default:
     266                 :             :       /* nothing to do */
     267                 :             :       break;
     268                 :             :     }
     269                 :             : 
     270                 :        3115 :   if (associated_self != nullptr)
     271                 :             :     {
     272                 :        2862 :       std::vector<std::unique_ptr<HIR::Type>> type_args;
     273                 :        2862 :       type_args.push_back (
     274                 :        2862 :         std::unique_ptr<HIR::Type> (associated_self->clone_type ()));
     275                 :        3306 :       for (auto &arg : args.get_type_args ())
     276                 :             :         {
     277                 :         444 :           type_args.push_back (std::unique_ptr<HIR::Type> (arg->clone_type ()));
     278                 :             :         }
     279                 :             : 
     280                 :        8586 :       args = HIR::GenericArgs (args.get_lifetime_args (), std::move (type_args),
     281                 :        2862 :                                args.get_binding_args (), args.get_const_args (),
     282                 :        5724 :                                args.get_locus ());
     283                 :        2862 :     }
     284                 :             : 
     285                 :             :   // we try to apply generic arguments when they are non empty and or when the
     286                 :             :   // predicate requires them so that we get the relevant Foo expects x number
     287                 :             :   // arguments but got zero see test case rust/compile/traits12.rs
     288                 :        3360 :   if (!args.is_empty () || predicate.requires_generic_args ())
     289                 :             :     {
     290                 :             :       // this is applying generic arguments to a trait reference
     291                 :        2870 :       predicate.apply_generic_arguments (&args, associated_self != nullptr);
     292                 :             :     }
     293                 :             : 
     294                 :        3115 :   context->insert_resolved_predicate (type_path.get_mappings ().get_hirid (),
     295                 :             :                                       predicate);
     296                 :             : 
     297                 :        3115 :   return predicate;
     298                 :        3115 : }
     299                 :             : 
     300                 :             : } // namespace Resolver
     301                 :             : 
     302                 :             : namespace TyTy {
     303                 :             : 
     304                 :       11758 : TypeBoundPredicate::TypeBoundPredicate (
     305                 :             :   const Resolver::TraitReference &trait_reference, BoundPolarity polarity,
     306                 :       11758 :   location_t locus)
     307                 :       23516 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     308                 :       11758 :     reference (trait_reference.get_mappings ().get_defid ()), locus (locus),
     309                 :       23516 :     error_flag (false), polarity (polarity)
     310                 :             : {
     311                 :       11758 :   rust_assert (!trait_reference.get_trait_substs ().empty ());
     312                 :             : 
     313                 :       11758 :   substitutions.clear ();
     314                 :       24598 :   for (const auto &p : trait_reference.get_trait_substs ())
     315                 :       12840 :     substitutions.push_back (p.clone ());
     316                 :             : 
     317                 :             :   // we setup a dummy implict self argument
     318                 :       11758 :   SubstitutionArg placeholder_self (&get_substs ().front (), nullptr);
     319                 :       11758 :   used_arguments.get_mappings ().push_back (placeholder_self);
     320                 :       11758 : }
     321                 :             : 
     322                 :        2082 : TypeBoundPredicate::TypeBoundPredicate (
     323                 :             :   DefId reference, std::vector<SubstitutionParamMapping> subst,
     324                 :        2082 :   BoundPolarity polarity, location_t locus)
     325                 :        4164 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     326                 :        2082 :     reference (reference), locus (locus), error_flag (false),
     327                 :        2082 :     polarity (polarity)
     328                 :             : {
     329                 :        2082 :   rust_assert (!subst.empty ());
     330                 :             : 
     331                 :        2082 :   substitutions.clear ();
     332                 :        4463 :   for (const auto &p : subst)
     333                 :        2381 :     substitutions.push_back (p.clone ());
     334                 :             : 
     335                 :             :   // we setup a dummy implict self argument
     336                 :        2082 :   SubstitutionArg placeholder_self (&get_substs ().front (), nullptr);
     337                 :        2082 :   used_arguments.get_mappings ().push_back (placeholder_self);
     338                 :        2082 : }
     339                 :             : 
     340                 :       38671 : TypeBoundPredicate::TypeBoundPredicate (mark_is_error)
     341                 :       77342 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     342                 :       38671 :     reference (UNKNOWN_DEFID), locus (UNDEF_LOCATION), error_flag (true),
     343                 :       38671 :     polarity (BoundPolarity::RegularBound)
     344                 :       38671 : {}
     345                 :             : 
     346                 :    11828879 : TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
     347                 :    23657758 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     348                 :    11828879 :     reference (other.reference), locus (other.locus),
     349                 :    11828879 :     error_flag (other.error_flag), polarity (other.polarity)
     350                 :             : {
     351                 :    11828879 :   substitutions.clear ();
     352                 :    23885775 :   for (const auto &p : other.get_substs ())
     353                 :    12056896 :     substitutions.push_back (p.clone ());
     354                 :             : 
     355                 :    11828879 :   std::vector<SubstitutionArg> mappings;
     356                 :    23724728 :   for (size_t i = 0; i < other.used_arguments.get_mappings ().size (); i++)
     357                 :             :     {
     358                 :    11895849 :       const SubstitutionArg &oa = other.used_arguments.get_mappings ().at (i);
     359                 :    11895849 :       SubstitutionArg arg (oa);
     360                 :    11895849 :       mappings.push_back (std::move (arg));
     361                 :             :     }
     362                 :             : 
     363                 :             :   // we need to remap the argument mappings based on this copied constructor
     364                 :    11828879 :   std::vector<SubstitutionArg> copied_arg_mappings;
     365                 :    11828879 :   size_t i = 0;
     366                 :    23724728 :   for (const auto &m : other.used_arguments.get_mappings ())
     367                 :             :     {
     368                 :    11895849 :       TyTy::BaseType *argument
     369                 :    11895849 :         = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone ();
     370                 :    11895849 :       SubstitutionArg c (&substitutions.at (i++), argument);
     371                 :    11895849 :       copied_arg_mappings.push_back (std::move (c));
     372                 :             :     }
     373                 :             : 
     374                 :    11828879 :   used_arguments
     375                 :    11828879 :     = SubstitutionArgumentMappings (copied_arg_mappings, {},
     376                 :             :                                     other.used_arguments.get_regions (),
     377                 :    23657758 :                                     other.used_arguments.get_locus ());
     378                 :    11828879 : }
     379                 :             : 
     380                 :             : TypeBoundPredicate &
     381                 :       25533 : TypeBoundPredicate::operator= (const TypeBoundPredicate &other)
     382                 :             : {
     383                 :       25533 :   reference = other.reference;
     384                 :       25533 :   locus = other.locus;
     385                 :       25533 :   error_flag = other.error_flag;
     386                 :       25533 :   polarity = other.polarity;
     387                 :       25533 :   used_arguments = SubstitutionArgumentMappings::empty ();
     388                 :             : 
     389                 :       25533 :   substitutions.clear ();
     390                 :       53056 :   for (const auto &p : other.get_substs ())
     391                 :       27523 :     substitutions.push_back (p.clone ());
     392                 :             : 
     393                 :       25533 :   if (other.is_error ())
     394                 :             :     return *this;
     395                 :             : 
     396                 :       19744 :   std::vector<SubstitutionArg> mappings;
     397                 :       47261 :   for (size_t i = 0; i < other.used_arguments.get_mappings ().size (); i++)
     398                 :             :     {
     399                 :       27517 :       const SubstitutionArg &oa = other.used_arguments.get_mappings ().at (i);
     400                 :       27517 :       SubstitutionArg arg (oa);
     401                 :       27517 :       mappings.push_back (std::move (arg));
     402                 :             :     }
     403                 :             : 
     404                 :             :   // we need to remap the argument mappings based on this copied constructor
     405                 :       19744 :   std::vector<SubstitutionArg> copied_arg_mappings;
     406                 :       19744 :   size_t i = 0;
     407                 :       47261 :   for (const auto &m : other.used_arguments.get_mappings ())
     408                 :             :     {
     409                 :       27517 :       TyTy::BaseType *argument
     410                 :       27517 :         = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone ();
     411                 :       27517 :       SubstitutionArg c (&substitutions.at (i++), argument);
     412                 :       27517 :       copied_arg_mappings.push_back (std::move (c));
     413                 :             :     }
     414                 :             : 
     415                 :       19744 :   used_arguments
     416                 :       19744 :     = SubstitutionArgumentMappings (copied_arg_mappings, {},
     417                 :             :                                     other.used_arguments.get_regions (),
     418                 :       39488 :                                     other.used_arguments.get_locus ());
     419                 :             : 
     420                 :       19744 :   return *this;
     421                 :       19744 : }
     422                 :             : 
     423                 :             : TypeBoundPredicate
     424                 :       38671 : TypeBoundPredicate::error ()
     425                 :             : {
     426                 :       38671 :   return TypeBoundPredicate (mark_is_error ());
     427                 :             : }
     428                 :             : 
     429                 :             : std::string
     430                 :        1558 : TypeBoundPredicate::as_string () const
     431                 :             : {
     432                 :        1558 :   return get ()->as_string () + subst_as_string ();
     433                 :             : }
     434                 :             : 
     435                 :             : std::string
     436                 :        4267 : TypeBoundPredicate::as_name () const
     437                 :             : {
     438                 :        4267 :   return get ()->get_name () + subst_as_string ();
     439                 :             : }
     440                 :             : 
     441                 :             : const Resolver::TraitReference *
     442                 :       46248 : TypeBoundPredicate::get () const
     443                 :             : {
     444                 :       46248 :   auto context = Resolver::TypeCheckContext::get ();
     445                 :             : 
     446                 :       46248 :   Resolver::TraitReference *ref = nullptr;
     447                 :       46248 :   bool ok = context->lookup_trait_reference (reference, &ref);
     448                 :       46248 :   rust_assert (ok);
     449                 :             : 
     450                 :       46248 :   return ref;
     451                 :             : }
     452                 :             : 
     453                 :             : std::string
     454                 :         660 : TypeBoundPredicate::get_name () const
     455                 :             : {
     456                 :         660 :   return get ()->get_name ();
     457                 :             : }
     458                 :             : 
     459                 :             : bool
     460                 :         110 : TypeBoundPredicate::is_object_safe (bool emit_error, location_t locus) const
     461                 :             : {
     462                 :         110 :   const Resolver::TraitReference *trait = get ();
     463                 :         110 :   rust_assert (trait != nullptr);
     464                 :         110 :   return trait->is_object_safe (emit_error, locus);
     465                 :             : }
     466                 :             : 
     467                 :             : void
     468                 :        2923 : TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args,
     469                 :             :                                              bool has_associated_self)
     470                 :             : {
     471                 :        2923 :   rust_assert (!substitutions.empty ());
     472                 :        2923 :   if (has_associated_self)
     473                 :             :     {
     474                 :        2862 :       used_arguments = SubstitutionArgumentMappings::empty ();
     475                 :             :     }
     476                 :             :   else
     477                 :             :     {
     478                 :             :       // we need to get the substitutions argument mappings but also remember
     479                 :             :       // that we have an implicit Self argument which we must be careful to
     480                 :             :       // respect
     481                 :          61 :       rust_assert (!used_arguments.is_empty ());
     482                 :             :     }
     483                 :             : 
     484                 :             :   // now actually perform a substitution
     485                 :        5846 :   used_arguments = get_mappings_from_generic_args (
     486                 :             :     *generic_args,
     487                 :        2923 :     Resolver::TypeCheckContext::get ()->regions_from_generic_args (
     488                 :        2923 :       *generic_args));
     489                 :             : 
     490                 :        2923 :   error_flag |= used_arguments.is_error ();
     491                 :        2923 :   auto &subst_mappings = used_arguments;
     492                 :        6574 :   for (auto &sub : get_substs ())
     493                 :             :     {
     494                 :        3651 :       SubstitutionArg arg = SubstitutionArg::error ();
     495                 :        3651 :       bool ok
     496                 :        3651 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
     497                 :        3651 :       if (ok && arg.get_tyty () != nullptr)
     498                 :        3588 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
     499                 :             :     }
     500                 :             : 
     501                 :             :   // associated argument mappings
     502                 :        2966 :   for (auto &it : subst_mappings.get_binding_args ())
     503                 :             :     {
     504                 :          43 :       std::string identifier = it.first;
     505                 :          43 :       TyTy::BaseType *type = it.second;
     506                 :             : 
     507                 :          43 :       TypeBoundPredicateItem item = lookup_associated_item (identifier);
     508                 :          43 :       rust_assert (!item.is_error ());
     509                 :             : 
     510                 :          43 :       const auto item_ref = item.get_raw_item ();
     511                 :          43 :       item_ref->associated_type_set (type);
     512                 :          43 :     }
     513                 :        2923 : }
     514                 :             : 
     515                 :             : bool
     516                 :           0 : TypeBoundPredicate::contains_item (const std::string &search) const
     517                 :             : {
     518                 :           0 :   auto trait_ref = get ();
     519                 :           0 :   const Resolver::TraitItemReference *trait_item_ref = nullptr;
     520                 :           0 :   return trait_ref->lookup_trait_item (search, &trait_item_ref);
     521                 :             : }
     522                 :             : 
     523                 :             : TypeBoundPredicateItem
     524                 :        5973 : TypeBoundPredicate::lookup_associated_item (const std::string &search) const
     525                 :             : {
     526                 :        5973 :   auto trait_ref = get ();
     527                 :        5973 :   const Resolver::TraitItemReference *trait_item_ref = nullptr;
     528                 :        5973 :   if (!trait_ref->lookup_trait_item (search, &trait_item_ref))
     529                 :         498 :     return TypeBoundPredicateItem::error ();
     530                 :             : 
     531                 :        5475 :   return TypeBoundPredicateItem (this, trait_item_ref);
     532                 :             : }
     533                 :             : 
     534                 :        8560 : TypeBoundPredicateItem::TypeBoundPredicateItem (
     535                 :             :   const TypeBoundPredicate *parent,
     536                 :        8560 :   const Resolver::TraitItemReference *trait_item_ref)
     537                 :        8560 :   : parent (parent), trait_item_ref (trait_item_ref)
     538                 :        8560 : {}
     539                 :             : 
     540                 :             : TypeBoundPredicateItem
     541                 :        3015 : TypeBoundPredicateItem::error ()
     542                 :             : {
     543                 :        3015 :   return TypeBoundPredicateItem (nullptr, nullptr);
     544                 :             : }
     545                 :             : 
     546                 :             : bool
     547                 :        8481 : TypeBoundPredicateItem::is_error () const
     548                 :             : {
     549                 :        8481 :   return parent == nullptr || trait_item_ref == nullptr;
     550                 :             : }
     551                 :             : 
     552                 :             : const TypeBoundPredicate *
     553                 :         506 : TypeBoundPredicateItem::get_parent () const
     554                 :             : {
     555                 :         506 :   return parent;
     556                 :             : }
     557                 :             : 
     558                 :             : TypeBoundPredicateItem
     559                 :        2462 : TypeBoundPredicate::lookup_associated_item (
     560                 :             :   const Resolver::TraitItemReference *ref) const
     561                 :             : {
     562                 :        2462 :   return lookup_associated_item (ref->get_identifier ());
     563                 :             : }
     564                 :             : 
     565                 :             : BaseType *
     566                 :        3997 : TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
     567                 :             : {
     568                 :        3997 :   TyTy::BaseType *trait_item_tyty = get_raw_item ()->get_tyty ();
     569                 :        3997 :   if (parent->get_substitution_arguments ().is_empty ())
     570                 :             :     return trait_item_tyty;
     571                 :             : 
     572                 :        3997 :   const Resolver::TraitItemReference *tref = get_raw_item ();
     573                 :        3997 :   bool is_associated_type = tref->get_trait_item_type ();
     574                 :        3997 :   if (is_associated_type)
     575                 :             :     return trait_item_tyty;
     576                 :             : 
     577                 :             :   // set up the self mapping
     578                 :        2520 :   SubstitutionArgumentMappings gargs = parent->get_substitution_arguments ();
     579                 :        2520 :   rust_assert (!gargs.is_empty ());
     580                 :             : 
     581                 :             :   // setup the adjusted mappings
     582                 :        2520 :   std::vector<SubstitutionArg> adjusted_mappings;
     583                 :        5810 :   for (size_t i = 0; i < gargs.get_mappings ().size (); i++)
     584                 :             :     {
     585                 :        3290 :       auto &mapping = gargs.get_mappings ().at (i);
     586                 :             : 
     587                 :        3290 :       bool is_implicit_self = i == 0;
     588                 :        3290 :       TyTy::BaseType *argument
     589                 :        3290 :         = is_implicit_self ? receiver->clone () : mapping.get_tyty ();
     590                 :             : 
     591                 :        3290 :       SubstitutionArg arg (mapping.get_param_mapping (), argument);
     592                 :        3290 :       adjusted_mappings.push_back (std::move (arg));
     593                 :             :     }
     594                 :             : 
     595                 :        2520 :   SubstitutionArgumentMappings adjusted (adjusted_mappings, {},
     596                 :             :                                          gargs.get_regions (),
     597                 :             :                                          gargs.get_locus (),
     598                 :        2520 :                                          gargs.get_subst_cb (),
     599                 :        2520 :                                          true /* trait-mode-flag */);
     600                 :        2520 :   return Resolver::SubstMapperInternal::Resolve (trait_item_tyty, adjusted);
     601                 :        2520 : }
     602                 :             : bool
     603                 :       49795 : TypeBoundPredicate::is_error () const
     604                 :             : {
     605                 :       49795 :   auto context = Resolver::TypeCheckContext::get ();
     606                 :             : 
     607                 :       49795 :   Resolver::TraitReference *ref = nullptr;
     608                 :       49795 :   bool ok = context->lookup_trait_reference (reference, &ref);
     609                 :             : 
     610                 :       49795 :   return !ok || error_flag;
     611                 :             : }
     612                 :             : 
     613                 :             : BaseType *
     614                 :       14934 : TypeBoundPredicate::handle_substitions (
     615                 :             :   SubstitutionArgumentMappings &subst_mappings)
     616                 :             : {
     617                 :       31343 :   for (auto &sub : get_substs ())
     618                 :             :     {
     619                 :       16409 :       if (sub.get_param_ty () == nullptr)
     620                 :           0 :         continue;
     621                 :             : 
     622                 :       16409 :       ParamType *p = sub.get_param_ty ();
     623                 :       16409 :       BaseType *r = p->resolve ();
     624                 :       16409 :       BaseType *s = Resolver::SubstMapperInternal::Resolve (r, subst_mappings);
     625                 :             : 
     626                 :       16409 :       p->set_ty_ref (s->get_ty_ref ());
     627                 :             :     }
     628                 :             : 
     629                 :             :   // associated argument mappings
     630                 :       14951 :   for (auto &it : subst_mappings.get_binding_args ())
     631                 :             :     {
     632                 :          17 :       std::string identifier = it.first;
     633                 :          17 :       TyTy::BaseType *type = it.second;
     634                 :             : 
     635                 :          17 :       TypeBoundPredicateItem item = lookup_associated_item (identifier);
     636                 :          17 :       if (!item.is_error ())
     637                 :             :         {
     638                 :           0 :           const auto item_ref = item.get_raw_item ();
     639                 :           0 :           item_ref->associated_type_set (type);
     640                 :             :         }
     641                 :          17 :     }
     642                 :             : 
     643                 :             :   // FIXME more error handling at some point
     644                 :             :   // used_arguments = subst_mappings;
     645                 :             :   // error_flag |= used_arguments.is_error ();
     646                 :             : 
     647                 :       14934 :   return nullptr;
     648                 :             : }
     649                 :             : 
     650                 :             : bool
     651                 :         245 : TypeBoundPredicate::requires_generic_args () const
     652                 :             : {
     653                 :         245 :   if (is_error ())
     654                 :             :     return false;
     655                 :             : 
     656                 :         245 :   return substitutions.size () > 1;
     657                 :             : }
     658                 :             : 
     659                 :             : bool
     660                 :           0 : TypeBoundPredicate::contains_associated_types () const
     661                 :             : {
     662                 :           0 :   return get_num_associated_bindings () > 0;
     663                 :             : }
     664                 :             : 
     665                 :             : size_t
     666                 :          86 : TypeBoundPredicate::get_num_associated_bindings () const
     667                 :             : {
     668                 :          86 :   size_t count = 0;
     669                 :          86 :   auto trait_ref = get ();
     670                 :         258 :   for (const auto &trait_item : trait_ref->get_trait_items ())
     671                 :             :     {
     672                 :         172 :       bool is_associated_type
     673                 :         172 :         = trait_item.get_trait_item_type ()
     674                 :         172 :           == Resolver::TraitItemReference::TraitItemType::TYPE;
     675                 :         172 :       if (is_associated_type)
     676                 :          86 :         count++;
     677                 :             :     }
     678                 :          86 :   return count;
     679                 :             : }
     680                 :             : 
     681                 :             : TypeBoundPredicateItem
     682                 :          43 : TypeBoundPredicate::lookup_associated_type (const std::string &search)
     683                 :             : {
     684                 :          43 :   TypeBoundPredicateItem item = lookup_associated_item (search);
     685                 :             : 
     686                 :             :   // only need to check that it is infact an associated type because other
     687                 :             :   // wise if it was not found it will just be an error node anyway
     688                 :          43 :   if (!item.is_error ())
     689                 :             :     {
     690                 :          43 :       const auto raw = item.get_raw_item ();
     691                 :          43 :       if (raw->get_trait_item_type ()
     692                 :             :           != Resolver::TraitItemReference::TraitItemType::TYPE)
     693                 :           0 :         return TypeBoundPredicateItem::error ();
     694                 :             :     }
     695                 :          43 :   return item;
     696                 :             : }
     697                 :             : 
     698                 :             : std::vector<TypeBoundPredicateItem>
     699                 :           0 : TypeBoundPredicate::get_associated_type_items ()
     700                 :             : {
     701                 :           0 :   std::vector<TypeBoundPredicateItem> items;
     702                 :           0 :   auto trait_ref = get ();
     703                 :           0 :   for (const auto &trait_item : trait_ref->get_trait_items ())
     704                 :             :     {
     705                 :           0 :       bool is_associated_type
     706                 :           0 :         = trait_item.get_trait_item_type ()
     707                 :           0 :           == Resolver::TraitItemReference::TraitItemType::TYPE;
     708                 :           0 :       if (is_associated_type)
     709                 :             :         {
     710                 :           0 :           TypeBoundPredicateItem item (this, &trait_item);
     711                 :           0 :           items.push_back (std::move (item));
     712                 :             :         }
     713                 :             :     }
     714                 :           0 :   return items;
     715                 :             : }
     716                 :             : 
     717                 :             : bool
     718                 :        6983 : TypeBoundPredicate::is_equal (const TypeBoundPredicate &other) const
     719                 :             : {
     720                 :             :   // check they match the same trait reference
     721                 :       13056 :   if (reference != other.reference)
     722                 :             :     return false;
     723                 :             : 
     724                 :             :   // check that the generics match
     725                 :         923 :   if (get_num_substitutions () != other.get_num_substitutions ())
     726                 :             :     return false;
     727                 :             : 
     728                 :             :   // then match the generics applied
     729                 :        2180 :   for (size_t i = 0; i < get_num_substitutions (); i++)
     730                 :             :     {
     731                 :        1270 :       const SubstitutionParamMapping &a = substitutions.at (i);
     732                 :        1270 :       const SubstitutionParamMapping &b = other.substitutions.at (i);
     733                 :             : 
     734                 :        1270 :       const ParamType *ap = a.get_param_ty ();
     735                 :        1270 :       const ParamType *bp = b.get_param_ty ();
     736                 :             : 
     737                 :        1270 :       const BaseType *apd = ap->destructure ();
     738                 :        1270 :       const BaseType *bpd = bp->destructure ();
     739                 :             : 
     740                 :             :       // FIXME use the unify_and infer inteface or try coerce
     741                 :        1270 :       if (!apd->can_eq (bpd, false /*emit_errors*/))
     742                 :             :         {
     743                 :         316 :           if (!bpd->can_eq (apd, false /*emit_errors*/))
     744                 :             :             return false;
     745                 :             :         }
     746                 :             :     }
     747                 :             : 
     748                 :             :   return true;
     749                 :             : }
     750                 :             : 
     751                 :             : // trait item reference
     752                 :             : 
     753                 :             : const Resolver::TraitItemReference *
     754                 :       16500 : TypeBoundPredicateItem::get_raw_item () const
     755                 :             : {
     756                 :       16500 :   return trait_item_ref;
     757                 :             : }
     758                 :             : 
     759                 :             : bool
     760                 :           0 : TypeBoundPredicateItem::needs_implementation () const
     761                 :             : {
     762                 :           0 :   return !get_raw_item ()->is_optional ();
     763                 :             : }
     764                 :             : 
     765                 :             : location_t
     766                 :           3 : TypeBoundPredicateItem::get_locus () const
     767                 :             : {
     768                 :           3 :   return get_raw_item ()->get_locus ();
     769                 :             : }
     770                 :             : 
     771                 :             : // TypeBoundsMappings
     772                 :             : 
     773                 :    13106672 : TypeBoundsMappings::TypeBoundsMappings (
     774                 :    13106672 :   std::vector<TypeBoundPredicate> specified_bounds)
     775                 :    13106672 :   : specified_bounds (specified_bounds)
     776                 :    13106672 : {}
     777                 :             : 
     778                 :             : std::vector<TypeBoundPredicate> &
     779                 :       20843 : TypeBoundsMappings::get_specified_bounds ()
     780                 :             : {
     781                 :       20843 :   return specified_bounds;
     782                 :             : }
     783                 :             : 
     784                 :             : const std::vector<TypeBoundPredicate> &
     785                 :    12389460 : TypeBoundsMappings::get_specified_bounds () const
     786                 :             : {
     787                 :    12389460 :   return specified_bounds;
     788                 :             : }
     789                 :             : 
     790                 :             : TypeBoundPredicate
     791                 :        1157 : TypeBoundsMappings::lookup_predicate (DefId id)
     792                 :             : {
     793                 :        1211 :   for (auto &b : specified_bounds)
     794                 :             :     {
     795                 :        1250 :       if (b.get_id () == id)
     796                 :        1142 :         return b;
     797                 :             :     }
     798                 :          15 :   return TypeBoundPredicate::error ();
     799                 :             : }
     800                 :             : 
     801                 :             : size_t
     802                 :      117160 : TypeBoundsMappings::num_specified_bounds () const
     803                 :             : {
     804                 :      117160 :   return specified_bounds.size ();
     805                 :             : }
     806                 :             : 
     807                 :             : std::string
     808                 :       17563 : TypeBoundsMappings::raw_bounds_as_string () const
     809                 :             : {
     810                 :       17563 :   std::string buf;
     811                 :       18095 :   for (size_t i = 0; i < specified_bounds.size (); i++)
     812                 :             :     {
     813                 :         532 :       const TypeBoundPredicate &b = specified_bounds.at (i);
     814                 :         532 :       bool has_next = (i + 1) < specified_bounds.size ();
     815                 :        1596 :       buf += b.as_string () + (has_next ? " + " : "");
     816                 :             :     }
     817                 :       17563 :   return buf;
     818                 :             : }
     819                 :             : 
     820                 :             : std::string
     821                 :       17082 : TypeBoundsMappings::bounds_as_string () const
     822                 :             : {
     823                 :       34164 :   return "bounds:[" + raw_bounds_as_string () + "]";
     824                 :             : }
     825                 :             : 
     826                 :             : std::string
     827                 :        4287 : TypeBoundsMappings::raw_bounds_as_name () const
     828                 :             : {
     829                 :        4287 :   std::string buf;
     830                 :        8554 :   for (size_t i = 0; i < specified_bounds.size (); i++)
     831                 :             :     {
     832                 :        4267 :       const TypeBoundPredicate &b = specified_bounds.at (i);
     833                 :        4267 :       bool has_next = (i + 1) < specified_bounds.size ();
     834                 :       12801 :       buf += b.as_name () + (has_next ? " + " : "");
     835                 :             :     }
     836                 :             : 
     837                 :        4287 :   return buf;
     838                 :             : }
     839                 :             : 
     840                 :             : void
     841                 :       17765 : TypeBoundsMappings::add_bound (TypeBoundPredicate predicate)
     842                 :             : {
     843                 :       19658 :   for (auto &bound : specified_bounds)
     844                 :             :     {
     845                 :        9625 :       bool same_trait_ref_p = bound.get_id () == predicate.get_id ();
     846                 :        1893 :       if (same_trait_ref_p)
     847                 :       17765 :         return;
     848                 :             :     }
     849                 :             : 
     850                 :       10033 :   specified_bounds.push_back (predicate);
     851                 :             : }
     852                 :             : 
     853                 :             : } // namespace TyTy
     854                 :             : } // 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.