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