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.6 % 503 476
Test Date: 2025-06-21 16:26:05 Functions: 92.7 % 55 51
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-full-decls.h"
      20                 :             : #include "rust-hir-type-bounds.h"
      21                 :             : #include "rust-hir-trait-resolve.h"
      22                 :             : #include "rust-substitution-mapper.h"
      23                 :             : #include "rust-hir-trait-resolve.h"
      24                 :             : #include "rust-type-util.h"
      25                 :             : 
      26                 :             : namespace Rust {
      27                 :             : namespace Resolver {
      28                 :             : 
      29                 :       24404 : TypeBoundsProbe::TypeBoundsProbe (const TyTy::BaseType *receiver)
      30                 :       24404 :   : TypeCheckBase (), receiver (receiver)
      31                 :       24404 : {}
      32                 :             : 
      33                 :             : std::vector<std::pair<TraitReference *, HIR::ImplBlock *>>
      34                 :       24404 : TypeBoundsProbe::Probe (const TyTy::BaseType *receiver)
      35                 :             : {
      36                 :       24404 :   TypeBoundsProbe probe (receiver);
      37                 :       24404 :   probe.scan ();
      38                 :       24404 :   return probe.trait_references;
      39                 :       24404 : }
      40                 :             : 
      41                 :             : bool
      42                 :          91 : TypeBoundsProbe::is_bound_satisfied_for_type (TyTy::BaseType *receiver,
      43                 :             :                                               TraitReference *ref)
      44                 :             : {
      45                 :          91 :   for (auto &bound : receiver->get_specified_bounds ())
      46                 :             :     {
      47                 :           0 :       const TraitReference *b = bound.get ();
      48                 :           0 :       if (b->is_equal (*ref))
      49                 :          91 :         return true;
      50                 :             :     }
      51                 :             : 
      52                 :          91 :   std::vector<std::pair<TraitReference *, HIR::ImplBlock *>> bounds
      53                 :          91 :     = Probe (receiver);
      54                 :         106 :   for (auto &bound : bounds)
      55                 :             :     {
      56                 :         106 :       const TraitReference *b = bound.first;
      57                 :         106 :       if (b->is_equal (*ref))
      58                 :          91 :         return true;
      59                 :             :     }
      60                 :             : 
      61                 :             :   return false;
      62                 :          91 : }
      63                 :             : 
      64                 :             : void
      65                 :       24404 : TypeBoundsProbe::scan ()
      66                 :             : {
      67                 :       24404 :   std::vector<std::pair<HIR::TypePath *, HIR::ImplBlock *>>
      68                 :       24404 :     possible_trait_paths;
      69                 :       24404 :   mappings.iterate_impl_blocks (
      70                 :       24404 :     [&] (HirId id, HIR::ImplBlock *impl) mutable -> bool {
      71                 :             :       // we are filtering for trait-impl-blocks
      72                 :      628239 :       if (!impl->has_trait_ref ())
      73                 :             :         return true;
      74                 :             : 
      75                 :             :       // can be recursive trait resolution
      76                 :      552090 :       HIR::Trait *t = TraitResolver::ResolveHirItem (impl->get_trait_ref ());
      77                 :      552090 :       if (t == nullptr)
      78                 :             :         return true;
      79                 :      552090 :       DefId trait_id = t->get_mappings ().get_defid ();
      80                 :      552090 :       if (context->trait_query_in_progress (trait_id))
      81                 :             :         return true;
      82                 :             : 
      83                 :      550106 :       HirId impl_ty_id = impl->get_type ().get_mappings ().get_hirid ();
      84                 :      550106 :       TyTy::BaseType *impl_type = nullptr;
      85                 :      550106 :       if (!query_type (impl_ty_id, &impl_type))
      86                 :             :         return true;
      87                 :             : 
      88                 :      548558 :       if (!receiver->can_eq (impl_type, false))
      89                 :             :         {
      90                 :      486676 :           if (!impl_type->can_eq (receiver, false))
      91                 :             :             return true;
      92                 :             :         }
      93                 :             : 
      94                 :       87156 :       possible_trait_paths.push_back ({&impl->get_trait_ref (), impl});
      95                 :       87156 :       return true;
      96                 :             :     });
      97                 :             : 
      98                 :      111560 :   for (auto &path : possible_trait_paths)
      99                 :             :     {
     100                 :       87156 :       HIR::TypePath *trait_path = path.first;
     101                 :       87156 :       TraitReference *trait_ref = TraitResolver::Resolve (*trait_path);
     102                 :             : 
     103                 :       87156 :       if (!trait_ref->is_error ())
     104                 :       87156 :         trait_references.push_back ({trait_ref, path.second});
     105                 :             :     }
     106                 :             : 
     107                 :             :   // marker traits...
     108                 :       24404 :   assemble_sized_builtin ();
     109                 :             : 
     110                 :             :   // add auto trait bounds
     111                 :       24440 :   for (auto *auto_trait : mappings.get_auto_traits ())
     112                 :          36 :     add_trait_bound (auto_trait);
     113                 :       24404 : }
     114                 :             : 
     115                 :             : void
     116                 :       24404 : TypeBoundsProbe::assemble_sized_builtin ()
     117                 :             : {
     118                 :       24404 :   const TyTy::BaseType *raw = receiver->destructure ();
     119                 :             : 
     120                 :             :   // https://runrust.miraheze.org/wiki/Dynamically_Sized_Type
     121                 :             :   // everything is sized except for:
     122                 :             :   //
     123                 :             :   //   1. dyn traits
     124                 :             :   //   2. slices
     125                 :             :   //   3. str
     126                 :             :   //   4. ADT's which contain any of the above
     127                 :             :   //   t. tuples which contain any of the above
     128                 :       24404 :   switch (raw->get_kind ())
     129                 :             :     {
     130                 :       19346 :     case TyTy::ARRAY:
     131                 :       19346 :     case TyTy::REF:
     132                 :       19346 :     case TyTy::POINTER:
     133                 :       19346 :     case TyTy::PARAM:
     134                 :       19346 :     case TyTy::FNDEF:
     135                 :       19346 :     case TyTy::FNPTR:
     136                 :       19346 :     case TyTy::BOOL:
     137                 :       19346 :     case TyTy::CHAR:
     138                 :       19346 :     case TyTy::INT:
     139                 :       19346 :     case TyTy::UINT:
     140                 :       19346 :     case TyTy::FLOAT:
     141                 :       19346 :     case TyTy::USIZE:
     142                 :       19346 :     case TyTy::ISIZE:
     143                 :       19346 :     case TyTy::CLOSURE:
     144                 :       19346 :     case TyTy::INFER:
     145                 :       19346 :     case TyTy::NEVER:
     146                 :       19346 :     case TyTy::PLACEHOLDER:
     147                 :       19346 :     case TyTy::PROJECTION:
     148                 :       19346 :     case TyTy::OPAQUE:
     149                 :       19346 :       assemble_builtin_candidate (LangItem::Kind::SIZED);
     150                 :       19346 :       break;
     151                 :             : 
     152                 :             :       // FIXME str and slice need to be moved and test cases updated
     153                 :        4817 :     case TyTy::SLICE:
     154                 :        4817 :     case TyTy::STR:
     155                 :        4817 :     case TyTy::ADT:
     156                 :        4817 :     case TyTy::TUPLE:
     157                 :             :       // FIXME add extra checks
     158                 :        4817 :       assemble_builtin_candidate (LangItem::Kind::SIZED);
     159                 :        4817 :       break;
     160                 :             : 
     161                 :             :     case TyTy::DYNAMIC:
     162                 :             :     case TyTy::ERROR:
     163                 :             :       break;
     164                 :             :     }
     165                 :       24404 : }
     166                 :             : 
     167                 :             : void
     168                 :       23916 : TypeBoundsProbe::add_trait_bound (HIR::Trait *trait)
     169                 :             : {
     170                 :       23916 :   auto trait_ref = TraitResolver::Resolve (*trait);
     171                 :             : 
     172                 :       23916 :   trait_references.push_back ({trait_ref, mappings.lookup_builtin_marker ()});
     173                 :       23916 : }
     174                 :             : 
     175                 :             : void
     176                 :       24163 : TypeBoundsProbe::assemble_builtin_candidate (LangItem::Kind lang_item)
     177                 :             : {
     178                 :       24163 :   auto lang_item_defined = mappings.lookup_lang_item (lang_item);
     179                 :       24163 :   if (!lang_item_defined)
     180                 :         283 :     return;
     181                 :       23880 :   DefId &id = lang_item_defined.value ();
     182                 :             : 
     183                 :       23880 :   auto defid = mappings.lookup_defid (id);
     184                 :       23880 :   if (!defid)
     185                 :             :     return;
     186                 :       23880 :   auto item = defid.value ();
     187                 :             : 
     188                 :       23880 :   rust_assert (item->get_item_kind () == HIR::Item::ItemKind::Trait);
     189                 :       23880 :   HIR::Trait *trait = static_cast<HIR::Trait *> (item);
     190                 :       23880 :   const TyTy::BaseType *raw = receiver->destructure ();
     191                 :             : 
     192                 :       23880 :   add_trait_bound (trait);
     193                 :             : 
     194                 :       23880 :   rust_debug ("Added builtin lang_item: %s for %s",
     195                 :             :               LangItem::ToString (lang_item).c_str (),
     196                 :             :               raw->get_name ().c_str ());
     197                 :             : }
     198                 :             : 
     199                 :             : TraitReference *
     200                 :        5375 : TypeCheckBase::resolve_trait_path (HIR::TypePath &path)
     201                 :             : {
     202                 :        5375 :   return TraitResolver::Resolve (path);
     203                 :             : }
     204                 :             : 
     205                 :             : TyTy::TypeBoundPredicate
     206                 :       21568 : TypeCheckBase::get_predicate_from_bound (
     207                 :             :   HIR::TypePath &type_path,
     208                 :             :   tl::optional<std::reference_wrapper<HIR::Type>> associated_self,
     209                 :             :   BoundPolarity polarity, bool is_qualified_type_path)
     210                 :             : {
     211                 :       21568 :   TyTy::TypeBoundPredicate lookup = TyTy::TypeBoundPredicate::error ();
     212                 :       21568 :   bool already_resolved
     213                 :       21568 :     = context->lookup_predicate (type_path.get_mappings ().get_hirid (),
     214                 :             :                                  &lookup);
     215                 :       21568 :   if (already_resolved)
     216                 :       16193 :     return lookup;
     217                 :             : 
     218                 :        5375 :   TraitReference *trait = resolve_trait_path (type_path);
     219                 :        5375 :   if (trait->is_error ())
     220                 :          18 :     return TyTy::TypeBoundPredicate::error ();
     221                 :             : 
     222                 :        5357 :   TyTy::TypeBoundPredicate predicate (*trait, polarity, type_path.get_locus ());
     223                 :        5357 :   HIR::GenericArgs args
     224                 :        5357 :     = HIR::GenericArgs::create_empty (type_path.get_locus ());
     225                 :             : 
     226                 :        5357 :   auto &final_seg = type_path.get_final_segment ();
     227                 :        5357 :   switch (final_seg.get_type ())
     228                 :             :     {
     229                 :         712 :       case HIR::TypePathSegment::SegmentType::GENERIC: {
     230                 :         712 :         auto &final_generic_seg
     231                 :             :           = static_cast<HIR::TypePathSegmentGeneric &> (final_seg);
     232                 :         712 :         if (final_generic_seg.has_generic_args ())
     233                 :             :           {
     234                 :         712 :             args = final_generic_seg.get_generic_args ();
     235                 :         712 :             if (args.get_binding_args ().size () > 0
     236                 :         712 :                 && associated_self.has_value () && is_qualified_type_path)
     237                 :             :               {
     238                 :           2 :                 auto &binding_args = args.get_binding_args ();
     239                 :             : 
     240                 :           2 :                 rich_location r (line_table, args.get_locus ());
     241                 :           4 :                 for (auto it = binding_args.begin (); it != binding_args.end ();
     242                 :           2 :                      it++)
     243                 :             :                   {
     244                 :           2 :                     auto &arg = *it;
     245                 :           2 :                     r.add_fixit_remove (arg.get_locus ());
     246                 :             :                   }
     247                 :           2 :                 rust_error_at (r, ErrorCode::E0229,
     248                 :             :                                "associated type bindings are not allowed here");
     249                 :           2 :               }
     250                 :             :           }
     251                 :             :       }
     252                 :             :       break;
     253                 :             : 
     254                 :          26 :       case HIR::TypePathSegment::SegmentType::FUNCTION: {
     255                 :          26 :         auto &final_function_seg
     256                 :             :           = static_cast<HIR::TypePathSegmentFunction &> (final_seg);
     257                 :          26 :         auto &fn = final_function_seg.get_function_path ();
     258                 :             : 
     259                 :             :         // we need to make implicit generic args which must be an implicit
     260                 :             :         // Tuple
     261                 :          26 :         auto crate_num = mappings.get_current_crate ();
     262                 :          26 :         HirId implicit_args_id = mappings.get_next_hir_id ();
     263                 :          26 :         Analysis::NodeMapping mapping (crate_num,
     264                 :          26 :                                        final_seg.get_mappings ().get_nodeid (),
     265                 :          26 :                                        implicit_args_id, UNKNOWN_LOCAL_DEFID);
     266                 :             : 
     267                 :          26 :         std::vector<std::unique_ptr<HIR::Type>> params_copy;
     268                 :          56 :         for (auto &p : fn.get_params ())
     269                 :             :           {
     270                 :          30 :             params_copy.push_back (p->clone_type ());
     271                 :             :           }
     272                 :             : 
     273                 :          26 :         std::vector<std::unique_ptr<HIR::Type>> inputs;
     274                 :          26 :         inputs.push_back (
     275                 :          26 :           std::make_unique<HIR::TupleType> (mapping, std::move (params_copy),
     276                 :          26 :                                             final_seg.get_locus ()));
     277                 :             : 
     278                 :             :         // resolve the fn_once_output type which assumes there must be an output
     279                 :             :         // set
     280                 :          26 :         rust_assert (fn.has_return_type ());
     281                 :          26 :         TypeCheckType::Resolve (fn.get_return_type ());
     282                 :             : 
     283                 :          26 :         HIR::TraitItem *trait_item
     284                 :          26 :           = mappings
     285                 :          26 :               .lookup_trait_item_lang_item (LangItem::Kind::FN_ONCE_OUTPUT,
     286                 :             :                                             final_seg.get_locus ())
     287                 :          26 :               .value ();
     288                 :             : 
     289                 :          26 :         std::vector<HIR::GenericArgsBinding> bindings;
     290                 :          26 :         location_t output_locus = fn.get_return_type ().get_locus ();
     291                 :          52 :         HIR::GenericArgsBinding binding (Identifier (
     292                 :          26 :                                            trait_item->trait_identifier ()),
     293                 :          52 :                                          fn.get_return_type ().clone_type (),
     294                 :          26 :                                          output_locus);
     295                 :          26 :         bindings.push_back (std::move (binding));
     296                 :             : 
     297                 :          52 :         args = HIR::GenericArgs ({} /* lifetimes */,
     298                 :             :                                  std::move (inputs) /* type_args*/,
     299                 :             :                                  std::move (bindings) /* binding_args*/,
     300                 :          52 :                                  {} /* const_args */, final_seg.get_locus ());
     301                 :          26 :       }
     302                 :          26 :       break;
     303                 :             : 
     304                 :             :     default:
     305                 :             :       /* nothing to do */
     306                 :             :       break;
     307                 :             :     }
     308                 :             : 
     309                 :        5357 :   if (associated_self.has_value ())
     310                 :             :     {
     311                 :        4835 :       std::vector<std::unique_ptr<HIR::Type>> type_args;
     312                 :        4835 :       type_args.push_back (std::unique_ptr<HIR::Type> (
     313                 :        4835 :         associated_self.value ().get ().clone_type ()));
     314                 :        5537 :       for (auto &arg : args.get_type_args ())
     315                 :             :         {
     316                 :         702 :           type_args.push_back (std::unique_ptr<HIR::Type> (arg->clone_type ()));
     317                 :             :         }
     318                 :             : 
     319                 :       14505 :       args = HIR::GenericArgs (args.get_lifetime_args (), std::move (type_args),
     320                 :        4835 :                                args.get_binding_args (), args.get_const_args (),
     321                 :        9670 :                                args.get_locus ());
     322                 :        4835 :     }
     323                 :             : 
     324                 :             :   // we try to apply generic arguments when they are non empty and or when the
     325                 :             :   // predicate requires them so that we get the relevant Foo expects x number
     326                 :             :   // arguments but got zero see test case rust/compile/traits12.rs
     327                 :        5357 :   if (!args.is_empty () || predicate.requires_generic_args ())
     328                 :             :     {
     329                 :             :       // this is applying generic arguments to a trait reference
     330                 :        4873 :       predicate.apply_generic_arguments (&args, associated_self.has_value ());
     331                 :             :     }
     332                 :             : 
     333                 :        5357 :   context->insert_resolved_predicate (type_path.get_mappings ().get_hirid (),
     334                 :             :                                       predicate);
     335                 :             : 
     336                 :        5357 :   return predicate;
     337                 :       21568 : }
     338                 :             : 
     339                 :             : } // namespace Resolver
     340                 :             : 
     341                 :             : namespace TyTy {
     342                 :             : 
     343                 :       17381 : TypeBoundPredicate::TypeBoundPredicate (
     344                 :             :   const Resolver::TraitReference &trait_reference, BoundPolarity polarity,
     345                 :       17381 :   location_t locus)
     346                 :       34762 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     347                 :       17381 :     reference (trait_reference.get_mappings ().get_defid ()), locus (locus),
     348                 :       17381 :     error_flag (false), polarity (polarity),
     349                 :       52143 :     super_traits (trait_reference.get_super_traits ())
     350                 :             : {
     351                 :       17381 :   rust_assert (!trait_reference.get_trait_substs ().empty ());
     352                 :             : 
     353                 :       17381 :   substitutions.clear ();
     354                 :       36726 :   for (const auto &p : trait_reference.get_trait_substs ())
     355                 :       19345 :     substitutions.push_back (p.clone ());
     356                 :             : 
     357                 :             :   // we setup a dummy implict self argument
     358                 :       17381 :   SubstitutionArg placeholder_self (&get_substs ().front (), nullptr);
     359                 :       17381 :   used_arguments.get_mappings ().push_back (placeholder_self);
     360                 :       17381 : }
     361                 :             : 
     362                 :        3155 : TypeBoundPredicate::TypeBoundPredicate (
     363                 :             :   DefId reference, std::vector<SubstitutionParamMapping> subst,
     364                 :        3155 :   BoundPolarity polarity, location_t locus)
     365                 :        6310 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     366                 :        3155 :     reference (reference), locus (locus), error_flag (false),
     367                 :        6310 :     polarity (polarity)
     368                 :             : {
     369                 :        3155 :   rust_assert (!subst.empty ());
     370                 :             : 
     371                 :        3155 :   substitutions.clear ();
     372                 :        6779 :   for (const auto &p : subst)
     373                 :        3624 :     substitutions.push_back (p.clone ());
     374                 :             : 
     375                 :             :   // we setup a dummy implict self argument
     376                 :        3155 :   SubstitutionArg placeholder_self (&get_substs ().front (), nullptr);
     377                 :        3155 :   used_arguments.get_mappings ().push_back (placeholder_self);
     378                 :        3155 : }
     379                 :             : 
     380                 :       70040 : TypeBoundPredicate::TypeBoundPredicate (mark_is_error)
     381                 :      140080 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     382                 :       70040 :     reference (UNKNOWN_DEFID), locus (UNDEF_LOCATION), error_flag (true),
     383                 :       70040 :     polarity (BoundPolarity::RegularBound)
     384                 :       70040 : {}
     385                 :             : 
     386                 :    31622038 : TypeBoundPredicate::TypeBoundPredicate (const TypeBoundPredicate &other)
     387                 :    63244076 :   : SubstitutionRef ({}, SubstitutionArgumentMappings::empty (), {}),
     388                 :    31622038 :     reference (other.reference), locus (other.locus),
     389                 :    31622038 :     error_flag (other.error_flag), polarity (other.polarity),
     390                 :    63244076 :     super_traits (other.super_traits)
     391                 :             : {
     392                 :    31622038 :   substitutions.clear ();
     393                 :    63807589 :   for (const auto &p : other.get_substs ())
     394                 :    32185551 :     substitutions.push_back (p.clone ());
     395                 :             : 
     396                 :    31622038 :   std::vector<SubstitutionArg> mappings;
     397                 :    63424868 :   for (size_t i = 0; i < other.used_arguments.get_mappings ().size (); i++)
     398                 :             :     {
     399                 :    31802830 :       const SubstitutionArg &oa = other.used_arguments.get_mappings ().at (i);
     400                 :    31802830 :       SubstitutionArg arg (oa);
     401                 :    31802830 :       mappings.push_back (std::move (arg));
     402                 :             :     }
     403                 :             : 
     404                 :             :   // we need to remap the argument mappings based on this copied constructor
     405                 :    31622038 :   std::vector<SubstitutionArg> copied_arg_mappings;
     406                 :    31622038 :   size_t i = 0;
     407                 :    63424868 :   for (const auto &m : other.used_arguments.get_mappings ())
     408                 :             :     {
     409                 :    31802830 :       TyTy::BaseType *argument
     410                 :    31802830 :         = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone ();
     411                 :    31802830 :       SubstitutionArg c (&substitutions.at (i++), argument);
     412                 :    31802830 :       copied_arg_mappings.push_back (std::move (c));
     413                 :             :     }
     414                 :             : 
     415                 :    31622038 :   used_arguments
     416                 :    31622038 :     = SubstitutionArgumentMappings (copied_arg_mappings, {},
     417                 :             :                                     other.used_arguments.get_regions (),
     418                 :    63244076 :                                     other.used_arguments.get_locus ());
     419                 :    31622038 : }
     420                 :             : 
     421                 :             : TypeBoundPredicate &
     422                 :       48589 : TypeBoundPredicate::operator= (const TypeBoundPredicate &other)
     423                 :             : {
     424                 :       48589 :   reference = other.reference;
     425                 :       48589 :   locus = other.locus;
     426                 :       48589 :   error_flag = other.error_flag;
     427                 :       48589 :   polarity = other.polarity;
     428                 :       48589 :   used_arguments = SubstitutionArgumentMappings::empty ();
     429                 :             : 
     430                 :       48589 :   substitutions.clear ();
     431                 :      105886 :   for (const auto &p : other.get_substs ())
     432                 :       57297 :     substitutions.push_back (p.clone ());
     433                 :             : 
     434                 :       48589 :   if (other.is_error ())
     435                 :             :     return *this;
     436                 :             : 
     437                 :       40018 :   std::vector<SubstitutionArg> mappings;
     438                 :       97300 :   for (size_t i = 0; i < other.used_arguments.get_mappings ().size (); i++)
     439                 :             :     {
     440                 :       57282 :       const SubstitutionArg &oa = other.used_arguments.get_mappings ().at (i);
     441                 :       57282 :       SubstitutionArg arg (oa);
     442                 :       57282 :       mappings.push_back (std::move (arg));
     443                 :             :     }
     444                 :             : 
     445                 :             :   // we need to remap the argument mappings based on this copied constructor
     446                 :       40018 :   std::vector<SubstitutionArg> copied_arg_mappings;
     447                 :       40018 :   size_t i = 0;
     448                 :       97300 :   for (const auto &m : other.used_arguments.get_mappings ())
     449                 :             :     {
     450                 :       57282 :       TyTy::BaseType *argument
     451                 :       57282 :         = m.get_tyty () == nullptr ? nullptr : m.get_tyty ()->clone ();
     452                 :       57282 :       SubstitutionArg c (&substitutions.at (i++), argument);
     453                 :       57282 :       copied_arg_mappings.push_back (std::move (c));
     454                 :             :     }
     455                 :             : 
     456                 :       40018 :   used_arguments
     457                 :       40018 :     = SubstitutionArgumentMappings (copied_arg_mappings, {},
     458                 :             :                                     other.used_arguments.get_regions (),
     459                 :       80036 :                                     other.used_arguments.get_locus ());
     460                 :       40018 :   super_traits = other.super_traits;
     461                 :             : 
     462                 :       40018 :   return *this;
     463                 :       40018 : }
     464                 :             : 
     465                 :             : TypeBoundPredicate
     466                 :       70040 : TypeBoundPredicate::error ()
     467                 :             : {
     468                 :       70040 :   return TypeBoundPredicate (mark_is_error ());
     469                 :             : }
     470                 :             : 
     471                 :             : std::string
     472                 :        2350 : TypeBoundPredicate::as_string () const
     473                 :             : {
     474                 :        2350 :   return get ()->as_string () + subst_as_string ();
     475                 :             : }
     476                 :             : 
     477                 :             : std::string
     478                 :        8475 : TypeBoundPredicate::as_name () const
     479                 :             : {
     480                 :        8475 :   return get ()->get_name () + subst_as_string ();
     481                 :             : }
     482                 :             : 
     483                 :             : const Resolver::TraitReference *
     484                 :      141234 : TypeBoundPredicate::get () const
     485                 :             : {
     486                 :      141234 :   auto context = Resolver::TypeCheckContext::get ();
     487                 :             : 
     488                 :      141234 :   Resolver::TraitReference *ref = nullptr;
     489                 :      141234 :   bool ok = context->lookup_trait_reference (reference, &ref);
     490                 :      141234 :   rust_assert (ok);
     491                 :             : 
     492                 :      141234 :   return ref;
     493                 :             : }
     494                 :             : 
     495                 :             : std::string
     496                 :        1040 : TypeBoundPredicate::get_name () const
     497                 :             : {
     498                 :        1040 :   return get ()->get_name ();
     499                 :             : }
     500                 :             : 
     501                 :             : bool
     502                 :         188 : TypeBoundPredicate::is_object_safe (bool emit_error, location_t locus) const
     503                 :             : {
     504                 :         188 :   const Resolver::TraitReference *trait = get ();
     505                 :         188 :   rust_assert (trait != nullptr);
     506                 :         188 :   return trait->is_object_safe (emit_error, locus);
     507                 :             : }
     508                 :             : 
     509                 :             : void
     510                 :        4934 : TypeBoundPredicate::apply_generic_arguments (HIR::GenericArgs *generic_args,
     511                 :             :                                              bool has_associated_self)
     512                 :             : {
     513                 :        4934 :   rust_assert (!substitutions.empty ());
     514                 :        4934 :   if (has_associated_self)
     515                 :             :     {
     516                 :        4835 :       used_arguments = SubstitutionArgumentMappings::empty ();
     517                 :             :     }
     518                 :             :   else
     519                 :             :     {
     520                 :             :       // we need to get the substitutions argument mappings but also remember
     521                 :             :       // that we have an implicit Self argument which we must be careful to
     522                 :             :       // respect
     523                 :          99 :       rust_assert (!used_arguments.is_empty ());
     524                 :             :     }
     525                 :             : 
     526                 :             :   // now actually perform a substitution
     527                 :        4934 :   auto args = get_mappings_from_generic_args (
     528                 :             :     *generic_args,
     529                 :        4934 :     Resolver::TypeCheckContext::get ()->regions_from_generic_args (
     530                 :        9868 :       *generic_args));
     531                 :             : 
     532                 :        4934 :   apply_argument_mappings (args);
     533                 :        4934 : }
     534                 :             : 
     535                 :             : void
     536                 :        8251 : TypeBoundPredicate::apply_argument_mappings (
     537                 :             :   SubstitutionArgumentMappings &arguments)
     538                 :             : {
     539                 :        8251 :   used_arguments = arguments;
     540                 :        8251 :   error_flag |= used_arguments.is_error ();
     541                 :        8251 :   auto &subst_mappings = used_arguments;
     542                 :       17888 :   for (auto &sub : get_substs ())
     543                 :             :     {
     544                 :        9637 :       SubstitutionArg arg = SubstitutionArg::error ();
     545                 :        9637 :       bool ok
     546                 :        9637 :         = subst_mappings.get_argument_for_symbol (sub.get_param_ty (), &arg);
     547                 :        9637 :       if (ok && arg.get_tyty () != nullptr)
     548                 :        9526 :         sub.fill_param_ty (subst_mappings, subst_mappings.get_locus ());
     549                 :             :     }
     550                 :             : 
     551                 :             :   // associated argument mappings
     552                 :        8310 :   for (auto &it : subst_mappings.get_binding_args ())
     553                 :             :     {
     554                 :          59 :       std::string identifier = it.first;
     555                 :          59 :       TyTy::BaseType *type = it.second;
     556                 :             : 
     557                 :          59 :       TypeBoundPredicateItem item = lookup_associated_item (identifier);
     558                 :          59 :       rust_assert (!item.is_error ());
     559                 :             : 
     560                 :          59 :       const auto item_ref = item.get_raw_item ();
     561                 :          59 :       item_ref->associated_type_set (type);
     562                 :          59 :     }
     563                 :             : 
     564                 :       11568 :   for (auto &super_trait : super_traits)
     565                 :             :     {
     566                 :        3317 :       auto adjusted
     567                 :             :         = super_trait.adjust_mappings_for_this (used_arguments,
     568                 :        3317 :                                                 true /*trait mode*/);
     569                 :        3317 :       super_trait.apply_argument_mappings (adjusted);
     570                 :        3317 :     }
     571                 :        8251 : }
     572                 :             : 
     573                 :             : bool
     574                 :           0 : TypeBoundPredicate::contains_item (const std::string &search) const
     575                 :             : {
     576                 :           0 :   auto trait_ref = get ();
     577                 :           0 :   const Resolver::TraitItemReference *trait_item_ref = nullptr;
     578                 :           0 :   return trait_ref->lookup_trait_item (search, &trait_item_ref);
     579                 :             : }
     580                 :             : 
     581                 :             : TypeBoundPredicateItem
     582                 :       10274 : TypeBoundPredicate::lookup_associated_item (const std::string &search) const
     583                 :             : {
     584                 :       10274 :   auto trait_ref = get ();
     585                 :       10274 :   const Resolver::TraitItemReference *trait_item_ref = nullptr;
     586                 :       10274 :   if (trait_ref->lookup_trait_item (search, &trait_item_ref,
     587                 :             :                                     false /*lookup supers*/))
     588                 :        9432 :     return TypeBoundPredicateItem (*this, trait_item_ref);
     589                 :             : 
     590                 :         846 :   for (auto &super_trait : super_traits)
     591                 :             :     {
     592                 :         140 :       auto lookup = super_trait.lookup_associated_item (search);
     593                 :         140 :       if (!lookup.is_error ())
     594                 :         136 :         return lookup;
     595                 :         140 :     }
     596                 :             : 
     597                 :         706 :   return TypeBoundPredicateItem::error ();
     598                 :             : }
     599                 :             : 
     600                 :       14521 : TypeBoundPredicateItem::TypeBoundPredicateItem (
     601                 :             :   const TypeBoundPredicate parent,
     602                 :       14521 :   const Resolver::TraitItemReference *trait_item_ref)
     603                 :       14521 :   : parent (parent), trait_item_ref (trait_item_ref)
     604                 :       14521 : {}
     605                 :             : 
     606                 :        5900 : TypeBoundPredicateItem::TypeBoundPredicateItem (
     607                 :        5900 :   const TypeBoundPredicateItem &other)
     608                 :        5900 :   : parent (other.parent), trait_item_ref (other.trait_item_ref)
     609                 :        5900 : {}
     610                 :             : 
     611                 :             : TypeBoundPredicateItem &
     612                 :        4294 : TypeBoundPredicateItem::operator= (const TypeBoundPredicateItem &other)
     613                 :             : {
     614                 :        4294 :   parent = other.parent;
     615                 :        4294 :   trait_item_ref = other.trait_item_ref;
     616                 :             : 
     617                 :        4294 :   return *this;
     618                 :             : }
     619                 :             : 
     620                 :             : TypeBoundPredicateItem
     621                 :        5006 : TypeBoundPredicateItem::error ()
     622                 :             : {
     623                 :        5006 :   return TypeBoundPredicateItem (TypeBoundPredicate::error (), nullptr);
     624                 :             : }
     625                 :             : 
     626                 :             : bool
     627                 :       14578 : TypeBoundPredicateItem::is_error () const
     628                 :             : {
     629                 :       14578 :   return parent.is_error () || trait_item_ref == nullptr;
     630                 :             : }
     631                 :             : 
     632                 :             : const TypeBoundPredicate *
     633                 :         730 : TypeBoundPredicateItem::get_parent () const
     634                 :             : {
     635                 :         730 :   return &parent;
     636                 :             : }
     637                 :             : 
     638                 :             : TypeBoundPredicateItem
     639                 :        4239 : TypeBoundPredicate::lookup_associated_item (
     640                 :             :   const Resolver::TraitItemReference *ref) const
     641                 :             : {
     642                 :        4239 :   return lookup_associated_item (ref->get_identifier ());
     643                 :             : }
     644                 :             : 
     645                 :             : BaseType *
     646                 :        6465 : TypeBoundPredicateItem::get_tyty_for_receiver (const TyTy::BaseType *receiver)
     647                 :             : {
     648                 :        6465 :   TyTy::BaseType *trait_item_tyty = get_raw_item ()->get_tyty ();
     649                 :        6465 :   if (parent.get_substitution_arguments ().is_empty ())
     650                 :             :     return trait_item_tyty;
     651                 :             : 
     652                 :        6465 :   const Resolver::TraitItemReference *tref = get_raw_item ();
     653                 :        6465 :   bool is_associated_type = tref->get_trait_item_type ();
     654                 :        6465 :   if (is_associated_type)
     655                 :             :     return trait_item_tyty;
     656                 :             : 
     657                 :             :   // set up the self mapping
     658                 :        4216 :   SubstitutionArgumentMappings gargs = parent.get_substitution_arguments ();
     659                 :        4216 :   rust_assert (!gargs.is_empty ());
     660                 :             : 
     661                 :             :   // setup the adjusted mappings
     662                 :        4216 :   std::vector<SubstitutionArg> adjusted_mappings;
     663                 :        9749 :   for (size_t i = 0; i < gargs.get_mappings ().size (); i++)
     664                 :             :     {
     665                 :        5533 :       auto &mapping = gargs.get_mappings ().at (i);
     666                 :             : 
     667                 :        5533 :       bool is_implicit_self = i == 0;
     668                 :        5533 :       TyTy::BaseType *argument
     669                 :        5533 :         = is_implicit_self ? receiver->clone () : mapping.get_tyty ();
     670                 :             : 
     671                 :        5533 :       SubstitutionArg arg (mapping.get_param_mapping (), argument);
     672                 :        5533 :       adjusted_mappings.push_back (std::move (arg));
     673                 :             :     }
     674                 :             : 
     675                 :        4216 :   SubstitutionArgumentMappings adjusted (adjusted_mappings, {},
     676                 :             :                                          gargs.get_regions (),
     677                 :             :                                          gargs.get_locus (),
     678                 :        4216 :                                          gargs.get_subst_cb (),
     679                 :        4216 :                                          true /* trait-mode-flag */);
     680                 :        4216 :   return Resolver::SubstMapperInternal::Resolve (trait_item_tyty, adjusted);
     681                 :        4216 : }
     682                 :             : bool
     683                 :      105025 : TypeBoundPredicate::is_error () const
     684                 :             : {
     685                 :      105025 :   auto context = Resolver::TypeCheckContext::get ();
     686                 :             : 
     687                 :      105025 :   Resolver::TraitReference *ref = nullptr;
     688                 :      105025 :   bool ok = context->lookup_trait_reference (reference, &ref);
     689                 :             : 
     690                 :      105025 :   return !ok || error_flag;
     691                 :             : }
     692                 :             : 
     693                 :             : BaseType *
     694                 :       28905 : TypeBoundPredicate::handle_substitions (
     695                 :             :   SubstitutionArgumentMappings &subst_mappings)
     696                 :             : {
     697                 :       60668 :   for (auto &sub : get_substs ())
     698                 :             :     {
     699                 :       31763 :       if (sub.get_param_ty () == nullptr)
     700                 :           0 :         continue;
     701                 :             : 
     702                 :       31763 :       ParamType *p = sub.get_param_ty ();
     703                 :       31763 :       BaseType *r = p->resolve ();
     704                 :       31763 :       BaseType *s = Resolver::SubstMapperInternal::Resolve (r, subst_mappings);
     705                 :             : 
     706                 :       31763 :       p->set_ty_ref (s->get_ty_ref ());
     707                 :             :     }
     708                 :             : 
     709                 :             :   // associated argument mappings
     710                 :       28931 :   for (auto &it : subst_mappings.get_binding_args ())
     711                 :             :     {
     712                 :          26 :       std::string identifier = it.first;
     713                 :          26 :       TyTy::BaseType *type = it.second;
     714                 :             : 
     715                 :          26 :       TypeBoundPredicateItem item = lookup_associated_item (identifier);
     716                 :          26 :       if (!item.is_error ())
     717                 :             :         {
     718                 :           0 :           const auto item_ref = item.get_raw_item ();
     719                 :           0 :           item_ref->associated_type_set (type);
     720                 :             :         }
     721                 :          26 :     }
     722                 :             : 
     723                 :             :   // FIXME more error handling at some point
     724                 :             :   // used_arguments = subst_mappings;
     725                 :             :   // error_flag |= used_arguments.is_error ();
     726                 :             : 
     727                 :       28905 :   return nullptr;
     728                 :             : }
     729                 :             : 
     730                 :             : bool
     731                 :         484 : TypeBoundPredicate::requires_generic_args () const
     732                 :             : {
     733                 :         484 :   if (is_error ())
     734                 :             :     return false;
     735                 :             : 
     736                 :         484 :   return substitutions.size () > 1;
     737                 :             : }
     738                 :             : 
     739                 :             : bool
     740                 :           0 : TypeBoundPredicate::contains_associated_types () const
     741                 :             : {
     742                 :           0 :   return get_num_associated_bindings () > 0;
     743                 :             : }
     744                 :             : 
     745                 :             : size_t
     746                 :         118 : TypeBoundPredicate::get_num_associated_bindings () const
     747                 :             : {
     748                 :         118 :   size_t count = 0;
     749                 :         118 :   auto trait_ref = get ();
     750                 :         354 :   for (const auto &trait_item : trait_ref->get_trait_items ())
     751                 :             :     {
     752                 :         236 :       bool is_associated_type
     753                 :         236 :         = trait_item.get_trait_item_type ()
     754                 :         236 :           == Resolver::TraitItemReference::TraitItemType::TYPE;
     755                 :         236 :       if (is_associated_type)
     756                 :         118 :         count++;
     757                 :             :     }
     758                 :         118 :   return count;
     759                 :             : }
     760                 :             : 
     761                 :             : TypeBoundPredicateItem
     762                 :          59 : TypeBoundPredicate::lookup_associated_type (const std::string &search)
     763                 :             : {
     764                 :          59 :   TypeBoundPredicateItem item = lookup_associated_item (search);
     765                 :             : 
     766                 :             :   // only need to check that it is infact an associated type because other
     767                 :             :   // wise if it was not found it will just be an error node anyway
     768                 :          59 :   if (!item.is_error ())
     769                 :             :     {
     770                 :          59 :       const auto raw = item.get_raw_item ();
     771                 :          59 :       if (raw->get_trait_item_type ()
     772                 :             :           != Resolver::TraitItemReference::TraitItemType::TYPE)
     773                 :           0 :         return TypeBoundPredicateItem::error ();
     774                 :             :     }
     775                 :          59 :   return item;
     776                 :          59 : }
     777                 :             : 
     778                 :             : std::vector<TypeBoundPredicateItem>
     779                 :           0 : TypeBoundPredicate::get_associated_type_items ()
     780                 :             : {
     781                 :           0 :   std::vector<TypeBoundPredicateItem> items;
     782                 :           0 :   auto trait_ref = get ();
     783                 :           0 :   for (const auto &trait_item : trait_ref->get_trait_items ())
     784                 :             :     {
     785                 :           0 :       bool is_associated_type
     786                 :           0 :         = trait_item.get_trait_item_type ()
     787                 :           0 :           == Resolver::TraitItemReference::TraitItemType::TYPE;
     788                 :           0 :       if (is_associated_type)
     789                 :             :         {
     790                 :           0 :           TypeBoundPredicateItem item (*this, &trait_item);
     791                 :           0 :           items.push_back (std::move (item));
     792                 :           0 :         }
     793                 :             :     }
     794                 :           0 :   return items;
     795                 :             : }
     796                 :             : 
     797                 :             : bool
     798                 :       18035 : TypeBoundPredicate::is_equal (const TypeBoundPredicate &other) const
     799                 :             : {
     800                 :             :   // check they match the same trait reference
     801                 :       34777 :   if (reference != other.reference)
     802                 :             :     return false;
     803                 :             : 
     804                 :             :   // check that the generics match
     805                 :        1323 :   if (get_num_substitutions () != other.get_num_substitutions ())
     806                 :             :     return false;
     807                 :             : 
     808                 :             :   // then match the generics applied
     809                 :        3138 :   for (size_t i = 0; i < get_num_substitutions (); i++)
     810                 :             :     {
     811                 :        1845 :       const SubstitutionParamMapping &a = substitutions.at (i);
     812                 :        1845 :       const SubstitutionParamMapping &b = other.substitutions.at (i);
     813                 :             : 
     814                 :        1845 :       const ParamType *ap = a.get_param_ty ();
     815                 :        1845 :       const ParamType *bp = b.get_param_ty ();
     816                 :             : 
     817                 :        1845 :       const BaseType *apd = ap->destructure ();
     818                 :        1845 :       const BaseType *bpd = bp->destructure ();
     819                 :             : 
     820                 :             :       // FIXME use the unify_and infer inteface or try coerce
     821                 :        1845 :       if (!apd->can_eq (bpd, false /*emit_errors*/))
     822                 :             :         {
     823                 :         456 :           if (!bpd->can_eq (apd, false /*emit_errors*/))
     824                 :             :             return false;
     825                 :             :         }
     826                 :             :     }
     827                 :             : 
     828                 :             :   return true;
     829                 :             : }
     830                 :             : 
     831                 :             : bool
     832                 :        7002 : TypeBoundPredicate::validate_type_implements_super_traits (
     833                 :             :   TyTy::BaseType &self, HIR::Type &impl_type, HIR::Type &trait) const
     834                 :             : {
     835                 :        7002 :   if (get_polarity () != BoundPolarity::RegularBound)
     836                 :             :     return true;
     837                 :             : 
     838                 :        6992 :   auto &ptref = *get ();
     839                 :       10047 :   for (auto &super : super_traits)
     840                 :             :     {
     841                 :        3057 :       if (super.get_polarity () != BoundPolarity::RegularBound)
     842                 :           0 :         continue;
     843                 :             : 
     844                 :        3057 :       if (!super.validate_type_implements_this (self, impl_type, trait))
     845                 :             :         {
     846                 :           2 :           auto &sptref = *super.get ();
     847                 :             : 
     848                 :             :           // emit error
     849                 :           2 :           std::string fixit1
     850                 :           2 :             = "required by this bound in: " + ptref.get_name ();
     851                 :           4 :           std::string fixit2 = "the trait " + sptref.get_name ()
     852                 :           4 :                                + " is not implemented for "
     853                 :           4 :                                + impl_type.as_string ();
     854                 :             : 
     855                 :           2 :           rich_location r (line_table, trait.get_locus ());
     856                 :           2 :           r.add_fixit_insert_after (super.get_locus (), fixit1.c_str ());
     857                 :           2 :           r.add_fixit_insert_after (trait.get_locus (), fixit2.c_str ());
     858                 :           2 :           rust_error_at (r, ErrorCode::E0277,
     859                 :             :                          "the trait bound %<%s: %s%> is not satisfied",
     860                 :           4 :                          impl_type.as_string ().c_str (),
     861                 :           2 :                          sptref.get_name ().c_str ());
     862                 :             : 
     863                 :           2 :           return false;
     864                 :           2 :         }
     865                 :             : 
     866                 :        3055 :       if (!super.validate_type_implements_super_traits (self, impl_type, trait))
     867                 :             :         return false;
     868                 :             :     }
     869                 :             : 
     870                 :             :   return true;
     871                 :             : }
     872                 :             : 
     873                 :             : bool
     874                 :        3057 : TypeBoundPredicate::validate_type_implements_this (TyTy::BaseType &self,
     875                 :             :                                                    HIR::Type &impl_type,
     876                 :             :                                                    HIR::Type &trait) const
     877                 :             : {
     878                 :        3057 :   const auto &ptref = *get ();
     879                 :        3057 :   auto probed_bounds = Resolver::TypeBoundsProbe::Probe (&self);
     880                 :       12525 :   for (auto &elem : probed_bounds)
     881                 :             :     {
     882                 :       12523 :       auto &tref = *(elem.first);
     883                 :       12523 :       if (ptref.is_equal (tref))
     884                 :        3057 :         return true;
     885                 :             :     }
     886                 :             : 
     887                 :             :   return false;
     888                 :        3057 : }
     889                 :             : 
     890                 :             : // trait item reference
     891                 :             : 
     892                 :             : const Resolver::TraitItemReference *
     893                 :       27328 : TypeBoundPredicateItem::get_raw_item () const
     894                 :             : {
     895                 :       27328 :   return trait_item_ref;
     896                 :             : }
     897                 :             : 
     898                 :             : bool
     899                 :           0 : TypeBoundPredicateItem::needs_implementation () const
     900                 :             : {
     901                 :           0 :   return !get_raw_item ()->is_optional ();
     902                 :             : }
     903                 :             : 
     904                 :             : location_t
     905                 :           6 : TypeBoundPredicateItem::get_locus () const
     906                 :             : {
     907                 :           6 :   return get_raw_item ()->get_locus ();
     908                 :             : }
     909                 :             : 
     910                 :             : // TypeBoundsMappings
     911                 :             : 
     912                 :    34141542 : TypeBoundsMappings::TypeBoundsMappings (
     913                 :    34141542 :   std::vector<TypeBoundPredicate> specified_bounds)
     914                 :    34141542 :   : specified_bounds (specified_bounds)
     915                 :    34141542 : {}
     916                 :             : 
     917                 :             : std::vector<TypeBoundPredicate> &
     918                 :       35874 : TypeBoundsMappings::get_specified_bounds ()
     919                 :             : {
     920                 :       35874 :   return specified_bounds;
     921                 :             : }
     922                 :             : 
     923                 :             : const std::vector<TypeBoundPredicate> &
     924                 :    32996630 : TypeBoundsMappings::get_specified_bounds () const
     925                 :             : {
     926                 :    32996630 :   return specified_bounds;
     927                 :             : }
     928                 :             : 
     929                 :             : TypeBoundPredicate
     930                 :        1647 : TypeBoundsMappings::lookup_predicate (DefId id)
     931                 :             : {
     932                 :        1857 :   for (auto &b : specified_bounds)
     933                 :             :     {
     934                 :        2049 :       if (b.get_id () == id)
     935                 :        1629 :         return b;
     936                 :             :     }
     937                 :          18 :   return TypeBoundPredicate::error ();
     938                 :             : }
     939                 :             : 
     940                 :             : size_t
     941                 :      158242 : TypeBoundsMappings::num_specified_bounds () const
     942                 :             : {
     943                 :      158242 :   return specified_bounds.size ();
     944                 :             : }
     945                 :             : 
     946                 :             : std::string
     947                 :       29302 : TypeBoundsMappings::raw_bounds_as_string () const
     948                 :             : {
     949                 :       29302 :   std::string buf;
     950                 :       30193 :   for (size_t i = 0; i < specified_bounds.size (); i++)
     951                 :             :     {
     952                 :         891 :       const TypeBoundPredicate &b = specified_bounds.at (i);
     953                 :         891 :       bool has_next = (i + 1) < specified_bounds.size ();
     954                 :        3540 :       buf += b.as_string () + (has_next ? " + " : "");
     955                 :             :     }
     956                 :       29302 :   return buf;
     957                 :             : }
     958                 :             : 
     959                 :             : std::string
     960                 :       28488 : TypeBoundsMappings::bounds_as_string () const
     961                 :             : {
     962                 :       56976 :   return "bounds:[" + raw_bounds_as_string () + "]";
     963                 :             : }
     964                 :             : 
     965                 :             : std::string
     966                 :        8331 : TypeBoundsMappings::raw_bounds_as_name () const
     967                 :             : {
     968                 :        8331 :   std::string buf;
     969                 :       16806 :   for (size_t i = 0; i < specified_bounds.size (); i++)
     970                 :             :     {
     971                 :        8475 :       const TypeBoundPredicate &b = specified_bounds.at (i);
     972                 :        8475 :       bool has_next = (i + 1) < specified_bounds.size ();
     973                 :       33716 :       buf += b.as_name () + (has_next ? " + " : "");
     974                 :             :     }
     975                 :             : 
     976                 :        8331 :   return buf;
     977                 :             : }
     978                 :             : 
     979                 :             : void
     980                 :       39289 : TypeBoundsMappings::add_bound (TypeBoundPredicate predicate)
     981                 :             : {
     982                 :       42820 :   for (auto &bound : specified_bounds)
     983                 :             :     {
     984                 :       17731 :       bool same_trait_ref_p = bound.get_id () == predicate.get_id ();
     985                 :        3531 :       if (same_trait_ref_p)
     986                 :       39289 :         return;
     987                 :             :     }
     988                 :             : 
     989                 :       25089 :   specified_bounds.push_back (predicate);
     990                 :             : }
     991                 :             : 
     992                 :             : } // namespace TyTy
     993                 :             : } // 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.