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